硬汉嵌入式论坛

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

[μCOS-III] UCOSIII浮点寄存器出栈时进入错误中断

[复制链接]

98

主题

340

回帖

634

积分

金牌会员

积分
634
发表于 2021-6-7 10:39:29 | 显示全部楼层 |阅读模式
系统正常运行没问题,但是在大批量收发数据的时候,很容易进入错误中断,仿真发现是在执行OS_CPU_FP_Reg_Pop函数时进入的错误中断。
猜测应该是浮点寄存器出栈的时候导致的。UCOSIII版本是V3.08.00。
刚开始怀疑是不是默认打开了LazyStacking的缘故,但把它关闭掉,故障依旧。

回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2021-6-7 10:51:49 | 显示全部楼层
硬件是H743,请教硬汉哥是否遇到过这样的问题?
回复

使用道具 举报

1

主题

12

回帖

15

积分

新手上路

积分
15
发表于 2021-6-7 11:17:20 | 显示全部楼层
关注中,我用3.08出现了跑一段时间进入hardfault的问题,倒查导致hardfault问题的代码,查不到。改用3.06的系统就好了。怀疑3.08代码有bug,感觉跟楼主的有点像
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107028
QQ
发表于 2021-6-7 16:10:42 | 显示全部楼层
帮顶,没遇到过,我这个新版综合模板是基于uCOS-III V3.08,一切正常

基于STM32H7的uCOS-III + FatFS + emWin + ST USB的综合模板下载(已经发布2021-01-21)
http://www.armbbs.cn/forum.php?m ... 0125&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2021-6-8 09:29:44 | 显示全部楼层
eric2013 发表于 2021-6-7 16:10
帮顶,没遇到过,我这个新版综合模板是基于uCOS-III V3.08,一切正常

基于STM32H7的uCOS-III + FatFS +  ...

嗯,跟你移植的最新操作系统的例程对比了一下,操作系统内核部分是一样的,可能还是操作系统哪儿使用的不对,之前跑的V3.04.04版本的没出现过这个问题,V3.08.00版本无论是移植到M4上还是H7上都会有这个问题。
后面我抽空抓一下到底是哪个浮点寄存器被修改了。
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2021-6-8 09:30:52 | 显示全部楼层
gk112358 发表于 2021-6-7 11:17
关注中,我用3.08出现了跑一段时间进入hardfault的问题,倒查导致hardfault问题的代码,查不到。改用3.06的 ...

