shivency

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

先上流程图

A/B分别代表OS_EXIT_CRITICAL() OS_ENTER_CRITICAL()

然后可能会问,最后的 OS_EXIT_CRITICAL(), 为什么会对应A1/A2呢

于是,上源码,微长,分段上

 1 INT8U  OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt)
 2 {
 3     OS_TCB    *ptcb;
 4 #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
 5     OS_CPU_SR  cpu_sr = 0;
 6 #endif
 7 
 8 
 9 
10     OS_ENTER_CRITICAL();
11     ptcb = OSTCBFreeList;                                  /* Get a free TCB from the free TCB list    */
12     if (ptcb != (OS_TCB *)0) {
13         OSTCBFreeList            = ptcb->OSTCBNext;        /* Update pointer to free TCB list          */
14         OS_EXIT_CRITICAL();

这里可以看到A1和B1(如果ptcb不是指向NULL的话),但如果ptcb指向NULL呢?

另外,说一句,我只是为了方便分析把这个函数分尸了……其实这个if后面的内容才刚刚开始……

keep going!

 1      ptcb->OSTCBStkPtr        = ptos;                   /* Load Stack pointer in TCB                */
 2         ptcb->OSTCBPrio          = prio;                   /* Load task priority into TCB              */
 3         ptcb->OSTCBStat          = OS_STAT_RDY;            /* Task is ready to run                     */
 4         ptcb->OSTCBStatPend      = OS_STAT_PEND_OK;        /* Clear pend status                        */
 5         ptcb->OSTCBDly           = 0;                      /* Task is not delayed                      */
 6 
 7 #if OS_TASK_CREATE_EXT_EN > 0
 8         ptcb->OSTCBExtPtr        = pext;                   /* Store pointer to TCB extension           */
 9         ptcb->OSTCBStkSize       = stk_size;               /* Store stack size                         */
10         ptcb->OSTCBStkBottom     = pbos;                   /* Store pointer to bottom of stack         */
11         ptcb->OSTCBOpt           = opt;                    /* Store task options                       */
12         ptcb->OSTCBId            = id;                     /* Store task ID                            */
13 #else
14         pext                     = pext;                   /* Prevent compiler warning if not used     */
15         stk_size                 = stk_size;
16         pbos                     = pbos;
17         opt                      = opt;
18         id                       = id;
19 #endif
20 
21 #if OS_TASK_DEL_EN > 0
22         ptcb->OSTCBDelReq        = OS_ERR_NONE;
23 #endif
24 
25 #if OS_LOWEST_PRIO <= 63
26         ptcb->OSTCBY             = (INT8U)(prio >> 3);          /* Pre-compute X, Y, BitX and BitY     */
27         ptcb->OSTCBX             = (INT8U)(prio & 0x07);
28         ptcb->OSTCBBitY          = (INT8U)(1 << ptcb->OSTCBY);
29         ptcb->OSTCBBitX          = (INT8U)(1 << ptcb->OSTCBX);
30 #else
31         ptcb->OSTCBY             = (INT8U)((prio >> 4) & 0xFF); /* Pre-compute X, Y, BitX and BitY     */
32         ptcb->OSTCBX             = (INT8U) (prio & 0x0F);
33         ptcb->OSTCBBitY          = (INT16U)(1 << ptcb->OSTCBY);
34         ptcb->OSTCBBitX          = (INT16U)(1 << ptcb->OSTCBX);
35 #endif

第二块代码即是流程图所说的,设置TCB中的各个域(现在想先弄清结构问题,暂不具体分析是哪些域)。

 1 #if (OS_EVENT_EN)
 2         ptcb->OSTCBEventPtr      = (OS_EVENT  *)0;         /* Task is not pending on an  event         */
 3 #if (OS_EVENT_MULTI_EN > 0)
 4         ptcb->OSTCBEventMultiPtr = (OS_EVENT **)0;         /* Task is not pending on any events        */
 5 #endif
 6 #endif
 7 
 8 #if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEL_EN > 0)
 9         ptcb->OSTCBFlagNode  = (OS_FLAG_NODE *)0;          /* Task is not pending on an event flag     */
10 #endif
11 
12 #if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0))
13         ptcb->OSTCBMsg       = (void *)0;                  /* No message received                      */
14 #endif
15 
16 #if OS_TASK_PROFILE_EN > 0
17         ptcb->OSTCBCtxSwCtr    = 0L;                       /* Initialize profiling variables           */
18         ptcb->OSTCBCyclesStart = 0L;
19         ptcb->OSTCBCyclesTot   = 0L;
20         ptcb->OSTCBStkBase     = (OS_STK *)0;
21         ptcb->OSTCBStkUsed     = 0L;
22 #endif
23 
24 #if OS_TASK_NAME_SIZE > 1
25         ptcb->OSTCBTaskName[0] = '?';                      /* Unknown name at task creation            */
26         ptcb->OSTCBTaskName[1] = OS_ASCII_NUL;
27 #endif

这一块是关于事件操作的代码,在后面的章节里会提到,这里无视。

1         OSTCBInitHook(ptcb);
2 
3         OSTaskCreateHook(ptcb);                            /* Call user defined hook                   */

神奇的hook()函数,钩子函数,书上说与windows的钩子函数性质相同,但我没学过win下的编程;

 1         OS_ENTER_CRITICAL();
 2         OSTCBPrioTbl[prio] = ptcb;
 3         ptcb->OSTCBNext    = OSTCBList;                    /* Link into TCB chain                      */
 4         ptcb->OSTCBPrev    = (OS_TCB *)0;
 5         if (OSTCBList != (OS_TCB *)0) {
 6             OSTCBList->OSTCBPrev = ptcb;
 7         }
 8         OSTCBList               = ptcb;
 9         OSRdyGrp               |= ptcb->OSTCBBitY;         /* Make task ready to run                   */
10         OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
11         OSTaskCtr++;                                       /* Increment the #tasks counter             */
12         OS_EXIT_CRITICAL();
13         return (OS_ERR_NONE);
14     }
15     OS_EXIT_CRITICAL();
16     return (OS_ERR_TASK_NO_MORE_TCB);
17 }

 

这是这个函数的最后一块内容
可以看到A2和B2内包着设置任务优先级指针表设置就绪表和就绪组的代码;

最后还有一个OS_EXIT_CRITICAL(),就是对应A1的_ENTER_;

也许我的流程图有点歧义,但没准这样记得更清楚= =?

 

至此这个任务控制块的初始函数已经拆分完毕。

 

 

 

posted on 2013-06-07 19:51  shivency  阅读(566)  评论(0编辑  收藏  举报