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

[复制链接]
 楼主| feifan570 发表于 2008-5-8 12:46 | 显示全部楼层 |阅读模式
&nbsp;&nbsp;&nbsp;&nbsp;我使用LM3S6916,用的是zlg的移植。我发现在一个任务里面读取OSPrioCur读取出来,发现OSPrioCur的值不等于这个任务建立时的优先级。<br />&nbsp;&nbsp;&nbsp;&nbsp;然后我在OSTaskSwHook()函数里面做判断if(OSPrioCur&nbsp;==&nbsp;OSPrioHighRdy)。居然发现可以进入到这。OSTaskSwHook()是在<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R4,&nbsp;=OSPrioCur&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;OSPrioCur&nbsp;=&nbsp;OSPrioHighRdy<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R5,&nbsp;=OSPrioHighRdy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDRB&nbsp;&nbsp;&nbsp;&nbsp;R6,&nbsp;[R5]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STRB&nbsp;&nbsp;&nbsp;&nbsp;R6,&nbsp;[R4]<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R4,&nbsp;=OSTCBCur&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;OSTCBCur&nbsp;&nbsp;=&nbsp;OSTCBHighRdy;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R6,&nbsp;=OSTCBHighRdy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R6,&nbsp;[R6]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R6,&nbsp;[R4]<br />这段代码之前调用的,也就是说OSPrioCur&nbsp;和&nbsp;OSPrioHighRdy相等也执行了任务切换。但是通过看OSIntExit()和OS_Sched()的代码可以知道:OSPrioCur&nbsp;和&nbsp;OSPrioHighRdy相等是不会进行任务切换的。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;那么这只能说是移植出了问题吧?
zlgarm 发表于 2008-5-8 16:53 | 显示全部楼层

仿真显示问题

楼主:<br />&nbsp;&nbsp;&nbsp;“发现在一个任务里面读取OSPrioCur读取出来,发现OSPrioCur的值不等于这个任务建立时的优先级。”<br />&nbsp;&nbsp;&nbsp;这种问题通常是IAR或KEIL编译时,把某些变量优化了,仿真显示的数值不是该变量的,而是某个寄存器或中间量的,但这不会影响代码的运行。<br /><br />(zlgarm_zsg)<br />
 楼主| feifan570 发表于 2008-5-8 17:27 | 显示全部楼层

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

我把这些变量从串口打印出来也是和该任务的优先级对不上。而且第二个问题又如何解析呢:OSTaskSwHook()函数出现(OSPrioCur&nbsp;==&nbsp;OSPrioHighRdy)?
zlgarm 发表于 2008-5-9 08:52 | 显示全部楼层

中断嵌套

“OSPrioCur&nbsp;==&nbsp;OSPrioHighRdy”我们也有同事出现过。Cortex-M3的中断是有优先级、可嵌套的,首相检查OS_CRITICAL_INT_PRIO是否为0,然后看看你写的中断会不会因为嵌套而破坏系统。<br /><br />(zlgarm_zsg)
 楼主| feifan570 发表于 2008-5-9 10:48 | 显示全部楼层

找到原因了

原因是这样的:<br />&nbsp;&nbsp;&nbsp;&nbsp;在高优先级任务自动放弃CPU的使用权,即要调用OS_Sched()进行任务调度,但是在这个OS_Sched()中并不是在OS_TASK_SW()马上进行切换,而是等待中断打开后OS_EXIT_CRITICAL()才能进入任务切换的中断。但是一旦中断被打开,其他的中断先被执行,然后中断退出调用OSIntExit()使得OSPrioHighRdy再次被改写。就会出现这个问题。解决办法应该把软件中断的优先级提高。
zlgarm 发表于 2008-5-9 11:40 | 显示全部楼层

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

&nbsp;&nbsp;软件中断一定要最低优先级,如果不是最低优先级调度是有问题的,您可以在嵌套、末尾连锁、占先等情况下分析一下。<br />&nbsp;&nbsp;&nbsp;至于“中断退出调用OSIntExit()使得OSPrioHighRdy再次被改写”,肯定是这个中断把某个任务的优先级提高了,这是符合UCOS-II规定的,而不是移植的问题。<br /><br />(zlgarm_zsg)<br />
 楼主| feifan570 发表于 2008-5-9 11:51 | 显示全部楼层

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

zlg工程师是否验证了这个问题?&nbsp;<br />&nbsp;&nbsp;&nbsp;关键是“中断退出调用OSIntExit()使得OSPrioHighRdy再次被改写”使得最高优先级再次改回当前优先级,按ucos-ii的规定这不应该进行调度的吧?难道“最高优先级==当前优先级”进行调度也是“这是符合UCOS-II规定的,而不是移植的问题。”?
zlgarm 发表于 2008-5-9 14:54 | 显示全部楼层

不明白

