OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9360|回复: 22

移植原子的,UCOS 系统不定期死机

[复制链接]

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
发表于 2022-8-5 11:29:54 | 显示全部楼层 |阅读模式
1金钱
各位大神好!
最近移植了原子的综合例程的UCOS到自己的H7板子上,开启一个主任务和UART/WATCH共3个任务。主任务中有个LVGL APP,采集ADC并显示处理结果, 有个SAI中断开启 .  测试时发现,如果主任务中执行普通应用,运行正常,但是当运行一个比较复杂的解码程序,就会不定期的死机,短时几分钟,长时几小时都有,死机位置不相同,也找不到明显的逻辑错误。 于是怀疑任务堆栈过小,于是将其加大到8192字节,现象没有改善。 系统栈已经设置为53K字节了,HEAP为41K字节。
我怀疑UCOS的任务堆栈是不是还是不够,或者是系统堆栈不够?

查阅原子的UCOS文档,讲到UCOS在任务切换时只是压栈保存几十个寄存器到任务堆栈中,我的问题如下
1. 任务切换点的函数和其子函数在系统堆栈的临时变量是不是任然在系统堆栈中,仍然由CPU管理?
2. 任务切换后新任务的函数的临时变量是不是任然由CPU管理,并在系统堆栈中申请?
3. 如果以上成立,UCOS任务堆栈中仅仅只存储几十个寄存器,堆栈大小就不必要设置很大了吧? 而主要的局部变量在系统堆栈上,则系统堆栈必须保持比较大,对吗?

望众神不吝赐教!多谢了!

最佳答案

