How to define critical sections for the trace recorder?

Oct 27, 2014 |

Our Tracealyzer versions for microcontroller RTOS uses Percepio’s own recorder library, which uses separate definitions for critical sections within the recorder. This since the standard critical sections offered by some RTOS kernels, like portENTER_CRITICAL/portEXIT_CRITICAL in FreeRTOS, might not safe to use from interrupt (kernel) context. Some recorder functions are called both from task-level and interrupt-level context.

For FreeRTOS+Trace for example, we use portSET_INTERRUPT_MASK_FROM_ISR and portCLEAR_INTERRUPT_MASK_FROM_ISR for critical sections in the ports where these are implemented (ARM Cortex M, ARM Cortex A, Microchip PIC32 and Renesas RX):

    #define TRACE_SR_ALLOC_CRITICAL_SECTION() int __irq_status;
    #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}
    #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);}

If you are using a FreeRTOS port that doesn’t implement portSET_INTERRUPT_MASK_FROM_ISR and portCLEAR_INTERRUPT_MASK_FROM_ISR, you need to define TRACE_ENTER_CRITICAL_SECTION and TRACE_EXIT_CRITICAL_SECTION yourself (see trcKernelPortFreeRTOS.h.). However, in such FreeRTOS ports there are no nested interrupts, so critical sections are only needed in task-context. In this case, a generic solution is:

    #define TRACE_ENTER_CRITICAL_SECTION() if (IN_TASK_CONTEXT) portENTER_CRITICAL()
    #define TRACE_EXIT_CRITICAL_SECTION()  if (IN_TASK_CONTEXT) portEXIT_CRITICAL()

Another solution is to implement a something like the portSET_INTERRUPT_MASK_FROM_ISR solution above. That design is required if your chip allows for nested interrupts.

Note 1: Make sure you understand what interrupts that are disabled by TRACE_ENTER_CRITICAL_SECTION. For instance, portSET_INTERRUPT_MASK_FROM_ISR only disables interrupts with priorities below the configuration constant configMAX_SYSCALL_INTERRUPT_PRIORITY. It is important that you don’t call call the recorder from other interrupts, as you otherwise risk corrupting the trace data. Preempted calls to the recorder are however detected and results in the error message “Recorder busy – high priority ISR using syscall?” (shown when opening the trace).

Note 2: In v2.6 and earlier, we incorrectly used portENTER_CRITICAL as default solution in some recorder ports. This has now been replaced with an #error macro that reminds you to provide a proper solution for critical sections.

If you have questions, please contact support@percepio.com