Советы по программированию для протокола XMODEM.
Подпрограмма приема символа должна вызываться с параметром, где указывается таймаут в секундах, в течение которого можно ждать приема символа. Первый вызов этой подпрограммы должен быть сделан с временем 10 секунд, так что после истечения 10 секунд таймаута должен быть отправлен символ NAK, и так должно быть сделано 10 раз. После приема SOH (это первый символ, который передан передатчиком) приемник должен вызывать подпрограмму приема символа с таймаутом в 1 секунду, и так до всей оставшейся части сообщения, включая контрольную сумму CRC. Поскольку данные будут передаваться как непрерывный поток байт, то истечение таймаута 1 сек будет означать серьезную ошибку - скажем, принято 127 символов вместо 128.
Когда приемник хочет передать NAK, он должен вызвать "очищающую" подпрограмму (PURGE), в которой будет реализован прием с 1-секундным таймаутом, и зацикливание, пока таймаут не истечет. Эта процедура в сущности заключается в ожидании "чистой" линии связи на входе, когда передатчик не передает, что будет гарантировать, что передатчик правильно примет и обработает символ NAK. Вспомните, что протокол рассчитан на обмен в полудуплексе, т. е. передатчик на время своей передачи блокирует работу своего входного канала, что гарантирует отсутствие ошибочной интерпретации помех, которые могли бы возникнуть во входном канале передатчика в процессе передачи.
Желательно добавить код для обработки специальных ошибок приема, таких как ошибка фрейма UART, или переполнение входного буфера. Двухбайтная контрольная сумма (CRC16) лучше защищает данные, чем однобайтная (CRC8), потому что, к примеру, CRC8 дает для байт 0x80 и 0x80 тот же результат, что и для байт 0x00 и 0x00.
Пример кода, вычисляющего CRC8.
Это простейший алгоритм, который просто считает сумму всех байт (нужно вычислять сумму от 128 байт данных пакета, байты 4..131) с отбрасыванием переполнения. Получится байт суммы, который должен совпадать с байтом 132 пакета.
u8 crc8(u8 *buf, int sz)
{
u8 crc = 0;
for (int i=0; i < sz; i++)
crc += buf[i];
return crc;
}
>>
|