查看完整内容[请看2#楼]

多谢兄弟热心帮助,是的,之前理解错误,后来验证出,UCOS每个任务都在自己的堆栈上分配局部变量,包括中断。改大中断堆栈解决问题。 多谢!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-5 11:29:55 | 显示全部楼层
多谢兄弟热心帮助,是的,之前理解错误,后来验证出,UCOS每个任务都在自己的堆栈上分配局部变量,包括中断。改大中断堆栈解决问题。
多谢!
回复

使用道具 举报

14

主题

821

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2096
金钱
2096
注册时间
2021-7-17
在线时间
656 小时
发表于 2022-8-5 12:18:20 | 显示全部楼层
任务中有没有数组越界或者中断处理异常的情况
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-5 13:36:30 | 显示全部楼层
多谢兄弟。
出问题的处理函数部分的确有比较大的数组(160k)分配在SRAM12上。但应该没有越界,因为一般情况也能正常工作一段时间。 如果有越界,是非常容易重复出现的。有时能正常运行几个小时。
不运行此处理函数时没有出现死机现象。我怀疑UCOS任务切换时,是不是要求更大的系统堆栈/任务堆栈。 我已经尝试将很多函数内部大数组移动到函数外面改为全局,减小动态堆栈的需求,还是没有改善。
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-5 14:21:25 | 显示全部楼层
补充一下,我搜了原子的官方文档,其介绍CPU硬件会将25个寄存器自动入栈,另外24个是手动入栈。没有介绍其他会被压入任务堆栈的数据或变量。 而任哲和卢有亮的书也没有介绍任务堆栈里面会存什么东西。这么看来,系统堆栈才是各局部变量的分配区域了,所以任务堆栈实际并不需要很大空间,不知道理解对吗?  我上面还说错了,其实任务堆栈大小改为了8192*4=32K字节,应该太大了。

望众神不吝赐教!
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13079
金钱
13079
注册时间
2012-11-26
在线时间
3809 小时
发表于 2022-8-5 15:08:36 | 显示全部楼层
如果任务比较大,必须设置很大     而且  .s文件的 stack和heap也要改大
学无止境
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-5 15:37:26 | 显示全部楼层
我的主任务应该比较大,里面是LVGL的主应用,任务堆栈设置多大为好呢? 根据以上分析,任务堆栈里面仅仅保存任务切换时候的50个左右的寄存器,最多加上当前TCB的一些现场,不涉及新任务函数内部变量的分配,应该不需要很大空间吧?  系统堆栈当然要匹配最大的嵌套状态,难道是目前我的系统堆栈还不够?
愿闻其详

多谢兄弟!
回复

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3348
金钱
3348
注册时间
2013-5-28
在线时间
468 小时
发表于 2022-8-5 16:58:48 | 显示全部楼层
你是UCOS几啊?UCOSII的话免费版就不要开启浮点,开启浮点要修改源文件的
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-5 17:19:25 | 显示全部楼层
我是UCOSII ,已经改过代码,浮点没有问题。现在是运行一个数据处理函数,时间长了会死机的问题。

多谢兄弟!
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-6 18:53:10 | 显示全部楼层
求助!
哪位大神了解 UCOS任务堆栈中 到底存放了什么东西?

多谢众神!
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-8 18:01:34 | 显示全部楼层
有朋友了解这个问题吗? 能否指导下?多谢!
回复

使用道具 举报

1

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2018-8-21
在线时间
10 小时
发表于 2022-8-9 11:10:22 | 显示全部楼层
检查一下看看是否有数组越界
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-9 11:30:28 | 显示全部楼层
多谢兄弟!  我查查看。 任务堆栈开4K字应该够了吧?  UCOS的任务堆栈到底存放什么东西呢?
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-9 12:20:40 | 显示全部楼层
网上搜了一圈,对UCOS任务堆栈最多的说法如下:
UCOS任务堆栈:
【函数嵌套、所调用函数局部变量分配内存、中断服务子程序嵌套】
1、当任务运行时保存一些局部变量(CPU寄存器有限)。
2、当任务挂起时,负责保存运行现场,即CPU寄存器的值。

而对于上面第一点,我觉得如果成立,那么每次函数调用,都必然要调用UCOS系统服务。这显然是不成立的。UCOS系统服务只是在任务切换挂起等事件发生时才通过PENDSV调用。
这样实际上任务堆栈里面存放的仅仅是任务相关的寄存器或TCB等现场,局部变量还是在系统堆栈上,所以系统堆栈仍然是最大和最主要的堆栈区。

不知我理解正确吗? 众神不吝赐教!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2022-8-11 01:09:38 | 显示全部楼层
szszjdb 发表于 2022-8-9 12:20
网上搜了一圈,对UCOS任务堆栈最多的说法如下:
UCOS任务堆栈:
【函数嵌套、所调用函数局部变量分配内存 ...

MCU的固定堆栈,肯定得大于任务堆栈,任务堆栈则是根据每个任务的嵌套深度,局部变量多少来决定的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-11 20:07:42 | 显示全部楼层
多谢原子哥,我的问题是 UCOS的任务堆栈上面会存放局部变量吗? 我理解任务函数在嵌套调用时,没有调用UCOS系统服务,所以其局部变量没有分配在任务堆栈上,而是仍然在系统堆栈。如果是这样任务堆栈不必很大,最大的还是系统堆栈。这个理解正确吗?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2022-8-12 01:18:24 | 显示全部楼层
szszjdb 发表于 2022-8-11 20:07
多谢原子哥,我的问题是 UCOS的任务堆栈上面会存放局部变量吗? 我理解任务函数在嵌套调用时,没有调用UCOS ...

凡是任务内部的局部变量,都是存储在任务堆栈的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-12 11:00:05 | 显示全部楼层
多谢原子哥!

这点在很多书上都提到了这个说法。但是很奇怪没有一本书详细讲出局部变量开在任务堆栈的方法和原理。 根据我的实测这是很值得推敲的地方。
跟您的综合例子一样,目前我的代码启动初始化后就建立并运行了3个UCOS任务。其中主任务中运行LVGL 和主APP,  如果局部变量都开在任务堆栈的话,显然目前主任务的4K字堆栈是不够的。
另外当用调试器中断任何一个主任务中的函数时,KEIL的CALLSTACK窗口列出的所有局部变量显然是在系统堆栈上。难道UCOS运行后修改了系统初始堆栈指针,同时任务切换时通过改变这个指针来改变函数使用的堆栈?
另外MCU的系统堆栈和UCOS的任务堆栈并不是重合的,您上面说的系统堆栈必须大于UCOS任务堆栈,而UCOS局部变量又全部开在任务堆栈上,这两点不是有点矛盾吗?

还请不吝赐教!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2022-8-15 01:44:31 | 显示全部楼层
szszjdb 发表于 2022-8-12 11:00
多谢原子哥!

这点在很多书上都提到了这个说法。但是很奇怪没有一本书详细讲出局部变量开在任务堆栈的方 ...

具体原理,建议你看UCOS的源码或者相关详细的介绍。
我也不是很记得了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-16 16:02:55 | 显示全部楼层
正点原子 发表于 2022-8-15 01:44
具体原理,建议你看UCOS的源码或者相关详细的介绍。
我也不是很记得了。

多谢原子哥!
详细跟踪了,的确任务的局部变量是在任务堆栈上,但是中断函数的局部变量好像全部在OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE],且这个空间才128字,而不是启动时的系统堆栈区, 我的系统有定时器中断和SAI中断,这个大小够用吗? 是不是要改动到合适大小才能保证中断函数堆栈不会溢出?
目前查到 void  OSInitHookBegin (void) 对堆栈的初始化如下:
OS_CPU_ExceptStkBase = (OS_STK *)&OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE];

查了你们的资料,没有介绍这块堆栈是否要特别配置,还请不吝赐教!
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-16 17:09:27 | 显示全部楼层

下面是运行截图,MSP指向的就是OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE],这是在中断断点。
ucos_int.jpg
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2022-8-17 17:52:29 | 显示全部楼层
多谢各位,判断是这个OS_CPU_ExceptStk 数组太小。改后测试中。
回复

使用道具 举报

0

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2017-5-8
在线时间
12 小时
发表于 2022-8-19 23:29:00 | 显示全部楼层
1. 你问的第一个问题没有描述清楚你的意图,任务切换点的函数,你指的是哪一个函数?
2. 任务切换后新任务的函数的临时变量,位于你为该任务分配的任务堆栈里,而非main函数所使用的系统堆栈。(参考一下ARM的ATPCS文档。)
3. 你说的这个不正确,理由见第二点。每个任务的局部变量都在自己的任务堆栈里,实际开发建议估算一下每个任务最深堆栈用量,并且建议,局部变量如果很大的时候,有条件的话就改用堆里的内存。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-8 21:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表