cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupt priority with Freertos

Uhv
Associate II

Hello,

I have made a project with FreeRTOS 10.0.1.

However there is a problem: when I try to call a function with ‘ISR’ suffix from interrupt service routine the macros configASSERT catches mismatch between priority that ISR has and priority that is permissible.

The project was generated by CubeMX v5.1.0. The LIBRARY_LOWEST_INTERRUPT_PRIORITY is set to 15, the configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY is set to 5. Interrupt that is served by the ISR has priority 8. It’s seems that parameters are correct.

I have excluded the checking by configASSERT and the code works properly now, but I am doubting, is it correctly? Why macros gave an error?

Victor

8 REPLIES 8
Jack Peacock_2
Senior III

FreeRTOS will assert fail if you use an ISR call where your ISR priority is numerically lower than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY parameter. If you see the assert then your assumptions about priorities may not be accurate. Did you check in the debugger?

Make sure the configPRIO_BITS is set to 4 (assuming this is an M3/M4). Otherwise your priorities are shifted incorrectly.

I can tell you the asserts do work correctly when Cube is not used, so check the runtime with the debugger, don't assume what you entered is actually being used.

If you disable the asserts you aren't thread-safe in FreeRTOS. It may still work, most of the time....

Jack Peacock

Uhv
Associate II

Hi, Jack.

configPRIO_BITS is set 4 (controller is STM32L476RG). As I wrote earlier, ISR has priority 8, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY  is set to 5. Therefore everything is ok, I think so.

But when I start the program it stops at configASSERT that checks a priority matching.

I saw that place in debugger, it's here (without Cube's comments):

void vPortValidateInterruptPriority( void )
{
	uint32_t ulCurrentInterrupt;
	uint8_t ucCurrentPriority;
 
        __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
	if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
	{
		ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
 
		configASSERT(ucCurrentPriority >= ucMaxSysCallPriority );
	}
		configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <=  ulMaxPRIGROUPValue );
}

The asm code puts to ulCurrentInterrupt value 57. ucCurrentPriority gets from array value 0. The const array pcInterruptPriorityRegisters has almost all values 0, only two members are non-zero and both are not 57th (I don't remember exactly). And first configASSERT stops an execution.

Should array be so long? Or does asm code return wrong value?

I think that error occurs in some place but I don't know where exactly.

Jack Peacock_2
Senior III

Use the debugger to set a breakpoint at the assert. It will show you the actual priority for the ISR, not what a source file (which may not be linking properly) says. It may be that Cube isn't using the file you think it should be using.

Uhv
Associate II

Yes, I had done it so as you said, see my answer above.

I can't understand, wherefrom does it get the priority value to check? What is the 57? If priority of interrupt is 8, and we shift it left for 4 bits, result should be 80. But we have 57... Very strange. Or do I something not understand?

I see very well that assert is necessary therefore I want to understand the question.

Jack Peacock_2
Senior III

If ucCurrentPriority is zero you need to look at where you set the priority for that interrupt vector. The assert is saying you haven't set the priority for the right vector. The priority is not 8, as you assume.

The IPSR vector number, 57, is the index into the VTOR, the table of all interrupt vectors. Look at entry 57. That is not the same as interrupt 57. You need to subtract the ARM core vectors at the beginning, usually 16, to get the interrupt number for an external (i.e. not in core) interrupt. I believe interrupt number 41 (57-16) is I2C2 errors on an 'L476.

Jack Peacock

Uhv
Associate II

Hi, Jack.

I agree that it' look like interrupt priority is not set. It's very strange because when I set a breakpoint to place where HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 8, 0) - in stm32l4xx_hal_msp.c - is called debugger stops.

RTC_Alarm_IRQn is 41 and when we add 16 to it we get 57. All is correct. But when I see pcInterruptPriorityRegisters[57] at breakpoint in vPortValidateInterruptPriority it is zeroed.

Non-zeroed values in that array are:

  • 30th is 122, it suits to DMA1_Channel4_IRQn (14), it was set to priority 7;
  • 31th is 112, it suits to DMA1_Channel5_IRQn (15), it was set to priority 7;
  • 53th is 96 , it suits to USART1_IRQn (37), it was set to priority 6;
  • 56th is 160, it suits to EXTI15_10_IRQn (40), it was set to priority 10;
  • 66th is 144, it suits to TIM5_IRQn (50), it was set to priority 9.

Only 57th element is not set correctly :(

Why doesn't HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 8, 0) work properly?

Victor

Uhv
Associate II

0690X000008AHkBQAW.pngI have seen the Cube's NVIC Settings. Settings for RTC and for other interruprts are same. You can see they at this screenshot.

Uhv
Associate II

I have found a bug...

The priority of RTC was set from two places =)

One place was in Cube's code, about that I have told earlier. It set priority to value 8.

Second place was in my one code about that I have fogotten at all =) And second place set priority to 0! =)

When we came to configASSERT the 57th element in array had been set to 0 already =)

When I have killed the second priority setting everything works fine.

Thanks for help!

The question is closed.