打印

求助:uC/OSII 代码中 进入临界段时机的疑问(跟循环相关)

[复制链接]
1827|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
afterqcd|  楼主 | 2008-9-22 12:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面是时钟节拍函数的源码

void  OSTimeTick (void)
{
    ...   
    OS_TCB    *ptcb;

    OSTimeTickHook();                                      /* Call user definable hook                 */
    ...

    if (OSRunning == TRUE) {    
        ptcb = OSTCBList;                                  /* Point at first TCB in TCB list           */
        while (ptcb->OSTCBPrio != OS_IDLE_PRIO) {          /* Go through all TCBs in TCB list          */       (1)
            OS_ENTER_CRITICAL();                                                                                (2)
            if (ptcb->OSTCBDly != 0) {                     /* Delayed or waiting for event with TO     */
                if (--ptcb->OSTCBDly == 0) {               /* Decrement nbr of ticks to end of delay   */
                    if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended?    */
                        OSRdyGrp               |= ptcb->OSTCBBitY; /* No,  Make task R-to-R (timed out)*/
                        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
                    } else {                               /* Yes, Leave 1 tick to prevent ...         */
                        ptcb->OSTCBDly = 1;                /* ... loosing the task when the ...        */
                    }                                      /* ... suspension is removed.               */
                }
            }
            ptcb = ptcb->OSTCBNext;                        /* Point at next TCB in TCB list            */
            OS_EXIT_CRITICAL();                                                                                 (3)
        }                                                                                                       (4)
    }
}

这里(1)(4)是循环体,循环处理每个TCB(除了OSTaskIdle),(2)(3)是进出临界段

我的疑问就是 这里设置临界段是因为要访问全局资源TCB,而while循环的测试条件(1)里面也包含了对TCB优先级的读取,那为什么临界段没有包括while循环判断?既为什么没有包括整个while循环呢?如果是出于对关中断时间的长短的考虑,是不是在功能上出错了呢?

不知道,请大虾指点

相关帖子

沙发
古代C人| | 2008-9-22 18:15 | 只看该作者

如下:

出于对关中断时间的长短的考虑

使用特权

评论回复
板凳
afterqcd|  楼主 | 2008-9-23 17:01 | 只看该作者

功能上要出问题的嘛

如果循环条件(1)刚测试完,被高优先级的任务抢占了,并且删除了测试过的TCB对应的任务,那再次进入到(2)(3)执行程序访问TCB的时候不是越权访问了

使用特权

评论回复
地板
John_Lee| | 2008-9-23 20:38 | 只看该作者

没有问题

抢占是不会改变OSTCBList链表的。

使用特权

评论回复
5
Swd21ic| | 2008-9-23 22:15 | 只看该作者

RE

我觉得放到while()外面貌似很好啊..

只需要关一次..不用每一个去开和关..反倒节约了时间

使用特权

评论回复
6
xcsjava| | 2008-10-5 12:47 | 只看该作者

参考一下。

1 OSTimeIick()是在OSTIickISR()中被调用的。
  ps: 关于“自身中断的问题”本论坛中有详细的介绍。自身中断是不能嵌套的.可以认为同一中断源是同一优先级,则不能打断前一中断响应,等前一中断响应完成后再响应后一次中断请求.我以前认为OSTickISR()会自己发生嵌套。
ps:当然也可实现自身的嵌套服务。如下所示: 
ISR:PUSH Next的地址
acall int_ret
   ;PUSH Next的地址,这个地方做了手脚。才保证了自嵌套。
Next:

;做你要作的事

int_ret: RETI;实际就是跳转到Next去运行,并且把中断标志清了RET

搞定。

2 这里设置临界段是因为要访问全局资源TCB,而while循环的测试条件(1)里面也包含了对TCB优先级的读取,那为什么临界段没有包括while循环判断?
   临界资源,不可被修改。看循环里面的内容,ostcbdly ostcbstat ostcbnext 都是不能被其他任务(Isr)修改的。
3 既为什么没有包括整个while循环呢?
 ostimetick的任务 让延时的程序计时。时间到然后就绪。判断时间到的条件 
  if (--ptcb->OSTCBDly == 0) 。可是如果在这个期间,有某个任务 要求自身删除。如问题:如果循环条件(1)刚测试完,被高优先级的任务抢占了,并且删除了测试过的TCB对应的任务,那再次进入到(2)(3)执行程序访问TCB的时候不是越权访问了??
4 因为”如果循环条件(1)刚测试完,被高优先级的任务抢占了“这就是为什么临界段没有包括while循环判断,如果包含了while循环判断,那么哪有时间让高高优先级的任务抢占cpu? 
5 “并且删除了测试过的TCB对应的任务,那再次进入到(2)(3)执行程序访问TCB的时候不是越权访问了??”
  为了防止这种越权访问,作者在条件上做了工作。如果删除任务,会做一下工作:
  其他的工作略了,有些条件就是防止在ostimetick中越权的。
  设置任务状态 OS_STAT_RDY
              OSTCBDLY = 0
这样再次进入到(2)时就退出了。
   注意tcb还存在,存储空间没有删除,只是里面的内容改变了,使他永远不满足再次就绪的条件,那这个任务就”删除了“

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

10

帖子

0

粉丝