Сброс маски событий связи

В последнее время я занимаюсь перекрытием последовательного порта в Delphi, и есть одна проблема, которую я не знаю, как решить.

Я общаюсь с модемом. Я пишу фрейм запроса (AT-команду) в COM-порт модема и жду ответа модема. Маска события порта установлена ​​в EV_RXCHAR, поэтому, когда я пишу запрос, я вызываю WaitCommEvent() и начинаю ждать появления данных во входной очереди. При перекрытии ожидания завершения события я сразу начинаю читать данные из очереди и читаю сразу все, что отправляет устройство:

1) напишите запрос
2) вызовите WaitCommEvent() и дождитесь завершения ожидания
3) прочитайте все данные, которые отправляет устройство (а не только те, которые в этот момент находятся во входной очереди)
4) сделать что-то, а затем перейти к 1

Ожидание завершения события после появления первого байта во входной очереди. Однако во время моей операции чтения в очереди появляется больше байтов, и каждый из них вызывает установку внутреннего флага события. Это означает, что когда я прочитаю все данные из очереди, а затем вызову функцию WaitCommEvent() во второй раз, она немедленно вернется с маской EV_RXCHAR, даже если данных для чтения нет.

Как мне обрабатывать чтение и ожидание события, чтобы убедиться, что маска события, возвращаемая функцией WaitCommEvent(), всегда действительна? Можно ли сбросить флаги последовательного порта, чтобы при чтении всех данных из очереди и последующем вызове WaitCommEvent() он не возвращался немедленно с маской, которая была действительной до того, как я прочитал данные?

Единственное решение, которое приходит мне в голову, это:

1) напишите запрос
2) вызовите WaitCommEvent() и дождитесь завершения ожидания
3) прочитайте все данные, которые отправляет устройство (а не только те, которые в этот момент находятся во входной очереди)
4) вызвать функцию WaitCommEvent(), которая должна немедленно вернуть значение true, одновременно сбрасывая внутренний флаг события
5) сделать что-нибудь и перейти к 1

Это хорошая идея или глупость? Конечно я знаю, что модем почти всегда заканчивает свои ответы символами CRLF, поэтому я мог бы установить маску связи в EV_RXFLAG и дождаться появления символа #10, но есть много других устройств, с которыми я общаюсь, и они не всегда отправляют символы конца кадра.

Ваша помощь будет оценена по достоинству. Заранее спасибо!

Мариуш.


person Mariusz Schimke    schedule 23.07.2009    source источник
comment
Вы можете писать списки, используя расширение . вместо круглых скобок, таким образом, вам не нужно добавлять теги BR для принудительного перевода строки. Кроме того, чтобы принудительно перевести строку в уценке, просто добавьте два пробела в конец строки.   -  person Lasse V. Karlsen    schedule 24.07.2009


Ответы (1)


Ваше решение звучит работоспособно. Я просто использую конечный автомат для обработки переходов.

(псевдокод)

ioState := ioIdle;
while (ioState <> ioFinished) and (not aborted) do
Case ioState of
  ioIdle : if there is data to read then set state to ioMidFrame
  ioMidframe : if data to read then read, if end of frame set to ioEndFrame
  ioEndFrame : process the data and set to ioFinished
  ioFinished : // don't do anything, for doc purposes only.
end;
person skamradt    schedule 24.07.2009