打印
[ZLG-MCU]

ucos-ii奇怪的现象,应该是移植的问题

[复制链接]
2173|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
feifan570|  楼主 | 2008-5-8 12:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    我使用LM3S6916,用的是zlg的移植。我发现在一个任务里面读取OSPrioCur读取出来,发现OSPrioCur的值不等于这个任务建立时的优先级。
    然后我在OSTaskSwHook()函数里面做判断if(OSPrioCur == OSPrioHighRdy)。居然发现可以进入到这。OSTaskSwHook()是在
        LDR     R4, =OSPrioCur         ; OSPrioCur = OSPrioHighRdy
        LDR     R5, =OSPrioHighRdy     
        LDRB    R6, [R5]
        STRB    R6, [R4]

        LDR     R4, =OSTCBCur          ; OSTCBCur  = OSTCBHighRdy;
        LDR     R6, =OSTCBHighRdy      
        LDR     R6, [R6]
        STR     R6, [R4]
这段代码之前调用的,也就是说OSPrioCur 和 OSPrioHighRdy相等也执行了任务切换。但是通过看OSIntExit()和OS_Sched()的代码可以知道:OSPrioCur 和 OSPrioHighRdy相等是不会进行任务切换的。
     那么这只能说是移植出了问题吧?

相关帖子

沙发
zlgarm| | 2008-5-8 16:53 | 只看该作者

仿真显示问题

楼主:
   “发现在一个任务里面读取OSPrioCur读取出来,发现OSPrioCur的值不等于这个任务建立时的优先级。”
   这种问题通常是IAR或KEIL编译时,把某些变量优化了,仿真显示的数值不是该变量的,而是某个寄存器或中间量的,但这不会影响代码的运行。

(zlgarm_zsg)

使用特权

评论回复
板凳
feifan570|  楼主 | 2008-5-8 17:27 | 只看该作者

这个问题不仅是仿真时出现

我把这些变量从串口打印出来也是和该任务的优先级对不上。而且第二个问题又如何解析呢:OSTaskSwHook()函数出现(OSPrioCur == OSPrioHighRdy)?

使用特权

评论回复
地板
zlgarm| | 2008-5-9 08:52 | 只看该作者

中断嵌套

“OSPrioCur == OSPrioHighRdy”我们也有同事出现过。Cortex-M3的中断是有优先级、可嵌套的,首相检查OS_CRITICAL_INT_PRIO是否为0,然后看看你写的中断会不会因为嵌套而破坏系统。

(zlgarm_zsg)

使用特权

评论回复
5
feifan570|  楼主 | 2008-5-9 10:48 | 只看该作者

找到原因了

原因是这样的:
    在高优先级任务自动放弃CPU的使用权,即要调用OS_Sched()进行任务调度,但是在这个OS_Sched()中并不是在OS_TASK_SW()马上进行切换,而是等待中断打开后OS_EXIT_CRITICAL()才能进入任务切换的中断。但是一旦中断被打开,其他的中断先被执行,然后中断退出调用OSIntExit()使得OSPrioHighRdy再次被改写。就会出现这个问题。解决办法应该把软件中断的优先级提高。

使用特权

评论回复
6
zlgarm| | 2008-5-9 11:40 | 只看该作者

回5楼:软件中断一定要最低优先级

  软件中断一定要最低优先级,如果不是最低优先级调度是有问题的,您可以在嵌套、末尾连锁、占先等情况下分析一下。
   至于“中断退出调用OSIntExit()使得OSPrioHighRdy再次被改写”,肯定是这个中断把某个任务的优先级提高了,这是符合UCOS-II规定的,而不是移植的问题。

(zlgarm_zsg)

使用特权

评论回复
7
feifan570|  楼主 | 2008-5-9 11:51 | 只看该作者

zlg工程师是否验证了这个问题?

zlg工程师是否验证了这个问题? 
   关键是“中断退出调用OSIntExit()使得OSPrioHighRdy再次被改写”使得最高优先级再次改回当前优先级,按ucos-ii的规定这不应该进行调度的吧?难道“最高优先级==当前优先级”进行调度也是“这是符合UCOS-II规定的,而不是移植的问题。”?

使用特权

评论回复
8
zlgarm| | 2008-5-9 14:54 | 只看该作者

不明白

“中断退出调用OSIntExit()使得OSPrioHighRdy再次被改写”这句话按我的理解是不对的。OSIntExit()的核心语句如下:

