Critical Section issues

Christian
2013-01-24
2013-09-16
  • Christian

    Christian - 2013-01-24

    Hello forks,

    I'd like to describe a bad scenario we encountered during our project using the uxCriticalNesting variable.  In our design, we use Cortex-M3 and the free RTOS version is v7.1.0.

    In the enter critical section function called in a task, the first instruction executed is a DISABLE interrupts.  In our case, a higher priority interrupt occured just right after the disable interrupt instruction.  In the interrupt handler, an enter and exit critical section was called. In the exit critical section from the handler, the interrupts were enabled again because the nesting counter was set to 1.

    When the handler interrupt completed, it returns in the critical section in the task with nesting counter to 0 and interrupt enabled…  So, the next instruction is the nesting counter increment to 1 and sometimes a switch context can occur in this critical section.  In another task, if an other critical section is called, disable interrupt instruction is called and the nesting counter set to 2,  and when exit critical section function is called, the nesting decrements to 1 and the interrupts remains disabled. 

    The task will not be interrupted by other task and the system is still frozen for ever!  

    An other situation,  if higher interrupt priority occurs in a critical section, we called xSemaphoreGiveFromISR(). In that function, we noticed that it enables the interrupts.  So, we can provoke context switch in the task's critical section area and maybe corrupt the protected resource. 

    In brief, the FreeRTOS configMAX_SYSCALL_INTERRUPT_PRIORITY is actually set to 191.  We can see in that case higher priority can break our system. 

    Is there any document available to be aware about some rules about critical section?  It's hard to reproduce the problem, but it can happen!

    Thanks!

    Christian

     
  • Dave

    Dave - 2013-01-24

    In the enter critical section function called in a task, the first instruction executed is a DISABLE interrupts.  In our case, a higher priority interrupt occured just right after the disable interrupt instruction.  In the interrupt handler, an enter and exit critical section was called. In the exit critical section from the handler, the interrupts were enabled again because the nesting counter was set to 1.

    I have not read past this paragraph but have already noted two things that are wrong with your application and guess the rest of your post relates to that.

    1) You must not use taskENTER_CRITICAL from an ISR. In fact, you must not call any API functions that don't end in FromISR in an ISR. You can use

    uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
    portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
    

    (code cut from queue.c)

    2) If you have an interrupt calling API function when the task is in a critical section then the rule that interrupts that use the FromISR API functions must have a priority at or below configMAX_SYSCALL_INTERRUPT_PRIORITY.

    Some links that might help you

    http://www.freertos.org/FAQHelp.html
    http://www.freertos.org/RTOS-Cortex-M3-M4.html

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks