Hi! Just when you thought you were done with my long posts about tracing hooks…
I have been working on my tracer and also looking at the target implementations of both systemview and tracealyzer, and there is one more aspect about the FreeRTOS tracing hooks/API that I find unfortunate.
Most (all?) tracing hooks will end up writing to some shared resource - usually a RAM buffer used as a journal/ring buffer, a trace peripheral, a RAM buffer used for communication via systems like RTT etc. This requires the access to this resource to be done in a critical section to avoid overlapping/corrupted trace messages.
FreeRTOS supports (nested) critical sections in both ISR and task contexts, but this requires the tracing hook to know in which context it is running. Because there currently is no documentation (or mechanism) to enable this, all tracers that I have seen rely on writing their own per-platform ports to handle this, usually by detecting an interrupt context or writing an agnostic critical section.
In a sense FreeRTOS is an abstraction layer over platform-specific synchronization mechanisms, so it is unfortunate that a FreeRTOS API can not be properly consumed in a cross-platform fashion without platform-specific implementations.
As it stands right now, tracing hooks are called from any kind of context:
- Before the scheduler is started
- From tasks, from outside a critical section
- From tasks, from critical sections.
- From ISRs, from outside a critical section.
- From ISRs, from critical sections.
- From croutines (which I don’t claim to understand).
Some are only ever called from one place and one context, but others (like taskTASK_PRIORITY_DISINHERIT
) can be called from a number of different contexts.
As far as I am aware, some ports (like CM4F one) feature a port macro that detects if an interurpt context is active, but this is not required - the unix port for one does not feature one.
If there were a mechanism to guarantee and document that every hook is either called from only a task or ISR context, or called from both but always in a critical section, this would enable tracers to be written purely against the FreeRTOS APIs.
I am, however, not sure if this is even feasible for API enter and exit tracing hooks - as far as I am aware it is allowed to call functions like UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask )
from any context - so I don’t know if there would be any mechanism to track what context is currently active. But maybe supporting this for all normal “non-api” hooks is feasible?
I look forward to hearing your thoughts!