打印

用了多年UCOS,自以为已经摸透了她的脾气,然而...

[复制链接]
3035|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kanprin|  楼主 | 2010-6-1 11:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
终极问题:空闲任务使用的堆栈与实际计算值出入太大
************************************************
案例如下:

目标器件:mega64
编译环境:winavr20100110
OS版本:主要是V2.76,东拼西凑了一些移植文件,自己修改了几条语句,并修改到能支持mega2561
系统时钟:使用定时器0的CTC模式


一个简单的demo,用户任务3个,加IDLE任务,总共4个,分别是
GLED显示任务:1秒闪一次,简单指示此任务在执行
UART1接收任务:以115200bps的速率收发数据
堆栈统计任务:5秒统计一次,从UART1打出调试信息,同时让RLED闪一次
空闲任务:系统决定

***********************
当窜口不接收数据时,空闲任务所使用的堆栈与理论值一样,37个字节。但是,用sscom往UART1以1ms的间隔发一串数据,
空闲任务堆栈飙到149甚至更大,偶尔系统还会crash down 。GLED显示任务堆栈却一直很稳定,所以搞不明白是啥道理了。

希望达人们诊断诊断(是否中断任务的写法有问题?),谢谢。

ucos_uart_demo.rar

239.64 KB

相关帖子

沙发
ayb_ice| | 2010-6-1 11:38 | 只看该作者
可能移植有BUG

使用特权

评论回复
板凳
kanprin|  楼主 | 2010-6-1 11:46 | 只看该作者
移植部分能想到的,会引起错误情况的地方都认真检查过了,或许我没那水平再去揪出这个BUG来了,呵呵。
所以才会发上来请求高人支援啊。

使用特权

评论回复
地板
hgjinwei| | 2010-6-1 12:25 | 只看该作者
以1秒或以上间隔发数据会怎样?

看到你在中断函数中有这样一句“OSTCBCur->OSTCBStkPtr = (OS_STK *)SP;”
甚是不解。为什么要修改当前优先级堆栈指针呢?这个应该交给“OSIntCtxSw()”处理会好点吧。

使用特权

评论回复
5
kanprin|  楼主 | 2010-6-1 14:35 | 只看该作者
4# hgjinwei

这一句是用户中断程序中对SP进行保存,在OSIntCtxSw()中有对SP进行恢复的动作,所以此处应该需要有一个保存的动作。我觉得要是能放到OSIntEnter()去的话会更好些,只是这个函数作者归到了系统内核函数非移植部分,没有去改动内核的情况下,放在此处应该没什么问题吧?

使用特权

评论回复
6
kanprin|  楼主 | 2010-6-1 14:42 | 只看该作者
本帖最后由 kanprin 于 2010-6-1 14:46 编辑

至于1秒以上的间隔发数据其实也是一样的,只是时间间隔大了,堆栈增加的速度会没那么快而已,说不定也就不至于crash down了,呵呵。为了加速调试,所以才用1ms的间隔,从理论上来讲应该不成问题才对。就算是进行了中断嵌套,那堆栈增加的字节数也应该是中断保护部分的个数,而问题是空闲任务堆栈的增加基本上是以几个字节的速度增加,中断保护的入栈是33个字节。更何况AVR在进入中断服务时会硬件把全局中断关闭,在程序没有开中断的时候是不会再进行中断嵌套的,只有程序去执行开全局中断后才会有可能产生中断嵌套,这也与实际产生的现象不相符。

使用特权

评论回复
7
emailli| | 2010-6-1 17:56 | 只看该作者
1ms的间隔和1秒的间隔肯定不一样的
1ms的间隔在不用操作系统的情况下
单片机都经常受不了而堆栈溢出而死机
何况你用了操作系统呢?
我觉得这个主要是由于 反复进中断,然后带来的 现场保护过于频繁导致。
应该和操作系统无关。
AVR不太清楚。
不过51进中断服务是需要自己去关闭全局中断才可以实现的。
然后如果发送用中断方式发送的话,是无法关闭全局中断的。
也就是说,很容易出现中断嵌套等现象

使用特权

评论回复
8
Quentin| | 2010-6-1 20:27 | 只看该作者
来学习了。

设置断点观察sp的值,然后单步执行,观察sp变化以及堆栈内值的变化,是否有助于发现问题?

使用特权

评论回复
9
kanprin|  楼主 | 2010-6-1 21:43 | 只看该作者
事实上调试过以2秒发送一次,而堆栈还是往上涨,只是每次长的字节数比较小,一般是几个字节的频率在长而已,所以我认为应该跟频率的关系不大。在没有应用代码的中断,而只有系统时钟中断的情况下堆栈一直都很稳定,应该是跟中断有关系,至于中断嵌套,在115200bps下,就算是以1ms的频率发送数据,对AVR来说,肯定是不至于发生中断嵌套的。我们没有仿真工具,调试一般直接通过串口来调试的,呵呵。

使用特权

评论回复
10
IJK| | 2010-6-2 12:30 | 只看该作者
通过串口来调试,也能发现问题的。用性能差的仿真器,跟通过串口来调试,其实差不太多。

使用特权

评论回复
11
kanprin|  楼主 | 2010-6-2 16:04 | 只看该作者
问题已经解决,多谢各位的顶贴,最终是因为中断嵌套引起的错误,在移植部分把所有可能引起中断嵌套的地方都修改之后,空闲任务的堆栈就不往上涨了。另外用串口调试非常方便,不想对仿真器形成依赖,呵呵。

使用特权

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

本版积分规则

39

主题

343

帖子

0

粉丝