鸿蒙轻内核M核源码分析系列六 任务及任务调度(3)任务调度模块

调度,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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值