Eventos / Interrupções na comunicação série
-
05-07-2019 - |
Pergunta
Eu quero ler e escrever a partir de série usando eventos / interrupções. Atualmente, eu tê-lo em um loop while e continuamente leituras e gravações através da porta serial. Eu quero que ele leia somente quando algo vem da porta serial. Como posso implementar isso em C ++?
Este é o meu código atual:
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); }
Solução
Use uma declaração select
, que irá verificar os buffers de leitura e gravação sem bloquear e devolver seu status, assim você só precisa de ler quando você sabe que o porto tem dados ou gravação quando você sabe que há espaço no buffer de saída.
O terceiro exemplo em http://www.developerweb.net/forum /showthread.php?t=2933 e os comentários associados podem ser úteis.
Editar: A página man para selecionar tem um exemplo mais simples e mais completo perto do fim. Você pode encontrá-lo em http://linux.die.net/man/2/select se man 2 select
não funciona em seu sistema.
Nota: Mastering select()
lhe permitirá trabalhar com ambas as portas seriais e tomadas; é no coração de muitos clientes de rede e servidores.
Outras dicas
Em um ambiente Windows a abordagem mais natural seria a utilização de E / S assíncrona . Neste modo você ainda usa chamadas para ReadFile e WriteFile, mas em vez de bloqueá-lo a passar em uma função de retorno de chamada que será chamado quando o conclui operação.
É bastante complicado para obter todos os detalhes certo, entretanto.
Aqui está uma cópia de um artigo que foi publicado no c / C ++ jornal dos usuários de alguns anos atrás. Ele entra em detalhes sobre a API Win32.
aqui um código que ler dados de entrada serial usando interrompido em janelas você pode ver o tempo decorrido durante o tempo de interrupção de espera
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);
}
}