Eventi / Interrupt nella comunicazione seriale
-
05-07-2019 - |
Domanda
Voglio leggere e scrivere da seriale usando eventi / interrupt. Attualmente, l'ho in un ciclo while e legge e scrive continuamente attraverso il seriale. Voglio che legga solo quando qualcosa viene dalla porta seriale. Come posso implementarlo in C ++?
Questo è il mio codice attuale:
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); }
Soluzione
Usa un'istruzione select
, che controllerà i buffer di lettura e scrittura senza bloccarli e restituirà il loro stato, quindi devi solo leggere quando sai che la porta ha dati o scrivere quando sai che c'è spazio nel buffer di output.
Il terzo esempio su http://www.developerweb.net/forum /showthread.php?t=2933 e i commenti associati potrebbero essere utili.
Modifica: la pagina man di select ha un esempio più semplice e completo verso la fine. Puoi trovarlo su http://linux.die.net/man/2/select se man 2 select
non funziona sul tuo sistema.
Nota: il Mastering select ()
ti permetterà di lavorare sia con porte seriali che con socket; è al centro di molti client e server di rete.
Altri suggerimenti
Per un ambiente Windows l'approccio più nativo sarebbe usare I / O asincrono . In questa modalità usi ancora le chiamate a ReadFile e WriteFile, ma invece di bloccare passi una funzione di callback che verrà invocata al termine dell'operazione.
È abbastanza difficile ottenere tutti i dettagli giusti.
Ecco una copia di un articolo che è stato pubblicato nel c / C ++ diario degli utenti qualche anno fa. Entra in dettaglio nell'API Win32.
qui un codice che legge i dati seriali in entrata usando l'interruzione su Windows puoi vedere il tempo trascorso durante il tempo di interruzione dell'attesa
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);
}
}