[Этот ответ был составлен для исходного размещенного вопроса, который с тех пор был пересмотрен в различных деталях. Основная ошибка осталась прежней.]
... закончились использованием неканонических настроек, найденных здесь: http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html с несколькими небольшими изменениями.
Вы выбрали неверно, и у вас есть код инициализации termios, который не является надежным.
Он может работать сегодня в вашей нынешней системе, но этот код может не переноситься в другую систему.
См. Настройка терминалаПравильный режим .
A: почему я получаю 254 байта начальных нулей в моем первом буфере и как этого избежать,
Ваш кодчтение с последовательного терминала имеет несколько недостатков.
res = read(fd,buf,BUFSIZE); /* returns after 255 chars have been input */
//the buffer position increments by res (read)
if (res > 0)
{
pos += res;
//cpy buf to whereever pos is at res amount
memcpy(pos,buf,res);
total += res;
}
Ваш код (в целом) не проверяет возможные ошибки от системных вызовов.
Если предположить, что первое read () прошло успешно, тогда в вашем буфере будет возвращено 255 байтов buf
, и res
будет иметь значение 255.
Перед копированием полученных данных с buf
на buf1
ваша программа преждевременно обновляет указатель назначения pos
на счетчик приема.
Это начало «смещения» на что вы жалуетесь.
Указатель pos
должен обновляться после операции копирования, а не раньше.
B: почемумой ввод всегда отключен одним байтом.
Это предполагаемое "однобайтовое" связано с проблемой выравнивания байтов.
Поскольку вы по ошибке сохранили первый буфер со смещением 255, это смещение не являетсяцелое число коротких целых чисел.
То есть 255 байтов - это 127 коротких целых чисел с одним оставшимся байтом.
Этот оставшийся байт является источником вашего предполагаемого "всегда отключенного одним байтом" .
Обратите внимание, что такая проблема выравнивания с коротким целым числом допускается процессорами x86.
Не все архитектуры процессоров допускают такой не выровненный доступ, поэтому имейте в виду, что ваша программа может быть не переносимой.
IOW "254 байта старших нулей" плюс "отключение одним байтом" равно 255 количество байтов, возвращаемое начальными значениями read () .
Ваша идея передачи ряда двоичных значений в виде необработанных данных проблематична.
Многобайтовые значения, такие как короткие целые числа, могутприниматься с неправильным выравниванием байтов.
Похоже, что вы используете ручную синхронизацию передающей программы с принимающей программой для обеспечения выравнивания байтов. Это не надежная процедура и, конечно, не может быть автоматизирована.
Кроме того, нет проверки целостности данных.
Эта ошибка обновления указателя также может привести к засорению уже полученных данных вновь прочитанными данными, но ваша программа не обнаружит этот или любой другой прием. ошибка.
Обратите внимание, что ваш код генерирует предупреждения компилятора:
test.c: In function ‘main’:
test.c:72:35: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
unsigned short * ps = buf1 + OFFSET;
^
test.c:75:33: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
unsigned char* cs = ps;
^
test.c:77:16: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
ps = cs;
Вы должны исправить эти неаккуратные выражения указателя, чтобы избежать потенциальных ошибок, которые могут быть трудно отследить.
тот факт, что у вас есть проблемы с вашей программой, должен был заставить вас исключить любые предупреждения компилятора.
ADDENDUM к пересмотренному вопросу
Пересмотр вашего кода значения VMIN проблематичен по нескольким причинам.
Это проблематично для эффективности во время выполнения, потому что VMIN = 0 и VTIME = 0 настраивают последовательный терминал для формы неблокирующих операций чтения.
Согласно этому руководству такая конфигурация должна быть толькоиспользуется, когда «Вы действительно, действительно знаете, что делаете» .
Анализ вашей ошибки кодирования проблематичен.
На основании вашего пересмотренного отчета о том, что "offset" теперь составляет 256 байтов (вместо 255), я должен предположить, что выручное инициирование передающей программы перед этой принимающей программой.
Это даст достаточно времени для последовательной передачи и заполнения буфера терминала. (См. Размер FIFO программного обеспечения BeagleBone Black UART? )
Следовательно, начальное значение read () для 256 байтов может быть полностью удовлетворено, поскольку (исходный) буфер терминала уже заполнен даннымиготов к «чтению».
Это «полное» чтение в сочетании с ошибкой вашей программы сохраняет эти данные со смещением 256 байт.
Если вы инициируете эту принимающую программу перед передающей программой, то фактическое смещение копии, созданное ошибкой, подвержено изменениям обработки.
Но независимо от значения смещения причина всегда одна и та же (т. Е. указатель назначения для копии преждевременно обновляется).