“中断退出调用OSIntExit()使得OSPrioHighRdy再次被改写”这句话按我的理解是不对的。OSIntExit()的核心语句如下:<br /><br />OSIntExitY&nbsp;&nbsp;&nbsp;=&nbsp;OSUnMapTbl[OSRdyGrp];&nbsp;&nbsp;&nbsp;<br />OSPrioHighRdy&nbsp;=&nbsp;(INT8U)(&nbsp;(OSIntExitY&nbsp;&lt&lt&nbsp;3)&nbsp;+&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSUnMapTbl[OSRdyTbl][OSIntExitY]]&nbsp;);<br /><br />&nbsp;&nbsp;从上面可以看出,“新”的OSPrioHighRdy是根据OSRdyGrp和OSRdyTbl[]而定的,如果中断函数里面没有调用OSSemPost()等uCOS-II函数,OSRdyGrp和OSRdyTbl[]是不会变的,也就是说执行完上面的语句后OSPrioHighRdy是不变的。另外,如果调用了OSSemPost()等函数,使得OSRdyGrp和OSRdyTbl[]改变了,也就说明有更高优先级的任务等着运行,这个任务比进入中断前准备运行的任务还有迫切,这些是和用户的实际应用有关的。<br /><br />(zlgarm_zsg)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
 楼主| feifan570 发表于 2008-5-9 15:49 | 显示全部楼层

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

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我的一个中断确实是调用了OSSemPost()的函数,使得中断退出时要重新调度。但是这是UCOS-II允许的。<br />&nbsp;&nbsp;&nbsp;&nbsp;“中断退出调用OSIntExit()使得OSPrioHighRdy再次被改写”所说的也就是你所说的,就是调用下面的语句而被改写的,因为OSPrioHighRdy在OS_Sched()已经被更新过,现在再次被OSIntExit()更新,所以我加了一个“再次”。<br />OSIntExitY&nbsp;&nbsp;&nbsp;=&nbsp;OSUnMapTbl[OSRdyGrp];&nbsp;&nbsp;&nbsp;<br />OSPrioHighRdy&nbsp;=&nbsp;(INT8U)(&nbsp;(OSIntExitY&nbsp;&lt&lt&nbsp;3)&nbsp;+<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSUnMapTbl[OSRdyTbl][OSIntExitY]]&nbsp;);<br /><br />我觉得问题就在这:<br />&nbsp;&nbsp;&nbsp;&nbsp;OSPrioHighRdy&nbsp;本来在OS_Sched()中已经设置成新的最高优先级了,应该在OS_TASK_SW()把它切换到新的最高优先级的任务,但是这个动作实际上没有完成,要等待中断打开后才能完成。<br />&nbsp;&nbsp;&nbsp;&nbsp;如果OS_TASK_SW()能把任务切换这件事情做完,那就不会有这个问题。或者中断一打开,马上把任务切换这件事做完也不会有这个问题出现。所以我觉得系统要求任务切换而并没有进行任务切换,就是不按照UCOS-II的要求办事了。UCOS-II要求是在OS_TASK_SW()进行任务切换!
ZLGARM 发表于 2008-5-9 17:09 | 显示全部楼层

ARM7的思路

&nbsp;&nbsp;&nbsp;&nbsp;楼主的是ARM7的思路。ARM7的中断不能嵌套,它切换任务的思路是“就地尽快切换”;而Cortex-M3的中断可嵌套,它的思路是“中断优先”。<br />&nbsp;&nbsp;&nbsp;&nbsp;假设任务使用OS_TASK_SW()“就地”把任务切换好,重开中断后,正准备执行新任务时,楼主的某个中断产生了,中断程序调用OSSemPost()找到更高优先级的任务,最后调用OSIntExit()切换到这个更加新的任务,单片机最后运行的是这一个任务,而不是先前切换好的任务,先前的切换过程是“白干”的。<br /><br />(zlgarm_zsg)
 楼主| feifan570 发表于 2008-5-9 17:29 | 显示全部楼层

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

“软件中断一定要最低优先级”?能解释一下吗?如果把软件中断优先级设最高了除了做多点“白干”的活,还有其他问题吗?
zlgarm 发表于 2008-5-10 08:51 | 显示全部楼层

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

假设软件中断为最高优先级。当它嵌套某一个低优先级的中断后,它要保存的寄存器已经被低优先级中断使用过,而不是原始的任务内容。<br /><br />(zlgarm_zsg)
 楼主| feifan570 发表于 2008-5-10 15:36 | 显示全部楼层

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

&nbsp;&nbsp;&nbsp;&nbsp;我修改了移植代码,让“最高优先级==当前优先级”不进行调度。发现我在第一贴所说的问题“在一个任务里面读取OSPrioCur读取出来,发现OSPrioCur的值不等于这个任务建立时的优先级”却奇迹般没有出现了,当然我现在还不能肯定这个问题解决了,还待测试!
zlgarm 发表于 2008-5-12 08:35 | 显示全部楼层

特别是IAR会这样

如上面所说:&nbsp;&nbsp;&quot;这种问题通常是IAR或KEIL编译时,把某些变量优化了,仿真显示的数值不是该变量的,而是某个寄存器或中间量的,但这不会影响代码的运行。&quot;,特别是IAR会这样。<br /><br />(zlgarm_zsg)<br />
您需要登录后才可以回帖 登录 | 注册

本版积分规则

92

主题

195

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部