시리얼 통신 타임아웃 설정 [Win] COMMTIMEOUTS

Posted by 빵빵빵
2009/12/30 22:19 전산(컴퓨터)/PC-Windows



타임아웃

통신 제어 프로그램은 상대 장치의 상태에 따라 통신이 도중에 끊어질 수 있다.
만약 100바이트가 올것이 데이터 수신 중에 송신 쪽의 문제로 80바이트만 송신한 경우
수신을 도중에 멈추고 알람을 표시할 필요가 있다.
타이머는 이런 목적으로 사용한다.

타이머의 설정은 SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts)
를사용하고 설정된 데이터를 읽을 때는 GetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts)를 사용한다.


SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts)


인수
hFile :
CreateFile()이 반환한 핸들

lpCommTimeouts :
타이머의 값이 들어있는 COMMTIMEOUTS 구조체의 포인터

반환값
함수가 성공하면 0이 아니고 실패하면 0

typedef struct _COMMTIMEOUTS{
  DWORD ReadIntervalTimeout;
  DWORD ReadTotalTimeoutMultiplier;
  DWORD ReadTotalTimeoutConstant;
  DWORD WriteTotalTimeoutMultiplier;
  DWORD WriteTotalTimeoutConstant;
}COMMTIMEOUTS、*LPCOMMTIMEOUTS;

ReadIntervalTimeout
데이터를 수신할 때 한문자를 수신한 후 다음 문자를 수신할 때까지의 대기 시간으로
밀리초 단위로 설장한다. 이 대기 시간 만큼 기다린 후 입력이 없을 경우 수신한 데이터를
반환한다.

이 값이 0인 경우, 타이머는 사용하지 않는다.
이 값이 MAXDWORD로 ReadTotalTimeoutMultiplier와 ReadTotalTimeoutConstant가
0인 경우 지정한 수신 수를 수신 전이라도 읽기 작업에서 빠져서 수신 데이터를 반환한다.


ReadTotalTimeoutMultiplier
읽기 작업을 위한 토탈 타임아웃 시간을 계산하기 위한 밀리초 단위의 곱하기 계수를 지정한다.

ReadTotalTimeoutConstant
읽기 작업을 위한 토탈 타임아웃 시간을 계산하기 위한 밀리 초 단위로 지정하는 정수로
사용된다.

ReadTotalTimeoutMultiplier와 ReadTotalTimeoutConstant는 읽기 작업에 걸리는
총시간을 설정하는 변수들로 이 두변수가 0인 경우 읽기 작업에는
토탈 타임아웃 타이머가 사용하지 않는다.


WriteTotalTimeoutMultiplier
쓰기  작업을 위한 토탈 타임아웃 시간을 계산하기 위한 밀리초 단위의 곱하기 계수를 지정한다.

WriteTotalTimeoutConstant
쓰기 작업을 위한 토탈 타임아웃 시간을 계산하기 위한 밀리 초 단위로 지정하는 정수로
사용된다.

WriteTotalTimeoutMultiplier와 WriteTotalTimeoutConstant는 쓰기 작업에 걸리는
총시간을 설정하는 변수들로 이 두변수가 0인 경우 쓰기 작업에는
토탈 타임아웃 타이머가 사용하지 않는다.



어플리케이션이 ReadIntervalTimeout과 ReadTotalTimeoutMultilier를 MAXDWORD로 설정하고
MAXDWORD > ReadTotalTimeoutConstant > 0으로 설정하면
ReadFile함수가 사용될 때 아래와 같이 된다.

- 입력 버퍼에 수신 데이터가 있으면 ReadFile은 바로 버퍼의 문자를 반환한다.
- 입력 버퍼에 수신 데이터가 없으면 ReadFile은 수신할 때까지 기다렸다가 반환한다.
- ReadTotalTimeoutConstant에 의해 지정된 시간 이내에 1바이트라도 수신하지 않으면
  ReadFile은 타임아웃이 된다.

타이머의 시간 설정
구체적으로 어떻게 타이머의 시간을 설정하면 좋을까?
COMMTIMEOUTS 구조체의 변수를 보면 알 수 있는 것처럼 감시하는 대상은 2종류가 있다.
하나는 인터벌 시간이고 다른 하나는 토탈 시간이다.
인터벌 시간은 수신할 데이터 별로 타이머 감시를 하기 위한 것이기 때문에
예를들면 9600bps로 수신할 경우 1케릭터는 1ms정도이기 때문에 여유를 봐서
10ms이면 충분하다. (단 상대가 연속해서 데이터를 송신하는 경우이다.)
토털 시간은 이하의 계산식으로 계산된다. 이 두개의 감시시간을 넘으면 타임아웃이 발생한다.
타임아웃의 결과 수신 동작이나 송신 동자은 도중에 중단되고 수신일 때는
타임아웃이 발생한 시점까지의 데이터를 읽는다.

