3811|3

15

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

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

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

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); //初始化任务控制块

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

最新回复

谢谢分享,楼主辛苦了  详情 回复 发表于 2012-1-12 13:41
点赞 关注

回复
举报

2万

帖子

74

TA的资源

管理员

沙发
 

回复 楼主 416561760 的帖子

嘿嘿 谢谢分享 :)
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 

回复

375

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

回复 楼主 416561760 的帖子

学习了!!
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

4
 
谢谢分享,楼主辛苦了
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表