Cortex M3/4 BASEPRI

kujensen wrote on Wednesday, February 05, 2014:

On this page: http://www.freertos.org/RTOS-Cortex-M3-M4.html
It states:

An aside: FreeRTOS API functions that are safe to be called from an interrupt use BASEPRI to implement interrupt safe critical sections. BASEPRI is set to config MAX_SYSCALL_INTERRUPT_PRIORITY when the critical section is entered, and 0 when the critical section is exited. Many bug reports are received that claim BASEPRI should be returned to its original value on exit, and not just set to zero, but the Cortex-M NVIC will never accept an interrupt that has a priority below that of the currently executing interrupt - no matter what BASEPRI is set to. An implementation that always sets BASEPRI to zero will result in faster code execution than an implementation that stores, then restores, the BASEPRI value (when the compiler’s optimiser is turned on).

However, when I go to the official ARM Cortex M4 documentation at
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CIHCAEJD.html
I see that in table 2.9 they claim that writing 0x00 to BASEPRI has no effect.

If this is the case, then this write of 0 to BASEPRI is just a wasted operation. Is there a contradiction here? There seems to be something I am not understanding here…

Thanks!

rtel wrote on Thursday, February 06, 2014:

First, not really relevant to your question, I think the statement on the webpage may be slightly out of date. Inside a task the basepri will always have been 0 anyway, and it is still always returned to 0. Inside an interrupt, which is really what the statement is referring to, the original basepri could have been 0 or the max syscall interrupt priority. This behaviour was changed a few versions ago anyway, I can’t remember exactly why, but it was something to do with its use inside the tick hook function, or the run time stats callback function. The webpage needs updating.

…but to answer your question.

0 has a special value in the basepri register and basically means “don’t mask any interrupts”. Normally you would set basepri to the level of interrupt you want to mask, then any interrupt above that priority (lower numeric value) can still execute, but interrupt at and below the basepri value cannot. The highest possible interrupt priority is 0 - and the lowest possible is 255 (assuming all 8-bits of interrupt priority are implemented). It is essential that you can mask low priority interrupts, so setting basepri to 255 will mask priority 255 as expected. It is also essential that there is a basepri value that means no interrupts are masked, and that value is 0. Using 0 to say no priorities are masked is logical, but does of course mean you cannot mask interrupts that actually have a priority of 0.

I can’t see the table you are referring to on the URL you posted as it goes to a different page, so I’m not sure exactly in what context they are making the statement that writing 0 to basepri has not effect - maybe it means has no effect on the interrupts that will be accepted because none are masked?

Regards.

kujensen wrote on Thursday, February 06, 2014:

Oops - Sorry about the bad link to the ARM documentation. I meant
http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/CHDBIBGJ.html
near the end of the page.
I suppose ‘No effect’ means that a BASEPRI setting of 0 is not inhibiting any exceptions
rather than meaning that the effect of a write of 0 to the BASEPRI register does not change which exceptions are permitted to execute. Perhaps I simply got hung up on the wording of the documentation.