Q&A

  • [질문]시리얼(RS232) 통신관련, OPEN과 CLOSE시 에러가 납니다
안녕하십니까? 하나 문의 좀 드릴까 합니다.

TMS Async32 의 VaComm 를 가지고 시리얼 통신으로 open과 close를 빠르게 반복하다보면
메모리 에러가 발생합니다. 아래와 같은 내용인데요. open하고 난 후 데이타 처리하고 close할때까지 시간의 여유가 있으면
에러가 발생하지않는데요.

위의 것을 가지고 comport 를 자동확인하려고 하는데 총 컴퓨터에서 생성될 수 있는 comport 는 256개이기때문에..
256번을 open, close하면서 해당 comport의 상태를 확인합니다. 오픈될 경우 정상사용가능 comport로 보이고
오픈이 되지않을 경우는 표시를 해주지 않고 사용중인 경우는 사용중이라고 표시합니다.

256개를 체크를 하다보니 딜레이타임이 짧아야하는데요. open close를 0.5초 정도 딜레이를 줄 경우 128초가 걸립니다.
체크 하는것만 그렇게 걸리는것도 문제긴하지만.. 0.5초를 주던 길게 주던.. 간간히 메모리 에러가 발생한다는것입니다.

다른 시리얼통신 component(TApdComPort)를 사용하면 open close를 반복해도 발생하지않으나 시리얼케이블로
연결했을 경우는 정상적으로 되나 가끔 UsbToSerial로 연결했을 경우 데이타 처리가 되지않아 위의 VaComm으로 변경하니
시리얼케이블이든 UsbToSerial이든 모두 정상적으로 처리됩니다.

한데 위의 open, close시 에러가 발생해서요. 아마도 open과 close시 내부적으로 처리를 뭔가 하고 있는데
메모리 반납전에 다른처리가 들어오니 다 못처리해서 메모리 에러가 발생하는듯하는데요.

아래의 리플내용처럼.. 의 내용은 처리되어있습니다.
if not VaComm.Active then
    begin

1. TApdComPort component 로 시리얼통신시 시리얼케이블로 처리시는 모두 정상적으로 되나 UsbToSerial케이블 사용시
    정상적으로 데이타가 못넘어가는 현상이 가~~ 아끔 나타남(정상적으로 사용하다가 어쩌다가 발생)

2. TMS Async32 의 VaComm component 사용시 open, close를 빠른속도로 반복시 메모리 에러 발생.

일단 현재는 2번째 방법으로 처리하였으나 (comport 자동확인 기능 주석으로 빼버리고) open 후 close를 많이 반복하지않음
으로 하지만 사용하고 난후 프로그램을 종료때나 가끔 메모리 에러가 발생합니다.

고수분들의 주옥같은 말씀 부탁드립니다.

혹 위의 내용으로 문제를 겪어보시고 처리하신 분들의 조언 좀 부탁드리겠습니다.

아래는 다른분의 같은 내용이라 적어봅니다.
링크) http://www.delmadang.com/community/bbs_view.asp?bbsNo=17&indx=407323

델파이7, VaComm 컴퍼넌트를 이용해서
시리얼(RS232)통신 테스를 하고 있는데요,
OPEN과 CLOSE를 빠른 속도로 반복하다 보면,
System Error. Code: 5.        <-----    이런 에러가 납니다. ( 그리고 일정하지 않고 랜덤하게 발생 합니다. )

아래는 해당 자동 comport 확인 부분
===============================================================================
        //자동 Comport 확인
        VaComm.Baudrate := br9600;

        tmpString := ComboBox3.Text;
        ComboBox3.Clear;
        ComboBox1.Clear;

        ComboBox3.Text := tmpString;
        ComboBox1.Text := tmpString;

        for i:=1 to 256 do begin
            try
                VaComm.PortNum := i;
                VaComm.Open;

                ComboBox3.Items.Add('COM' + IntToStr(i));
                ComboBox1.Items.Add('COM' + IntToStr(i));
            except
                on E:Exception do
                begin
                    //if copy(E.Message,0,7) = 'ie_Open' then
                    if copy(E.Message,0,10) = 'Can''t open' then
                    begin
                        ComboBox3.Items.Add('COM' + IntToStr(i));
                        ComboBox1.Items.Add('COM' + IntToStr(i) + ' 사용중');
                    end;
                end;
            end;
            VaComm.Close;
        end;
