手把手,嘴对嘴,讲解UCOSII嵌入式操作系统的任务调度策略(五)

 

整个UCOSII嵌入式操作系统的任务调度策略便是如此,现在进行一个总结:

①某个任务在执行中,每隔一定周期发生滴答时钟中断,在中断中遍历整个任务链表,更新每个任务的延时时间,修改就绪状态。

②任务执行完毕后,进入延时函数,在延时函数中会把当前任务挂起(清空当前任务的就绪状态,使其进入未就绪状态),然后根据查表发找到在就绪任务中,优先级最高的那一个任务。

③找到新任务以后,人工强制发生一个中断,保存上个任务的堆栈信息,弹出下个任务的堆栈信息,同时更改PC指针,进行任务切换。

经过以上三个步骤,便可以完成任务的调度。

现在回到第一篇提出的那个问题:UCOSII到底是如何保证它的实时性的呢? 

如果任务的调度都是发生在当前任务进入延时之后,似乎操作系统根本无法自身的保障实时性。

比如一个优先级最低的任务由于某些处理非常耗费时间,它一直无法进入延时,导致无法进入任务切换,那么优先级高的任务反而是一只都无法被执行了……

同样在第一篇说过,UCOSII系统除了在当前任务进入延时函数会发生调度之外,还有别的时机会进行任务切换:

  1.当前任务进入了延时。

  2.当前任务被挂起。

  3.当前任务执行时,发生了某些中断。

 

第1点我们已经全部讲完,第2点非常好理解,我们现在看一个函数:OSTaskSuspend()

这个函数的作用是把某个任务挂起(也就是不进行调度),现在来分析一个实例:

有一个任务调用了这个函数:

void App1_task(void *pdata)
{
    while(1)
    {
        if (OS_ERR_NONE != OSTaskSuspend(OS_PRIO_SELF))
        {
            Dbg_SendStr("App1_task Suspend Error£¡\r\n");
        }
        delay_ms(10);
    };
}

当前任务执行了红色代码之后,便会把自身挂起来,如果没有再别的地方对它进行激活,这个任务便永远也不会执行下去了。

深入分析OSTaskSuspend函数:

INT8U  OSTaskSuspend (INT8U prio)
{
    BOOLEAN    self;
    OS_TCB    *ptcb;
    INT8U      y;
#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr = 0u;
#endif



#if OS_ARG_CHK_EN > 0u
    if (prio == OS_TASK_IDLE_PRIO) {                            /* Not allowed to suspend idle task    */
        return (OS_ERR_TASK_SUSPEND_IDLE);
    }
    if (prio >= OS_LOWEST_PRIO) {                               /* Task priority valid ?               */
        if
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值