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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> STM32F UART + DMA на чтение, Как реализовать чтение через DMA для потока данных?
KnightIgor
сообщение Jul 17 2012, 07:18
Сообщение #16


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(SSerge @ Jul 16 2012, 22:20) *
Как-то сложновато...
Если отказаться от счётчика (а зачем он нужен?) и оперировать только указателями на "голову" и "хвост" буфера, то и флаг не понадобиться, и прерывания можно не трогать, один раз только разрешить при инициализации и всё.

Если оба указателя равны друг другу, буфер пуст или полон?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 17 2012, 08:06
Сообщение #17


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

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



Цитата(KnightIgor @ Jul 17 2012, 11:18) *
Если оба указателя равны друг другу, буфер пуст или полон?
Принять на веру что пуст.
Просто размер фифо нужно с запасом выбрать и выгребать его достаточно регулярно.
По сути те же самые ограничения на производительность что и у вас, но у вас всё гавкнется гораздо раньше...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
kan35
сообщение Sep 28 2012, 06:04
Сообщение #18


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Я сделал драйвер для USART, который работает через DMA, может быть пригодится кому нибудь. Извлекал его потом из реального проекта, так что мог что то упустить, но надеюсь не упустил.
Длайвер работает через USART1, адаприровать под другие порты, думаю не составит труда.
Основной прием данных производится в буфер через DMA канал. По заполнению половинок буфера данные извлекаются и передаются в обработчик. В случае применения RTOS данные передаются в предусмотренный для данных queue (или в другой терминологии - в "message box"). Буфер может быть достаточно большого размера - 128 и более байт и в случае, если передача остановилась где то посередине и DMA прерывание не возникает, то через несколько пустых временных окон приема символов возникает прерывание "IDLE line" от USART, в данном прерывании вытаскивается хвост данных и DMA канал сбрасывается в стартовое состояние.
Дан проект-пример. Основные файлы - main.c и STM32F10x_it.c. В main.c производится вся настрока периферии. В во втором прерывании все необходимые обработчики, а именно - от DMA и от USART.
Ссылка
Go to the top of the page
 
+Quote Post
Rash
сообщение Jan 9 2013, 14:51
Сообщение #19


Знающий
****

Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231



А есть ли возможность аппаратно увидеть что начался приём данных?, что бы не начать новую передачу в случае RS-485 и не подгонять тайм ауты посылок. А то принимать всю посылку по IDLE удобно, но не знаешь есть она или нет в данный момент. Проверка флага RXNE в регистре USARTx_SR не помогла, этот флаг иногда ловится на несколько приходящих посылок, причём сбрасывался он сам, наверное DMA когда забирает байт данных очищает его.
Мк ST32F407.
Go to the top of the page
 
+Quote Post
Rash
сообщение Jan 23 2013, 14:01
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231



Отвечу сам на свой вопрос. Экспериментально проверил, если использовать режим IDLE и при этом DMA забирает всю посылку, то и флаг RXNE очищается когда его забрало DMA и прерывание по приёму USART_IT_RXNE никогда не произойдёт. Вижу только 2 выхода что бы определить старт приёма: Принять 1-ый байт и подключить потом DMA для приёма оставшейся посылки, 2-ой использовать ещё один бит порта как внешнее прерывание (поймать старт бит и отключить потом внешнее прерывания, до приёма полной посылки).
Go to the top of the page
 
+Quote Post
kan35
сообщение Jan 27 2013, 12:25
Сообщение #21


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Если я правильно понимаю в чем проблема - то можно контроллировать счетчик передачи DMA. Если он не равен одному из 2 указателей, то передача в процессе.
Go to the top of the page
 
+Quote Post
Rash
сообщение Jan 27 2013, 14:55
Сообщение #22


Знающий
****

Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231



Задача такая: хотелось бы контролировать что начался приём. Как я понял вы предлагаете периодически опрашивать счётчик байтов DMA, и если он не равен 0, то значит идёт прём данных. Как то не подумал о таком, попробую при случае, спасибо за идею.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jan 28 2013, 05:20
Сообщение #23


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

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



