Skip to content

[BUG] vTaskEnterCritical disables interrupts on static allocation #1306

@KammutierSpule

Description

@KammutierSpule

Describe the bug
I found this bug with the following scenario: Using C++, with classes, static objects allocation, the object is instantiated before the main runs (i.e: it is static allocated).

If the the object constructor contains functions calls, it will be called before the main is called and other system initializations. eg: FreeRTOS calls will be called before the main() or other? initializations.

In this case, I'm only considering static initialization of FreeRTOS items.

Example creating a static Semaphore, the function trace call is:

xSemaphoreCreateMutexStatic -> xQueueGenericCreateStatic -> prvInitialiseNewQueue -> xQueueGenericReset -> taskENTER_CRITICAL -> portENTER_CRITICAL

And the, the portENTER_CRITICAL
in this case, I'm using: PIC32MZ

portENTER_CRITICAL -> vTaskEnterCritical

and then:

    void vTaskEnterCritical( void )
    {
        traceENTER_vTaskEnterCritical();

        portDISABLE_INTERRUPTS();   <--- this is what causes the issue!

        if( xSchedulerRunning != pdFALSE )
        {

I don't know why but this won't make my project to work and the problem is that call to "portDISABLE_INTERRUPTS". since the enable interrupts wont' be called again.

Target

  • Development board: PIC32MZ
  • Instruction Set Architecture: MIPS
  • IDE and version: -
  • Toolchain and version: XC32

Host

  • Host OS:
  • Version: -

To Reproduce

  • Create a class object that initialize in constructor a static created Mutex.
  • If you use another interrupts, they won't work. (or at least for my project)

Expected behavior
portDISABLE_INTERRUPTS should check if interrupts are enabled and only disable if need?
Shall it disable interrupts only if xSchedulerRunning ?

Screenshots

Additional context

    #define portDISABLE_INTERRUPTS()                                        \
    {                                                                       \
    uint32_t ulStatus;                                                      \
                                                                            \
        /* Mask interrupts at and below the kernel interrupt priority. */   \
        ulStatus = _CP0_GET_STATUS();                                       \
        ulStatus &= ~portALL_IPL_BITS;                                      \
        _CP0_SET_STATUS( ( ulStatus | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) ); \
    }

Somehow, this sets some state that interrupts don't work again untill enable interrupts.
event if I use the __builtin_enable_interrupts of XC32

Also note that:


void vTaskExitCritical( void )
if( xSchedulerRunning != pdFALSE )
{
...
portENABLE_INTERRUPTS();  <-- vTaskExitCritical only calls enable interrupts if the scheduler is running

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions