当前位置:网站首页>Ucos-iii learning records (11) - task management
Ucos-iii learning records (11) - task management
2022-07-06 14:04:00 【Mount256】
Reference Content :《[ Wildfire ]uCOS-III Kernel Implementation and application development practice guide —— be based on STM32》 The first 15、16 and 21 Chapter .
Start with this article , yes uCOS Of API application .
List of articles
- 1 Task status
- 2 Modify and add relevant codes
- 3 Function of task management
- 4 Application of task management
- 4.1 The main function main()(app.c)
- 4.2 Operation process
- 4.2.1 In the main function
- 4.2.2 For the first time in Task1 in
- 4.2.3 For the first time in Task2 in
- 4.2.4 For the first time in Task3 in
- 4.2.5 In idle tasks SysTick Initiate a break
- 4.2.6 The second time Task2 in
- 4.2.7 The second time Task3 in
- 4.2.8 In idle tasks SysTick Initiate a break
- 4.2.9 For the third time Task2 in
- 4.2.10 The second time Task1 in
- 4.3 Experimental phenomena
1 Task status
stay uCOS in , Task status is divided into the following , The task changes back and forth in these States :
- be ready (
OS_TASK_STATE_RDY
): The task is on the ready list , The ready task has the ability to execute , Just wait for the scheduler to schedule , The newly created task will be initialized to ready state . - Time delay (
OS_TASK_STATE_DLY
): The task is in the delayed scheduling state . - wait for (
OS_TASK_STATE_PEND
): Task call OSQPend()、OSSemPend() This kind of waiting function , The system will set a timeout to make the task wait , If the timeout is set to 0, The status of the task , Wait indefinitely , Until the event . If the timeout is N(N>0), stay N No event or signal waiting for the task occurred within a period of time , Just exit the waiting state and turn to the ready state .( Ignore at this stage ) - function (
OS_TASK_STATE_PEND_TIMEOUT
): This state indicates that the task is executing , Now it takes up the processor ,uCOS The scheduler always chooses to run the highest priority ready tasks , When the task is run , Its task state becomes running state , In fact, running tasks are also in the ready list . - Hang up (
OS_TASK_STATE_SUSPENDED
): The task is executed by calling OSTaskSuspend() Function can suspend itself or other tasks , call OSTaskResume() Is the only way to get the suspended task back running . Suspending a task means that the task cannot be obtained before it is resumed CPU Right to use , Similar to forcibly suspending a task . - Time delay + Hang up (
OS_TASK_STATE_DLY_SUSPENDED
): The task first generates a delay , Suspended by other tasks when the delay is not over , Suspended effects are superimposed , If and only if the delay ends and the Hang is resumed , The task can be run again . - wait for + Hang up (
OS_TASK_STATE_PEND_SUSPENDED
): The task waits for an event or signal to occur ( Waiting indefinitely ), He was suspended by other tasks before waiting , Suspended effects are superimposed , If and only if the task waits for an event or signal and the Hang is resumed , The task can be run again .( Ignore at this stage ) - Overtime waiting + Hang up (
OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED
): The task waits for the generation of events or signals within a specified time , But the task has been suspended by other tasks .( Ignore at this stage ) - Delete (
OS_TASK_STATE_DEL
): Status after the task is deleted , After the task is deleted, it will no longer run , Unless you re create the task .
stay os.h Macro defines the status value of the task :
/* System status */
#define OS_STATE_OS_STOPPED (OS_STATE)(0u)
#define OS_STATE_OS_RUNNING (OS_STATE)(1u)
/* Task status */
#define OS_TASK_STATE_BIT_DLY (OS_STATE)(0x01u) /* Hang bit */
#define OS_TASK_STATE_BIT_PEND (OS_STATE)(0x02u) /* Waiting bit */
#define OS_TASK_STATE_BIT_SUSPENDED (OS_STATE)(0x04u) /* Time delay / Timeout bit */
#define OS_TASK_STATE_RDY (OS_STATE)( 0u) /* 0 0 0 be ready */
#define OS_TASK_STATE_DLY (OS_STATE)( 1u) /* 0 0 1 Time delay / Overtime */
#define OS_TASK_STATE_PEND (OS_STATE)( 2u) /* 0 1 0 wait for */
#define OS_TASK_STATE_PEND_TIMEOUT (OS_STATE)( 3u) /* 0 1 1 wait for + Overtime */
#define OS_TASK_STATE_SUSPENDED (OS_STATE)( 4u) /* 1 0 0 Hang up */
#define OS_TASK_STATE_DLY_SUSPENDED (OS_STATE)( 5u) /* 1 0 1 Hang up + Time delay / Overtime */
#define OS_TASK_STATE_PEND_SUSPENDED (OS_STATE)( 6u) /* 1 1 0 Hang up + wait for */
#define OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED (OS_STATE)( 7u) /* 1 1 1 Hang up + Overtime + wait for */
#define OS_TASK_STATE_DEL (OS_STATE)( 255u)
2 Modify and add relevant codes
2.1 modify TCB(os.h)
TCB Add two members in :
- TaskState: Mark the status of the task .
- SuspendCtr: The recording task was suspended several times . How many times a task is suspended, how many times it must be restored before it can be run again .
struct os_tcb{
CPU_STK *StkPtr;
CPU_STK_SIZE StkSize;
OS_PRIO Prio; /* Task priority */
OS_TCB *NextPtr; /* The next pointer of the two-way linked list of the ready list */
OS_TCB *PrevPtr; /* The previous pointer of the two-way linked list of the ready list */
OS_TCB *TickNextPtr; /* Points to the next link in the list TCB node */
OS_TCB *TickPrevPtr; /* Point to the previous in the linked list TCB node */
OS_TICK_SPOKE *TickSpokePtr; /* Used to point back to the root of the linked list */
OS_TICK TickCtrMatch; /* This value is equal to the time base counter OSTickCtr The value plus TickRemain Value */
OS_TICK TickRemain; /* Set how many clock cycles the task needs to wait */
OS_TICK TimeQuanta; /* How many time slices does the task need */
OS_TICK TimeQuantaCtr; /* The number of time slices remaining in the task */
OS_STATE TaskState; /* Indicates the status of the task */
#if OS_CFG_TASK_SUSPENDED_EN > 0u
OS_NESTING_CTR SuspendCtr; /* Task suspend function OSTaskSuspend() Counter */
#endif
};
2.2 Add macro definitions and data types
stay os_cfg.h Add to the definition , Used to enable task suspension and deletion , These two functions can be turned on or off :
/* Enable task suspend */
#define OS_CFG_TASK_SUSPENDED_EN 1u
/* Enable task deletion */
#define OS_CFG_TASK_DEL_EN 1u
stay os_type.h Add data type :
typedef CPU_INT08U OS_NESTING_CTR;
3 Function of task management
Suspend and resume functions of tasks It is very useful in many times , For example, we want to suspend a task for a period of time , But we need to continue to work when it recovers , Then it is impossible to delete the task , Because if you delete the task , All the information of the task is impossible to recover , Delete is completely deleted , The resources inside are released by the system , But this is not the case with suspended tasks . Call the suspend task function , Just put the task into the suspended state , Its internal resources will be preserved , At the same time, it will not participate in the scheduling of tasks in the system , When calling the recovery function , The whole task immediately enters the ready state from the suspended state , And participate in task scheduling , If the priority of this task is the task with the highest priority in the current ready state , Then it will immediately continue to execute the task according to the task status before suspension . in other words , What is the status before suspending the task , Will be retained by the system , In the moment of recovery , Carry on .
Deleting a task means that the task will be returned and deleted ( Sleep ) state , The code of the task is no longer uCOS call , Deleting a task is not deleting a code . Deleting a task is somewhat similar to suspending a task , But the biggest difference is Delete task TCB The operation of . We know that when the task is created , Each task needs to be assigned a TCB,TCB Store important information about this task , It plays a vital role between tasks , The suspended task will not move at all TCB, But deleting a task will put TCB To initialize , In this way, any information about the task is erased . Be careful , Deleting a task does not free the stack space of the task .
The three functions mentioned above , All belong to uCOS Of API function , Convenient for users to call .
3.1 Task suspend function OSTaskSuspend()(os_task.c)
This function is used to suspend a task , The suspended task is in the suspended state , its TCB Will be removed from the ready list , And will not participate in any task scheduling , Unless there are other tasks to take the initiative to restore this task , That is, from the suspended state to the ready state , Otherwise, it has no chance to get the right to run .
What this function does is :
- If the mission TCB It's empty. , By default, the task to be suspended is yourself .
- If the task is suspended by yourself , Then judge whether the scheduler is locked , If it is locked, exit and return the error code , If there is no lock, continue to execute .
Next, according to the different states of the task , Perform different actions :
- If the task is in the ready state , Then change the status of the task to suspended , Suspend the counter to 1, Then delete from the ready list .
- If the task is in a delayed state , Then change the status of the task to delayed and suspended , Suspend the counter to 1, Don't change TCB The location of , That is, it is still in the delayed time base list .
- If the task is waiting , Then change the status of the task to waiting and pending , Suspend the counter to 1, Don't change TCB The location of , I'm still waiting on the waiting list . The wait list has not yet been implemented .
- If the task is waiting plus hypertext , Then change the status of the task to wait + timeout + suspended , Suspend the counter to 1, Don't change TCB The location of , That is, they are still in the waiting list and the time base list . The wait list has not yet been implemented .
- If the task is suspended , Or suspend plus other States , Then add one to the pending counter , Don't change TCB The location of .
- Other states are invalid , Exit return status invalid error code .
- Last , After changing the task status , Task switching is required .
/* Task suspend function */
#if OS_CFG_TASK_SUSPENDED_EN > 0u
void OSTaskSuspend (OS_TCB *p_tcb, OS_ERR *p_err)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
if (p_tcb == (OS_TCB *)0)
{
p_tcb = OSTCBCurPtr;
}
if (p_tcb == OSTCBCurPtr)
{
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) /* If the scheduler is locked, you cannot suspend yourself */
{
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_SCHED_LOCKED;
return;
}
}
*p_err = OS_ERR_NONE;
switch (p_tcb->TaskState)
{
case OS_TASK_STATE_RDY:
OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();
p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
OS_RdyListRemove (p_tcb);
OS_CRITICAL_EXIT_NO_SCHED();
break;
case OS_TASK_STATE_DLY:
p_tcb->TaskState = OS_TASK_STATE_DLY_SUSPENDED;
p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
CPU_CRITICAL_EXIT();
break;
case OS_TASK_STATE_PEND:
p_tcb->TaskState = OS_TASK_STATE_PEND_SUSPENDED;
p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
CPU_CRITICAL_EXIT();
break;
case OS_TASK_STATE_PEND_TIMEOUT:
p_tcb->TaskState = OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED;
p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
CPU_CRITICAL_EXIT();
break;
case OS_TASK_STATE_SUSPENDED:
case OS_TASK_STATE_DLY_SUSPENDED:
case OS_TASK_STATE_PEND_SUSPENDED:
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
p_tcb->SuspendCtr++;
CPU_CRITICAL_EXIT();
break;
default:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_STATE_INVALID;
return;
}
OSSched(); /* Task switching */
CPU_CRITICAL_EXIT();
}
#endif
3.2 Task recovery function OSTaskResume()(os_task.c)
This function is used to restore a suspended task . such as ,A The task is in the suspend and postpone tense ,B The task is in the pending and waiting state ,C The task is in the suspend wait delay tense , Then when other tasks restore them ,A The task is in delayed tense ,B The task is in a waiting state ,C The task is in the wait and delay tense . The implication , Is to remove the suspended state .
It should be noted that , A task can hang on to itself , But you can't recover yourself , Because I have been suspended , No chance to be run , How can you recover yourself ! Only when other tasks resume , The task can recover from the suspended state .
This function depends on the different states of the task , Perform different actions :
- As long as the task is not suspended , Exit to return the error code that the task is not suspended .
- If the task is suspended , Then decrement the pending counter SuspendCtr, If SuspendCtr be equal to 0, Then change the status of the task to ready , And make the task ready .
- If the task is in the delayed and suspended state , Then decrement the pending counter SuspendCtr, If SuspendCtr be equal to 0, Then change the status of the task to deferred .
- If the task is in the delayed and waiting state , Then decrement the pending counter SuspendCtr, If SuspendCtr be equal to 0, Then change the status of the task to waiting .
- If the task is waiting, timeout and pending , Then decrement the pending counter SuspendCtr, If SuspendCtr be equal to 0, Then change the status of the task to wait plus timeout .
- Other states are invalid , Exit return status invalid error code .
- Last , After changing the task status , Task switching is required .
/* Task recovery function */
#if OS_CFG_TASK_SUSPENDED_EN > 0u
void OSTaskResume (OS_TCB *p_tcb, OS_ERR *p_err)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
*p_err = OS_ERR_NONE;
switch (p_tcb->TaskState)
{
case OS_TASK_STATE_RDY:
case OS_TASK_STATE_DLY:
case OS_TASK_STATE_PEND:
case OS_TASK_STATE_PEND_TIMEOUT:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_NOT_SUSPENDED;
break;
case OS_TASK_STATE_SUSPENDED:
OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();
p_tcb->SuspendCtr--;
if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0)
{
p_tcb->TaskState = OS_TASK_STATE_RDY;
OS_TaskRdy (p_tcb);
}
OS_CRITICAL_EXIT_NO_SCHED();
break;
case OS_TASK_STATE_DLY_SUSPENDED:
p_tcb->SuspendCtr--;
if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0)
{
p_tcb->TaskState = OS_TASK_STATE_DLY;
}
CPU_CRITICAL_EXIT();
break;
case OS_TASK_STATE_PEND_SUSPENDED:
p_tcb->SuspendCtr--;
if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0)
{
p_tcb->TaskState = OS_TASK_STATE_PEND;
}
CPU_CRITICAL_EXIT();
break;
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
p_tcb->SuspendCtr--;
if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0)
{
p_tcb->TaskState = OS_TASK_STATE_PEND_TIMEOUT;
}
CPU_CRITICAL_EXIT();
break;
default:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_STATE_INVALID;
return;
}
OSSched(); /* Task switching */
CPU_CRITICAL_EXIT();
}
#endif
3.3 Task delete function OSTaskDel()(os_task.c)
Tasks usually run in a dead loop , And will not quit , If a task is no longer needed , You can call uCOS Delete the task in API The function interface explicitly deletes it .
This function is used to delete the task . So called delete , Is the task to be deleted TCB Move out of the ready list , At the same time, empty the task TCB All the information about .
The work done by this function is :
- If it is found that idle tasks are deleted , The error code is returned , Because idle tasks cannot be deleted , The system must have at least one task running , When no other user task is running , The system will run idle tasks .
- If the mission TCB It's empty. , Then the task to be deleted is self by default .
Then according to the different states of the task , Perform different actions :
- If the task is ready , Then remove from the ready list .
- If the task is suspended , You don't have to do anything .
- If the task is in delayed state or delayed and suspended state , Then remove from the time base list .
- If the task is in waiting state or waiting plus other States , Then remove from the time base list and waiting list . The wait list has not yet been implemented .
- Other states are invalid , Exit return status invalid error code .
Last :
- Empty TCB To default .
- Modify the status of the task to delete , That is, sleep .
- Schedule tasks .
/* Task delete function */
#if OS_CFG_TASK_DEL_EN > 0u
void OSTaskDel (OS_TCB *p_tcb, OS_ERR *p_err)
{
CPU_SR_ALLOC();
if (p_tcb == &OSIdleTaskTCB) /* Idle tasks cannot be deleted */
{
*p_err = OS_ERR_TASK_DEL_IDLE;
return;
}
if (p_tcb == (OS_TCB *)0)
{
CPU_CRITICAL_ENTER();
p_tcb = OSTCBCurPtr;
CPU_CRITICAL_EXIT();
}
OS_CRITICAL_ENTER();
switch (p_tcb->TaskState)
{
case OS_TASK_STATE_RDY:
OS_RdyListRemove (p_tcb);
break;
case OS_TASK_STATE_SUSPENDED:
break;
case OS_TASK_STATE_DLY:
case OS_TASK_STATE_DLY_SUSPENDED:
OS_TickListRemove (p_tcb);
break;
case OS_TASK_STATE_PEND:
case OS_TASK_STATE_PEND_TIMEOUT:
case OS_TASK_STATE_PEND_SUSPENDED:
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
OS_TickListRemove (p_tcb);
default:
OS_CRITICAL_EXIT();
*p_err = OS_ERR_STATE_INVALID;
return;
}
OS_TaskInitTCB (p_tcb);
p_tcb->TaskState = OS_TASK_STATE_DEL;
OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();
OSSched(); /* Task switching */
*p_err = OS_ERR_NONE;
}
#endif
4 Application of task management
4.1 The main function main()(app.c)
Modify two tasks :
- Task1: Change the blocking delay twice to suspend the task itself twice .
- Task2: Add recovery tasks Task1.
- Task3 No need to modify .
#include "ARMCM3.h"
#include "os.h"
#define TASK1_STK_SIZE 128
#define TASK2_STK_SIZE 128
#define TASK3_STK_SIZE 128
static CPU_STK Task1Stk[TASK1_STK_SIZE];
static CPU_STK Task2Stk[TASK2_STK_SIZE];
static CPU_STK Task3Stk[TASK3_STK_SIZE];
static OS_TCB Task1TCB;
static OS_TCB Task2TCB;
static OS_TCB Task3TCB;
uint32_t flag1;
uint32_t flag2;
uint32_t flag3;
void Task1 (void *p_arg);
void Task2 (void *p_arg);
void Task3 (void *p_arg);
/* Software delay */
void delay(uint32_t count);
int main (void)
{
OS_ERR err;
/* Initialize the relevant global variables , Create idle tasks */
OSInit(&err);
/* CPU initialization : Initialization timestamp */
CPU_Init();
/* Close the interrupt , Because at this time OS Not activated , If open interrupt , that SysTick Will cause an interrupt */
CPU_IntDis();
/* initialization SysTick, To configure SysTick by 10ms Break once ,Tick = 10ms */
OS_CPU_SysTickInit(10);
/* Create tasks */
OSTaskCreate ((OS_TCB*) &Task1TCB,
(OS_TASK_PTR) Task1,
(void *) 0,
(OS_PRIO) 1,
(CPU_STK*) &Task1Stk[0],
(CPU_STK_SIZE) TASK1_STK_SIZE,
(OS_TICK) 0,
(OS_ERR *) &err);
OSTaskCreate ((OS_TCB*) &Task2TCB,
(OS_TASK_PTR) Task2,
(void *) 0,
(OS_PRIO) 2,
(CPU_STK*) &Task2Stk[0],
(CPU_STK_SIZE) TASK2_STK_SIZE,
(OS_TICK) 0,
(OS_ERR *) &err);
OSTaskCreate ((OS_TCB*) &Task3TCB,
(OS_TASK_PTR) Task3,
(void *) 0,
(OS_PRIO) 3,
(CPU_STK*) &Task3Stk[0],
(CPU_STK_SIZE) TASK3_STK_SIZE,
(OS_TICK) 0,
(OS_ERR *) &err);
/* start-up OS, Will not return */
OSStart(&err);
}
/* Software delay */
void delay (uint32_t count)
{
for(; count!=0; count--);
}
void Task1 (void *p_arg)
{
OS_ERR err;
for (;;)
{
flag1 = 1;
OSTaskSuspend (&Task1TCB, &err);
flag1 = 0;
OSTaskSuspend (&Task1TCB, &err);
}
}
void Task2 (void *p_arg)
{
OS_ERR err;
for (;;)
{
flag2 = 1;
OSTimeDly (2);
flag2 = 0;
OSTimeDly (2);
OSTaskResume (&Task1TCB, &err);
}
}
void Task3 (void *p_arg)
{
for (;;)
{
flag3 = 1;
OSTimeDly (2);
flag3 = 0;
OSTimeDly (2);
}
}
4.2 Operation process
4.2.1 In the main function
- System initialization : Initialize various global variables , Initialize priority table , Initialize the ready list , Initialize the time base list , Initialize idle tasks ( Including initializing the idle task stack and idle tasks TCB).
- CPU initialization : Temporarily empty .
- Close the interrupt : Because at this time OS Not activated , If open interrupt , that SysTick Will cause an interrupt , Interrupt the initialization process .
- initialization SysTick: To configure SysTick by 10ms Break once ,Tick = 10ms.
- Create tasks : Including creating task stacks and tasks TCB, And will be TCB Insert into the ready list , Set at the corresponding position of the priority table .
- Start the system : Find the highest priority first , Then start running the task corresponding to the highest priority ( The highest priority is 1, That is to say Task1), Start the first task switch ( At this point, the final initialization process will be completed , Namely related PendSV Interrupt priority configuration , Then trigger PendSV abnormal , Initiate task switching ), take CPU Possession is left to the task Task1.
4.2.2 For the first time in Task1 in
- flag1 = 1.
- Execute to task suspend function OSTaskSuspend: Suspend your task , Suspend counter plus one , Move out of the ready list , Schedule tasks .
- Perform task scheduling OSSched: The task scheduler finds the highest priority first , Then find the task with the highest priority . TCB. If you find that this task is the current task , No task switching . In this case, it is found that the highest priority is 2, The corresponding task is Task2, Not the current mission , Then initiate task switching ( launch PendSV abnormal ).
- PendSV Exception handler : preservation Task1 The state of , load Task2 The state of , Update the value of the global variable .
4.2.3 For the first time in Task2 in
- flag2 = 1.
- Execute to blocking function OSTimeDly: take Task2 Of TCB Insert into the time base list (TickCtrMatch = 2), Put... In the ready list TCB remove ( At the same time, in the corresponding position in the priority table , Priority 2 The position of the is cleared ), Then start task scheduling .
- Perform task scheduling OSSched: The task scheduler finds the highest priority first , Then find the task with the highest priority TCB. If you find that this task is the current task , No task switching . In this case, it is found that the highest priority is 3, The corresponding task is Task3, Not the current mission , Then initiate task switching ( launch PendSV abnormal ).
- PendSV Exception handler : preservation Task2 The state of , load Task3 The state of , Update the value of the global variable .
4.2.4 For the first time in Task3 in
- flag3 = 1.
- Execute to blocking function OSTimeDly: take Task3 Of TCB Insert into the time base list (TickCtrMatch = 2), Put... In the ready list TCB remove ( At the same time, in the corresponding position in the priority table , Priority 3 The position of the is cleared ), Then start task scheduling .
- Perform task scheduling OSSched: The task scheduler finds the highest priority first , Then find the task with the highest priority TCB. If you find that this task is the current task , No task switching . In this case, it is found that the highest priority is 31, The corresponding task is Idle tasks , Not the current mission , Then initiate task switching ( launch PendSV abnormal ).
- PendSV Exception handler : preservation Task3 The state of , Load the status of idle tasks , Update the value of the global variable .
4.2.5 In idle tasks SysTick Initiate a break
- perform OSTimeTick: Add one to the time base counter (OSTickCtr = 1), Check the time base list (OSCfg_TickWheel[1]), It is found that the delay of each task has not expired (TickCtrMatch = 2). Finally, initiate task scheduling , It is found that there is no need to switch tasks , Idle tasks continue to run .
- Initiate interrupt again , perform OSTimeTick: Add one to the time base counter (OSTickCtr = 2), Check the time base list (OSCfg_TickWheel[2]), It is found that the delay of each task has expired (TickCtrMatch = 2), Put them all in the ready state . The process of setting to ready state is : Delete the corresponding... In the time base list TCB, Add the corresponding... In the ready list TCB( At the same time Task2、Task3 The priority of is reset at the corresponding position in the priority table ). Finally, initiate task scheduling , The highest priority of discovery is 2, The corresponding is Task2, Switch to Task2 function .
4.2.6 The second time Task2 in
- Put the global variable flag2 from 1 become 0.
- Execute to blocking function OSTimeDly: take Task2 Of TCB Insert into the time base list (TickCtrMatch = 4), Put... In the ready list TCB remove ( At the same time, in the corresponding position in the priority table , Priority 1 The position of the is cleared ), Then start task scheduling .
- Perform task scheduling OSSched: The task scheduler finds the highest priority first , Then find the task with the highest priority TCB. If you find that this task is the current task , No task switching . In this case, it is found that the highest priority is 3, The corresponding task is Task3, Not the current mission , Then initiate task switching ( launch PendSV abnormal ).
- PendSV Exception handler : preservation Task2 The state of , load Task3 The state of , Update the value of the global variable .
4.2.7 The second time Task3 in
- Put the global variable flag3 from 1 become 0.
- Execute to blocking function OSTimeDly: take Task3 Of TCB Insert into the time base list (TickCtrMatch = 4), Put... In the ready list TCB remove ( At the same time, in the corresponding position in the priority table , Priority 1 The position of the is cleared ), Then start task scheduling .
- Perform task scheduling OSSched: The task scheduler finds the highest priority first , Then find the task with the highest priority TCB. If you find that this task is the current task , No task switching . In this case, it is found that the highest priority is 31, The corresponding task is Idle tasks , Not the current mission , Then initiate task switching ( launch PendSV abnormal ).
- PendSV Exception handler : preservation Task3 The state of , Load the status of idle tasks , Update the value of the global variable .
4.2.8 In idle tasks SysTick Initiate a break
- perform OSTimeTick: Add one to the time base counter (OSTickCtr = 3), Check the time base list (OSCfg_TickWheel[3]), It is found that the delay of each task has not expired (TickCtrMatch = 4). Finally, initiate task scheduling , It is found that there is no need to switch tasks , Idle tasks continue to run .
- Initiate interrupt again , perform OSTimeTick: Add one to the time base counter (OSTickCtr = 4), Check the time base list (OSCfg_TickWheel[4]), It is found that the delay of each task has expired (TickCtrMatch = 4), Put them all in the ready state . The process of setting to ready state is : Delete the corresponding... In the time base list TCB, Add the corresponding... In the ready list TCB( At the same time Task2、Task3 The priority of is reset at the corresponding position in the priority table ). Finally, initiate task scheduling , The highest priority of discovery is 2, The corresponding is Task2, Switch to Task2 function .
4.2.9 For the third time Task2 in
- perform OSTaskResume: recovery Task1, send Task1 The pending counter of decreases by one , take Task1 Of TCB Add to the ready list . Be careful , because TCB Does not exist in the time base list , Therefore, there is no need to delete . Then initiate task scheduling , The highest priority of discovery is 1, The corresponding is Task1, Switch to Task1 function .
4.2.10 The second time Task1 in
- Put the global variable flag1 from 1 become 0.
- Execute to task suspend function OSTaskSuspend: Suspend your task , Suspend counter plus one , Move out of the ready list , Schedule tasks .
- Perform task scheduling OSSched: The task scheduler finds the highest priority first , Then find the task with the highest priority . TCB. If you find that this task is the current task , No task switching . In this case, it is found that the highest priority is 2, The corresponding task is Task2, Not the current mission , Then initiate task switching ( launch PendSV abnormal ).
- PendSV Exception handler : preservation Task1 The state of , load Task2 The state of , Update the value of the global variable .
So again and again , I won't repeat .
4.3 Experimental phenomena
The experimental phenomenon is shown in the figure below , Conform to the above analysis :
边栏推荐
- HackMyvm靶机系列(2)-warrior
- Strengthen basic learning records
- How to turn wechat applet into uniapp
- 3. Input and output functions (printf, scanf, getchar and putchar)
- [err] 1055 - expression 1 of order by clause is not in group by clause MySQL
- 简单理解ES6的Promise
- MATLAB打开.m文件乱码解决办法
- 内网渗透之内网信息收集(一)
- 网络基础详解
- 7-3 construction hash table (PTA program design)
猜你喜欢
SRC mining ideas and methods
Matlab opens M file garbled solution
1. First knowledge of C language (1)
Record a penetration of the cat shed from outside to inside. Library operation extraction flag
Callback function ----------- callback
How to turn wechat applet into uniapp
7-5 走楼梯升级版(PTA程序设计)
实验六 继承和多态
3. Input and output functions (printf, scanf, getchar and putchar)
Relationship between hashcode() and equals()
随机推荐
Read only error handling
Strengthen basic learning records
7-14 错误票据(PTA程序设计)
渗透测试学习与实战阶段分析
网络基础之路由详解
实验七 常用类的使用
HackMyvm靶机系列(6)-videoclub
Experiment 7 use of common classes
2022 Teddy cup data mining challenge question C idea and post game summary
Force deduction 152 question multiplier maximum subarray
实验八 异常处理
强化學習基礎記錄
网络基础详解
The difference between overloading and rewriting
Hackmyvm target series (5) -warez
Record once, modify password logic vulnerability actual combat
Using qcommonstyle to draw custom form parts
Intensive literature reading series (I): Courier routing and assignment for food delivery service using reinforcement learning
MATLAB打开.m文件乱码解决办法
HackMyvm靶机系列(3)-visions