OSIntExitY   = OSUnMapTbl[OSRdyGrp];   
OSPrioHighRdy = (INT8U)( (OSIntExitY << 3) + 
                         OSUnMapTbl[OSRdyTbl][OSIntExitY]] );

  从上面可以看出,“新”的OSPrioHighRdy是根据OSRdyGrp和OSRdyTbl[]而定的,如果中断函数里面没有调用OSSemPost()等uCOS-II函数,OSRdyGrp和OSRdyTbl[]是不会变的,也就是说执行完上面的语句后OSPrioHighRdy是不变的。另外,如果调用了OSSemPost()等函数,使得OSRdyGrp和OSRdyTbl[]改变了,也就说明有更高优先级的任务等着运行,这个任务比进入中断前准备运行的任务还有迫切,这些是和用户的实际应用有关的。

(zlgarm_zsg)

       

使用特权

评论回复
9
feifan570|  楼主 | 2008-5-9 15:49 | 只看该作者

不明白“软件中断一定要最低优先级”?

     我的一个中断确实是调用了OSSemPost()的函数,使得中断退出时要重新调度。但是这是UCOS-II允许的。
    “中断退出调用OSIntExit()使得OSPrioHighRdy再次被改写”所说的也就是你所说的,就是调用下面的语句而被改写的,因为OSPrioHighRdy在OS_Sched()已经被更新过,现在再次被OSIntExit()更新,所以我加了一个“再次”。
OSIntExitY   = OSUnMapTbl[OSRdyGrp];   
OSPrioHighRdy = (INT8U)( (OSIntExitY << 3) +
                         OSUnMapTbl[OSRdyTbl][OSIntExitY]] );

我觉得问题就在这:
    OSPrioHighRdy 本来在OS_Sched()中已经设置成新的最高优先级了,应该在OS_TASK_SW()把它切换到新的最高优先级的任务,但是这个动作实际上没有完成,要等待中断打开后才能完成。
    如果OS_TASK_SW()能把任务切换这件事情做完,那就不会有这个问题。或者中断一打开,马上把任务切换这件事做完也不会有这个问题出现。所以我觉得系统要求任务切换而并没有进行任务切换,就是不按照UCOS-II的要求办事了。UCOS-II要求是在OS_TASK_SW()进行任务切换!

使用特权

评论回复
10
ZLGARM| | 2008-5-9 17:09 | 只看该作者

ARM7的思路

    楼主的是ARM7的思路。ARM7的中断不能嵌套,它切换任务的思路是“就地尽快切换”;而Cortex-M3的中断可嵌套,它的思路是“中断优先”。
    假设任务使用OS_TASK_SW()“就地”把任务切换好,重开中断后,正准备执行新任务时,楼主的某个中断产生了,中断程序调用OSSemPost()找到更高优先级的任务,最后调用OSIntExit()切换到这个更加新的任务,单片机最后运行的是这一个任务,而不是先前切换好的任务,先前的切换过程是“白干”的。

(zlgarm_zsg)

使用特权

评论回复
11
feifan570|  楼主 | 2008-5-9 17:29 | 只看该作者

其实“最高优先级==当前优先级”进行调度也是“白干”

“软件中断一定要最低优先级”?能解释一下吗?如果把软件中断优先级设最高了除了做多点“白干”的活,还有其他问题吗?

使用特权

评论回复
12
zlgarm| | 2008-5-10 08:51 | 只看该作者

假设软件中断为最高优先级

假设软件中断为最高优先级。当它嵌套某一个低优先级的中断后,它要保存的寄存器已经被低优先级中断使用过,而不是原始的任务内容。

(zlgarm_zsg)

使用特权

评论回复
13
feifan570|  楼主 | 2008-5-10 15:36 | 只看该作者

我认为“最高优先级==当前优先级”不进行调度才算合理

    我修改了移植代码,让“最高优先级==当前优先级”不进行调度。发现我在第一贴所说的问题“在一个任务里面读取OSPrioCur读取出来,发现OSPrioCur的值不等于这个任务建立时的优先级”却奇迹般没有出现了,当然我现在还不能肯定这个问题解决了,还待测试!

使用特权

评论回复
14
zlgarm| | 2008-5-12 08:35 | 只看该作者

特别是IAR会这样

如上面所说:  "这种问题通常是IAR或KEIL编译时,把某些变量优化了,仿真显示的数值不是该变量的,而是某个寄存器或中间量的,但这不会影响代码的运行。",特别是IAR会这样。

(zlgarm_zsg)

使用特权

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

本版积分规则

92

主题

195

帖子

1

粉丝