Quality RTOS & Embedded Software

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




Loading

vPortValidateInterruptPriority() bug or feature?

Posted by stephanhd on January 18, 2015

printf("hello world!")

I am just on 8.2.0 (FreeRTOSV8.2.0FreeRTOSSourceportableIARARM_CM3) port.

I wonder if the following code really works or if i had to continue studying....


// (port.c)
vPortValidateInterruptPriority( void ){
	uint32_t ulCurrentInterrupt;
	uint8_t ucCurrentPriority;

		/* Obtain the number of the currently executing interrupt. */
		__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );

		/* Is the interrupt number a user defined interrupt? */
		if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ){
			/* Look up the interrupt's priority. */
                        //ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
   [...]

Since pcInterruptPriorityRegisters is pointing to the very beginning of the NVICIP table at [#define portNVICIPREGISTERSOFFSET_16 ( 0xE000E3F0 )], pcInterruptPriorityRegisters[ ulCurrentInterrupt] will in my opinion point to the wrong location (by 16 Byte to short).

Using this small modification:


ucCurrentPriority = pcInterruptPriorityRegisters[ portFIRSTUSERINTERRUPT_NUMBER + ulCurrentInterrupt ];
ucCurrentPriority will be derived from the correct IRQn.

What do you think?

Kind regards, Stephan


vPortValidateInterruptPriority() bug or feature?

Posted by davedoors on January 18, 2015

I was sure the code is right because I tested it when it first appeared in FreeRTOS, and I dont think it has changed since. But you made me doubt myself so I looked again.

I think you have made a mistake here

Since pcInterruptPriorityRegisters is pointing to the very beginning of the NVICIP table at [#define portNVICIPREGISTERSOFFSET_16 ( 0xE000E3F0 )],

The table begins at 0xE000E400 so the OFFSET16 refers to a negative 16 from the start of the table. pcInterruptPriorityRegisters is not pointing to the very beginning of the NVICIP table it is pointing 16 bytes behind the beginning of the table.

But if you thought pcInterruptPriorityRegisters pointed to the start of the table I dont see why your modification is adding portFIRSTUSERINTERRUPTNUMBER to ulCurrentInterrupt rather than subtracting portFIRSTUSERINTERRUPTNUMBER from ulCurrentInterrupt?


vPortValidateInterruptPriority() bug or feature?

Posted by stephanhd on January 18, 2015

Hi Dave and thanks for taking care!

please let me explain how I came to this point: (using IAR EWARM; Cortex M4 - AT91SAM4S)

1.) NVICSetPriority(28, 11); // set somewhere at start; value visible in NVICIP29 2.) then PIOBIrq is fired 3.) and PIOB_IrqHandler is called 4.) some MessageProcessing is done and via xQueueSendToFrontFromISR() ... 5.) ... in vPortValidateInterruptPriority():

   __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );

ulCurrentInterrupt is derived as 28 (0x1C). 
Perfect as it fits to __vector_table[28] == PIOB_IrqHandler() :)

6.) Status at this point in time: * 0xE000E3F0: it contains (uint8t)0x00 * 0xE000E400: it contains (uint8t)0x00 * 0xE000E40C: it contains (uint8_t)0x00 (this is pcInterruptPriorityRegisters[ulCurrentInterrupt])

But: * 0xE000E41C: contains (uint8t)176 (0xB0) // (11 << 4) from (step 1.) and this is exactely: 0xE000E3F0 plus 16 + 28 == 0xE000E41C pcInterruptPriorityRegisters[portFIRSTUSERINTERRUPTNUMBER + ulCurrentInterrupt]

This is as I could see it in the debugger ...

Indeed: if portNVICIPREGISTERSOFFSET16 would not be pointing to 0xE000E3F0, but to 0xE000E400 (the real start of the NVIC_IP) then pcInterruptPriorityRegisters[ulCurrentInterrupt] would be fine as well.

Maybe you can help me to get the knot out of my brain? ;) Kind regards, Stephan


vPortValidateInterruptPriority() bug or feature?

Posted by stephanhd on January 18, 2015

I found it by myself. Finally it was too simple :) shame on me ;)

I made the mistake to set the idx of the _vectortable[] equal to the numbering of the specific IRQs like PIOBIRQn; which is 12 and thats __vectortable[16 + 12 == 28].

So setting NVICSetPriority(28, 11) is bullShit as it set the NVICIP for IRQ28 which is not equal PIOBIRQn... Use NVICSetPriority((IRQnType)PIOBIRQn, 11) instead....

Ok sessions learned; thanks a lot and good night! Kind regards, Stephan

p.s. FreeRTOS is a really cool thing!


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




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

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

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

OpenRTOS and SafeRTOS