![]() | ||||||||||||||||||||||||||||||||||||||||
![]() | ||||||||||||||||||||||||||||||||||||||||
직렬통신 프로그래밍에서 아주 중요한 것은 장치 제어 블록 구조체 (Device-Control Block, DCB)를 설정하는 것이다. 직렬 통신 프로그래밍의 대부분의 공통적인 오류는 이것을 잘못 설정한 것에 기인한다. 직렬 통신이 원하는데로 잘 동작하지 않으면 DCB구조체가 잘되어 있는지 문제점을 찾아 본다. DCB구조체를 초기화 하는 방법은 3가지가 있다. 첫 번째 방법은 GetCommState펑션을 사용하는 방법으로 이 펑션은 통신 포트의 현재 DCB를 돌려준다. 다음 코드는 GetCommState펑션의 사용법을 보인다. | ||||||||||||||||||||||||||||||||||||||||
DCB dcb = {0}; if (!GetCommState(hComm, &dcb)) | ||||||||||||||||||||||||||||||||||||||||
두 번째 방법은 BuildCommDCB를 사용하여 DCB를 초기화 하는 방법이다. 이 펑션은 DCB에 통신 속도, 패리티 종류, 스톱 비트 수, 데이터 비트의 수를 채워준다. 흐름제어 항목들은 기본 값으로 설정한다. BuildCommDCB펑션의 흐름제어에 대한 기본 값은 BuildCommDCB펑션에 대한 설명 문서를 참조한다. DCB의 다른 항목들은 이 펑션에 의하여 영향받지 않으므로 프로그램짜는 것을 난잡하게 한다. 아래에 사용법에 대한 소스이다. | ||||||||||||||||||||||||||||||||||||||||
DCB dcb;
FillMemory(&dcb, sizeof(dcb), 0); | ||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||
세 번째 방법은 DCB 구조체를 수작업으로 하는 것이다. DCB구조체의 메모리 를 할당하고 각 항목들을 설정한다. 이 방법은 향후 DCB가 변경될 소지가 있으므로 Win32에서는 권장할 것이 못된다. 응용프로그램은 일반적으로 DCB의 항목을 실행 도중에라도 변경해야 할 필요가 있다.DCB 구조체의 멤버를 수정하여도 SetCommState를 호출하기 전까지는 아무런 효과가 없다. 여기 예제에는 현재의 DCB를 구하여 통신 속도를 변경하여 적용시키는 것이다. | ||||||||||||||||||||||||||||||||||||||||
DCB dcb; FillMemory(&dcb, sizeof(dcb), 0); // DCB 속도 갱신. // 새로운 상태로 설정 | ||||||||||||||||||||||||||||||||||||||||
여기에 DCB의 각 멤버가 어떠한 의미를 갖는지에 대한 설명이 있다. 주의사항 : 대부분의 정보는 Win32 SDK 문서에 있다. 이 표는 운영체제의 변경이 일어나면 예고없이 변경될 수 있다. | ||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||
Member Description | ||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||
DTR_CONTROL_DISABLE 장치를 열었을 때 DTR 라인을 저위로 한다. 응용프로그램은 EscapeCommFunction으로 조정할 수 있다. DTR_CONTROL_ENABLE 장치를 열었을 때 DTR 라인을 고위로 한다. 응용프로그램은 EscapeCommFunction으로 조정할 수 있다. DTR_CONTROL_HANDSHAKE DTR 흐름제어 신호 변경 가능하도록 한다. 이 값이 사용되면 EscapeCommFunction으로 조정할 때 오류가 발생한다. | ||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||
RTS_CONTROL_DISABLE 장치가 열리면 RTS 라인은 저위가 된다. 응용프로그램은 EscapeCommFunction으로 조정할 수 있다. RTS_CONTROL_ENABLE 장치가 열리면 RTS 라인은 고위가 된다. 응용프로그램은 EscapeCommFunction으로 조정할 수 있다. RTS_CONTROL_HANDSHAKE RTS 흐름제어를 자동으로 하게 한다. 제어기는 입력 버퍼가 데이터를 받아들이기에 충분한 공간을 가지고 있을 때 RTS를 고위로 하고 DCE를 enabling한다. 입력 버퍼가 충분한 공간을 가지고 있지 않을 때 RTS라인을 저위로하고, 송신을 위해 DCE를 Prevening한다. 이 값을 사용하면 응용프로그램은 EscapeCommFunction으로 조정할 때 오류가 발생한다. RTS_CONTROL_TOGGLE 송신할 것이 있으면 RTS라인은 고위가 되고 송신이 모두 끝나면 RTS라인은 저위가 된다. 이 값을 사용하면 응용프로그램은 EscapeCommFunction으로 조정할 때 오류가 발생한다. 이 값은 윈도우 95에서 는 무시되어 RTS_CONTROL_ENABLE 지정한 상태가 된다. | ||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||
![]() | ||||||||||||||||||||||||||||||||||||||||
흐름제어는 직렬 통신에서 제공되는 메카니즘으로서 하나의 장치가 바쁘거나 어떤 이유로 인하여 어떤 통신도 불가능한 상태에 있는 동안에 통신을 억제하는 것이다. 거기에는 2가지 방식의 흐름제어가 있는데 하드웨어와 소프트웨어이다. 직렬 통신에서 공통적인 문제점은 쓰기 작업인데, 실질적으로 장치에 데이터 쓰기가 되지 않는 것이다. 흔히 프로그램에서 흐름제어에 대한 명시를 하지 않은 경우에 문제점이 있다. A close examination of the DCB structure reveals that one or more of the following members may be TRUE: fOutxCtsFlow, fOutxDsrFlow, or fOutX. Another mechanism to reveal that flow control is enabled is to call ClearCommError and examine the COMSTAT structure. It will reveal when transmission is suspended because of flow control. 흐름제어의 타입들을 설명하기에 앞서 이해를 돕기위한 설명을 하자면. 직렬 통신은 장치와 장치 사이에 있다. 전통적으로 그것들은 PC와 모뎀, PC와 프린터이다. PC는 데이터 터미널 장치(Data Terminal Equipment, DTE)라고 이 름이 붙고, DTE는 때로는 호스트라고도 한다. 모뎀이나 프린터 등은 데이터 통신 장치(Data Communications Equipment,DCE)라고 이름이 붙는다. DCE는 때론 장치(device)이다. | ||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||
하드웨어 흐름제어는 제어 라인에 전압을 이용하여 송신과 수신의 가능함을 제어하는 것이다. DTE와 DCE는 한 종류의 흐름 제어를 사용하여야만 한다. DCB 구초제에 흐름제어를 가능하도록 DTE에서만 세트하면 된다. 윈32에서는 DCE에 대한 흐름 제어를 하는 메카니즘을 제공하지 않는다. 장치에 있는 딥 스위치들을 이용한다거나 명령을 보낸다. 다음은 제어 라인, 흐름 제어 방향에 대하여 설명한다. | ||||||||||||||||||||||||||||||||||||||||
< 하드웨어 흐름제어 라인들 > | ||||||||||||||||||||||||||||||||||||||||
CTS(Clear To Send) : Output flow control | ||||||||||||||||||||||||||||||||||||||||
DCE는 데이터를 받을 수 있을 때 고위(high, 전압이 높음) 상태로 한다. | ||||||||||||||||||||||||||||||||||||||||
DSR(Data Set Ready) Output flow control | ||||||||||||||||||||||||||||||||||||||||
DCE 는 데이터를 수신할 수 있으면 고위로 한다. DCE 는 데이터를 수신할 수 없으면 저위로 한다. DCB의 fOutxDsrFlow 항목이 TRUE이면 DTE는 이 라인이 저위일 때 데이터를 보내지 않는다. | ||||||||||||||||||||||||||||||||||||||||
DSR(Data Set Ready) | ||||||||||||||||||||||||||||||||||||||||
DSR라인이 저위일 때 포트를 통해 들어온 데이터는 무시된다. DSR라인이 고위일 경우 도착한 데이터는 포트에 수신된다. | ||||||||||||||||||||||||||||||||||||||||
RTS (Ready To Send)Input flow control | ||||||||||||||||||||||||||||||||||||||||
RTS라인은 DTE에서 제어된다. DCB의 fRtsControl 항목이 RTS_CONTROL_HANDSHAKE로 되어 있을 때 흐름제어가 된다. 입력 버퍼가 데이터를 받기에 충분하면(적어도 버퍼의 절반이상이 비어야 한다) 장치 제어기는 RTS를 고위로 한다. 입력 버퍼가 데이터를 받기에 적으면(4분의 1보다 적게 버퍼가 비어 있는 경우) 장치 제어기는 RTS라인을 저위로 한다. | ||||||||||||||||||||||||||||||||||||||||
DTR(Data Terminal Ready)Input flow control | ||||||||||||||||||||||||||||||||||||||||
DTE에 의하여 DTR 라인이 제어된다. DCB의 fDtrControl항목이 DTR_CONTROL_HANDSHAKE로 설정되어 있다면 흐름제어가 사용된다.입력 버퍼가 충분하면(절반이상 비어있어야 함) 장치 제어기는 DTR라인을 고위로 한다. 만약 입력 버퍼가 작으면(4분의 1 이하만 비어 있는 경우)는 장치 제어기는 DTR를 저위로 한다. DCB의 fDtrControl 항목이 DTR_CONTROL_ENABLE 이나 DTR_CONTROL_DISABLE로 설정되어 있다면 응용프로그램은 이 라인의 상태를 필요에 따라 자유로이 변경할 수 있다. 이 경우 이 라인의 상태를 수신에 영향을 주지 않는다. 라인이 저위가 되면 DCE는 송신을 억제하고 라인이 고위가 되면 DCE는 송신을 계속한다. 흐름제어가 필요한 것은 CE_RXOVER 오류가 발생했을 때 쉽게 알아내기 위함이다. 이 오류는 수신 버퍼가 넘치고 데이터를 잃어 버렸다는 것을 나타낸다. 데이터를 읽는 것보다 빨리 수신되는 경우에 CE_RXOVER 가 발생할 수 있다. 수신 버퍼의 크기를 늘리는 것은 오류가 발생하는 빈도를 줄인다. 그러나 완벽하게 문제를 해결하는것이 아니다. 장치 제어기가 수신 버퍼가 이미 가득 찼다는 것을 검색하면 제어기는 입력 흐름 제어 라인들을 저위로 할 것이다. 이는 DCE로 하여금 송신을 멈추게 하고, DTE로 하여금 수신 버퍼에서 읽들일 시간을 준다. 수신 버퍼가 비게 되면 흐름제어 라인의 전압이 올라가서 DCE는 보내기를 계속한다. 이와 유사한 오류는 CE_OVERRUN이다. 이 오류는 새로운 데이터가 이전의 데이터 수신을 완료하기 전에 도착하였을 때 발생한다. 이 경우는 전송 속도가 통신 하드웨어나 CPU의 타입에 비해 너무 빠를 경우에 발생한다. 또한 운영체제가 통신 하드웨어를 서비스 하기에 바쁠 경우에도 발생한다. 이 문제점을 해결하는 방법은 통신 속도를 낮추거나 통신 하드웨어를 교체하거나 CPU의 속도를 증가시키는 방법이다. 때로는 (써드 파티)제3의 하드웨어 장치 제어기가 CPU와 매우 비능률적인 방법으로 동작하여 이런 오류가 발생하기도 한다. 흐름제어는 CE_OVERRUN 문제를 완벽하게 해결할 수는 없고 단지 발생 빈도를 줄이는 것이다. |
Software/Network