tcp/ip 통신이라면 프로토콜 자체네서 에러처리를 하고 있어서, 설령 랜케이블이 불량하더라도
체크썸을 통해 데이타 요구를 내부적으로 다시하는 식이라 데이타의 무결성을 보장받을 수 있지만
시리얼통신은 단순히 보내고 받는 형태라 데이타의 무결성을 보장 못합니다.
시리얼통신을 안전하게 데이타의 무결성을 보장받도록 하려면
보내고 받는 데이타에 체크썸 데이타를 같이 넣어서, 체크썸 결과가 정상인지 확인해서
비정상이면 데이타 요구를 다시 retry 하는 식으로 일종의 에러체크 레이어를 덧씌워줘야 합니다.
더 나아가서 retry를 줄이고 안정성을 위해선 rx/tx/ground 3선 케이블 방식을 사용하지 말고
하드웨어적인 핸드쉐이킹이 먹히도록 full cable 연결방식을 쓰고, 시리얼칩을 콘트롤 할 때도
하드웨어적인 핸드쉐이킹이 먹히도록 칩을 프로그래밍 해줘야 합니다.
이렇게 해줘야 rts/cts 같은 하드웨어적 핸드쉐이킹 기능이 동작하게 됩니다.
돌맹이 님이 쓰신 글 :
: 환경: C++ Builder XE5 + AsyncPro V4.07
:
: 10분에 한 번씩 PC에서 장비로 데이터를 요청하고, 장비가 응답하는 데이터를 가공 처리하는
: 프로그램입니다.
:
: 잘 돌다가 간혹 이상하게 동작하는데요..
: PC에서 데이터 요청 패킷을 보내면 응답 데이터가 길어서 7번에 걸쳐서 수신하게 되는데요(9600bps)
: 가끔 6번만 수신되고, 7번재 데이터는 10분 뒤에 데이터 요청 패킷을 보내면 그 때 수신됩니다.
: 도식화 하면 아래와 같은데요..
:
:
// 이는 정상 동작 --------------------------------------------
: PC <--------> 장비
: 요청1 ------->
: <------- 응답 1
: <------- 응답 2
: <------- ...
: <------- 응답 6
: <------- 응답 7
: ...
: // 10분 후
: 요청1 ------->
: <------- 응답 1
: <------- 응답 2
: <------- ...
: <------- 응답 6
: <------- 응답 7
:
: // 이상 동작 할 때 -----------------------------------------
:
: PC <--------> 장비
: 요청1 ------->
: <------- 응답 1
: <------- 응답 2
: <------- ...
: <------- 응답 6
: // 응답 7이 없음.. ...
: ..
: // 10분 후
: PC <--------> 장비
: 요청1 ------->
: <------- 응답 7 // 10분 전에 장비가 보낸 데이터가 지금 수신 됨.
: <------- 응답 1
: <------- 응답 2
: <------- ...
: <------- 응답 6
: <------- 응답 7
: ...
:
: 즉 10분 후에 수신 한 데이터가 10분 전 데이터의 끝부분을 가지고 있는데요..
: 3~4일에 한 두 건 발생할까말까하는 증상인데.. 계속 운영되다 보니 계속 찜찜하네요.
: 어떻게 해야 할 지..
:
: 한가지 좀 찜찜한 것은 통신 소켓에서 특정 수신 데이터를 받으면,
: 이 때 Serial Port에서 데이터를 요청을 하는데요,
:
: 통신 소켓 이벤트에서 Serial Port에 데이터를 보내고,
: MsgWaitForMultipleObjectsEx()를 써서 5초 동안 기다립니다.
: 5초 동안 AsycnPro Component에서 장비의 데이터를 받아서 처리할 시간을 준 것입니다.
: 7번 수신되는 시간은 모두 1초 안쪽입니다. 즉, 5초의 시간이면 충분하다는 것이지요.
:
: 그 5초 동안 AsycnPro는 수신 이벤트를 7번 받아서 위와 같이 처리하는데요..
: MsgWaitForMultipleObjectsEx()를 써서 윈도우 메세지는 처리하면서 5초 동안 기다리게 했는데,
: 이 부분에서 뭔가 문제가 있지나 않나 하는 생각입니다. 이 부분의 코드는 아래와 같습니다.
: 이 코드는 구굴링하다가 얻은 것인데.. 게시판에서는 잘 동작하는 것으로 나와 있습니다.
:
:
: // 윈도우 이벤트는 처리하면서 일정 시간을 기다린다.
: BOOL SleepMsg(DWORD dwTimeout)
: {
: DWORD dwStart = GetTickCount();
: DWORD dwElapsed;
: while ((dwElapsed = GetTickCount() - dwStart) < dwTimeout) {
: DWORD dwStatus = MsgWaitForMultipleObjectsEx(0, NULL,
: dwTimeout - dwElapsed, QS_ALLINPUT,
: // MWFMO_WAITANY | MWMO_INPUTAVAILABLE);
: 0 | MWMO_INPUTAVAILABLE);
: MSG msg;
: while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
: if (msg.message == WM_QUIT) {
: PostQuitMessage((int)msg.wParam);
: return FALSE; // abandoned due to WM_QUIT
: }
: TranslateMessage(&msg);
: DispatchMessage(&msg);
: }// end of while
: }// end of while
: return TRUE; // timed out
: }
:
: 혹, 이와 같은 경험이 있으신 분들은 도움을..
: 테스트도 어렵네요. 실행하고 상황 발생할 때까지 며칠을 기다려야 하니.... ㅠ.ㅠ;;;;
:
: 감사합니다.
: