portXYZ macro description

hooverphonique wrote on Wednesday, April 28, 2010:

FreeRTOS uses several macros named “portXYZ”…

For porting purposes, is there a detailed description of, what the exact functionality of these macros must be?
Looking at the usage gives some clues, but also leads to guesswork…

I’ve also noticed that queue.c makes uses of both “portENTER/EXIT_CRITICAL()” and “taskENTER/EXIT_CRITICAL” even though “task.h” hardcodes the latter to be equivalent to the former. Is this a simple mistake or are there cases, where they differ in functionality?
There is even a case where “portENTER/EXIT_CRITICAL()” is nested within “taskENTER/EXIT_CRITICAL” which doesn’t really make sense to me…


rtel wrote on Wednesday, April 28, 2010:

It is intended that application code does not (in most cases) call portXYZ macros directly, but instead calls the taskXYZ equivalents - as you point out in some cases the two are equivalent.  With regard to the ENTER/EXIT_CRITICAL() macros they are indeed the same and you could use either, although it is still recommended that application code only uses the taskXYZ versions for reasons of future compatibility.

It is possible that I have used both versions directly in the kernel code, and that is probably not a good thing to do, although the portXYZ versions are intended for use by the kernel itself.


hooverphonique wrote on Wednesday, April 28, 2010:

right… no comment on my first question rearding portXYZ functionality?

I’m primarily looking for documentation of “portENABLE/DISABLE_INTERRUPTS” and “portSET/CLEAR_INTERRUPT_MASK_FROM_ISR”… It’s not quite clear if these macros must disable/mask interrupt processing altogether or only the interrupts (priorities) that call API functions…

and then there’s “portCRITICAL_NESTING_IN_TCB”…


rtel wrote on Wednesday, April 28, 2010:

There is no quick answer to these because the implementation of the macros is very dependent on the architecture you are using and your design decisions.

ENABLE_DISABLE_INTERRUPTS() should either disable/enable interrupt completely, up just up to the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY - depending on whether you are implementing a port that allows interrupt nesting or not.

SET/CLEAR_INTERRUPT_MASK_FROM_ISR() is only needed if you are implementing interrupt nesting.  The SET part should return the current interrupt priority mask, and the CLEAR part should return the interrupt mask to whatever the SET part returned.  Note however that the Cortex M3 port does something slightly different because the hardware allows a bit of a simplification.

You also need to store the critical nesting count as part of the task context.  This can be done either on the task stack, or in the task TCB.  set portCRITICAL_NESTING_IN_TCB to 0 for the former, and 1 for the latter.  Again note that the Cortex M3 port is a bit different here too.

Which architecture are you porting too?


hooverphonique wrote on Tuesday, May 04, 2010:


sorry for not getting back to you earlier…

I’m porting to AVR XMega, or more correctly, have already done so… my plan is to contribute as soon as I’m confident everything works as expected…

The reason for asking the questions is that I have an issue that causes the tick to stop and because of some residual doubts about what the mentioned macros are supposed to do, I wanted to make sure I understood what they have to do correctly. The tick issue has been tracked down to a TWI problem, which is good :slight_smile:

Regarding portCRITICAL_NESTING_IN_TCB: If I understand correctly, I don’t have to implement anything related to this, but just “pick” a value of 0 or 1?

hooverphonique wrote on Tuesday, November 09, 2010:

Another question about taskENTER_EXIT_CRITICAL/portENTER_EXIT_CRITICAL:

does the kernel rely on the fact that these disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY (for an implementation supporting interrupt nesting) or is it ok if they only disable context switching? If they only disable switches, then what about the tick isr - must it be disabled as well?

the documentation for these state that they (only) disable context switches, but the code for xQueueGenericReceive suggests that they also must disable (some) interrupts…

I’m doing a port where all context switches happen through a soft-interrupt, which means that context switching may be disabled just by disabling that one isr instead of disabling whole priorities.

richard_damon wrote on Tuesday, November 09, 2010:

I believe that the actual requirement on the CRITICAL macros is that once you ENTER_CRITICAL you can not ENTER_CRITICAL by another execution path until you have done all the EXIT_CRITICAL (or use FromISR code that assumes that you can’t be in a critical section). This means that the ENTER_CRITICAL does need to disable interrupts that will call FreeRTOS API functions.