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
#define configCHECK_FOR_STACK_OVERFLOW 2
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?
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.