수신 
ReadIntervalTimeout은 다음에 수신할 때 까지의 최대 대기 시간을 msec로 지정한다.
ReadTotalTimeoutMuliplier와 ReadTotalTimeoutConstant로 수신 토탈 시간을
이하의 식으로 계산한다.

수신 인터벌 시간 = ReadIntervalTimeout(msec)
수신 토탈 시간 =
(ReadTotalTimeoutMuliplier * 수신할 Byte수) + ReadTotalTimeoutConstant(msec)

송신 
송신에는 데이터 간격 타이머는 없다.
WriteTotalTimeoutMuliplier와 WriteTotalTimeoutConstant로 송신 토탈 시간을
이하의 식으로 계산한다.

송신 토탈 시간 =
(WriteTotalTimeoutMuliplier * 송신할 Byte수) + WriteTotalTimeoutConstant(msec)

2009/12/30 22:19 2009/12/30 22:19

GTX 정말 하게 될까?

Posted by 빵빵빵
2009/12/18 17:58 경제



GTX 대 도심 지하도로
 2009-12-18 16:17:01

 오세훈 서울시장과 김문수 경기도지사는 서울 및 수도권 지하철보다 40~60m깊은 깊이에 길을 내는 소위 `대심도 교통망`을 추진하고 있다.

경기도는 지난 4월 경기도와 서울을 연결하는 수도권 광역급행철도(GTX) 추진 계획을 발표했으며 서울시는 지난 8월 지하도로(U-smart way) 건설 구상을 밝혔다. 경기도의 GTX와 서울시의 지하도로 차이점을 살펴본다.

◇ 오세훈·김문수, 지하도로·GTX 놓고 `맞대결`

경기도가 추진 중인 GTX노선은 고양 킨텍스~동탄신도시(74.8㎞), 의정부~군포 금정(49.3㎞), 청량리~인천 송도(49.9㎞) 등 3개 노선으로 구성된다. GTX가 개통되면 강남과 일산을 20분대에 오가는 등 경기도에서 서울로의 접근성이 크게 개선될 것으로 경기도는 기대하고 있다.

경기도는 GTX 사업안을 지난 4월 국토해양부에 제안했다. 국토부는 현재 교통연구원에 의뢰, GTX의 경제적 타당성 등을 검토 중이다. 사업 추진 여부는 내년 초에 결정될 전망이다.

서울시는 도심을 남·북간 3개축 동·서간 3개축의 총 6개 노선으로 구성해 서울의 땅밑을 거미줄처럼 잇는 지하도로망을 2020년까지 완공하는 것을 목표로 하고 있다. 남북 3개축 노선은 ▲시흥~도심~은평 ▲양재~한남~도봉 ▲세곡~성수~상계 노선이다. 동서 3개축 노선은 ▲상암~도심~중랑 ▲신월~도심~강동 ▲강서~서초~방이 노선이다.

서울시는 지하도로망이 구축되면 서울 전역을 30분대에 이동할 수 있을 뿐 아니라 지상교통량의 21%가 지하도로망으로 흡수돼 지상도로의 통행속도도 8.4km 증가할 것으로 기대하고 있다.

서울시는 지하도로 6개 노선 중 민자방식으로 추진되는 4개 노선(동서 1·2축 남북 1·2축)의 경우 2011년 발주, 2014년 착공한다는 계획이다. 재정사업으로 건설되는 동부간선 지하화 구간(남북 3축)도 이르면 2011년 발주할 예정이다.

◇ 천문학적인 공사비용 `부담`

경기도는 GTX사업을 재정사업으로 추진하면 13조9039억원, 민자사업일 경우에는 11조1231억원의 재원이 필요할 것으로 추산하고 있다. 재정사업은 지자체가 2조7808억원(사업비의 20%)를 조달해야 하지만 민자사업은 7897억원(사업비의 7.1%)만 지자체가 분담하면 된다.

문제는 추후 공사비가 늘어날 가능성이 높다는 점. 소음·진동을 줄이고 공사 안전성 확보를 위해 기계굴착방식을 적용할 계획이다. 일반적인 발파공법(NATM)에 비해 기계굴착공법(TBM)은 장비가 고가인 데다 가동율이 떨어질 경우 공사비 상승이 불가피하다.

서울시의 지하도로에는 11조2000억원이 투입될 예정이다. 서울시는 동부간선도로 지하화 사업의 경우 공적자금을 투입해 건설하고 나머지는 민간자본 유치를 통해 해결한다는 방침이다. 하지만 1개 노선별로 2조원 안팎의 막대한 자금이 들고 사업성도 불투명해 참여 건설사들이 많지 않을 것이라는 게 업계의 시각이다.

