Загадка DMA[STM32F205RG]

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Foxek
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Сб дек 28, 2013 20:31:22

Загадка DMA[STM32F205RG]

Сообщение Foxek »

Добрый день. Помогите решить загадку связанную с работой DMA на контроллере STM32F205RG.
Загадка состоит в следующем. Я в непрерывном цикле при помощи DMA снимаю данные с канала UART. Все прекрасно работает и приходят валидные данные. Но, порой, после 6 -8 часов непрерывной работы передача попросту прекращается. Причем данные на вход UART идут все также непрерывно как и раньше. Отловил проблему в отладчике, выяснилось что программа крутится в основном цикле ожидая прерывания от DMA, но прерывания не происходит, несмотря на наличие данных в регистре UART. И до тех пор пока не сбросишь контроллер в Reset, запись не возобновляется. Данная ошибка не имеет какой то осознанного цикла повторения: возникнуть может как через 2 часа так и через 8 часов.

Подскажите, может кто то сталкивался с такой ошибкой.
P.S. Выкладывать свой код не вижу смысла, так как все вполне себе отлично работает в течении долгого времени и ошибки в конфигурации чего либо быть не должно. Тут надо размышлять)
Реклама
Аватара пользователя
Neekeetos
Держит паяльник хвостом
Сообщения: 993
Зарегистрирован: Пн сен 18, 2006 11:16:05
Откуда: Тула
Контактная информация:

Re: Загадка DMA[STM32F205RG]

Сообщение Neekeetos »

Foxek писал(а):P.S. Выкладывать свой код не вижу смысла, так как все вполне себе отлично работает в течении долгого времени и ошибки в конфигурации чего либо быть не должно. Тут надо размышлять)
Пока гадалки подтягиваются выскажу свое предположение. Флаги статуса уарта не проверяются никак, происходит переполнение после чего уарт перестает делать запросы дма.
Информация по RLC mini находится >тут<
Реклама
Foxek
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Сб дек 28, 2013 20:31:22

Re: Загадка DMA[STM32F205RG]

Сообщение Foxek »

Допустим я выложу код, но какую именно его часть мне выложить? инициализацию и обработку прерывания?
Аватара пользователя
Neekeetos
Держит паяльник хвостом
Сообщения: 993
Зарегистрирован: Пн сен 18, 2006 11:16:05
Откуда: Тула
Контактная информация:

Re: Загадка DMA[STM32F205RG]

Сообщение Neekeetos »

Foxek писал(а):но какую именно его часть мне выложить? инициализацию и обработку прерывания?
Да, для начала будет достаточно. Сам процессор сильно загружен?
Информация по RLC mini находится >тут<
Реклама
Эиком - электронные компоненты и радиодетали
Foxek
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Сб дек 28, 2013 20:31:22

Re: Загадка DMA[STM32F205RG]

Сообщение Foxek »

Один канал DMA собирает данные по UART в кольцевой буфер, Другой канал по SDIO пишет на SD карту.+ Парочку счетных таймеров и один ШИМ таймер. Но их приоритеты меньше чем приоритет 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]

Сообщение Neekeetos »

Foxek писал(а):Один канал DMA собирает данные по UART в кольцевой буфер,
Как я и предположил исключения UART не обрабатываются, это приведет к остановке запросов к дма в случае возникновения переполнения или других ошибок. Поэтому нужно активировать прерывание уарта в нвик и написать обработчик уарт. В самом уарте нужно включить бит EIE в CR3, это будет генерировать прерывания в случае если активируются флажки ORE,FE,NF из SR. Соотв. в обработчике нужно будет зафиксировать что именно произошло и сбросить соответствующий флаг , это запустит нормальный прием.
Информация по RLC mini находится >тут<
Реклама
Foxek
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Сб дек 28, 2013 20:31:22

Re: Загадка DMA[STM32F205RG]

Сообщение Foxek »

Спасибо, попробую. А такой вопроса, какую именно ошибку я жду, какой именно флаг мне сбрасывать в прерывании?
Аватара пользователя
Neekeetos
Держит паяльник хвостом
Сообщения: 993
Зарегистрирован: Пн сен 18, 2006 11:16:05
Откуда: Тула
Контактная информация:

Re: Загадка DMA[STM32F205RG]

Сообщение Neekeetos »

Foxek писал(а):А такой вопроса, какую именно ошибку я жду
Это вопрос на 5 баллов, нужно писать прерывание и смотреть что вылезет. Я думаю что это скорее всего переполнение (aka overrun), но если процессор не занят ничем то она маловероятна, остаются ошибки фрейминга. Раз данные идут непрерывно вполне можно представить ситуацию, когда такты приемника и передатчика не совпадают и время от времени будет возникать ошибка синхронизации.
Foxek писал(а):какой именно флаг мне сбрасывать в прерывании?
Все сразу, при считывании SR и затем DR любой из них сбросится. Главное проверить что за флаги были активны, от этого зависят дальнейшие действия.
Информация по RLC mini находится >тут<
Foxek
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Сб дек 28, 2013 20:31:22

Re: Загадка DMA[STM32F205RG]

Сообщение Foxek »

А допустим, если я отловлю эту ошибку, как мне дальше поступать?)Ведь по идее, флаг прерывания сбрасывается если прочитать данные, а они читаются посредством DMA. То есть если я найду ошибку мне надо просто включить прерывания по нему и в обработике даже нчиего делать не надо?
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: Загадка DMA[STM32F205RG]

Сообщение B@R5uk »

Задача программиста — написать не ту программу, которая работает, когда всё хорошо, а ту, которая работает, когда всё плохо. Другими словами, если ошибка возможна, то всегда должен быть код, который эту ошибку в случае возникновения соответствующим образом обрабатывает.
Аватара пользователя
Neekeetos
Держит паяльник хвостом
Сообщения: 993
Зарегистрирован: Пн сен 18, 2006 11:16:05
Откуда: Тула
Контактная информация:

Re: Загадка DMA[STM32F205RG]

Сообщение Neekeetos »

Foxek писал(а):А допустим, если я отловлю эту ошибку, как мне дальше поступать?)
Барсук в общем верно сказал. Как минимум нужно обнаруживать факт ошибок и сбрасывать их, тогда будет восстанавливаться нормальная работа а не как сейчас все встает колом. С другой стороны, если будет известно что за ошибка, можно попробовать еще и сделать так, чтобы она не возникала. Например в передатчике сделать паузы передачи или увеличить количество стоп битов или еще что. Все сильно зависит от конкретной проблемы, может дело в помехах из за которых возникают ошибки и уж тут мало что можно поделать кроме как молча потерять байт - два на приеме.
Информация по RLC mini находится >тут<
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: Загадка DMA[STM32F205RG]

Сообщение B@R5uk »

Я тут внезапно понял, что при асинхронном приёме чтобы UART восстановил свою работу после неудачно принятой посылки необходимо, чтобы линия данных находилась в состоянии Idle в течении длительности хотя бы одной посылки или чтобы в одном из посылаемых сообщений все посылаемые биты (включая бит чётности) были единицами. Если данные шлются непрерывно, то может получиться так, что UART не сможет синхронизироваться по той причине, что каждый раз будет принимать за старт-бит какой-то из посылаемых нулей.

Возможно, у топикстартера именно такая проблема.
Ответить

Вернуться в «ARM»