Search code examples
cstm32rtosiarucos

uC/OS-iii Unresponsive Task


Consider the following code:

// uCOS-III
// Systick - 1ms
// ISR Stack Size 128
// All tasks have been created using OSTaskCreate

ISR_UART0()
{
    if(on receive)
    {
        OSFlagPost(UartRec); // Post Flag to activate TaskA
    }
}

TaskA()
{
    // Priority -> 6
    // StackSize -> 128
    // StackLimit -> 0
    
    for(;;)
    {
        OSFlagPend(UartRec);
        // Other Instructions
    }
}

TaskB()
{
    // Priority -> 8
    // StackSize -> 128
    // StackLimit -> 0
    
    for(;;)
    {
        OSDlyHSMS(0,0,0,2); // 2ms OS Delay
    }
}

TaskC()
{
    // Priority -> 9
    // StackSize -> 128
    // StackLimit -> 0
    
    for(;;)
    {
        OSDlyHSMS(0,0,0,2); // 2ms OS Delay
    }
}

I have an application with three tasks: TaskA, TaskB, and TaskC, managed by the uCOS-III operating system. TaskA is responsible for handling UART data reception and ISR posting a flag (UartRec) to activate TaskA when data is received. TaskB and TaskC are periodic tasks with lower priorities than TaskA.

Under normal conditions, when UART frames are sent slowly (around 1ms intervals), everything works fine. However, when the UART speed is increased, and frames are sent aggressively, TaskA becomes unresponsive after processing around 2K, 5K, or sometimes 300 frames. TaskB and TaskC continue to work correctly without any issues.

I have already ruled out stack overflow by checking the TaskA Task Control Block (TCB) and the CSTACK, but neither has reached its limit.

I have also verified the following:

TaskA is in the ready state. TaskA is not pending for any flag, as the required flag (UartRec) is ready. It seems that the scheduler is not prioritizing TaskA despite it having the highest priority among the tasks. As a result, TaskA remains unresponsive while the other tasks, including the idle task, function correctly.

I would appreciate any insights or suggestions on what might be causing this behavior and what configurations I should review to address this issue.


Solution

  • The problem is finally solved; here is what exactly happens:

    enter image description here

    As you can see, when the OS is inside the critical section, interrupts happen periodically. This leads to a shared resource problem occurring and damaging the OSprioTbl variable. This happens because the uCOS-III Cortex-M0 port only masks the ISR priorities other than BasePrio, which in my case was zero. Changing the ISR priority from zero to any other value greater than zero solved the problem.