求助:uC/OSII 代码中 进入临界段时机的疑问(跟循环相关)
下面是时钟节拍函数的源码<br /><br />void OSTimeTick (void)<br />{<br /> ... <br /> OS_TCB *ptcb;<br /><br /> OSTimeTickHook(); /* Call user definable hook */<br /> ...<br /><br /> if (OSRunning == TRUE) { <br /> ptcb = OSTCBList; /* Point at first TCB in TCB list */<br /> while (ptcb->OSTCBPrio != OS_IDLE_PRIO) { /* Go through all TCBs in TCB list */ (1)<br /> OS_ENTER_CRITICAL(); (2)<br /> if (ptcb->OSTCBDly != 0) { /* Delayed or waiting for event with TO */<br /> if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */<br /> if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */<br /> OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make task R-to-R (timed out)*/<br /> OSRdyTbl |= ptcb->OSTCBBitX;<br /> } else { /* Yes, Leave 1 tick to prevent ... */<br /> ptcb->OSTCBDly = 1; /* ... loosing the task when the ... */<br /> } /* ... suspension is removed. */<br /> }<br /> }<br /> ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */<br /> OS_EXIT_CRITICAL(); (3)<br /> } (4)<br /> }<br />}<br /><br />这里(1)(4)是循环体,循环处理每个TCB(除了OSTaskIdle),(2)(3)是进出临界段<br /><br />我的疑问就是 这里设置临界段是因为要访问全局资源TCB,而while循环的测试条件(1)里面也包含了对TCB优先级的读取,那为什么临界段没有包括while循环判断?既为什么没有包括整个while循环呢?如果是出于对关中断时间的长短的考虑,是不是在功能上出错了呢?<br /><br />不知道,请大虾指点如下:
出于对关中断时间的长短的考虑功能上要出问题的嘛
如果循环条件(1)刚测试完,被高优先级的任务抢占了,并且删除了测试过的TCB对应的任务,那再次进入到(2)(3)执行程序访问TCB的时候不是越权访问了没有问题
抢占是不会改变OSTCBList链表的。RE
我觉得放到while()外面貌似很好啊..<br /><br />只需要关一次..不用每一个去开和关..反倒节约了时间参考一下。
1 OSTimeIick()是在OSTIickISR()中被调用的。<br /> ps: 关于“自身中断的问题”本论坛中有详细的介绍。自身中断是不能嵌套的.可以认为同一中断源是同一优先级,则不能打断前一中断响应,等前一中断响应完成后再响应后一次中断请求.我以前认为OSTickISR()会自己发生嵌套。<br />ps:当然也可实现自身的嵌套服务。如下所示: <br />ISR:PUSH Next的地址<br />acall int_ret<br /> ;PUSH Next的地址,这个地方做了手脚。才保证了自嵌套。<br />Next:<br /><br />;做你要作的事<br /><br />int_ret: RETI;实际就是跳转到Next去运行,并且把中断标志清了RET<br /><br />搞定。<br /><br />2 这里设置临界段是因为要访问全局资源TCB,而while循环的测试条件(1)里面也包含了对TCB优先级的读取,那为什么临界段没有包括while循环判断?<br /> 临界资源,不可被修改。看循环里面的内容,ostcbdly ostcbstat ostcbnext 都是不能被其他任务(Isr)修改的。<br />3 既为什么没有包括整个while循环呢?<br /> ostimetick的任务 让延时的程序计时。时间到然后就绪。判断时间到的条件 <br /> if (--ptcb->OSTCBDly == 0) 。可是如果在这个期间,有某个任务 要求自身删除。如问题:如果循环条件(1)刚测试完,被高优先级的任务抢占了,并且删除了测试过的TCB对应的任务,那再次进入到(2)(3)执行程序访问TCB的时候不是越权访问了??<br />4 因为”如果循环条件(1)刚测试完,被高优先级的任务抢占了“这就是为什么临界段没有包括while循环判断,如果包含了while循环判断,那么哪有时间让高高优先级的任务抢占cpu? <br />5 “并且删除了测试过的TCB对应的任务,那再次进入到(2)(3)执行程序访问TCB的时候不是越权访问了??”<br /> 为了防止这种越权访问,作者在条件上做了工作。如果删除任务,会做一下工作:<br /> 其他的工作略了,有些条件就是防止在ostimetick中越权的。<br /> 设置任务状态 OS_STAT_RDY<br /> OSTCBDLY = 0<br />这样再次进入到(2)时就退出了。<br /> 注意tcb还存在,存储空间没有删除,只是里面的内容改变了,使他永远不满足再次就绪的条件,那这个任务就”删除了“<br /><br />
页:
[1]