События / Прерывания в Последовательной связи
-
05-07-2019 - |
Вопрос
Я хочу читать и записывать из 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); }
Решение
Используйте оператор select
, который будет проверять буферы чтения и записи без блокировки и возвращать их статус, поэтому вам нужно только читать, когда вы знаете, что порт имеет данные, или писать, когда вы знаете, что есть комната в выходном буфере.
Третий пример на http://www.developerweb.net/forum /showthread.php?t=2933 и соответствующие комментарии могут быть полезны.
Правка . В конце страницы руководства для select приведен более простой и полный пример. Вы можете найти его по адресу http://linux.die.net/man/2/select если man 2 select
не работает в вашей системе.
Примечание: мастеринг select ()
позволит вам работать как с последовательными портами, так и с сокетами; это лежит в основе многих сетевых клиентов и серверов.
Другие советы
Для среды Windows более естественным подходом будет использование асинхронный ввод / вывод . В этом режиме вы по-прежнему используете вызовы ReadFile и WriteFile, но вместо блокировки вы передаете функцию обратного вызова, которая будет вызываться после завершения операции.
Хотя довольно сложно все детали правильно понять.
Вот копия статьи , которая была опубликована в 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);
}
}