LINUX.ORG.RU

Работа с последовательным портом

 , , ,


0

1

Тут такая проблемка.

Есть плата Jetson Nano. Пишу прогу для работы с UART-ом. Надо отослать 5 мегабайт файла с бодрейтом в 1 000 000. Написал программку на C. Байты отсылает порциями по 33 байта. На той стороне принимает Xilinx. Xilinx принимает ориентируясь по задержкам в передаче: то есть, если есть пауза, то считается, что передача очередного пакета закончилась. И вот, при передаче очередных моих 33-х пакетов, иногда, происходит пауза в байт или два байта и на той стороне Xilinx решает, что передача окончилась.

Программку делал по вот этой статье.

Байты передаю через конструкцию

write(serial_port, msg, sizeof(msg));

Подскажите, пожалуйста, чего бы такого можно сделать, чтобы отсылать без этих задержек? Пробовал поэкспериментировать со всякими TCOFLUSH (man), но ничего путного не выходит.


если есть пауза, то считается, что передача очередного пакета закончилась.

	 * Set the receiver timeout. If it is not set, and the last few bytes
	 * of data do not trigger the over-water or full interrupt, the bytes
	 * will not be received. By default it is disabled.
	 *
	 * The setting of 8 will timeout after 8 x 4 = 32 bit periods.
	 * Increase the time out value if baud rate is high, decrease it if
	 * baud rate is low.
LINUX-ORG-RU ★★★★★
()

Заведи передачу на DMA и при необходимости перезаряжай ее в аппаратном таймере (а лучше по прерыванию окончания предыдущей передачи, если так у тебя можно)

aiqu6Ait ★★★★
()
Последнее исправление: aiqu6Ait (всего исправлений: 1)

Сначала убедитесь, что это точно задержки, а не потери байт на приёмной стороне. А потом начинайте ковырять исходники драйвера в ядре. Там же у UART есть аппаратный буфер, и ядро может «неспешно» его перезаряжать, то есть обрабатывать только прерывание когда там совсем байты закончились, откладывать обработку... Базово, передача асинхронная, значит никаких проблем от задержек быть не должно.

Ну, и ещё добавлю, что во всяких китайских поделках, закладывают 3 или 3,5 байта тишины, причём для 9600. Наверное, неспроста, видимо эта проблема присуще не только Линуксу.

mky ★★★★★
()

Подскажите, пожалуйста, чего бы такого можно сделать, чтобы отсылать без этих задержек?

  1. В вызове open() установить флаг O_SYNC.
  2. Использовать буферизованные вызовы fopen(), fwrite(), fflush(), fclose().
  3. Пойти к разработчику аппаратуры, с которой ты обмениваешься данными, и научить его принимать и отправлять данные по сети. RS-232C - линии связи из прошлого века.
Enthusiast ★★★
()

Xilinx принимает ориентируясь по задержкам в передаче

Есть вариант изменить это? Я бы посоветовал обернуть каждый пакет в заголовок с длиной и номером пакета и хвостом с контрольной суммой. Это будет надёжнее, чем полагаться на задержки.

u5er ★★
()
Ответ на: комментарий от anonymous2

RS-232 это поток. Работать там через таймауты это идиотизм.

Я работал с одним протоколом, так там весь протокол был построен на задержках и синхронизированной(под DOS производилась очистка буфера по времени) передаче данных по RS-232 как раз. Вот я хлебнул с этим говна, когда пришлось на современные системы переводить и эти задержки эмулировать.

Loki13 ★★★★★
()
Ответ на: комментарий от anonymous2

Это не идиотизм. Иногда бывает удобно перезаряжать DMA по паузе в дополнение к перерезарядке по заполнению, может ускорять разделение на кадры. Другое дело что делить кадры только по задержке - это не самое оптимальное решение.

aiqu6Ait ★★★★
()
Ответ на: комментарий от aiqu6Ait

Смотри, что пишут

When you see “/dev/ttyS2” and “/dev/ttyTHS2” you are looking at two drivers for a single UART. The “ttyS#” designation is the old style traditional driver, and is supported even in early boot stages prior to Linux loading. The “ttyTHS#” is the “Tegra High Speed” version of the driver, and this is DMA enabled. If you talk to “/dev/ttyS2”, then you are not using DMA; if you are talking to “/dev/ttyTHS2”, then you are talking to the same UART with DMA being used.

Когда у тебя операционка перестает управлять передачей, у тебя задержек внутри передачи пакета не будет. Не забудь только, что ты из функции передачи можешь выйти до ее фактического окончания.

aiqu6Ait ★★★★
()
Ответ на: комментарий от anonymous2

33 байта - откуда это магическое число?

Инженеру ПЛИС было удобно принимать данные длиной, кратной 32-м байтам. А 33-й байт - это заголовок.

czan
() автор топика
Последнее исправление: czan (всего исправлений: 1)