문제
이벤트/인터럽트를 사용하여 Serial을 읽고 쓰고 싶습니다. 현재, 나는 그것을 while 루프로 가지고 있으며 연속을 통해 지속적으로 읽고 씁니다. 직렬 포트에서 무언가가 올 때만 읽기를 원합니다. c ++에서 이것을 어떻게 구현합니까?
이것은 내 현재 코드입니다.
while(true) { //read if(!ReadFile(hSerial, szBuff, n, &dwBytesRead, NULL)){ //error occurred. Report to user. } //write if(!WriteFile(hSerial, szBuff, n, &dwBytesRead, NULL)){ //error occurred. Report to user. } //print what you are reading printf("%s\n", szBuff); }
해결책
a select
진술은 차단하지 않고 읽기 및 쓰기 버퍼를 확인하고 상태를 반환 할 수 있으므로 포트에 데이터가 있다는 것을 알 때만 읽거나 출력 버퍼에 공간이 있다는 것을 알 때만 읽어야합니다.
세 번째 예 http://www.developerweb.net/forum/showthread.php?t=2933 관련 의견이 도움이 될 수 있습니다.
편집하다: Select의 Man Page에는 끝 근처에 더 간단하고 완전한 예제가 있습니다. 당신은 그것을 찾을 수 있습니다 http://linux.die.net/man/2/select 만약에 man 2 select
시스템에서 작동하지 않습니다.
메모: 마스터 링 select()
직렬 포트와 소켓 모두에서 작업 할 수 있습니다. 많은 네트워크 클라이언트와 서버의 핵심입니다.
다른 팁
Windows 환경의 경우 더 기본적인 접근 방식은 사용하는 것입니다. 비동기 I/O. 이 모드에서는 여전히 통화를 사용하여 readfile 및 writefile을 사용하지만 차단하는 대신 작업이 완료되면 호출 될 콜백 함수를 전달합니다.
그래도 모든 세부 사항을 올바르게 얻는 것은 상당히 까다 롭습니다.
다음은 An의 사본입니다 기사 그것은 몇 년 전에 C/C ++ 사용자 저널에 게시되었습니다. Win32 API에 대해 자세히 설명합니다.
여기서는 Windows의 중단을 사용하여 직렬 불이행 데이터를 읽는 코드 대기 중단 시간 동안 시간이 경과 할 수 있습니다.
int pollComport(int comport_number, LPBYTE buffer, int size)
{
BYTE Byte;
DWORD dwBytesTransferred;
DWORD dwCommModemStatus;
int n;
double TimeA,TimeB;
// Specify a set of events to be monitored for the port.
SetCommMask (m_comPortHandle[comport_number], EV_RXCHAR );
while (m_comPortHandle[comport_number] != INVALID_HANDLE_VALUE)
{
// Wait for an event to occur for the port.
TimeA = clock();
WaitCommEvent (m_comPortHandle[comport_number], &dwCommModemStatus, 0);
TimeB = clock();
if(TimeB-TimeA>0)
cout <<" ok "<<TimeB-TimeA<<endl;
// Re-specify the set of events to be monitored for the port.
SetCommMask (m_comPortHandle[comport_number], EV_RXCHAR);
if (dwCommModemStatus & EV_RXCHAR)
{
// Loop for waiting for the data.
do
{
ReadFile(m_comPortHandle[comport_number], buffer, size, (LPDWORD)((void *)&n), NULL);
// Display the data read.
if (n>0)
cout << buffer <<endl;
} while (n > 0);
}
return(0);
}
}