调度,Schedule
也称为Dispatch
,是操作系统的一个重要模块,它负责选择系统要处理的下一个任务。调度模块需要协调处于就绪状态的任务对资源的竞争,按优先级策略从就绪队列中获取高优先级的任务,给予资源使用权。本文我们来一起学习下调度模块的源代码,文中所涉及的源代码,所涉及的源码,以OpenHarmony LiteOS-M
内核为例,均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_m 获取。
下面,我们剖析下任务调度模块的源代码,若涉及开发板部分,以开发板工程targets\cortex-m7_nucleo_f767zi_gcc\
为例进行源码分析。
1、调度模块的重要函数
文件kernel\src\los_sched.c
中定义了调度模块的几个重要的函数,我们来分析下源码。
1.1 调度初始化函数
调度初始化函数UINT32 OsSchedInit(VOID)
在任务初始化函数UINT32 OsTaskInit(VOID)
中调用。⑴处会初始化任务就绪队列,⑵处初始化任务排序链表,⑶处初始化调度响应时间全局变量为最大值OS_SCHED_MAX_RESPONSE_TIME
。
UINT32 OsSchedInit(VOID)
{
UINT16 pri;
⑴ for (pri = 0; pri < OS_PRIORITY_QUEUE_NUM; pri++) {
LOS_ListInit(&g_priQueueList[pri]);
}
g_queueBitmap = 0;
⑵ g_taskSortLinkList = OsGetSortLinkAttribute(OS_SORT_LINK_TASK);
if (g_taskSortLinkList == NULL) {
return LOS_NOK;
}
OsSortLinkInit(g_taskSortLinkList);
⑶ g_schedResponseTime = OS_SCHED_MAX_RESPONSE_TIME;
return LOS_OK;
}
1.2 任务调度函数
任务调度函数VOID LOS_Schedule(VOID)
是出镜率较高的一个函数。当系统完成初始化开始调度,并且没有锁任务调度时,会调用函数HalTaskSchedule()
进行任务调度。该函数定义在kernel\arch\arm\cortex-m7\gcc\los_dispatch.S
,由汇编语言实现,后文会详细分析。
VOID LOS_Schedule(VOID)
{
if (g_taskScheduled && LOS_CHECK_SCHEDULE) {
HalTaskSchedule();
}
}
1.3 开启调度函数
函数VOID OsSchedStart(VOID)
被kernel\src\los_init.c:UINT32 LOS_Start(VOID)-->kernel\arch\arm\cortex-m7\gcc\los_context.c:UINT32 HalStartSchedule(OS_TICK_HANDLER handler)
函数依次调用,在系统初始化时开启任务调度。我们看下该函数的源码,⑴处调用函数获取就绪队列中优先级最高的任务,⑵把该任务状态设置为运行状态,接着把当前运行任务和新任务都设置为就绪队列中优先级最高的那个任务。⑶处设置任务调度启动状态全局变量为1,标记任务调度已经开启。⑷处设置新任务的开始运行时间,然后把新任务从就绪队列中出队。⑸处设置全局变量。⑹处调用函数设置该任务的运行过期时间。
VOID OsSchedStart(VOID)
{
(VOID)LOS_IntLock();
⑴ LosTaskCB *newTask = OsGetTopTask();
⑵ newTask->taskStatus |= OS_TASK_STATUS_RUNNING;
g_losTask.newTask = newTask;
g_losTask.runTask = g_losTask.newTask;
⑶ g_taskScheduled = 1;
⑷ newTask->startTime = OsGetCurrSchedTimeCycle();
OsSchedTaskDeQueue(newTask);
⑸ g_schedResponseTime = OS_SCHED_MAX_RESPONSE_TIME;
g_schedResponseID = OS_INVALID;
⑹ OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, newTask->startTime + newTask->timeSlice);
PRINTK("Enterin