|
STM32F UART + DMA на чтение, Как реализовать чтение через DMA для потока данных? |
|
|
|
 |
Ответов
|
Feb 7 2013, 07:44
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Rash @ Jan 9 2013, 20:51)  А есть ли возможность аппаратно увидеть что начался приём данных?, что бы не начать новую передачу в случае RS-485 и не подгонять тайм ауты посылок От коллизий в RS485 вы так не защититесь. Это поможет сделать только протокол обмена. Когда вы проверяете идёт-ли у вас приём данных, в этот момент байт может только ещё начать приниматься, или на удалённой стороне аппаратура передатчика может только переключить выход в TX с последующей паузой для устаканивания канала в режиме передачи. Цитата(kan35 @ Feb 3 2013, 13:06)  Вероятность потери байта предельно низка, так как сначала достаются все байты из массива ДМА, затем еще раз проверяется счетчик ДМА и если он не изменился за время вытаскивания данных, то ДМА ресетится. Процедура сброса ДМА занимает доли микросекунды. Если вероятность потери !=0, то на помойку такое ПО. Которое может работать с некоторой вероятностью в зависимости от фазы луны. А если между проверкой и сбросом DMA как раз и придёт байт? И что значит "ресет DMA"? Это именно сброс канала или запрет его работы? Есть-ли у DMA каналов в STM32 FIFO? Знаю что у многих других контроллеров - есть, что будет приводить к потерям байт (при сбросе DMA) или появлению лишних байт (при его запрете) - сам лично сталкивался с такой проблемой. Должен быть алгоритм, позволяющий работать с 100% вероятностью. Иначе - зачем нужен STM32 если есть другие процессоры (например LPC или от TI) где есть нормальное FIFO на UARTах работающее со 100% вероятностью и не нужны пляски с бубном с DMA? Пишу не с целью разжигания религиозной войны STM vs LPC, а с целью понять плюсы и минусы STM32, как замены хорошо знакомым ядрам от NXP. Мои задачи подразумевают интенсивное использование UART-ов (несколько одновременно, до 5и) под ОС. Я пытаюсь понять во что это выльется при переходе с LPC на STM32? Очень настораживает сложность работы с UART на STM32 через DMA. Работа с частотами прерываний от одного UART порядка 11кГц/11кГц (TX/RX) на 115200 и суммарной эквивалентной частотой от 5-ти UART на 115200 порядка 110кГц очень напрягает, особенно под ОС. Прочитал сообщения этой ветки и возникли у меня большие сомнения в целесообразности использования STM32 вообще при работе с UART... В частности вопрос: если работать на приём так: Получаю IDLE-прерывание, в его обработчике запрещаю канал DMA, копирую данные из буфера DMA в программное FIFO, настраиваю канал DMA заново на приём в буфер DMA, разрешаю DMA, выхожу из ISR. Могут-ли в таком алгоритме быть потери байт или другие проблемы?
|
|
|
|
|
Feb 8 2013, 12:10
|
Знающий
   
Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594

