Проверка наличия обмена с использованием целых чисел

При автоматизации обмена с устройствами всегда необходимо знать: есть обмен с устройством или нет. Как реализовать такую проверку?

При отсутствии обмена функция ReadFile должна возвращать ошибку. Однако полагаться только на нее нельзя. Во-первых, перед ее вызовом мы должны определить сколько данных нужно прочитать из COM порта. Для этого используется функция ClearCommError, которую нужно вызывать в цикле (об этом читайте в одном из моих прошлых постов). Если обмена нет, то мы получим бесконечный цикл. Во-вторых, функция ReadFile сама может не возвращать управление длительное управление. В-третьих, данный подход не применим при асинхронной работе с COM портом. Если обмен реализован в отдельном потоке, то он может не пробуждаться длительное время. Нужен другой подход.
В своих проектах я проверяю наличие обмена с помощью целых чисел. В классе (потоке), получающем информацию от устройства, объявляется целочисленное поле rand_value (название может быть любым). При каждом успешном чтении его значение изменяется. Класс (поток), реализующий пользовательский интерфейс, периодически просматривает это поле и, если оно не изменяется, то обмена нет. Ниже приводится пример программы, реализующей такую проверку.

static unsigned long rand_reader = 0;
unsigned long new_rand;
new_rand = preader->GetRandValue();
if(new_rand != rand_reader)
{
   //Обмен есть
}else
{
   //Обмена нет
}
rand_reader = new_rand;

Поле rand_value может меняться произвольно или же увеличиваться на единицу при каждом успешном обмене. Данный метод будет одинаково работать в обоих случаях.
При проверке наличия обмена возникает еще один вопрос: что считать успешным обменом, чтение байт из порта, или же чтение пакета данных, соответствующего протоколу обмена (корректный размер, сигнатуры, контрольная сумма). Лично я предпочитаю первый вариант. Так как проблемы с неправильной интерпретацией читаемых данных, как правило, решаются во время отладки приложения, и в релизе практически не встречаются.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *