Random hangs with STM32

anonymous wrote on Wednesday, October 12, 2011:

I’m running FreeRTOS V6.0.3 on an STM32 (STM32F107RCT). I am randomly getting three different types of problems when I run the project:

1) Hard fault

2) Code hangs in the

for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )

loop of list.c

3) Code hangs in

while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 )

loop of tasks.c (due to uxMissedTicks being a very large number i.e. >0xFF000000)

I have searched this forum and found several posts that seem to be for this issue revolving around the setup of interrupts. I have the following settings:

#define configKERNEL_INTERRUPT_PRIORITY 0xFF    // Equivalent to priority 15 (lowest)
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 0x00    // Equivalent to priority 0 (highest)

Which should allow me to use interrupts with priorities between 1 and 15 I think. I am setting the interrupts I use to priority 13 with the following code:

    NVIC_InitStructure.NVIC_IRQChannel                      = SPI1_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority    = 13;          
    NVIC_InitStructure.NVIC_IRQChannelSubPriority           = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                   = ENABLE;

To check this I look in the Peripherals->Core Peripherals->NVIC window and I can see that the interrupts that I’m using are all set to priority 13. There seems to be five interrupts enabled (other than the ones I define):

- Non-maskable interrupt NMI (priority = -2)
- Hard fault HARDFAULT (priority = -1)
- System service call SVCALL (priority = 0)
- Pend system service PENDSV (priority = 15)
- System tick timer SYSTICK (priority = 15)

Does this look correct for these?

Another cause from the forum posts is a stack overflow. I have switched on the FreeRTOS stack checking with


and provided a vApplicationStackOverflowHook() function to catch a stack overflow. This never gets reached so my assumption is that the problem is not a stack issue.

Does anyone have any thoughts on what I might be doing wrong?


rtel wrote on Wednesday, October 12, 2011:

As you are using an STM32, I would also say make sure that all the priority bits are set as being preemption priority bits.  Most systems do that by default, but not the STM32 libraries.  To set them call NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );

#define configKERNEL_INTERRUPT_PRIORITY 0xFF    // Equivalent to priority 15 (lowest)
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 0x00    // Equivalent to priority 0 (highest)

You always have to take care on Cortex-M3 devices that priorities are set in accordance with the semantics of the library being used to set them.  Some want the priority set with the bits already shifted to the correct positions, some with the bits in the lowest significant places in the priority byte to allow the library function to do the shift itself.  The way you have intended to set these two parameters should, logically, effectively remove the any possibility of getting that wrong though, as it should prevent any interrupt nesting at all.  However, unfortunately 0 is not a valid interrupt priority, and has a special meaning on the Cortex-M3.  You cannot set a mask value of 0, and setting it to zero actually means you are not masking any interrupts at all, and those settings will definitely cause problems.

If you want a really simple test to see if interrupt nesting is causing a problem, then set both these parameters to 0xFF, then set all interrupt priorities in your code to 15.  That way, everything will use the lowest interrupt priority, and nothing will nest.  That would mean making the change from

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 13


NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15

for all interrupts.  Also make sure the sub priority is set to 0.  Once you have established if that fixes your problem, then you can work on having the priorities set how you actually want them, to get the benefit from interrupt nesting too.


anonymous wrote on Thursday, October 13, 2011:

Hi Richard,

Thanks for your quick response. I actually seem to have solved the problem by changing configMAX_SYSCALL_INTERRUPT_PRIORITY to 0x10. This sets it at a lower priority than the system service call SVCALL. Perhaps someone could explain why this might have made a difference? I was just trying to ensure that no user defined interrupts could be a higher priority by setting it to 0x00 but I’ve not seen any evidence that anyone else has used such a high (in priority terms) value. Most people seem to use 191 (priority 11).