totalsam wrote on Tuesday, January 18, 2011:
Dear all,
Thank you very much for reading my post. I have some issues with a custom board based on a STM32 (Cortex M3).
I use FreeRTOS v6.1.0 with CodeSourcery’s GCC and Eclipse.
In my design, I communicate with a GPRS device through an USART port. The crash occurs when receiving a packet from the GPRS device, after a few minutes running.
When a data arrives on the USART, the DMA copies it to a buffer, and an interrupt is generated. In the ISR, I just give a semaphore, which unblocks an other task.
I paid attention to the special remarks for CM3 users. Here is the init of the NVIC:
NVIC_InitStructure.NVIC_IRQChannel = UART_Gprs_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
In FreeRTOSconfig.h, is set to 255, which on the STM32 means 15. The interrupt priority is the same as the kernel interrupt priority. I tried to put it 1 above (set it to 14), but no change.
When the crash occurs, the code loops forever in list.c, in vListInsert(…), in the for(…) loop. By putting some traces, I was able to find that the code crashes either at the end of the ISR, either at the task side that waits for the semaphore.
Here is the ISR code :
void USART3_IRQHandler(void)
{
long xHigherPriorityTaskWoken = pdFALSE;
debug_flag = 51;
//Don't need to clear the bit, 'cause the DMA controller normally does it
USART_ITConfig(UART_Gprs, USART_IT_RXNE, DISABLE);//Disable interrupt
xSemaphoreGiveFromISR(xGprsRxSemaphore, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken == pdTRUE)
{
debug_hpw = 1;
debug_flag = 52;
}
else
{
debug_hpw = 0;
debug_flag = 55;
}
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
I also noticed that if I don’t put the portEND_SWITCHING_ISR(…) in this ISR, the crash does not occur.
Here is the code at the task side:
debug_flag = 53;
xSemaphoreTake(xGprsRxSemaphore, ( portTickType ) 200 / portTICK_RATE_MS );
debug_flag = 54;
dma_cnt = DMA_GetCurrDataCounter(UART_Gprs_Rx_DMA_Channel);
while( (gprsRxBuffIndex !=
(UART_BUFFER_SIZE - dma_cnt) ) && (data_cnt < maxLength))
{
buffer[*length] = gprsRxBuffer[gprsRxBuffIndex++];
*length = (*length) + 1;
data_cnt++;
if (gprsRxBuffIndex > UART_BUFFER_SIZE-1)
{
gprsRxBuffIndex = 0;
}
}
USART_ITConfig(UART_Gprs, USART_IT_RXNE, ENABLE);
Could someone give me a few hints to debug my code and try to find what’s going on ?
Thank you a lot in advance and best regards,
Sam