Загадка DMA[STM32F205RG]
Загадка DMA[STM32F205RG]
Добрый день. Помогите решить загадку связанную с работой DMA на контроллере STM32F205RG.
Загадка состоит в следующем. Я в непрерывном цикле при помощи DMA снимаю данные с канала UART. Все прекрасно работает и приходят валидные данные. Но, порой, после 6 -8 часов непрерывной работы передача попросту прекращается. Причем данные на вход UART идут все также непрерывно как и раньше. Отловил проблему в отладчике, выяснилось что программа крутится в основном цикле ожидая прерывания от DMA, но прерывания не происходит, несмотря на наличие данных в регистре UART. И до тех пор пока не сбросишь контроллер в Reset, запись не возобновляется. Данная ошибка не имеет какой то осознанного цикла повторения: возникнуть может как через 2 часа так и через 8 часов.
Подскажите, может кто то сталкивался с такой ошибкой.
P.S. Выкладывать свой код не вижу смысла, так как все вполне себе отлично работает в течении долгого времени и ошибки в конфигурации чего либо быть не должно. Тут надо размышлять)
Загадка состоит в следующем. Я в непрерывном цикле при помощи DMA снимаю данные с канала UART. Все прекрасно работает и приходят валидные данные. Но, порой, после 6 -8 часов непрерывной работы передача попросту прекращается. Причем данные на вход UART идут все также непрерывно как и раньше. Отловил проблему в отладчике, выяснилось что программа крутится в основном цикле ожидая прерывания от DMA, но прерывания не происходит, несмотря на наличие данных в регистре UART. И до тех пор пока не сбросишь контроллер в Reset, запись не возобновляется. Данная ошибка не имеет какой то осознанного цикла повторения: возникнуть может как через 2 часа так и через 8 часов.
Подскажите, может кто то сталкивался с такой ошибкой.
P.S. Выкладывать свой код не вижу смысла, так как все вполне себе отлично работает в течении долгого времени и ошибки в конфигурации чего либо быть не должно. Тут надо размышлять)
- Реклама
- Neekeetos
- Держит паяльник хвостом
- Сообщения: 993
- Зарегистрирован: Пн сен 18, 2006 11:16:05
- Откуда: Тула
- Контактная информация:
Re: Загадка DMA[STM32F205RG]
Пока гадалки подтягиваются выскажу свое предположение. Флаги статуса уарта не проверяются никак, происходит переполнение после чего уарт перестает делать запросы дма.Foxek писал(а):P.S. Выкладывать свой код не вижу смысла, так как все вполне себе отлично работает в течении долгого времени и ошибки в конфигурации чего либо быть не должно. Тут надо размышлять)
Информация по RLC mini находится >тут<
Re: Загадка DMA[STM32F205RG]
Допустим я выложу код, но какую именно его часть мне выложить? инициализацию и обработку прерывания?
- Neekeetos
- Держит паяльник хвостом
- Сообщения: 993
- Зарегистрирован: Пн сен 18, 2006 11:16:05
- Откуда: Тула
- Контактная информация:
Re: Загадка DMA[STM32F205RG]
Да, для начала будет достаточно. Сам процессор сильно загружен?Foxek писал(а):но какую именно его часть мне выложить? инициализацию и обработку прерывания?
Информация по RLC mini находится >тут<
Re: Загадка DMA[STM32F205RG]
Один канал DMA собирает данные по UART в кольцевой буфер, Другой канал по SDIO пишет на SD карту.+ Парочку счетных таймеров и один ШИМ таймер. Но их приоритеты меньше чем приоритет DMA.
Инициализация DMA и UART:
Обработка прерываний от DMA
Инициализация DMA и UART:
Код: Выделить всё
void UART_INIT(void){
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_DeInit(USART1);
USART_InitStructure.USART_BaudRate = 4000000;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx;
USART_OverSampling8Cmd(USART1, ENABLE);
USART_Init(USART1,&USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
void DMA_INIT(uint32_t* dma_buf_0, uint32_t* dma_buf_1 ){
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/* Configure RX DMA double buffering DMA2_Stream5 Channel 4 USART1_RX */
DMA_DeInit(DMA2_Stream5);
DMA_USARTStructure.DMA_Channel = DMA_Channel_4;
DMA_USARTStructure.DMA_PeripheralBaseAddr =(uint32_t) (&(USART1->DR)) ;
DMA_USARTStructure.DMA_Memory0BaseAddr = (uint32_t) dma_buf_0;
DMA_USARTStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_USARTStructure.DMA_BufferSize = (uint32_t) RECEIVE_BUF_SIZE;
DMA_USARTStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_USARTStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_USARTStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_USARTStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_USARTStructure.DMA_Mode = DMA_Mode_Circular;
DMA_USARTStructure.DMA_Priority = DMA_Priority_Medium;
DMA_USARTStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_USARTStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_USARTStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC16 ;
DMA_USARTStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_DoubleBufferModeConfig(DMA2_Stream5, (uint32_t) dma_buf_1, DMA_Memory_0);
DMA_DoubleBufferModeCmd(DMA2_Stream5, ENABLE);
DMA_Init(DMA2_Stream5,&DMA_USARTStructure);
/* Enable DMA Stream Transfer Complete interrupt */
DMA_ITConfig(DMA2_Stream5, DMA_IT_TC, ENABLE);
/* Enable DMA USART RX Stream */
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
DMA_Cmd(DMA2_Stream5,ENABLE);
}
Обработка прерываний от DMA
Код: Выделить всё
void DMA2_Stream5_IRQHandler(void){
if (DMA_GetFlagStatus(DMA2_Stream5, DMA_FLAG_TCIF5) == SET){
DMA_ClearFlag(DMA2_Stream5, DMA_FLAG_TCIF5);
if ( DMA_GetCurrentMemoryTarget(DMA2_Stream5) == 0 )
bufInfoSDWrite.buf = (uint32_t*) DMA2_Stream5->M1AR;
else
bufInfoSDWrite.buf= (uint32_t*) DMA2_Stream5->M0AR;
bufInfoSDWrite.bufSize = RECEIVE_BUF_SIZE;
DeviceMode = DEVICE_MODE_SD_WRITE;
}
}
- Реклама
- Neekeetos
- Держит паяльник хвостом
- Сообщения: 993
- Зарегистрирован: Пн сен 18, 2006 11:16:05
- Откуда: Тула
- Контактная информация:
Re: Загадка DMA[STM32F205RG]
Как я и предположил исключения UART не обрабатываются, это приведет к остановке запросов к дма в случае возникновения переполнения или других ошибок. Поэтому нужно активировать прерывание уарта в нвик и написать обработчик уарт. В самом уарте нужно включить бит EIE в CR3, это будет генерировать прерывания в случае если активируются флажки ORE,FE,NF из SR. Соотв. в обработчике нужно будет зафиксировать что именно произошло и сбросить соответствующий флаг , это запустит нормальный прием.Foxek писал(а):Один канал DMA собирает данные по UART в кольцевой буфер,
Информация по RLC mini находится >тут<
Re: Загадка DMA[STM32F205RG]
Спасибо, попробую. А такой вопроса, какую именно ошибку я жду, какой именно флаг мне сбрасывать в прерывании?
- Neekeetos
- Держит паяльник хвостом
- Сообщения: 993
- Зарегистрирован: Пн сен 18, 2006 11:16:05
- Откуда: Тула
- Контактная информация:
Re: Загадка DMA[STM32F205RG]
Это вопрос на 5 баллов, нужно писать прерывание и смотреть что вылезет. Я думаю что это скорее всего переполнение (aka overrun), но если процессор не занят ничем то она маловероятна, остаются ошибки фрейминга. Раз данные идут непрерывно вполне можно представить ситуацию, когда такты приемника и передатчика не совпадают и время от времени будет возникать ошибка синхронизации.Foxek писал(а):А такой вопроса, какую именно ошибку я жду
Все сразу, при считывании SR и затем DR любой из них сбросится. Главное проверить что за флаги были активны, от этого зависят дальнейшие действия.Foxek писал(а):какой именно флаг мне сбрасывать в прерывании?
Информация по RLC mini находится >тут<
Re: Загадка DMA[STM32F205RG]
А допустим, если я отловлю эту ошибку, как мне дальше поступать?)Ведь по идее, флаг прерывания сбрасывается если прочитать данные, а они читаются посредством DMA. То есть если я найду ошибку мне надо просто включить прерывания по нему и в обработике даже нчиего делать не надо?
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Загадка DMA[STM32F205RG]
Задача программиста — написать не ту программу, которая работает, когда всё хорошо, а ту, которая работает, когда всё плохо. Другими словами, если ошибка возможна, то всегда должен быть код, который эту ошибку в случае возникновения соответствующим образом обрабатывает.
- Neekeetos
- Держит паяльник хвостом
- Сообщения: 993
- Зарегистрирован: Пн сен 18, 2006 11:16:05
- Откуда: Тула
- Контактная информация:
Re: Загадка DMA[STM32F205RG]
Барсук в общем верно сказал. Как минимум нужно обнаруживать факт ошибок и сбрасывать их, тогда будет восстанавливаться нормальная работа а не как сейчас все встает колом. С другой стороны, если будет известно что за ошибка, можно попробовать еще и сделать так, чтобы она не возникала. Например в передатчике сделать паузы передачи или увеличить количество стоп битов или еще что. Все сильно зависит от конкретной проблемы, может дело в помехах из за которых возникают ошибки и уж тут мало что можно поделать кроме как молча потерять байт - два на приеме.Foxek писал(а):А допустим, если я отловлю эту ошибку, как мне дальше поступать?)
Информация по RLC mini находится >тут<
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Загадка DMA[STM32F205RG]
Я тут внезапно понял, что при асинхронном приёме чтобы UART восстановил свою работу после неудачно принятой посылки необходимо, чтобы линия данных находилась в состоянии Idle в течении длительности хотя бы одной посылки или чтобы в одном из посылаемых сообщений все посылаемые биты (включая бит чётности) были единицами. Если данные шлются непрерывно, то может получиться так, что UART не сможет синхронизироваться по той причине, что каждый раз будет принимать за старт-бит какой-то из посылаемых нулей.
Возможно, у топикстартера именно такая проблема.
Возможно, у топикстартера именно такая проблема.


