UCOSIII 任务管理(下)

本文详细介绍了UCOSIII操作系统的内核实现原理,包括任务调度机制、任务切换过程及系统初始化步骤。深入剖析了任务调度器的工作方式,并列举了各种触发任务调度的情景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文内容简介:
一共分为三部分:
第一部分:任务调度,讲述了任务级和中断级的任务调度和调度点
第二部分:任务切换
第三部分:系统初始化部分。

重点在于第三部分代码讲解

任务调度

  • UCOSIII可剥夺型内核调度

任务调度器

一、任务级调度器

OS_Sched(),在OSTimeDlyHMSM中调用了该函数

二、中断级调度器

OSInitExit(),在退出中断的时候,启动任务调度。

任务调度点

1、释放信号量或者发送消息,也可通过配置相应的参数不发生任务调度。
2、使用延时函数OSTimeDly()或者OSTimeDlyHMSM()。

Dly()是时间延迟,DlyHMSM()是按节拍延迟
delay_ms()封装了TimeDly

3、任务等待的事情还没发生(等待信号量,消息队列等)。
4、任务取消等待。
5、创建任务。
6、删除任务。
7、删除一个内核对象。
8、任务改变自身的优先级或者其他任务的优先级。
9、任务通过调用OSTaskSuspend()将自身挂起。
10、任务解挂某个挂起的任务。
11、退出所有的嵌套中断。
12、通过OSSchedUnlock()给调度器解锁。
13、任务调用OSSchedRoundRobinYield()放弃其执行时间片。
14、用户调用OSSched()。

调度器上锁和解锁

OSSchedLock()上锁
OSSchedUnlock()解锁

时间片轮转

  • 时间片轮转调度器为:OS_SchedRoundRobin()
  • 任务可以主动放弃时间片

任务切换

任务切换是任务调度的一部分

任务切换分为两种:任务级切换和中断级切换。
任务级切换函数为:OSCtxSw()
中断级切换函数为:OSIntCtxSw()。

系统初始化和启动

OS_ERR err;
...
OSInit(&err); //OSInit(&err)必须先于其他所有函数执行
OS_CRITICAL_ENTER();    //进入临界区
OSTaskCreate();
OS_CRITICAL_EXIT();     //退出临界区  
...
OSStart(&err);
  • 临界区是用于保护代码不被打断的

OSInit()系统初始化函数-讲解

代码讲解在于理清该函数的思路。部分代码会省略
中文备注的是讲解部分

void  OSInit (OS_ERR  *p_err)
{
    CPU_STK      *p_stk;
    CPU_STK_SIZE  size;
/*检查参数是否合格*/
#ifdef OS_SAFETY_CRITICAL 
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif
    OSInitHook();                                           /* Call port specific initialization code                 */
    OSIntNestingCtr                 = (OS_NESTING_CTR)0;    /* Clear the interrupt nesting counter                    */
    /*标识操作系统是否在运行*/
    OSRunning                       =  OS_STATE_OS_STOPPED; /* Indicate that multitasking not started                 */
    OSSchedLockNestingCtr           = (OS_NESTING_CTR)0;    /* Clear the scheduling lock counter                      */
    OSTCBCurPtr                     = (OS_TCB *)0;          /* Initialize OS_TCB pointers to a known state            */
    OSTCBHighRdyPtr                 = (OS_TCB *)0;

/*=============此处省略部分初始化,暂时不讲解==============================*/

    /*优先级位映射表初始化,在任务管理(中)中进行了讲解*/
    OS_PrioInit();                                          /* Initialize the priority bitmap table                   */
    /*任务就绪队列,在任务管理(中)中进行了讲解*/
    OS_RdyListInit();                                       /* Initialize the Ready List                              */

/*内存管理初始化*/
#if OS_CFG_MEM_EN > 0u                                      /* Initialize the Memory Manager module                   */
    OS_MemInit(p_err);
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif
/*消息池初始化*/
#if (OS_MSG_EN) > 0u                                        /* Initialize the free list of OS_MSGs                    */
    OS_MsgPoolInit(p_err);
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif
/*互斥量初始化*/
#if OS_CFG_MUTEX_EN > 0u                                    /* Initialize the Mutex Manager module                    */
    OS_MutexInit(p_err);
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif
/*消息队列初始化*/
#if OS_CFG_Q_EN > 0u
    OS_QInit(p_err);                                        /* Initialize the Message Queue Manager module            */
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif
/*信号量初始化*/
#if OS_CFG_SEM_EN > 0u                                      /* Initialize the Semaphore Manager module                */
    OS_SemInit(p_err);
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif

/*=============省略了task一些初始化,暂时不讲解==============================*/
    /*空闲任务初始化,优先级MAX-1*/
    OS_IdleTaskInit(p_err);                                 /* Initialize the Idle Task                               */
    if (*p_err != OS_ERR_NONE) {
        return;
    }
    /*时钟节拍任务初始化*/
    OS_TickTaskInit(p_err);                                 /* Initialize the Tick Task                               */
    if (*p_err != OS_ERR_NONE) {
        return;
    }
/*=============省略了一些初始化,暂时不讲解==============================*/
    OSCfg_Init();
}

通过如上OSInit对操作系统运行所需要的资源进行了准备

OSStart()系统初始化函数-讲解

  • 本质是开始运行就绪队列中最高优先级的任务
void  OSStart (OS_ERR  *p_err)
{
/*检查参数合法性*/
#ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif
    if (OSRunning == OS_STATE_OS_STOPPED) {
      /*找到就绪队列中最高优先级任务*/
        OSPrioHighRdy   = OS_PrioGetHighest();              /* Find the highest priority                              */
        OSPrioCur       = OSPrioHighRdy;
        OSTCBHighRdyPtr = OSRdyList[OSPrioHighRdy].HeadPtr;
        OSTCBCurPtr     = OSTCBHighRdyPtr;
        OSRunning       = OS_STATE_OS_RUNNING;
      /*开始执行*/
        OSStartHighRdy();                                   /* Execute target specific code to start task             */
       *p_err           = OS_ERR_FATAL_RETURN;              /* OSStart() is not supposed to return                    */
    } else {
       *p_err           = OS_ERR_OS_RUNNING;                /* OS is already running                                  */
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值