ARM-software / CMSIS-FreeRTOS

FreeRTOS adaptation for CMSIS-RTOS Version 2

Home Page:https://arm-software.github.io/CMSIS-FreeRTOS/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

FreeRTOS API functions must not be called from within a critical section.

zbianbiaos opened this issue · comments

In the cmsis_os2.c code, IS_IRQ_MASKED is used to determine whether context in interrupt or critical. Returning true will execute the *fromISR function, but in the FreeRTOS description, FreeRTOS API functions must not be called from within a critical section
. Use IS_IRQ_MASKED to execute fromISR in the critical section, which will cause inexplicable problems. I hope to use configASSERT to prohibit this operation.thanks

Hi,
I'm not sure if I understand the issue. Would you like to use configASSERT to catch the situation when RTOS2 function is called from the critical section?
Can you please provide further explanation or give an example?

Hi,

I am sorry, because there has been a long time and there is no way to reappear the BUG environment.

Specifically, the official FreeRTOS manual describes that it is not allowed to use any FreeRTOS API functions in critical code area, but under cmsis_os2.c, there are the following codes:

__STATIC_INLINE uint32_t IRQ_Context (void) {
  uint32_t irq;
  BaseType_t state;

  irq = 0U;

  if (IS_IRQ_MODE()) {
    /* Called from interrupt context */
    irq = 1U;
  }
  else {
    /* Get FreeRTOS scheduler state */
    state = xTaskGetSchedulerState();

    if (state != taskSCHEDULER_NOT_STARTED) {
      /* Scheduler was started */
      if (IS_IRQ_MASKED()) {
        /* Interrupts are masked */
        irq = 1U;           /***************** in critical but return irq mode ********************/
      }
    }
  }
uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) {
  EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id;
  uint32_t rflags;

  if (ef_id == NULL) {
    rflags = 0U;
  }
  else if (IRQ_Context() != 0U) {  /************************* this call FromISR function **********************/
    rflags = xEventGroupGetBitsFromISR (hEventGroup);
  }
  else {
    rflags = xEventGroupGetBits (hEventGroup);
  }

  /* Return current event flags */
  return (rflags);
}

在链接https://freertos.org/taskENTER_CRITICAL_taskEXIT_CRITICAL.html下有如下描述:

Critical sections must be kept very short, otherwise they will adversely affect interrupt response times. Every call to taskENTER_CRITICAL() must be closely paired with a call to taskEXIT_CRITICAL().

**FreeRTOS API functions must not be called from within a critical section.**

taskENTER_CRITICAL() and taskEXIT_CRITICAL() must not be called from an interrupt service routine (ISR) - see taskENTER_CRITICAL_FROM_ISR() and taskEXIT_CRITICAL_FROM_ISR() for interrupt safe equivalents.

thank you very much

Executing code in interrupt or from thread when interrupts are disabled is not the same as executing from the critical section.
Critical section is a small section of code that shall not be preempted (i.e. interrupted, either by a thread switch or by the interrupt handler).

The function IRQ_Context checks if the current code is either executed:

  • from the interrupt handler
  • from thread
  • from thread when interrupts are disabled.

Depending on the context correct functions are called: with *fromISR extension or without. Each FreeRTOS API may implement the critical section but none of them is called from the critical section.

Fine, I will take more care about it, thanks