|
Цитата(jcxz @ Feb 7 2013, 11:44)  Если вероятность потери !=0, то на помойку такое ПО. Которое может работать с некоторой вероятностью в зависимости от фазы луны. А если между проверкой и сбросом DMA как раз и придёт байт? И что значит "ресет DMA"? Это именно сброс канала или запрет его работы? Есть-ли у DMA каналов в STM32 FIFO? Знаю что у многих других контроллеров - есть, что будет приводить к потерям байт (при сбросе DMA) или появлению лишних байт (при его запрете) - сам лично сталкивался с такой проблемой. Сброс DMA занимает доли микросекунды. Стек на ДМА в F2/F4 отключаемый (в данном случае он не используется). Для того, чтоб вероятность потери свести к 0 на время сброса DMA нужно переключать прием на прерывание по RX. Однако, для GSM модема с его логикой это не обязательно, пропусков не наблюдается, для GPS тем более проблемы нет. Мы же работаем с реальными устройствами и знаем как они фунциклируют. Говоря о вероятности ошибки, я допускаю, что существует такой девайс которые не сможет работать через этот драйвер. Эта идея не просто замена стека, а возможность дать процессору время для сна. В основном это актуально про использовании ОС. просто аппаратный стек эту задачу вообще никак не решает.
Сообщение отредактировал kan35 - Feb 8 2013, 12:14
|
|
|
|
|
Feb 9 2013, 09:33
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(kan35 @ Feb 8 2013, 18:10)  Сброс DMA занимает доли микросекунды. Т.е. - если скажем сброс занимает 0.1мкс и через UART за сутки у вас проходит скажем 10МБ данных (вполне реальная ситуация - через интерфейс обычного счётчика электроэнергии может проходить и больше), то вероятность потери раз в сутки близка к 100%? А если скажем у вас работает система сбора данных из ста таких устройств? Будет сто сбоев в сутки? Но даже если траффик меньше, значит сбои будут происходить реже, что ещё хуже, так как найти причину таких сбоев будет крайне сложно. Лучше было сразу уволить программиста с такими кривыми руками  Цитата(kan35 @ Feb 8 2013, 18:10)  Стек на ДМА в F2/F4 отключаемый (в данном случае он не используется). Стек в DMA???  Это новость! Всегда считал что в канале DMA может быть FIFO, но никак не LIFO... Цитата(kan35 @ Feb 8 2013, 18:10)  Для того, чтоб вероятность потери свести к 0 на время сброса DMA нужно переключать прием на прерывание по RX. Однако, для GSM модема с его логикой это не обязательно, пропусков не наблюдается, для GPS тем более проблемы нет. Мы же работаем с реальными устройствами и знаем как они фунциклируют. Говоря о вероятности ошибки, я допускаю, что существует такой девайс которые не сможет работать через этот драйвер. Выйдет новая прошивка для вашего GSM-модема, или захотите заложить другой модем, потому что старого уже не купить, и в новой прошивке модем станет немножко по другому слать данные в UART (скажем - с небольшими паузами) и где будет ваше ПО?  Цитата(kan35 @ Feb 8 2013, 18:10)  Эта идея не просто замена стека, а возможность дать процессору время для сна. В основном это актуально про использовании ОС. просто аппаратный стек эту задачу вообще никак не решает. По-моему Вы путаете стек с FIFO - это вообще-то совершенно разные вещи. И как раз стандартное FIFO в UART очень хорошо решает эту проблему, снижая частоту RX-прерываний до 14раз. Цитата(AHTOXA @ Feb 8 2013, 22:04)  А может быть, потери в таком случае и не случится? Просто в момент включении DMA будет взведён флажок RXNE, и принятый байт из UARTx->DR благополучно отправится в буфер DMA. Наверное это можно достаточно просто проверить - принять байт, не вычитывая его, и затем включить DMA. Потеря может быть не в момент включения, а в момент сброса DMA. Если, как пишет автор, проверить наличие данных в DMA, потом его сбросить, то если байт пришёл между проверкой и сбросом и не успел записаться в память, то он потеряется. Здесь никогда нельзя делать сброс DMA, можно делать только его запрет с последующим разрешением в новый буфер. И если уж работаем через DMA, то только так - тогда никаких обращений к регистру DR UART программно. Всегда нужно помнить: если у канала DMA есть FIFO, то после запрета канала, там могут остаться данные считанные с периферии но не записанные в память.
|
|
|
|
|
Feb 9 2013, 14:33
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(jcxz @ Feb 9 2013, 15:33)  Потеря может быть не в момент включения, а в момент сброса DMA. Если, как пишет автор, проверить наличие данных в DMA, потом его сбросить, то если байт пришёл между проверкой и сбросом и не успел записаться в память, то он потеряется. Здесь никогда нельзя делать сброс DMA, можно делать только его запрет с последующим разрешением в новый буфер. Ну так, собственно, сброс - это и есть запрет с последующим разрешением. Не думаете же вы, что кто-то в здравом уме будет делать reset периферийного устройства посреди его работы? От запрета данные не теряются, просто замораживается работа. Запрещаем работу DMA (сбросом бита EN), забираем данные, перенастраиваем указатели, включаем DMA. Если за это время придёт байт в UART, то он не потеряется, а будет принят в новый буфер сразу после включения DMA.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Feb 9 2013, 17:16
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(AHTOXA @ Feb 9 2013, 20:33)  Ну так, собственно, сброс - это и есть запрет с последующим разрешением. Не думаете же вы, что кто-то в здравом уме будет делать reset периферийного устройства посреди его работы? Я также думал что никто в здравом уме не будет называть запрет (останов) чего-либо сбросом, а стек - FIFO-буфером Цитата(AHTOXA @ Feb 9 2013, 20:33)  От запрета данные не теряются, просто замораживается работа. Запрещаем работу DMA (сбросом бита EN), забираем данные, перенастраиваем указатели, включаем DMA. Если за это время придёт байт в UART, то он не потеряется, а будет принят в новый буфер сразу после включения DMA. Именно о таком алгоритме я и говорил. И при этом не должно быть никаких посторонних доступов к приёмному буферу UART помимо DMA, даже когда DMA запрещён. Цитата(kan35 @ Feb 9 2013, 17:52)  14 уровневый буфер на USART на сколько я понимаю не снизит частоту возникновений прерываний в 14 раз. А почему должен? Знаете как работает обыкновенный FIFO UART на других CPU? Он генерит прерывание при достижения метки заполнения буфера (максимум==14байт) или при паузе в приёмном потоке более чем сколько-то бит. Цитата(kan35 @ Feb 9 2013, 17:52)  Если как вы предлагаете переключать на новый буфер, то могут произойти потери при переключении буферов, тем более переключить буферы нельзя если не выключить ДМА (по крайней ере так в STM32). А я что писал? Цитата(kan35 @ Feb 9 2013, 17:52)  Есть еще вариант, как можно отработать прерывание IDLE от USART: - Считать все байты в дугой буфер - Проверить не нападало ли новых данных и если нападало - выйти без действий - Если данные не нападало - просто отключить триггер ДМА, сбросить ДМА, проверить RXNE и вытащить из него байт если он там образовался - Включить триггер ДМА В данном случае у нас времени на операцию сброса ДМА ~100мкс, на частоте 115200, что практически гарантирует защиту от сбоя. В Вашем алгоритме я вижу много дыр, но по-моему объяснять бесполезно.....
|
|
|
|
Сообщений в этой теме
krdmitry STM32F UART + DMA на чтение Jul 14 2012, 10:45 KnightIgor Цитата(krdmitry @ Jul 14 2012, 12:45) Мож... Jul 14 2012, 11:56 krdmitry Цитата(KnightIgor @ Jul 14 2012, 15:56) М... Jul 14 2012, 12:11  e-serg Цитата(krdmitry @ Jul 14 2012, 21:11) 3. ... Jul 14 2012, 14:45  KnightIgor Цитата(krdmitry @ Jul 14 2012, 14:11) Иго... Jul 14 2012, 19:20   krdmitry Цитата(KnightIgor @ Jul 14 2012, 23:20) П... Jul 16 2012, 07:18    KnightIgor Цитата(krdmitry @ Jul 16 2012, 09:18) Да,... Jul 16 2012, 08:02     SSerge Цитата(KnightIgor @ Jul 16 2012, 15:02) П... Jul 16 2012, 20:20      KnightIgor Цитата(SSerge @ Jul 16 2012, 22:20) Как-т... Jul 17 2012, 07:18       demiurg_spb Цитата(KnightIgor @ Jul 17 2012, 11:18) Е... Jul 17 2012, 08:06 kan35 Здесь прерывания на заполнение половины буфера и б... Jul 15 2012, 15:35 diwil Цитата(krdmitry @ Jul 14 2012, 14:45) Все... Jul 16 2012, 07:30 krdmitry Цитата(diwil @ Jul 16 2012, 11:30) Есть. ... Jul 16 2012, 07:53 kan35 krdmitry, поясните, а то из референс мануала не вп... Jul 16 2012, 08:45 krdmitry Цитата(kan35 @ Jul 16 2012, 12:45) krdmit... Jul 16 2012, 09:08 diwil - IDLE прерывание это когда контроллер фиксирует п... Jul 16 2012, 09:07 kan35 ой, да, diwill
krdmitry, спасибо за ответ
Я вот то... Jul 16 2012, 09:57 kan35 Я сделал драйвер для USART, который работает через... Sep 28 2012, 06:04  demiurg_spb Цитата(jcxz @ Feb 7 2013, 11:44) Всё прек... Feb 7 2013, 08:12  _Артём_ Цитата(jcxz @ Feb 7 2013, 09:44) копирую ... Feb 7 2013, 11:29   jcxz Цитата(_Артём_ @ Feb 7 2013, 17:29) Почем... Feb 7 2013, 13:40   AHTOXA А может быть, потери в таком случае и не случится?... Feb 8 2013, 16:04      AHTOXA Цитата(jcxz @ Feb 9 2013, 23:16) Я также ... Feb 9 2013, 19:44       jcxz У меня - нет.
Ещё на первое своё сообщение я получ... Feb 10 2013, 08:42 Rash Отвечу сам на свой вопрос. Экспериментально провер... Jan 23 2013, 14:01 kan35 Если я правильно понимаю в чем проблема - то можно... Jan 27 2013, 12:25 Rash Задача такая: хотелось бы контролировать что начал... Jan 27 2013, 14:55 demiurg_spb В этой идее есть недостаток. Счётчик ДМА может ещё... Jan 28 2013, 05:20  kan35 Цитата(demiurg_spb @ Jan 28 2013, 09:20) ... Feb 3 2013, 07:06   demiurg_spb А зачем вообще что-то ресетить? Ведь у дма есть ци... Feb 3 2013, 07:39 kan35 Он итак в циркулярном режиме.
Вы просто проверяете... Feb 4 2013, 16:17 demiurg_spb Понятно. У вас под ОС видимо заточка, а у меня под... Feb 5 2013, 05:42  kan35 Цитата(demiurg_spb @ Feb 5 2013, 09:42) П... Feb 6 2013, 16:24 Rash Цитата(jcxz @ Feb 7 2013, 11:44) От колли... Feb 7 2013, 08:15 kan35 Уважаемый jcxz,
Назвал буфер ДМА стеком, ну и что ... Feb 9 2013, 11:52 kan35 Да, я FIFO назвал стеком, предайте анафеме меня. Ч... Feb 9 2013, 17:49 jcxz Я ещё в самом первом своём посте в эту тему написа... Feb 9 2013, 19:14 uriy Не могу никак запустить UART1 DMA на прием.
По пре... Apr 5 2015, 15:17 PeterBr пример кода работы DMA->USART DMA-USART Apr 14 2016, 13:36 golf2109 вот ссылки
dma-to-usart
uart-dma-out
dma-uart-i... Apr 15 2016, 00:27 d_el Ловля конца пакета на IDLE. Видно задержку в 1,5 ... Aug 3 2016, 21:38 Obam Цитата(d_el @ Aug 4 2016, 01:38) Ловля ко... Aug 4 2016, 07:29
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|