В этой идее есть недостаток. Счётчик ДМА может ещё не измениться а приём байта быть в процессе.
Байты же не мгновенно принимаются, а по-битно...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
kan35
сообщение Feb 3 2013, 07:06
Сообщение #24


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Цитата(demiurg_spb @ Jan 28 2013, 09:20) *
В этой идее есть недостаток. Счётчик ДМА может ещё не измениться а приём байта быть в процессе.
Байты же не мгновенно принимаются, а по-битно...

Вероятность потери байта предельно низка, так как сначала достаются все байты из массива ДМА, затем еще раз проверяется счетчик ДМА и если он не изменился за время вытаскивания данных, то ДМА ресетится. Процедура сброса ДМА занимает доли микросекунды. В принципе, можно на время сброса ДМА переключать прием на прерывание, а затем назад. Но как показывает практика, и без этого все хорошо. По крайней мере через GPRS модем на 115200 (при скорости HCLK всего лишь 4МГц) удается принимать массивы несколько сот кБ без потерь (больше просто не пробовал). При этом контроллер под управлением freertos обслуживает около 10 задач и еще эпизодически работают 4 канала того же ДМА.

Сообщение отредактировал kan35 - Feb 3 2013, 07:08
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 3 2013, 07:39
Сообщение #25


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

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



А зачем вообще что-то ресетить? Ведь у дма есть циркулярный режим...

Код
//=============================================================================
int uart_getc(uart_t* const uart)
{
    dma_t* const dma = &uart->dma.rx;

    if (dma->size - dma->sfr->CNDTR != dma->idx)
    {
        int x = dma->buf[dma->idx];

        if (++dma->idx >= dma->size)
        {
            dma->idx = 0;
        }

        return (x);
    }

    return (-1);
}


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
kan35
сообщение Feb 4 2013, 16:17
Сообщение #26


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Он итак в циркулярном режиме.
Вы просто проверяете наличие данных в ДМА памяти, но не это цель. А цель сделать все максимально аппаратно. То есть без участия процессора.
В моем варианте при зполнении половинок буфера ДМА (или как вариант разных буферов в процессорах F2 и F4) возникают прерывания, в которых данные забираются. При паузе в передаче - данные так же успешно забираются из прерывания IDLE line. Никаких поллингов!
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 5 2013, 05:42
Сообщение #27


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

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



Понятно. У вас под ОС видимо заточка, а у меня под луп.
Цитата(kan35 @ Feb 4 2013, 20:17) *
Вы просто проверяете наличие данных в ДМА памяти
Да. Я ДМА как фифо использую.
Кстати, на передачу у вас тоже ДМА задействовано?
У меня нет. Красивого решения не придумалось...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
kan35
сообщение Feb 6 2013, 16:24
Сообщение #28


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Цитата(demiurg_spb @ Feb 5 2013, 09:42) *
Понятно. У вас под ОС видимо заточка, а у меня под луп.Да. Я ДМА как фифо использую.
Кстати, на передачу у вас тоже ДМА задействовано?
У меня нет. Красивого решения не придумалось...

Да, под ОСь.
На передачу не сделал, но надо бы, руки не дошли пока. Для Оси передача получится просто красиво: задача уснет до окончания выполнения передачи. Для лупа не так просто будет, придумывать надо что то...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 7 2013, 07:44
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 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. Могут-ли в таком алгоритме быть потери байт или другие проблемы?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 7 2013, 08:12
Сообщение #30


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

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



Цитата(jcxz @ Feb 7 2013, 11:44) *
Всё прекрасно работает на stm32. Не паникуйте!:)
Кстати, у stm32f0 много вкусностей в модуле uart появилось относительно stm32f1. Так-что не надо всех под одну гребёнку....
Вы всё равно не составите адекватного мнения, пока не попробуете лично. ИМХО.


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

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 15:07
Рейтинг@Mail.ru


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