реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> STM32, работа с UART и DMA, как правильно передавать?
esaulenka
сообщение Jul 8 2014, 16:24
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Доброго дня.

Нужен совет по архитектуре типичнейшей задачи, как правильно соорудить передачу по UART.

Мы используем кучу уартов, работая через прерывания. Далее - копипаста по нескольким uart'ам, различающаяся только указателями на uart, и на буфер: обработчик прерывания, который перекладывает байты из софт-буфера (ну и наоборот, в буфер); API - функции "получить 1 байт", "передать 1 байт", "передать N байт".
Типичное использование на передачу - функция формирует пакет и налету скидывает его порциями в буфер.

Так вот, все примеры общения с DMA, что я видел - сформировать большой буфер, настроить DMA на его передачу, курить бамбук, пока всё не отработает.
С нашим API как-то не очень совместимо - постоянно останавливать-запускать DMA при добавлении в очередь ещё одного байта совсем плохо.

Я что-то пропустил, или передача по DMA на мою задачу никак не ложится?


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 9 2014, 01:48
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



На Вашу задачу STM32 - никак не ложится, ибо очень неудобно в нём использовать UART, а тем более если нужна куча их. Нужно было выбирать что-то другое, где есть нормальное FIFO в UART.
А так - на каждый UART Вам придётся выделить в худшем случае по два DMA-канала. Может и не хватить их.

А использовать DMA совместно с кольцевым буфером никакой проблемы нет.
Зачем там что-то останавливать и перезапускать? Почитайте описание работы DMA.
Накопилось у Вас в Вашем кольцевом буфере сколько-то данных - программируете DMA-канал на передачу этого блока.
Закончилась DMA-передача блока - программируете на след. блок (если уже накопился).
Что тут сложного?

С приёмом сложнее. Так как размер входящих данных заранее не известен, то нужно будет программировать на какой-то размер блока,
а потом возможно - контролировать кол-во поступивших на данный момент данных и останавливать DMA-приём.
Я на STM32 связку UART.RX+DMA не использовал, так что сказать точно про приём не могу.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 9 2014, 05:40
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(jcxz @ Jul 9 2014, 04:48) *
а потом возможно - контролировать кол-во поступивших на данный момент данных и останавливать DMA-приём.
У UART есть хорошее прерывание IDLE.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Jul 9 2014, 05:51
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



DMA при работе с UART позволит вам снизить нагрузку на процессор при передаче больших объёмов данных. Если ресурсов процессора хватает или объём данных небольшой, то вам без DMA вполне можно обойтись. Отправляйте байт, в цикле дожидайтесь пустого передатчика, повторяйте.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 9 2014, 06:04
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(andrewlekar @ Jul 9 2014, 11:51) *
DMA при работе с UART позволит вам снизить нагрузку на процессор при передаче больших объёмов данных.

...либо снизить потребление электричества.

Цитата(andrewlekar @ Jul 9 2014, 11:51) *
Отправляйте байт, в цикле дожидайтесь пустого передатчика, повторяйте.

ЖЕСТЬ twak.gif
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Jul 9 2014, 07:30
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



В чём проблема то?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 9 2014, 08:13
Сообщение #7


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(jcxz @ Jul 9 2014, 05:48) *
Всё с точностью до наоборот. Я давно и успешно использую DMA для STM32.
На приём с помощью DMA никаких проблем нет. По сути получается аппаратный приёмный кольцевой буфер, который необходимо с достаточной интенсивностью выгребать.
И знать кол-во принимаемых данных совсем не нужно.
А вот с передачей действительно немного не тривиально.
Как вариант, можно организовать очередь из блоков памяти для отправки по ДМА. Но это не выгодно для байтовой передачи.
Но и здесь можно вывернуться накапливая байты в блоке и отправлять их например по таймеру и или таймауту и по заполнению блока.
На мой взгляд это всё не слишком красиво. А вашу идею с кольцевым буфером я не до конца понял.
Как передать участок кольцевого буфера перехлёстывающегося через его конец?
ПС: При использовании динамической памяти задача для передачи блоков данных по UART через DMA решается самым элегантным образом, но это не мой метод...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 9 2014, 09:27
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(demiurg_spb @ Jul 9 2014, 14:13) *
Всё с точностью до наоборот. Я давно и успешно использую DMA для STM32.
На приём с помощью DMA никаких проблем нет.

