Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32 + Freertos. Проблемы с DMA
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Vladimir Prokofiev
Помогите разобраться!

Процессор STM32F215, FreeRtos

В одной из задач используется запись на SD карточку текущих параметров устройства. По сути задача низкоприоритетная.

Есть вторая задача, высоко приоритетная, которая должна по ком-порту выдавать небольшие порции данных во вне.

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

Если записи сделать малый приоритет, то через n минут работы происходит сбой. Выглядит это так, как будто не может завершиться dma передача:

SD_ReadBlock( Buffer, SectorNumber * BLOCKSIZE, BLOCKSIZE );
Status = SD_WaitReadOperation(); <-- Сидим внутри этой функции, которая проверяет DMA_GetFlagStatus(SD_SDIO_DMA_STREAM, SD_SDIO_DMA_FLAG_TCIF) != RESET
while(SD_GetStatus() != SD_TRANSFER_OK)

Обламывается только чтение с карты. Если этот код помещен в критическую секцию то сбоев не происходит.

Вопросов по этому поводу несколько...

1. Почему оборачивание этого в критическую секцию вызывает реальные задержки выполнения высокоприоритетной задачи( в ней стоит мигание светодиодом, и глазом видно задержку sm.gif
2. Почему уход в этом месте в другую задачу может привести к тому, что DMA не выставляет флаг успешной отправки?

Ну и еще давно хотел узнать но не решался спросить:
Пример, отсылаем что-то в ком-порт в задаче. Чтобы не городить прерывания, пишем так:
while( USART_GetFlagStatus( AP_OUTUART2, USART_FLAG_TC ) == RESET );

USART_SendData( AP_OUTUART2, c );
Очевидно что процессор стоит в цикле и ждет пока байт не ушел. Можно ли отослав байт переключить задачу, или это получается неоправданно?
При скорости, скажем 9600 это занимает около 1/1000 сек. По умолчанию один тик фриртоса этому равен, и при таком тике я не вижу смысла переключать задачу -- дороже выйдет...

Заранее спасибо)
RabidRabbit
Я выдачу порций данных через UART организовал с помощью DMA - зарядил буфер и можно висеть на семафоре, пока он не уйдёт, за это время другие задачи чем-нибудь полезным занимаются...
kan35
У меня были проблемы несколько подобного рода.
Просто библиотека FAT не парилась и отправляла/принимала сектора не обязательно выровненные на 4 байта, у DMA в результате сносило крышу.

И по правильному надо сделать, чтобы по окончании DMA transfere происходило прерывание и в нем взводите семафор. А в задаче ждете семафор после начала трансфера.
Vladimir Prokofiev
Ну я пользую fatfs, правда все функции типо mem_cpy переписал на стандартные memcpy, и вроде работает если задачи не переключать, так что нареканий на fatfs в целом нет.

Написал сейчас так
taskENTER_CRITICAL();
SD_ReadBlock( Buffer, SectorNumber * BLOCKSIZE, BLOCKSIZE );
taskEXIT_CRITICAL();
Status = SD_WaitReadOperation();
while(SD_GetStatus() != SD_TRANSFER_OK)
и с утра работает без сбоев sm.gif

Таким образом получается что глюк случается когда другая задача прерывает эту внутри SD_ReadBlock.
Если я все правильно понимаю, то в этой функции мы говорим карточке выдать блок и настрайваем DMA на прием блока. Если другая задача влезает в тот момент, когда мы уже попросили блок, но не настроили DMA, то передача уже пошла и блок\часть блока мы профукали? Ну и тогда как раз и случится то, что случается, DMA не сбрасывает флаг потому, что по его мнению блок еще не дошел.
Или это все не так?
Sagittarius
если SD делается на базе stm324xg_eval_sdio_sd.c то там есть такие штуки как полинг битов статуса DMA в бесконечных или очень длинных циклах, из за этого может затыкаться все менее приоритетное во FreeRTOS, пока SD не отработает.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.