陆运物流到老挝公司:建立任务,OSTaskCreate()解析

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 16:26:12
2010-08-05 08:58:34|  分类:默认分类 |字号 订阅
想让?C/OS-Ⅱ管理用户的任务,用户必须要先建立任务。用户可以通过传递任务地址和其它参数到以下两个函数之一来建立任务:OSTaskCreate() 或 OSTaskCreateExt()。OSTaskCreate()与?C/OS是向下兼容的,OSTaskCreateExt()是OSTaskCreate()的扩展版本,提供了一些附加的功能。用两个函数中的任何一个都可以建立任务。任务可以在多任务调度开始前建立,也可以在其它任务的执行过程中被建立。在开始多任务调度(即调用OSStart())前,用户必须建立至少一个任务。任务不能由中断服务程序(ISR)来建立。     OSTaskCreate()的代码如程序清单 L4.1所述。从中可以知道,OSTaskCreate()需要四个参数:task是任务代码的指针,pdata是当任务开始执行时传递给任务的参数的指针,ptos是分配给任务的堆栈的栈顶指针(参看4.02,任务堆栈),prio是分配给任务的优先级。
程序清单 L4.1 OSTaskCreate()
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
void   *psp;
INT8U   err;
if (prio > OS_LOWEST_PRIO) {                                             (1)
return (OS_PRIO_INVALID);
}
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) {                                (2)
OSTCBPrioTbl[prio] = (OS_TCB *)1;                                    (3)
OS_EXIT_CRITICAL();                                                    (4)
psp = (void *)OSTaskStkInit(task, pdata, ptos, 0);                (5)
err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0);       (6)
if (err == OS_NO_ERR) {                                               (7)
OS_ENTER_CRITICAL();
OSTaskCtr++;                                                        (8)
OSTaskCreateHook(OSTCBPrioTbl[prio]);                           (9)
OS_EXIT_CRITICAL();
if (OSRunning) {                                                  (10)
OSSched();                                                     (11)
}
} else {
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0;                              (12)
OS_EXIT_CRITICAL();
}
return (err);
} else {
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
}
OSTaskCreate()一开始先检测分配给任务的优先级是否有效[L4.1(1)]。任务的优先级必须在0到OS_LOWEST_PRIO之间。接着,OSTaskCreate()要确保在规定的优先级上还没有建立任务[L4.1(2)]。在使用?C/OS-Ⅱ时,每个任务都有特定的优先级。如果某个优先级是空闲的,?C/OS-Ⅱ通过放置一个非空指针在OSTCBPrioTbl[]中来保留该优先级[L4.1(3)]。这就使得OSTaskCreate()在设置任务数据结构的其他部分时能重新允许中断[L4.1(4)]。
然后,OSTaskCreate()调用OSTaskStkInit()[L4.1(5)],它负责建立任务的堆栈。该函数是与处理器的硬件体系相关的函数,可以在OS_CPU_C.C文件中找到。有关实现OSTaskStkInit()的细节可参看第8章——移植?C/OS-Ⅱ。如果已经有人在你用的处理器上成功地移植了?C/OS-Ⅱ,而你又得到了他的代码,就不必考虑该函数的实现细节了。OSTaskStkInit()函数返回新的堆栈栈顶(psp),并被保存在任务的0S_TCB中。注意用户得将传递给OSTaskStkInit()函数的第四个参数opt置0,因为OSTaskCreate()与OSTaskCreateExt()不同,它不支持用户为任务的创建过程设置不同的选项,所以没有任何选项可以通过opt参数传递给OSTaskStkInit()。
C/OS-Ⅱ支持的处理器的堆栈既可以从上(高地址)往下(低地址)递减也可以从下往上递增。用户在调用OSTaskCreate()的时候必须知道堆栈是递增的还是递减的(参看所用处理器的OS_CPU.H中的OS_STACK_GROWTH),因为用户必须得把堆栈的栈顶传递给OSTaskCreate(),而栈顶可能是堆栈的最高地址(堆栈从上往下递减),也可能是最低地址(堆栈从下往上长)。
一旦OSTaskStkInit()函数完成了建立堆栈的任务,OSTaskCreate()就调用OSTCBInit()[L4.1(6)],从空闲的OS_TCB池中获得并初始化一个OS_TCB。OSTCBInit()的代码如程序清单 L4.2所示,它存在于0S_CORE.C文件中而不是OS_TASK.C文件中。OSTCBInit()函数首先从OS_TCB缓冲池中获得一个OS_TCB[L4.2(1)],如果OS_TCB池中有空闲的OS_TCB[L4.2(2)],它就被初始化[L4.2(3)]。注意一旦OS_TCB被分配,该任务的创建者就已经完全拥有它了,即使这时内核又创建了其它的任务,这些新任务也不可能对已分配的OS_TCB作任何操作,所以OSTCBInit()在这时就可以允许中断,并继续初始化OS_TCB的数据单元。
程序清单 L 4.2     OSTCBInit()
INT8U  OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt)
{
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
OS_CPU_SR  cpu_sr;
#endif
OS_TCB    *ptcb;
OS_ENTER_CRITICAL();
ptcb = OSTCBFreeList;                                  /* Get a free TCB from the free TCB list    */
if (ptcb != (OS_TCB *)0) {
OSTCBFreeList        = ptcb->OSTCBNext;            /* Update pointer to free TCB list          */
OS_EXIT_CRITICAL();
ptcb->OSTCBStkPtr    = ptos;                       /* Load Stack pointer in TCB                */
ptcb->OSTCBPrio      = (INT8U)prio;                /* Load task priority into TCB              */
ptcb->OSTCBStat      = OS_STAT_RDY;                /* Task is ready to run                     */
ptcb->OSTCBDly       = 0;                          /* Task is not delayed                      */
#if OS_TASK_CREATE_EXT_EN > 0
ptcb->OSTCBExtPtr    = pext;                       /* Store pointer to TCB extension           */
ptcb->OSTCBStkSize   = stk_size;                   /* Store stack size                         */
ptcb->OSTCBStkBottom = pbos;                       /* Store pointer to bottom of stack         */
ptcb->OSTCBOpt       = opt;                        /* Store task options                       */
ptcb->OSTCBId        = id;                         /* Store task ID                            */
#else
pext                 = pext;                       /* Prevent compiler warning if not used     */
stk_size             = stk_size;
pbos                 = pbos;
opt                  = opt;
id                   = id;
#endif
#if OS_TASK_DEL_EN > 0
ptcb->OSTCBDelReq    = OS_NO_ERR;
#endif
ptcb->OSTCBY         = prio >> 3;                  /* Pre-compute X, Y, BitX and BitY          */
ptcb->OSTCBBitY      = OSMapTbl[ptcb->OSTCBY];
ptcb->OSTCBX         = prio & 0x07;
ptcb->OSTCBBitX      = OSMapTbl[ptcb->OSTCBX];
#if OS_EVENT_EN > 0
ptcb->OSTCBEventPtr  = (OS_EVENT *)0;              /* Task is not pending on an event          */
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEL_EN > 0)
ptcb->OSTCBFlagNode  = (OS_FLAG_NODE *)0;          /* Task is not pending on an event flag     */
#endif
#if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0))
ptcb->OSTCBMsg       = (void *)0;                  /* No message received                      */
#endif
#if OS_VERSION >= 204
OSTCBInitHook(ptcb);
#endif
OSTaskCreateHook(ptcb);                            /* Call user defined hook                   */
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = ptcb;
ptcb->OSTCBNext    = OSTCBList;                    /* Link into TCB chain                      */
ptcb->OSTCBPrev    = (OS_TCB *)0;
if (OSTCBList != (OS_TCB *)0) {
OSTCBList->OSTCBPrev = ptcb;
}
OSTCBList               = ptcb;
OSRdyGrp               |= ptcb->OSTCBBitY;         /* Make task ready to run                   */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return (OS_NO_MORE_TCB);
}
转发至微博
0人  |  分享到:
阅读(207)| 评论(0)| 引用 (0) |举报
直齿圆柱齿轮的基本参数
任务控制块OS_TCB
任务建立问题 建立任务失败 怎么建立的计划任务[未能启动]? 怎么把用右键建立迅雷任务? 怎么建立的计划任务未能启动 蒸汽幻想公会建立后的任务 如何在任务拦建立桌面的快捷方式 请问,如何在SQL中建立一个自动化任务? 如何在迅雷上使用“建立批量任务”? 迅雷重复提示建立新的下载任务 CS1。5版的建立局域网游戏后 怎么加任务和电脑玩 啊 ?? 请问LC4破解的ADMINISTARTOR的密码存在哪,如何建立新的任务来破解? 我想在计划任务里设置定时音乐但是却告诉我:无法建立指定的帐户 我想在计划任务里设置定时音乐但是却告诉我:无法建立指定的帐户 电脑学习.怎样在任务拦上建立一个应用程序的快捷方式?有几种方式? BT连接到了,任务也建立了但是下载速度为零为什么啊 ? Web讯雷在下载东西时怎么老是建立任务失败? 将"拨号网络"建立在任务栏上,成为任务子栏如何操作? 建立下载任务后,没有显示下载进度,下载时间等,什么反应也没有. 使命召唤2进入任务提示我无法建立hunkusage.dat??? 凄凉之地任务 和那个部族建立良好关系好啊 为什么我不能使用网际快车,就是点右键IE栏里网际快车下载电脑说无法建立下载任务 我用BT下载,为什么在建立任务后老是不开始,始终下载数是0 各位大虾,怎么解决讯雷5建立任务但不开始下载的问题?请帮帮小弟