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 loses task

Posted by dpursell on October 1, 2013

Hello,

I'm developing using Red Suite 5 and FreeRTOS 7.5.2 on the STM32F4. A certain task seems to be getting dropped from the task list after running for an hour or so, after which the program will either behave erratically or hardfault right away.

When crashing, the program appears to be trying to swap in an invalid task address (pxCurrentTCB == 0x0) during the PendSV interrupt handler. Additionally, the internal bookkeeping data is inconsistent: uxCurrentNumberOfTasks == 9, but only 8 tasks exist in the list returned by uxTaskGetSystemState(). Also pxReadyTasksLists[3].uxNumberOfItems == 2 (the lost task and another task ran at the same priority), but there only seems to be one valid item, the other is a pointer to pxReadyTasksLists[3].xListEnd.

I'm 99% sure it's not a stack problem, I'm using "#define configCHECKFORSTACK_OVERFLOW 2" and when calling uxTaskGetSystemState() or manually checking stacks in the debugger I've never come within 150 bytes for any task, and never within 500 bytes for the task in question.

I'm guessing I have an interrupt priority problem, since that seems to be the most common issue on the Cortex-M chips, but as far as I can tell I'm doing everything correctly.

~~~~~ // Definitions in FreeRTOSConfig.h

define configLIBRARYLOWESTINTERRUPT_PRIORITY 0xF
define configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 5
define configKERNELINTERRUPTPRIORITY ( configLIBRARYLOWESTINTERRUPTPRIORITY << (8 - configPRIOBITS) )
define configMAXSYSCALLINTERRUPTPRIORITY ( configLIBRARYMAXSYSCALLINTERRUPTPRIORITY << (8 - configPRIOBITS) )

// Called when the program starts before any other NVIC functions NVIC_SetPriorityGrouping(3);

// Calls to install each individual interrupt, where: // irq is the interrupt number // prio is the assigned priority, I only use (configLIBRARYMAXSYSCALLINTERRUPTPRIORITY + 0) to (configLIBRARYMAXSYSCALLINTERRUPTPRIORITY + 2) NVICSetPriority(irq, prio); NVICEnableIRQ(irq); ~~~~~

Here's information from the hard fault: R0 = 2001C064 R1 = 0 R2 = 0 R3 = 20000F74 R12 = 200004BC LR [R14] = 557CF342 subroutine call return address PC [R15] = 557CF342 program counter PSR = 6000000E BFAR = E000ED38 CFSR = 00000001 HFSR = 40000000 DFSR = 00000001 AFSR = 00000000 SCB_SHCSR = 00000400

Any insight into what might be going wrong would be greatly appreciated, I've been banging my head against this for a few days without much progress. If anything is unclear I would be happy to elaborate.

Thanks, David


STM32F4 loses task

Posted by richardbarry on October 1, 2013

NVIC_SetPriorityGrouping(3);

This is almost certainly the cause of your problem. Change the "3" to a "4". As you are using V7.5.2 I would also recommend defining configASSERT() as some additional asserts were added to catch exactly this problem.

If you have not already done so, take a look at: http://www.freertos.org/RTOS-Cortex-M3-M4.html

Noting the red text ;o)

Regards.


STM32F4 loses task

Posted by dpursell on October 1, 2013

Thanks for the quick response Richard,

I should have pointed this out, but I'm using the function NVICSetPriorityGrouping(), not NVICPriorityGroupConfig() (note slightly different name). I am not using the standard peripheral library so NVICPriorityGroupConfig() and NVICPriorityGroup4 are not available. Instead I found this function in my corecm4.h file:

~~~~~ static _INLINE void NVICSetPriorityGrouping(uint32t PriorityGroup) { uint32t regvalue; uint32t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */

regvalue = SCB->AIRCR; /* read old register configuration */ regvalue &= ~(SCBAIRCRVECTKEYMsk | SCBAIRCRPRIGROUPMsk); /* clear bits to change / regvalue = (regvalue | ((uint32t)0x5FA << SCBAIRCRVECTKEYPos) | (PriorityGroupTmp << 8)); / Insert write key and priorty group */ SCB->AIRCR = reg_value; } ~~~~~

I am fairly certain that my call to NVICSetPriorityGrouping(3) does the exact same thing as your suggested NVICPriorityGroupConfig(NVICPriorityGroup4) since NVICPriorityGroup4 is defined as 0x300.

Additionally I have tried using 0 instead of 3, and also have the assert defined as:

~~~~~

define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

~~~~~

but it never registers any problems.


STM32F4 loses task

Posted by richardbarry on October 1, 2013

Ah yes, I didn't notice that subtle change.

Are you using the STM32 standard peripheral library at all? If not, you can probably not call any of the priority grouping functions - and just leave it at its default. That is how all the other Cortex-M ports work. There is only a special case for STM32 because the standard peripheral libraries silently bug your code if the priority grouping is left at its default value (you will see why if you step through the STM32 version of "priority set").

Regards.


STM32F4 loses task

Posted by dpursell on October 1, 2013

Ah, thanks for the clarification. As suggested, I've removed the NVIC_SetPriorityGrouping() call, and the configASSERT still never triggers so I assume you are correct that it was not necessary in my case. However, the original problem still remains, the same task continues to disappear after running for a while.

I will try to keep troubleshooting and post results here if I discover anything, in case others are having a similar problem. If anything comes to mind you think I should try, or any specific variables I should examine in the debugger, please let me know.

Thanks, David


STM32F4 loses task

Posted by dpursell on October 2, 2013

It looks like the problem was caused by interrupt nesting, but I'm still not sure why the nesting caused corruption of the internal FreeRTOS structures. I doubt it's a bug in FreeRTOS since nobody else seems to have noticed this, so I'm probably doing something wrong, but at least for now I've worked around it by just assigning my interrupts to the same priority.

I'm attaching a FreeRTOS+ Trace clip showing the problem. My two tasks are named "MPU" and "Amulet", and they have the same FreeRTOS priority. This exact sequence seems to be present immediately before each crash: 1. Idle task is active 2. SPI interrupt (prio = 7) releases a semaphore 3. "MPU", waiting on SPI semaphore, becomes ready 4. Before "MPU" becomes active, UART5 interrupt (prio = 6, logically higher than SPI) pushes into a queue 5. "Amulet", waiting on UART5 queue, becomes ready 6. "Amulet" becomes active 7. "MPU" tries to become active, but somehow pxCurrentTCB is now NULL and the program crashes

If by chance anyone is experiencing a similar issue, my advice is to set your interrupts to be the same priority, seemed to work for me.

Thanks, David

Attachments

crash.png (14779 bytes)


[ 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