RTOS支持多任务同优先级运行
目标
允许RTOS支持多个任务拥有同一优先级,同一优先级的任务按时间片来占用CPU运行
实现
将任务就绪表taskTable
的类型改为’listHead’,即在任务就绪表中保存一个链表的头节点,就绪表中不同的表项表示不同的优先级,同一个优先级的任务则通过链表结点连接到taskTable中对应的链表头上。
在task
结构中添加linkNode
元素,用于将任务插入到对应的优先级链表上,同时要添加一个slice
字段,用于记录任务的时间片,使得同一优先级的任务能够按时间片运行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef struct _t_Task {
taskStack_t *stack; // 任务的栈指针
uint32_t slice; // 时间片
uint32_t delayTicks; // 任务延时计数器,在调用延时函数时每SysTick中断减一
listNode linkNode;
listNode delayNode; // 延时队列结点
uint32_t state; //任务此时的状态
uint32_t priority; // 任务的优先级
}task_t;
任务初始化时要将linkNdoe
字段进行初始化,同时要将task
插入对应的优先级链表上。
将原本对taskTable直接进行的操作修改为对taskTable中对应优先级链表的插入或删除操作。
在时钟中断处理时,要对任务的时间片进行减一处理,若当前任务的时间片已经用完,则查看当前优先级是否还有其它任务需要运行,如果有则需要将当前任务移动到该优先级链表的末尾,使得其它任务能够获得CPU进行运行。记得还要将时间片重置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void taskTimeSliceHandler() {
for (listNode* node = taskDelayedList.firstNode; node != &(taskDelayedList.headNode); node = node->next) {
task_t *task = getListNodeParent(node, task_t, delayNode);
if (--task->delayTicks == 0) {
taskWakeUp(task);
taskSched2Ready(task);
}
}
if (--currentTask->slice == 0) {
if (getListNodeNum(&taskTable[currentTask->priority]) > 1) {
listRemoveFirst(&taskTable[currentTask->priority]);
listNodeInsert2Tail(&taskTable[currentTask->priority], ¤tTask->linkNode);
}
currentTask->slice = TIME_SLICE;
}
taskSched();
}
本文由作者按照 CC BY 4.0 进行授权