Cortex M4 Port: Creating interrupt-safe critical section

Hello, I’m using the IAR Cortex M4F port of FreeeRTOS. In a certain section of code, I need to do the following: ~~~ /* Enter critical section */ oldPrio = __get_BASEPRI(); __set_BASEPRI( /* Some priority higher than configMAX_SYSCALL_INTERRUPT_PRIORITY */ ); … vTaskPrioritySet(); … /* Exit critical section */ __set_BASEPRI( oldPrio ); ~~~ The issue I see is that vTaskPrioritySet()’s call to taskEXIT_CRITICAL() sets BASEPRI to 0, which exits my critical section before I would like to. Is there a recommended way to do this (i.e. create an interrupt-safe critical section but still be able to call RTOS API functions within it)? Thanks, Brian

Cortex M4 Port: Creating interrupt-safe critical section

A couple of general rules of thumb, which apply in most cases: 1) Do not call FreeRTOS API functions that could cause a context switch (such as changing the priority of a task) from a critical section as it can create logic errors as the context switch will not be able to occur. 2) The FreeRTOS kernel ‘owns’ BASEPRI because it keeps a nesting count of critical sections, which update BASEPRI. Perhaps if you could describe what you are trying to achieve we could suggest some alternatives for you?

Cortex M4 Port: Creating interrupt-safe critical section

Hi Richard, Thanks for the info. Really what we’re trying to accomplish is creating a critical section w.r.t. interrupts that use the FreeRTOS API. We have an ISR that basically does the following: ~~~ myISR() { /* Read/modify/write hardware registers / xQueueSendFromISR( / Data read from hw */ ); } ~~~ And a set of utilities, called from a task context, that can also read/modify/write this hardware. We don’t want to completely disable interrupts, hence the use of BASEPRI. From your reply above, it sounds like as long as we don’t make FreeRTOS API calls within this critical section, we should be ok. Is that correct? In certain situations, we may want to change a task’s priority before we allow the scheduler to run again (based on hardware state, etc.) Is there a way to do this? Thanks, Brian

Cortex M4 Port: Creating interrupt-safe critical section

The interrupt must have a priority at or below configMAXSYSCALLINTERRUPTPRIORITY as it is using a FreeRTOS API function in the interrupt’s handler. That means, if you have a task that is accessing the same hardware as the interrupt, all you need to do is wrap the access in the task in taskENTERCRITICAL()/taskEXITCRITICAL(). Those macros will set the BASPI to a value that will prevent the interrupt executing, but not prevent interrupts that have a priority above configMAXSYSCALLINTERRUPTPRIORITY from executing.