/* 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 NVIC_IP table at [#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )], pcInterruptPriorityRegisters[ ulCurrentInterrupt] will in my opinion point to the wrong location (by 16 Byte to short).
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
NVIC_IP table at [#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )],
The table begins at 0xE000E400 so the OFFSET_16 refers to a negative 16 from the start of the table. pcInterruptPriorityRegisters is not pointing to the very beginning of the NVIC_IP 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 portFIRST_USER_INTERRUPT_NUMBER to ulCurrentInterrupt rather than subtracting portFIRST_USER_INTERRUPT_NUMBER from ulCurrentInterrupt?
please let me explain how I came to this point: (using IAR EWARM; Cortex M4 - AT91SAM4S)
1.) NVIC_SetPriority(28, 11); // set somewhere at start; value visible in NVICIP29
2.) then PIOB_Irq 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 (uint8_t)0x00
* 0xE000E400: it contains (uint8_t)0x00
* 0xE000E40C: it contains (uint8_t)0x00 (this is pcInterruptPriorityRegisters[ulCurrentInterrupt])
and this is exactely: 0xE000E3F0 plus 16 + 28 == 0xE000E41C
pcInterruptPriorityRegisters[portFIRST_USER_INTERRUPT_NUMBER + ulCurrentInterrupt]
This is as I could see it in the debugger …
Indeed: if portNVIC_IP_REGISTERS_OFFSET_16 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
I found it by myself. Finally it was too simple shame on me
I made the mistake to set the idx of the __vector_table[] equal to the numbering of the specific IRQs like PIOB_IRQn; which is 12 and thats __vector_table[16 + 12 == 28].
So setting NVIC_SetPriority(28, 11) is bullShit as it set the NVIC_IP for IRQ28 which is not equal PIOB_IRQn…
Use NVIC_SetPriority((IRQn_Type)PIOB_IRQn, 11) instead…
Ok sessions learned; thanks a lot and good night!
Kind regards, Stephan