Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

STM32F4 SPI interrupt and task communication

Posted by https://www.google.com/accounts on April 16, 2013
Hi,

I am working on a project with STM32F4 and FreeRTOS. I have a SPI ISR for receiving data from SPI in the speed of about 5Mbps, I also have a task which handles those data. The Queue is used to be between the interrupt and task.

xQueue=xQueueCreate(10,sizeof(uint8_t)*BufferSize);


The problem is that the task stops working after some time of normal running. But the SPI receive seems to be still continuing because I can still see the waveforms in the oscillopscope. The implementation of SPI receive ISR is as follows:


void SPI1_IRQHandler(void)
{
static portBASE_TYPE xHigherPriorityTaskWoken;
portBASE_TYPE xStatus;
xHigherPriorityTaskWoken = pdFALSE;



while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
if(index_spi<512)
{
lValueSend[index_spi]=SPI_I2S_ReceiveData(SPI1);
index_spi++;
SPI_I2S_SendData(SPI1,0x22);
}
else{
index_spi=0;
xStatus=xQueueSendToBackFromISR(xQueue,&lValueSend,&xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
}


And inside the task infinite loop:
xStatus=xQueueReceive(xQueue,&lValueReceive,xTicksToWait);

if(xStatus==pdPASS){
dataProcess(lValueReceive);

}


After some debugging, I found out that the queue becomes full very easily, and the context switch doesn't happen. So it seems that my task just never gets a chance of running again. But if I understand correctly, after the ISR, either we switch the context to the task waiting for queue if this task waiting for the queue has a higher priority than the current one which was interrupted, either we return to the task which was interrupted. My Datahandling task is already set to configMAX_PRIORITIES, so even if we return to the privious task, my task should have been given control to run. Someone can help to analyse and understand?

And also the interrupt priority thing makes me confused. My SPI IRQ settings is:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;


In the FreeRTOS document, there are two which are absolutely not my settings at all. One is http://www.freertos.org/RTOS-Cortex-M3-M4.html,
"If you are using an STM32 with the STM32 driver library then ensure all the priority bits are assigned to be preempt priority bits by calling NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); before the RTOS is started."

Another one is that the interrupt with priority between configMAX_SYSCALL_INTERRUPT_PRIRITY and configMAX_SYSCALL_INTERRUPT_PRIORITY can use the freeRTOS API functions. My settings are
#define configKERNEL_INTERRUPT_PRIORITY       255
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */


With the mapping of STM32, the priority between 11 and 15 can use FreeRTOS API. But my settings are completely out of these two rules, but after test, this is the best config. If I put the NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ) and set the PreemptionPriority to 15. The task stops even more quickly. Someone may also help to understand with this?



RE: STM32F4 SPI interrupt and task communication

Posted by Richard on April 16, 2013
First, you have in part answered your own question when (paraphrasing) you say "the documentation says not to do this because it won't work correctly, but I have done it anyway". So the first piece of advise is to configure your system in accordance with the documentation.

That done, you should not find that a queue becoming full would in any way prevent a task from executing, you would just miss characters that could not be placed into the queue as they were received.

“while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);”


I'm not sure what this line of code is doing, but if it is polling a bit in a register then it is not the sort of code I would necessarily expect to see in an interrupt handler. Generally the interrupt handler should only be entered when a character is actually available, otherwise *all* your tasks are going to be prevented from executing while the interrupt handler is polling.

On the other hand if the line of code is somehow resetting a bit in a register and just reading it back to ensure it is reset before continuing then it should be ok.

Similar comments for calling functions that send data from inside the receive handler.


As more general comments - normally when attempting to received data at that rate it is not a good idea to use an RTOS queue to send the data to a task. Instead it is better to either use a RAM circular buffer, or ideally a DMA. The DMA would receive the data and the DMA end Rx interrupt would be used to unblock a task only when there was a break in the reception.

Regards.

RE: STM32F4 SPI interrupt and task communication

Posted by https://www.google.com/accounts on April 16, 2013
Thanks for your reply, richardbarry. I've already tried to use the recommanded configuration, like I said with NVIC_group4 and Preemption priority 15(lowest), the task stops anyway. And it's like stopping immediately as I start to send something from SPI. With my current wrong setting, it can still run for several seconds and then stops.

Then I tried to slow down my SPI to about 1Mbps, it works very stable with my wrong settings, the task didn't stop at all, but with the config which is supposed to be the right one, the task stops at some point in the same test. So that's why it's so strange.


You are right about the flag staff, I just comment it now but it doesn't seem to change anything. I've done another test which just doesn't process the data anymore and only keep the queue receive there.
xStatus=xQueueReceive(xQueue,&lValueReceive,xTicksToWait);

if(xStatus==pdPASS){
//dataProcess(lValueReceive);

}


Then my task still stops, so it seems that it's not my processing which is slow but the queue just doesn't catch up.

RE: STM32F4 SPI interrupt and task communication

Posted by https://www.google.com/accounts on April 16, 2013
And also I found something similar in the STM32 examples which seemed to be wrong. In the STM32F4 FreeRTOS httpserver_netconn example, the Ethernet interrupt is used with FreeRTOS API functions.

void ETH_IRQHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;


/* Frame received */
if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET) {
/* Give the semaphore to wakeup LwIP task */
xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );
}

/* Clear the interrupt flags. */
/* Clear the Eth DMA Rx IT pending bits */
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);

/* Switch tasks if necessary. */
if ( xHigherPriorityTaskWoken != pdFALSE ) {
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
}


However, its setting is also not like the recommandations:

void ETH_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;


/* 2 bit for pre-emption priority, 2 bits for subpriority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

/* Enable the Ethernet global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}


This is becoming more and more confusing, can anyone give a clear explanation?

RE: STM32F4 SPI interrupt and task communication

Posted by Richard on April 16, 2013
The ETH_NVIC_Config() function is also wrong, but I can't find it in the FreeRTOS download. Which file is it in?

Regards.

RE: STM32F4 SPI interrupt and task communication

Posted by https://www.google.com/accounts on April 16, 2013
It's in the STM32F4DIS-BB examples. You can find a download here: http://www.element14.com/community/docs/DOC-51670?ICID=knode-STM32F4-space
The httpserver_netconn project in /STM32F4xx_Ethernet_Example/project/FreeRTOS/httpserver_netconn, and then this ETH_NVIC_Config() function is defined in the stm32f4x7_eth_bsp.c, the ETH_IRQHandler is in the stm32f4xx_it.c.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists