社区导航

 
快捷导航
  • 首页
  • 论坛
  • 查看新帖
  • 最新回复
  • 社区活动
  • 联系管理员
  • 消灭零回复
  • E金币兑换
  • 干货
搜索
查看: 2619|回复: 3

uC/OS II学习《二》—uC/OS II内核完全解析之空闲任务的建立

[复制链接]

23

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2010-5-30 18:50:46 | 显示全部楼层 |阅读模式

上次说到空闲任务的建立:

OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[0], OS_IDLE_PRIO);//建立空闲任务

空闲任务的建立是调用OS_TASK.C中的OSTaskCreate 任务创建函数完成的,OSTaskCreate函数接收4个变量:task是任务代码的指针,pdata是当任务开始执行时传递给任务的参数的指针,ptos是分配给任务的堆栈的栈顶指针,prio是分配给任务的优先级。

 

INT8U OSTaskCreate (void (*task)(void *pd), void *ppdata, OS_STK *ptos, INT8U prio)

{

    void   *psp;

    INT8U   err;

 

if (prio > OS_LOWEST_PRIO)// 判断分配给任务的优先级是否有效。任务的优先级//必须在064之间

 {       

      return (OS_PRIO_INVALID); //优先级无效,返回42

     }

OS_ENTER_CRITICAL();  //关中断,EA=0

if (OSTCBPrioTbl[prio] == (OS_TCB *)0) //确保在规定的优先级上还没有建立任务,//果此优先级prio上有任务建立则OSTCBPrioTbl[prio] = (OS_TCB *)1

 {

   OSTCBPrioTbl[prio] = (OS_TCB *)1; //占用该优先级,其他任务就不能再应用//该优先级           

      OS_EXIT_CRITICAL();     //开中断 EA=1

psp = (void *)OSTaskStkInit(task, ppdata, ptos, 0);//堆栈初始化,返回栈顶指针

err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0); //初始化任务控制块       

        if (err == OS_NO_ERR) //如果初始化成功

  {

            OS_ENTER_CRITICAL(); //关中断EA=0

            OSTaskCtr++;     //任务计数器加一                   

            OS_EXIT_CRITICAL(); //开中断 EA=1

            if (OSRunning)  //如果任务运行标志为1

 {     

                OSSched();  //调用任务调用任务调度函数

              }

           }

else {

           OS_ENTER_CRITICAL(); //关中断EA=0

OSTCBPrioTbl[prio] = (OS_TCB *)0;  //初始化不成功,讲此优先级//还给优先级表,让其他任务建立时可用

          OS_EXIT_CRITICAL(); //开中断 EA=1

            }

        return (err); //返回错误

}

else {

        OS_EXIT_CRITICAL();//开中断 EA=1

        return (OS_PRIO_EXIST); //返回此任务优先级已经存在

       }

}

 

 到这空闲任务就算建立起来了,从上面的函数来看,空闲任务的建立主要做的事情就是:

psp = (void *)OSTaskStkInit(task, ppdata, ptos, 0);//堆栈初始化,返回栈顶指针

err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0); //初始化任务控制块

其余的语句都是为了做这两件事情服务的。

下面我们在来看堆栈初始化函数OSTaskStkInit(),堆栈的初始化是要自己根据处处理器的特点编写的,51单片机在任务切换和中断来临时需要入栈的寄存器有12个:R0-R7ACCBPSWDPTRDPHDPL)共13个字节,在加上任务的地址(2字节),共15字节。

   从上面看出OSTaskStkInit()函数接收4个参数:

task          指向任务代码的指针

pdata         当任务第一次执行时将要传入任务的用户数据结构指针

         ptos         栈顶指针。ptos指针被默认为用户堆栈入口指针。OS_STK_GROWTH被置1,那么,ptos指向用户堆栈的最高有效地址。同样地,如果OS_STK_GROWTH0ptos将指向用户堆栈的最低有效地址。

         opt           指定可以改变OSTaskStkInit()行为的选项。

void *OSTaskStkInit (void (*task)(void *pd), void *ppdata, void *ptos, INT16U opt)

{   

    OS_STK *stk;   // typedef unsigned char  OS_STK栈单元宽度为8比特

 

    ppdata = ppdata;

    opt    = opt;                           //opt没被用到,保留此语句防止告警产生    

    stk    = (OS_STK *)ptos;                    //用户堆栈最低有效地址

    *stk++ = 15;                                //用户堆栈长度

    *stk++ = (INT16U)task & 0xFF;               //任务地址低8

    *stk++ = (INT16U)task >> 8;                 //任务地址高8   

    *stk++ = 0x00;                              //PSW

    *stk++ = 0x0A;                              //ACC

    *stk++ = 0x0B;                              //B

    *stk++ = 0x00;                              //DPL

    *stk++ = 0x00;                              //DPH

    *stk++ = 0x00;                              //R0

    *stk++ = 0x01;                              //R1

    *stk++ = 0x02;                              //R2

    *stk++ = 0x03;                              //R3

    *stk++ = 0x04;                              //R4

    *stk++ = 0x05;                              //R5

    *stk++ = 0x06;                              //R6

    *stk++ = 0x07;                              //R7

                   

    return ((void *)ptos);                       //返回用户堆栈最低有效地址

}

上面这四个参数是由OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[0], OS_IDLE_PRIO);任务创建函数传递进来的。初始化完任务堆栈后,函数返回用户堆栈的栈顶指针,即最低地址。将这个地址传递给任务控制块初始化函数OSTCBInit()

即:err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0); //初始化任务控制块

该上班了,有空再说任务控制块的初始化……



2万

TA的帖子

74

TA的资源

管理员

Rank: 13Rank: 13Rank: 13Rank: 13

发表于 2010-5-31 07:52:38 | 显示全部楼层

回复 楼主 416561760 的帖子

嘿嘿 谢谢分享 :)
2017,加油!继续为中国电子行业做出小小的贡献吧!
QQ 1206973913


回复

使用道具 举报

403

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2010-12-19 10:53:43 | 显示全部楼层

回复 楼主 416561760 的帖子

学习了!!


回复

使用道具 举报

2

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2012-1-12 13:41:28 | 显示全部楼层
谢谢分享,楼主辛苦了


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2018-7-23 02:44 , Processed in 0.181528 second(s), 17 queries , Gzip On, Redis On.

快速回复 返回顶部 返回列表