我也是,用3.04的跑很多年都没问题,换成3.08的就出现这个现象,无论在M4还是M7上都会出现,怪异了。
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2021-6-20 22:00:52 | 显示全部楼层
周末用2天的时间专门研究了一下这个问题,已经解决,做个总结:
运行环境:STM32H743+UCOSIII(V3.08.00)
故障现象:
程序运行一段时间后,总是不定期的进入HardFault_Handler,长则2三天,短则几分钟就会浮现,尤其在串口/SPI口有大量数据收发的时候,更容易浮现。
排查过程:
统计发现,每次总是在执行OSTaskSwHook函数中的OS_CPU_FP_Reg_Pop时进入的错误中断。
         第一步还是先查自身的问题,把系统额外的任务全部关闭,浮点运算也全部屏蔽,仅保留通信任务,测试大数据收发,发现故障依旧。之后又在整个数据收发过程中添加多个测试点,发现每次异常前的位置有所区别,但无一例外的都是调用了系统的服务时发生的异常(程序收发涉及到了2个任务用事件同步),至此基本排除程序收发逻辑问题,转向排查系统问题。
         因为以前在跑老版本系统时就修改过浮点入栈出栈这块儿代码,所以刚开始还是简单认为是源码问题,可惜老版本没找到M7DEMO,从M4上迁移过来难度较大,懒得去折腾老版本了。后来试着关掉FPU后,故障更诡异,进入错误中断后压根找不到源头了,最后只能暂时放弃了这个排查方向。
         后来无意间发现,进入中断后,OSTCBHighRdyPtr指向的地址竟然为0。于是在OS_CPU_FP_Reg_Pop函数前加了一个if语句,判断OSTCBHighRdyPtr的指向是否为真,果然,异常情况时OSTCBHighRdyPtr的指针指向了0,这个指针总是指向最高优先级就绪任务控制块儿,不可能指向0
         首先想到的是数组越界修改了OSTCBHighRdyPtr的值,但仿真发现,指针指向0时,它在内存中的地址前的数据并没有发生异常,因此排除是数组越界造成的。
         仔细分析OSTaskSwHook这个函数,最开始是把当前控制块的浮点寄存器压栈,最后把最高优先级的控制块浮点寄存器出栈。中间是一堆可有可无的系统监控操作,并没有对OSTCBHighRdyPtr的赋值操作。于是接下来就是逐步往前排查,什么时候OSTCBHighRdyPtr的值被修改为了0,先在一进OSTaskSwHook函数的地方添加一个判断指向的语句,没想到还真有一进函数就会出现OSTCBHighRdyPtr指向为空的情况,但更诡异的情况是,大多数时候一进函数判断为空之后,等到执行OS_CPU_FP_Reg_Pop时,指针又不为空了,问题是这个函数里面并没有对OSTCBHighRdyPtr的赋值操作啊。
         UCOS系统是有自我修复的功能,但不至于凭空就把指针校准回来了,难不成中间发生过异常中断?也不对啊,任务调度时的第一条汇编指令就是关中断啊“CPSID   I ”。这里特别注意到在这句汇编语句后面的注释“Cortex-M7 errata notice. See Note #5”,硬汉哥之前提到过,Cortex-M7r0p1版本这块儿有BUG,用仿真器看了一下,我板子上芯片的版本是r1p1,于是排除是硬件版本的问题。
         但是如果期间没有发生过中断,说不通指针的值为何被修改啊。顺着汇编代码往下看,发现个新变量“OS_KA_BASEPRI_Boundary”,这个在之前的系统版本中可没见过,于是顺藤摸瓜,找到了“CPU_CFG_KA_IPL_BOUNDARY”这个宏,英文解释如下“ARMv7-M:Since the port is using BASEPRI to separate kernel vs non-kernel aware ISR,please make sure your external interrupt priorities are set accordingly. Forexample, if CPU_CFG_KA_IPL_BOUNDARY is set to 4 then external interruptpriorities 4-15 will be kernel aware while priorities 0-3 will be use asnon-kernel aware.”,通俗解释,系统调度时关中断不再是以一刀切的方式全关闭了,而是根据设置阈值选择性关闭,即优先级在这个阈值以下的中断是不关闭的,此功能应该是为了照顾一些需要在系统关中断时也要响应的中断。默认值是4,再看我的程序,还真有几个较频繁的中断优先级是4以下的,且中断里面调用了系统发消息的函数。
         难道是这个原因造成的?于是乎,把这个值改成1,把程序的中断优先级都改成1以上,我程序中目前没有啥中断是晚个几微妙就不行的,所以这个功能没必要用。修改后再次运行,顿感顺畅无比,对比很明显,之前一个通信端口大量收发数据时,调度1万次左右一般就会出现一次指针指向0的情况,修改后几个通信端口开足马力收发数据跑了一天,截止目前已经调度了一千五百万次左右,还没发生过一次异常,至此,遗留个把月的BUG彻底解决。
         折腾了一大圈,最根本原因还是对新版本的操作系统不熟悉导致,看来以后抽空还得多撸撸UCOSIII的源码。

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107028
QQ
发表于 2021-6-21 00:15:13 | 显示全部楼层
云琴箫龙 发表于 2021-6-20 22:00
周末用2天的时间专门研究了一下这个问题,已经解决,做个总结:运行环境:STM32H743+UCOSIII(V3.08.00)故障 ...

现在M内核的各种RTOS都开始使用BasePri做全局开关中断了。
回复

使用道具 举报

22

主题

93

回帖

159

积分

初级会员

积分
159
发表于 2021-7-19 09:56:21 | 显示全部楼层
感谢楼主分享,我目前也用的3.08.00,也出现了不定时进入HardFault,正在排除中,不过我好像不是这个问题引起的,我现在中断优先级都设置的比4大。我想问问LazyStacking是什么功能?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107028
QQ
发表于 2021-7-20 08:50:51 | 显示全部楼层
shibinjie 发表于 2021-7-19 09:56
感谢楼主分享,我目前也用的3.08.00,也出现了不定时进入HardFault,正在排除中,不过我好像不是这个问题引 ...

部分浮点寄存器自动入栈。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-14 15:45 , Processed in 0.255353 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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