In order to make a function I am writing able to be used both inside and outside ISRs, is it safe to just use the ISR-safe version of the FreeRTOS API calls?
// NOT ISR-safe
uint32_t messages_waiting(void)
{
return uxQueueMessagesWaiting(queue);
}
// ISR-safe
// - maybe just use this function ALL THE TIME??--both inside and outside ISRs?
uint32_t messages_waiting(void)
{
return uxQueueMessagesWaitingFromISR(queue);
}
FreeRTOS API reference: https://www.freertos.org/a00018.html#ucQueueMessagesWaitingFromISR
Here are the FreeRTOS implementations for each of these functions, from queue.c:
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue )
{
UBaseType_t uxReturn;
configASSERT( xQueue );
taskENTER_CRITICAL();
{
uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting;
}
taskEXIT_CRITICAL();
return uxReturn;
} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */
UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue )
{
UBaseType_t uxReturn;
configASSERT( xQueue );
uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting;
return uxReturn;
} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */
Follow-up: I can see that the non-ISR-safe version adds access guards:
taskENTER_CRITICAL();
taskEXIT_CRITICAL();
Maybe I could add the ISR-safe versions of these too, as follows? Now, can this function be used both inside and outside ISRs?
uint32_t messages_waiting(void)
{
UBaseType_t saved_interrupt_status = taskENTER_CRITICAL_FROM_ISR();
uint32_t num_msgs_waiting = uxQueueMessagesWaitingFromISR(queue);
taskEXIT_CRITICAL_FROM_ISR(saved_interrupt_status);
return num_msgs_waiting;
}
Reference & example usage of taskENTER_CRITICAL_FROM_ISR()
: https://www.freertos.org/taskENTER_CRITICAL_FROM_ISR_taskEXIT_CRITICAL_FROM_ISR.html