Проблема не с DMA, проблема с их количеством. ТС написал про "кучу UART-ов", а кол-во DMA-каналов у нас сильно ограниченно.
И если для передачи ещё можно как-то попытаться расшарить один DMA-канал на неск. UART-ов, то вот для приёма ой....
А ведь в девайсе возможно DMA и для других нужд могут быть нужны.

Цитата(demiurg_spb @ Jul 9 2014, 14:13) *
Как передать участок кольцевого буфера перехлёстывающегося через его конец?
ПС: При использовании динамической памяти задача для передачи блоков данных по UART через DMA решается самым элегантным образом, но это не мой метод...

С передачей как раз всё просто.
При перехлёсте очевидно же - передавать в два приёма: до конца и с начала.
В обработчике завершения DMA проверять "имеются-ли ещё символы в TX-буфере?" и стартовать новый блок если да.
Если нет - стоп, сброс флага активности TX.DMA (с опциональным освобождением DMA-канала в пул).

Стартовать сам процесс передачи можно либо в каком-то периодическом процессе (периодически проверяя есть-ли байты в TX-FIFO),
либо в функции, пишущей в TX-FIFO при достижении некоей water mark.
Либо и так и так.
Но это при условии, что флаг активности TX.DMA сброшен.

Недавно когда я переносил некоторый шаблонный проект с LPC на STM32 (там имелся символьный вывод потока в UART), в LPC DMA для этого не использовался (так как там хватало FIFO).
На STM32 пришлось сделать через DMA именно так как и описал.
Заняло это около дня.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 9 2014, 10:09
Сообщение #9


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(jcxz @ Jul 9 2014, 13:27) *
Хорошо.
Но тогда при записи блока в фифо равного его размеру мы не сможем больше записать в фифо ни одного байта до окончания DMA транзакции,
а это весьма долго, т.к. мы привязаны к скорости UART. Это как-бы не совсем то что хочется, или вы как-то обходите эту ситуацию?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 9 2014, 10:51
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



А откуда вы знаете долго или нет? вы же не знаете какими блоками будет писать ТС, и вообще - блоками-ли он будет писать? Он писал как раз про байтовый ввод/вывод.
Размер FIFO можно выбрать соответствующим (побольше) и стартовать DMA-транзакцию, как я уже писал, можно раньше, до полного заполнения буфера.
У меня был простой символьный вывод, DMA-транзакция стартовала по некоему таймауту (с величиной задержки некритичной для потока)
или по заполнению трети буфера.
Как оптимально - будет зависеть от протокола обмена, который идёт через этот канал.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 9 2014, 13:29
Сообщение #11


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(jcxz @ Jul 9 2014, 14:51) *
Ваша точка зрения понятна. Спасибо.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 9 2014, 13:33
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(jcxz @ Jul 9 2014, 14:51) *
DMA-транзакция стартовала по некоему таймауту (с величиной задержки некритичной для потока) или по заполнению трети буфера.

Или по "пинку" из программы. Особенно в протокольных вещах часто бывает известно, когда пакет уже готов польностью.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 9 2014, 13:37
Сообщение #13


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(adnega @ Jul 9 2014, 17:33) *
Или по "пинку" из программы. Особенно в протокольных вещах часто бывает известно, когда пакет уже готов польностью.

+1 uart_flush


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th August 2025 - 23:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01983 секунд с 7
ELECTRONIX ©2004-2016