硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1274|回复: 20
收起左侧

[RTOS] H7板子运行UCOSII, 运行大处理函数会时间长了会死机

  [复制链接]

9

主题

85

回帖

112

积分

初级会员

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

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

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

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106578
QQ
发表于 2022-8-5 18:09:05 | 显示全部楼层
我觉得是你的应用程序问题,你可以把你的应用代码都注释掉看看。
回复

使用道具 举报

9

主题

85

回帖

112

积分

初级会员

积分
112
 楼主| 发表于 2022-8-6 13:33:46 | 显示全部楼层
多谢硬汉哥! 是当APP里面运行一个对内存消耗比较大的解码程序时才容易进入死机,死的地方不一致,大致跟lv_mem 相关操作有关,如 lv_mem_free 或 _lv_mem_buf_get 等等,都是数据指针=0;所以我初步判断是任务、系统堆栈溢出,破坏了 lvgl内存部分。 我目前将 lv_mem 开在了SDRAM里面 2M字节,平时看也就消耗了70K-90K字节左右,系统STACK=61K字节, HEAP=57K字节, 任务STACK=4K字 。 解码程序移植别人验证过的,应该没有问题,而且一般都能稳定运行一段时间,如果有逻辑错误,是很容易再现并被抓出来的。
所以在考虑是不是UCOS任务堆栈开小了,我试过加大任务STACK=8K字, 没有改善,而且 OSTaskStkChk 抓出来任务堆栈才 1.6K字,应该是足够使用了。

我目前的疑问是
1. UCOS任务堆栈 到底存了什么东西?  有资料说存了新任务函数局部变量,这不是存在系统堆栈上的吗? 我理解任务函数切换的现场寄存器保存进了任务堆栈,但是新任务的局部变量还是在系统堆栈上由CPU而不是UCOS管理,这个理解对吗?
2. 还有哪些可能的排查方向?

多谢硬汉哥和众神!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106578
QQ
发表于 2022-8-6 15:26:43 | 显示全部楼层
szjdb 发表于 2022-8-6 13:33
多谢硬汉哥! 是当APP里面运行一个对内存消耗比较大的解码程序时才容易进入死机,死的地方不一致,大致跟lv ...

1、理解的有偏差,任务里面所有函数的局部变量,保护层层调用的函数现场和这些函数里面的局部变量都是用的任务栈,系统主要是进入中断后才使用的。
2,可以打印下任务栈的使用情况。
回复

使用道具 举报

9

主题

85

回帖

112

积分

初级会员

积分
112
 楼主| 发表于 2022-8-6 19:32:31 | 显示全部楼层
多谢硬汉哥周末的解答!

关于任务堆栈是否存放新旧任务函数局部变量的问题,想向您再请教下。
我查过仁哲的书,上面没有写清楚任务堆栈存放什么东西。一般也只提到现场寄存器的保护。
根据UCOS在移植STM32时,只使用了 PENDSV这个系统接口,这个只是UCOS在进行任务切换时才调用。再加新任务函数及其子函数的局部变量是需要在堆栈上申请和销毁的,这个申请和销毁动作是不可能由UCOS接管了而应该还是CPU在负责吧? 所以我认为任务堆栈仅仅压如了任务切换时的现场和其它一些UCOS的TCB相关的现场,而函数局部变量还是在系统堆栈上。这个分析正确吗?

打扰硬汉哥了!
回复

使用道具 举报

9

主题

32

回帖

59

积分

初级会员

积分
59
发表于 2022-8-8 12:31:27 | 显示全部楼层
你应该怀疑LVGL,分配 2M内存,4M显示缓存,我跑裸机,跑FREERTOS时间久了都会死机,串口打印信息的内存耗尽
跑官方仪表盘例程,更容易死机
回复

使用道具 举报

9

主题

85

回帖

112

积分

初级会员

积分
112
 楼主| 发表于 2022-8-8 18:00:46 | 显示全部楼层
多谢兄弟,我跑的LVGL 7.11比较稳定,LVGL内存变化不大。

还是想搞清楚UCOS 任务堆栈到底干什么活。 望大家不吝赐教!多谢!
回复

使用道具 举报

9

主题

85

回帖

112

积分

初级会员

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

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

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

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106578
QQ
发表于 2022-8-9 16:27:14 | 显示全部楼层
image.png

image.png
回复

使用道具 举报

9

主题

85

回帖

112

积分

初级会员

积分
112
 楼主| 发表于 2022-8-9 16:56:31 | 显示全部楼层
多谢硬汉哥的文档!

我只是对函数嵌套调用时的局部变量要不要进入任务栈有疑问。 因为普通的任务内函数的调用发生时,并没有去调用UCOS系统服务,所以参数传递和局部变量的申请空间还应该是系统堆栈,我的分析正确吗?

回复

使用道具 举报

2

主题

18

回帖

24

积分

新手上路

积分
24
发表于 2022-8-10 09:15:55 | 显示全部楼层
你可以简单理解在RTOS中,有没有进中断就是区分使用任务栈还是系统栈
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106578
QQ
发表于 2022-8-10 09:45:43 | 显示全部楼层
szjdb 发表于 2022-8-9 16:56
多谢硬汉哥的文档!

我只是对函数嵌套调用时的局部变量要不要进入任务栈有疑问。 因为普通的任务内函数 ...

理解不对,只有进入中断后才使用系统栈,含中断嵌入,中断里面函数嵌套等。

这个问题,你可以手动调试代码查看的,看下栈内容变换就行,这样可以加深理解。
回复

使用道具 举报

210

主题

1042

回帖

1682

积分

至尊会员

More we do, more we can do.

积分
1682
发表于 2022-8-10 11:23:10 | 显示全部楼层
启用编译器栈分析,见官方文档 Stack use in C and C++,链接: Arm Compiler for Embedded User Guide
回复

使用道具 举报

9

主题

85

回帖

112

积分

初级会员

积分
112
 楼主| 发表于 2022-8-10 11:25:24 | 显示全部楼层
多谢楼上兄弟和硬汉哥!

如果是这样我的任务栈可能开小了。但是奇怪的是用 OSTaskStkChk 抓出来  free=0x9bc=2492字 ,used=0x644=1604字 , 还有一半以上的空间没用。 难道是没抓到峰值堆栈分配?
另外,死的地方多数是LVGL的内存操作函数,如 lv_mem_free,_lv_mem_buf_get,此时的堆栈已经被破坏,看不到前面的调用嵌套了,只有HARDFAULT前一个调用可以看到。目前我把LV MEM 放到了SDRAM里面,2M字节,应该是不会溢出的。

大家还有什么查找问题的方法和建议吗?
多谢各位大神!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106578
QQ
发表于 2022-8-11 14:22:36 | 显示全部楼层
szjdb 发表于 2022-8-10 11:25
多谢楼上兄弟和硬汉哥!

如果是这样我的任务栈可能开小了。但是奇怪的是用 OSTaskStkChk 抓出来  free=0 ...

要抓max峰值。

估计其它的地方有问题,得再查查了。
回复

使用道具 举报

9

主题

85

回帖

112

积分

初级会员

积分
112
 楼主| 发表于 2022-8-15 10:32:15 | 显示全部楼层
硬汉哥您好!
实际验证了,用调试器跟踪,在任务函数中 MSP的确指向任务堆栈,局部变量应该都在上面。而在SAI中断时 PSP 指向 OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE]; 这个空间才512字,难道中断是用的这块区域作为堆栈而不是系统堆栈? 因为KEIL调试环境不能显示局部变量的实际地址(局部变量无法加入MEMORY窗口,看不到地址),所以到底中断中局部变量是使用 OS_CPU_ExceptStk 还是系统原堆栈,还不是特别明确。

查了任哲的书,没有这方面的介绍。

硬汉哥及各位大神能否帮忙确认下?


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106578
QQ
发表于 2022-8-15 10:51:05 | 显示全部楼层
szjdb 发表于 2022-8-15 10:32
硬汉哥您好!
实际验证了,用调试器跟踪,在任务函数中 MSP的确指向任务堆栈,局部变量应该都在上面。而在 ...


你这个还是没有理解到点上啊,学习下这个视频教程吧,系统的了解下。

ThreadX视频教程第2期:通俗易懂的介绍Cortex-M内核的OS特性,双堆栈,非特权级,PendSV,SVC,Systick等,争取人人都可以掌握
https://www.armbbs.cn/forum.php? ... d=110579&fromuid=58
(出处: 硬汉嵌入式论坛)



回复

使用道具 举报

9

主题

85

回帖

112

积分

初级会员

积分
112
 楼主| 发表于 2022-8-16 10:11:53 | 显示全部楼层
多谢硬汉哥!
您的视频和文档看过了,非常精彩。 明白了UCOS是通过修改堆栈栈顶指针来控制任务或中断使用的实际堆栈区。我实测的确观察到任务堆栈指针是指向预设的任务堆栈RAM区 ,这点符合预期。但是您视频说中断中硬件强制使用MSP,而我观察到中断使用的RAM区是OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE],且这个空间才512字,而不是启动时的系统堆栈区。 这是否是我使用的这个别人移植好的版本的问题?
目前查到 void  OSInitHookBegin (void) 对堆栈的初始化如下:
OS_CPU_ExceptStkBase = (OS_STK *)&OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE];

是不是应该将OS_CPU_EXCEPT_STK_SIZE 改大到合适为止?

还请硬汉哥不吝赐教!
回复

使用道具 举报

9

主题

85

回帖

112

积分

初级会员

积分
112
 楼主| 发表于 2022-8-16 11:06:48 | 显示全部楼层
下面是运行截图,MSP指向的就是OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE]
ucos_int.jpg
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106578
QQ
发表于 2022-8-17 09:30:25 | 显示全部楼层
szjdb 发表于 2022-8-16 10:11
多谢硬汉哥!
您的视频和文档看过了,非常精彩。 明白了UCOS是通过修改堆栈栈顶指针来控制任务或中断使用 ...

不错,终于理解到点上了。

这个地方是uCOS区别于其它RTOS的地方,uCOS这里在上电初始化时,重新设置了MSP的位置,也就是没有再使用xxxx.s文件的stack,而是新开了一个msp系统栈空间,方便检测系统栈的使用情况。
回复

使用道具 举报

9

主题

85

回帖

112

积分

初级会员

积分
112
 楼主| 发表于 2022-8-17 10:52:20 | 显示全部楼层
多谢硬汉哥!
看来是定位到问题所在了。改后初步测试问题解决,受教了!
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-25 14:09 , Processed in 0.521234 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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