경기도의 GTX와 서울시의 지하도로 모두 사업에 앞서 선결해야 할 문제들이 적지 않다.
GTX와 지하도로 모두 지하 40~60m에 건설되는 만큼 환·배기 시스템, 방재 시스템을 충분히 갖춰야 한다.

사업의 경제성도 논란거리다. 지하 깊숙한 곳에 교통망을 구축하면 공사 비용의 상당 부분을 차지하는 토지보상비가 들지 않는 장점이 있다. 대신 지하로 가면 공사비가 늘어나고 안전시설을 구축하는 비용이 추가로 필요한 만큼 경제성을 잘 따져봐야 한다는 지적이다.

 
 

사용자 삽입 이미지


2009/12/18 17:58 2009/12/18 17:58

sprintf & strncpy 와 sprintf_s & strncpy_s 의 차이점???

Posted by 빵빵빵
2009/12/11 15:49 전산(컴퓨터)/PC-Windows



2008-04-01-마술감자 명국진 (http://magicpotato.com http://xyz2.net)

원문 : http://xyz2.net/bbs/zboard.php?id=notes&no=76


strncpy()는 복사되었으면 하는 문자열의 길이를 넘어서지 않게 복사해 준다.
그리고 대상 버퍼를 넘어서게 되면 NULL로 끝나지 않는 문자열까지 복사하게 된다. 예를 들면 아래와 같다.



strncpy_s() 는 대상 버퍼가 실제 수용가능한 크기와 복사되었으면 하는 문자열의 길이 두가지를 넘긴다.
strncpy()와 strncpy_s()의 다른점이 있다면 strncpy_s()는 '복사 되었으면 하는 문자열의 길이'를 넘어서서 복사를 할 때 마지막을 항상 NULL로 끝나게 해준다는 점이다.

다음과 같은 코드는 런타임 에러를 발생시킨다.



따라서 strncpy_s()를 사용할 때는 버퍼 크기와, 복사하고 싶은 길이를 다르게 주어야 한다.




참고.

strcpy_s()를 사용하면 버퍼 크기를 넘어서는 데이터를 넘을 때
자동으로 막아준다고 착각하는 경우가 있다. (strncpy처럼)

strcpy_s()에 넘기는 2번째 인자인 dest_size는 '내가 이 정도까지만 복사하고싶다'의 의미가 아니라
'여기 지정한 크기를 넘어서 복사하려고 하면 프로그램을 멈추고 에러창을 띄워라' 의 의미로 보아야 한다.



연장해서 sprintf_s() 와 _snprintf_s() 에도 똑같이 적용된다.




* gpg의 비회원님의 내용 추가 - 보충 감사드립니다.

strncpy_s(), _snprintf_s() 함수의 복사하고 싶은 길이(size_t count)에 _TRUNCATE 를 넣으면

수용가능한 버퍼 크기(size_t sizeOfBuffer)에 지정한 값 -1 을 넣은것과 같게 동작한다.

다음 두개의 코드는 결과가 같다.



** _TRUNCATE와 관련한 버그 안내 (2008-04-02, VS2005 VC8.0.50727.762 - SP.050727.7600 기준)

다음 프로토타입을 갖는 함수에는 count에 _TRUNCATE를 사용해도 된다.
int _snprintf_s( char *buffer, size_t sizeOfBuffer, size_t count, const char *format [, argument] ... );

다음 프로토타입을 갖는 함수의 count에 _TRUNCATE를 사용하면 스택이 깨진다.
// C++ only
template <size_t> int _snprintf_s( char (&buffer)[size], size_t count, const char *format [, argument] ... ); 

템플릿버전에서는 내부적으로 매크로를 사용하고 있는데 sizeOfBuffer와 count값 두가지가 모두 -1 로 넘어가면서 코드 내부적으로 buffer[(size_t)-1] = NULL; 이라는 코드를 실행하면서 잘못된 메모리를 쓰게 된다.



** 티벳의 독립을 지지하는 아이스닥님이 알려주신 버그 수정법

CRTDEFS.h 파일 열어서
모든 _Size를 _SUCKS_MS_BUG_Size 등 다른 이름으로 수정하면 된다. (원작자 표현 존중)

다만, 자기 컴퓨터의 버그만 고쳐지는 것이므로 되도록 혼자 작업하는게 아니라면 우회해서 사용하는것이 좋겠다.


- 버그내용 설명
stdio.h의 매크로 선언부와 crtdefs.h의 매크로 내용 정의부의 인자이름 _Size가 서로 겹쳐서 발생하는 버그라고 한다.


2009/12/11 15:49 2009/12/11 15:49