joyko 发表于 2009-10-7 17:12:18

ucos_ii~。。。蝴蝶效应,求助

之前学UC,用在STM32上,拿别人移植好了过来的程序跑了几个灯,就好久没动了,现在把前后台做的一个人机界面,把它弄进OS去,发现了几个问题,请教下各位大侠:
1、任务B中定义了一个较大的数组,用来对采集到的数据进行处理用的,有360B,而CM3的内核通用寄存器是16个,开始我吧任务B的堆栈设为64B,结果该任务一旦开跑之后挂起,就跑进HardFault去,也就是当机了。后来把堆栈设大了之后该任务可以挂起(还有BUG见问题2),现在不明白的是,任务中的变量是存储在堆栈中去的吗,而堆栈的设置只要大于CPU内核寄存器+变量大小就可以了呢?

2、这个也是最想不明白的,按常理来说两个没直接联系的东西影响对方了。现在有三个有可能关联的任务,任务A,B,C优先级分别是8,12,10,开始除了A都挂起了

任务A显示主菜单及相关的按键处理,一旦按下菜单1,任务B,任务C解挂,任务A自动挂起,C是采集数据用的1S读三次。任务B里面有个挂起延时的动作,OSTimeDly(),只要有这个动作存在,对18B20采集的温度就会偶尔失误了。但是即使我没有进入到任务B,在只有A运行的情况下,采集的数据也有误。   而只要把任务B里面OSTimeDly(),这个动作去掉,整个系统就都不会出现采集数据有误的情况。。还有其他任务里出现OSTimeDly()也都正常!

18B20也不是刚开始用了,出现这种情况一般是某个函数读温度的时候,发生一个中断,中断里再次操作18B20,造成时序乱了的结果,但是在这里,我搞不清楚了,也许对这个OS还不熟悉吧,希望大家指点指点!!

joyko 发表于 2009-10-7 17:56:40

好像和编译器有关。。。IAR用高度优化后就出现这个情况,用中度优化就没了,但是还不大清楚哪个环节出错了,给读温度函数设为一个等待接收信号量的任务应该问题不大了。

liguangqang 发表于 2009-10-8 08:22:23

cosii 的任务切换原理是,每个任务有独立的任务栈,每次切换时先保存CPU寄存器,同时保存了当前任务栈SP指针。然后把最高优先级任务的变量装载到CPU,这时SP指向这个高优先级任务栈,一般编译器对变量的处理是基于SP指针来安排存放位置,因此每个任务的变量也就存在自已的任务栈中。如任务有很多变量就得为任务安排允足的任务栈。由于cosii对内存管理比较弱也存在内存浪费。所有安排时尽可能合理。 1问题我认为任务栈太小。

DS18B20对时序要求很高,如果用OSTimeDly()来控制时序,并温度采集不是高优先级时序我认为很难控制得好。可用视波器看一下就知了解了。

joyko 发表于 2009-10-8 09:36:27

谢谢2楼的朋友,我原来可能讲的不够清楚,是这样的,
A任务处理主菜单的活,哪个键按下我就解挂哪个任务,由于其他任务比A任务优先级较低,所以解挂完其他任务后再把自己挂起其他任务才能运行。

B任务处理由C任务采集到的数据,并将其显示到LCD上,我在这里开了个较大变量的缓存。

C任务采集任务,数据放到全局变量里去。优先级比B高,用OSTimeDly()来确定采集时间(原来前后台我是用中断采集的,用了OS感觉省了个定时器?),C可以打断B,而B得OSTimeDly(),是为了在显示到LCD上去的时候减少闪烁,其实用一般的软件延时也可以,但是不够精确,也不明白在最大优化的情况下位什么会影响18B20的读数。哦,18C20的读数只是简单采用延时来控制时序的。

还没有示波器呢。。业余学习,对任务栈有点了解了,其他任务栈设的不够,也有可能在运行时影响全局变量。只是现在设栈还有点盲目,任务B栈有那么多变量,我试凑这给栈150,就可以正常跑起来了。。

xm042041 发表于 2009-10-9 11:30:08

你说:18B20也不是刚开始用了,出现这种情况一般是某个函数读温度的时候,发生一个中断,中断里再次操作18B20,造成时序乱了的结果,但是在这里,我搞不清楚了,也许对这个OS还不熟悉吧,希望大家指点指点!!

那在这个过程前加屏蔽中断函数,完后再开放中断。如果实时性不够高,你可以改下OSTimeDly()函数,这个好像是1MS的中断延时,你改的更快一些呢,我没有UCOS的源码,刚接触,说的不对的地方请见谅!

liguangqang 发表于 2009-10-9 14:24:02

我觉得可能是时钟节拍中断的影响,由于cosii 时钟节拍中断服务一般都是在运行的,你的C采用的是简单延时又没有示波器,很有可能在运行C时由于中断的打入产生时序出错,你可采用进入临界状态来处理要求高的部分,在处理精度不高时用系统的延时程序。还要注意这时A最高优先级的打入。

joyko 发表于 2009-10-9 20:48:54

楼上说的有道理,我的时钟节拍设置为150/S,但是想不通的是为什么我在没有运行B的时候(C也不可能运行),B的OSTimeDly()存在与否会干扰A运行时读出的数据呢,读数是设为的一个函数,读出的数据时放到全局变量里的,A和C都可以调用这个函数。

4楼的朋友,开始我在读数的函数进入前后也加了屏蔽中断的函数了,结果是一样的。OSTimeDly()这个是可以设置延时时间的,以时钟节拍为单位来设置的。

现在又把编译器的优化程度设为高,读数又正常了,改动的地方包括每个任务的栈都做了不同程度的扩大,在其他栈设的比较小的时候也有这种情况,由于读出的数据放到全局变量里,我只能理解为栈太小了的时候任务中的变量占用了全局变量的内存了。

ddcour 发表于 2009-10-9 21:58:47

都玩os了
页: [1]
查看完整版本: ucos_ii~。。。蝴蝶效应,求助