OS_Sched()
– When the running task gives up the CPU(complete)
ISR-level scheduling is done during OSIntExit()
– When the running task is preempted
Rescheduling will not be performed if the scheduler is locked or
some interrupt is currently serviced (why?).
The uC/OS-II uses a preemptive scheduler which means it can interrupt a running task to start or resume a higher priority task.
However, there are certain situations where you don't want preemption to occur. For example, if a task is in the middle of updating shared data, and it gets preempted before it's finished, the data might be left in an inconsistent state. This would lead to problems when other tasks access that data.
To prevent such situations, uC/OS-II provides mechanisms to "lock" the scheduler. When the scheduler is locked (i.e., OSLockNesting is non-zero), tasks can still run, but rescheduling won't occur, so a running task won't get preempted even if a higher priority task becomes ready to run.
Similarly, when an interrupt service routine (ISR) is being executed (i.e., OSIntNesting is non-zero), it's important to let the ISR finish before performing a context switch. This is because an ISR usually deals with low-level hardware or time-critical operations, and delaying or interrupting these operations could lead to serious problems, such as lost data or incorrect behavior.
So, in the given OS_Sched function, the check (OSLockNesting | OSIntNesting) == 0 is used to ensure that rescheduling only happens when neither the scheduler is locked nor an ISR is being serviced.
How to perform cxtsw when a task voluntarily
gives up the CPU (task-level cxtsw)?
– There is no “interrupt” at this time, so generate one
Context Switching (CxtSw) is the process of storing the context or state of a task, so that it can be reloaded when required. This is essential for a multitasking operating system to function properly.
If a task voluntarily gives up the CPU, for instance by calling a yield function, we need a mechanism to perform the context switch even though there isn't an actual hardware interrupt happening.
The method to generate a context switch varies based on the specific Real-Time Operating System (RTOS) and the architecture of the processor. In uC/OS-II, a software interrupt can be used to initiate a context switch. In this case, an interrupt service routine (ISR) is set up to handle this interrupt, and its job is to save the current context of the task that's running, choose the next task to run, and then load the saved context of the new task.
The function OS_TASK_SW() in uC/OS-II triggers the context switch. This function causes a software interrupt, which is caught by the context switch interrupt handler. This handler saves the context of the current task, determines the next task to run (usually the highest priority task that is ready to run), and then loads the context of this new task.
Remember that using a software interrupt to yield the processor is dependent on the specific architecture of the processor, and the interrupt number (0x80 in the case of x86) might vary across different architectures. Always refer to the documentation of your specific RTOS and processor for accurate information.
|