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 (opennet.ru)), но ничего путного не выходит.

★

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

	 * 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 ★★★
()

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

Байты отсылает порциями по 33 байта

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

anonymous2 ★★★★★
()
Ответ на: комментарий от 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 ★★★★★
()
Ответ на: комментарий от u5er

В конечном итоге инженер ПЛИС переписал свою прошивку и теперь принимает подряд всё, что приходит ему.

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

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

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

czan ★
() автор топика
Последнее исправление: czan (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему: топик перемещен в архив.