FreeRTOS和Ucos中不同优先级的任务运行时采用的是抢占式调度,同一优先级下有多个任务需要运行时,则对同优先级的任务进行时间片轮转调度。将抢占式调度和时间片轮转调度联合使用就是混合式调度。

在 RTOS 中,最小的时间单位为一个Tick,即 SysTick 的中断周期, 同优先级轮转调度时Ucos可以指定每个任务运行多少个 Tick,但是FreeRTOS的任务运行时间片是固定的一个Tick,不可调整。在Ucos中若优先级0下有两个任务A和B,任务时间片设置为10ms,SysTick 的中断周期为1ms。则系统运行结果 是A运行10ms后切换B运行10ms然后再切换为任务A运行如此反复。在FreeRTOS中则是A运行1ms切换任务B运行1ms再切换任务A运行。
为了方便在同一优先级下面挂载与删除任务,RTOS的任务控制块当中(Task Control Block TCB)中引入了双向链表结构。FreeRTOS和Ucos任务控制块结构体如下,本例程中模仿FreeRTOS中链表的用法来实现双向循环链表。
/*FreeRTOS*/
typedef struct tskTaskControlBlock
{
volatile StackType_t *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */
#if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
#endif
ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
ListItem_t xEventListItem; /*< Used to reference a task from an event list. */
UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */
StackType_t *pxStack; /*< Points to the start of the stack. */
...
...
...
}
/*Ucos*/
struct os_tcb {
CPU_STK *StkPtr; /* Pointer to current top of stack */
void *ExtPtr; /* Pointer to user definable data for TCB extension */
CPU_STK *StkLimitPtr; /* Pointer used to set stack 'watermark' limit */
OS_TCB *NextPtr; /* Pointer to next TCB in the TCB list */
OS_TCB *PrevPtr; /* Pointer to previous TCB in the TCB list */
OS_TCB *TickNextPtr;
OS_TCB *TickPrevPtr;
...
...
...
}
一、双向链表的实现
网上关于双向循环链表的教程有很多,这里不再叙述链表的实现过程直接贴代码。推荐B站上的两个视频教程,一个是关于C语言指针的《强烈推荐】4小时彻底掌握C指针 - 顶尖程序员图文讲解 - UP主翻译校对 (已完结)》<
本文分析了在FreeRTOS和Ucos中的混合式调度机制,详细介绍了同优先级任务的时间片轮转调度,并通过STM32实现了一个简单的案例。通过双向链表管理任务控制块,当任务时间片耗尽时,系统会自动进行任务切换。在仿真验证中,创建了两个优先级为0的任务,观察到它们按预设时间片交替运行。
最低0.47元/天 解锁文章
2557

被折叠的 条评论
为什么被折叠?



