Приём данных
В типичной системе постоянно приходится обрабатывать поток входящих данных. Простой подход - опрос. Вы просто в цикле опрашиваете буфер, проверяя, есть ли в нём данные, и когда появляются свежие данные, что-то с ними делаете. Выглядит это так:
sub on_sys_init
while ser.rxlen = 0
wend ' basically keeps executing again and again as long as ser.rxlen = 0
s = ser.getdata(255) ' once loop is exited, it means data has arrived. We extract it.
end sub
Такой подход работает, но навсегда оставит вас в конкретном обработчике события (например, on_sys_init), а другие события так и не получат возможности выполниться. Это пример блокирующего кода, из-за которого система может зависнуть. Конечно, можно использовать оператор doevents, но в целом мы советуем этот подход не применять.
Поскольку наша платформа управляется событиями, о появлении новых данных должны сообщать события. Есть событие on_ser_data_arrival, которое генерируется всякий раз, когда в буфере приёма (RX) есть данные:
sub on_ser_data_arrival
dim s as string
s = ser.getdata(255) ' Extract the data -- but in a non-blocking way.
' .... code to process data ....
end sub
Это событие on_ser_data_arrival генерируется всякий раз, когда в буфере приёма (RX) есть данные, но только один раз. В очереди никогда не бывает двух ожидающих событий on_ser_data_arrival. Следующее событие генерируется только после завершения обработки предыдущего, если к тому моменту в буфере приёма (RX) есть данные.
Это значит, что при обработке этого события не обязательно забирать все данные из буфера приёма (RX). Можно обработать порцию данных, и после выхода из обработчика будет сгенерировано новое событие того же типа, если необработанные данные остались.
Вот правильный пример обработки поступающих последовательных данных через событие on_ser_data_arrival. Он реализует петлю данных: всё, что принято последовательным портом, сразу отправляется обратно.
sub on_ser_data_arrival
ser.setdata(ser.getdata(ser.txfree))
ser.send
end sub
Мы хотим обработать эту петлю как можно эффективнее, но переполнять буфер передачи (TX) нельзя. Поэтому нельзя просто копировать все поступающие данные из буфера приёма (RX) в буфер передачи (TX): нужно проверить, сколько свободного места есть в буфере передачи (TX). Первая строка кода делает именно это: метод ser.getdata берёт из буфера приёма (RX) как можно больше данных, но не больше, чем ser.txfree (доступное место в буфере передачи (TX)). Вторая строка просто отправляет данные.
На самом деле за один проход этот вызов обработает не более 255 байт. Хотя данные как будто копируются напрямую из буфера приёма (RX) в буфер передачи (TX), это делается через временную строковую переменную, которая автоматически создаётся для этой цели. На этой платформе строковые переменные не могут превышать 255 байт.
Метод обработки данных опросом иногда бывает полезен. См. Генерация динамических HTML-страниц.