2  COMMENTS
  • Profile
    바람 2009.08.07 23:43
    Serial Component를 잘 사용해 보지 않아서 에러 이유는 모르겠지만

    제가 기억하고 있는 MS-Dos System Error Code는

    2 = File Not Found.
    3 = Path Not Found.
    4 = Too many open files.
    5 = File access denied.
    6 = Invalid file handle.

    등의 의미인데 윈도에서도 같은의미가 아닐런지요.

  • Profile
    타마마 2009.08.12 00:36
    간단한 문제가 아니라 설명드리기 난해하긴 한데..
    해당 컴포넌트가 CreateFile을 사용했는가, DeviceIoControl을 사용했는가에 따라서 달라집니다.

    Api의 Open, Close가 리턴값을 반환하는지 모르겠지만, 일반적으로 GetLastError를 통해 Error처리를 반드시 해주어야 하며 API의 호출 결과에 따라 재시도 루틴도 추가되어야 합니다.

    또한 내부적으로는 Thread를 돌릴 수도 있기 때문에 동기화처리가 내부에 들어가 있다면 관련해서 외부에서 호출할 경우 Wait 타임도 고려해 주어야 합니다.

    일반적으로 300ms 정도를 할애합니다.

    Comport를 Open, 사용할 수 있는 상태가 되기 위해서 필요한 처리가 상당히 많습니다.

    쓰레드의 생성, CommTimeOuts 값을 설정하고 Port의 가비지 값을 Purge 하는 등 3rd party의 open 함수 내에서는 한꺼번에 처리하기 때문에 얼마나 많은 시간이 필요한 지 알 수 없습니다.

    특히 USB Comm Port의 경우 Driver를 하나 더 거치기 때문에 시간 딜레이가 더 걸립니다.

    결론은 DeviceIoControl 이나 CreateFile을 사용하시는 편이 나은 선택이 될 것 같습니다.

    보통 상업용에서는 DeviceIoControl이 더 좋습니다. (단순히 쿼리를 통해 포트의 상태를 알 수도 있습니다.)

    CreateFile은 내부적으로 DeviceIoControl을 호출하게 되어 있으므로 약간의 딜레이가 있을 수 있습니다.

    혹은, Registry를 직접 액세스하여 현재 장착된 장비들의 상태정보를 쿼리할 수 있습니다.
    • 하늘사랑
      2009.08.11 01:57
      문제 해결했습니다 모두 감사드립니다 ^^
    • 김동원
    • 2009.08.10 18:42
    • 2 COMMENTS
    • /
    • 0 LIKES
    • KDDG_Apine
      2009.08.12 04:04
      정확히 이해가 가지 않습니다. 프로시져는 반복문으로 처리 하기 위해 만드는 것이고 같은 것이라면 ...
    • 김동원
      2009.08.14 18:13
      답변 감사드립니다. 추후에 자세히 올리도록 하겠습니다.꾸벅
    • 백록화
      2009.08.11 01:13
      보기 를 할경우엔 줄바꿈이 그대로 보여지고... 검색해서 보여줄땐 줄바꿈이 없이 보여준다는 말씀이신...
    • 구창민
      2009.08.11 02:25
      안녕하세요.. 엄밀히 말하면 이미지를 넣는것이 아니고.. 포인터를 기억하는 것이겠지요.. 추가시는 ...
    • 이은주
      2009.08.11 19:38
      ^ 사용하지 않은 이런 형태로도 포인터를 기억하게 하는 것인가 보군요. 감사합니다.
    • 장용석
    • 2009.08.07 20:23
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 이정욱
      2009.08.07 21:03
      2007 입니다~ www.devtools.co.kr 로 문의 해보세요 ㅋ
    • 이정욱
      2009.08.07 21:03
      혹시나 새로 프로젝트를 하는거라면 당연히 2009 를 추천하구요... 2010도 좋다는 소문이 있습니다.
    • 이문배
    • 2009.08.07 20:06
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 바람
      2009.08.07 23:43
      Serial Component를 잘 사용해 보지 않아서 에러 이유는 모르겠지만 제가 기억하고 있는 MS-Dos S...
    • 타마마
      2009.08.12 00:36
      간단한 문제가 아니라 설명드리기 난해하긴 한데.. 해당 컴포넌트가 CreateFile을 사용했는가, DeviceIo...
    • 이경원
    • 2009.08.07 19:04
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 구창민
      2009.08.07 23:14
      except 구문속을 아래처럼 수정하시고, 에러 내용을 로그로 남겨 확인해보세요.. except on E : Ex...
    • 하늘사랑
      2009.08.07 03:31
      글올리고 하나보니.. 다시질문드릴께요 ㅠㅠ;; <p0 AVG="0.28"> 이부분에서 0.28 이란 값이없...
    • 하늘사랑
      2009.08.07 19:20
      에구.. 답글이 없내요 ㅠㅠ;; 그냥 except처리해버렸는뎅.. ㅠㅠ;; 또한가지 <p0 AVG="0.28"> ...
    • 구창민
      2009.08.07 23:21
      안녕하세요.. XMLDocument 를 사용하셨다 가정하구 말씀드릴께요~ p0 노드까지 구해내셨다면, 아래...
    • 하늘사랑
      2009.08.10 20:11
      답변 감사드립니다 ^^ 가져오는거 하고 수정하는것도 다 처리했습니다 ^^;;; 글을 늦게 봤내요 ㅠㅠ;;;...
    • 구창민
      2009.08.11 00:25
      안녕하세요.. 노드까지 찾으셨다면.. for 문은 사용하실 필요없고요.. 단순히 아래 문장을 호출 하시...
    • 하늘사랑
      2009.08.11 01:56
      답변감사합니다 ^^ 문제해결했습니다 정말 감사드립니다 ^^
    • 최용일
      2009.08.04 20:12
      WM_USER + 100로 검색해서 메세지핸들러를 찾으시고 디버깅을 해보세요. 쩝~ 질문하신것을 보니 책한권...
    • 초보자
      2009.08.04 22:09
      책을 보라면 API관련책을 말씀하시는건지요? 가르쳐주는 사람없이 혼자 해나가려니 힘이드네요~
    • 최용일
      2009.08.03 22:12
      기존 연결을 끊고 해보세요.
    • 델델
      2009.08.12 02:43
      myDB.Database1.KeepConnection :=false; 이 부분이 기존 연결을 끊는거 아닌가요? ㅠㅠ
    • 최용일
      2009.08.12 17:51
      전혀 아닌데요... Database1.Connected := False;
    • 오경용
      2009.07.30 10:26
      LongDateFormat := 'yyyy-MM-dd'; LongTimeFormat := 'hh:mm:ss'; ... ... if Fields[i].F...
    • 윤영훈
      2009.08.09 22:15
      오오- 감사합니다. TStringList로 자르고 오후가 나오면 +12하는 등으로 해서 복잡하게 만들었던 부분이...
    • 유경민
    • 2009.07.30 03:54
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 소울해커
      2009.08.05 18:40
      확인눌렀을때 위의 if문을 전부 확인할수 있게 하고 싶습니다. <-- 의미파악 불명 뭘 확인을 누...
    • 유경민
      2009.08.26 06:25
      ㅎㅎ 죄송해요 답변이 늦었죠 어떻게 쪼물딱 거리니 되더라고요 답변 감사합니다^^
    • 여운병
      2009.07.31 00:24
      어떤 오류인지 알아야 답변 가능할 것 같은데요? 소스코드라도...
    • 박찬석
      2009.07.31 00:55
      uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Men...
    • 여운병
      2009.07.31 01:42
      uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, M...
    • 소울해커
      2009.08.05 18:47
      델파이에서 필드를 불러올때 인덱스 값으로 불러오시면서 Suju 테이블의 필드 수를 초과해서 지정하신...
    • 유경민
    • 2009.07.29 11:43
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 소울해커
      2009.08.05 18:42
      전역 키보드 후킹에 대하여 공부하셔야 될 겁니다. 그런데 뭘 만드시기 위해 고런 형태가 필요하신지....
    • 유경민
      2009.08.07 01:26
      출결 프로그램 만들고 있습니다. 컴퓨터가 2대면 상관없는대 출결프로그램 구동시 다른작업을 할수 없기...
    • 임대순
      2009.07.27 23:37
      흠...레코드카운더면 될꺼 같은데요...이상 초보의 답변있었습니다.
    • 백록화
      2009.07.28 20:45
      A로 시작하는거 Select 회원코드필드 from tbl_name where 회원코드필드 like 'A%'; max 함수로 ...
    • 정락문
      2009.07.28 22:22
      백록화님이 하신 것 처럼... 모방을 하면 조건절에 이렇게 들어가도 될 듯 해요. Select 회원코드필드 ...
    • phono
      2009.07.29 07:30
      일단 파이어버드는 인터베이스랑 거의 같은 sql을 쓸텐데.. , 일단 지금 제가 사용하고 있는 db가 ms-...
    • 윤영훈
      2009.07.29 19:02
      사실은 방법을 못찾다가 A, B, C를 구분하는 새로운 필드를 하나 더 만들어서 검색하고 있었는데, 좋은 ...
    • 얼씨구
    • 2009.07.25 19:47
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 정락문
      2009.07.28 22:29
      델파이 코딩으로 하려면, 제일 단순한 방법은 2개의 DB에 접근해서 처리하는 거죵. 1. 10분 주기로 프...