完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
问题描述
在移植公司的实时操作系统到一款国产 RISC-V 架构芯片时,为了测试 systick 中断是否有效,在此中断 isr 中对一个静态变量加一,打断点观察变量的变化来确定中断是否正确执行了! 中断 isr 的主要内容如下: isr_handler(void) { ... static int i = 0; i++; clear_interrupt_flag(); ... } 在调试的过程中发现,进入到这个函数后确实给变量加 1 了,但是下一次再进入时变量值又会变为 0,调试了下汇编没发现问题。多执行几次发现效果相同,问题能够不断【复现】。 调试方法 变量的值被意外修改这样的问题之前也已经遇到过,直接的方法就是 watch 这个变量的地址,在修改的时候程序会停下来,这样就能看到哪里进行了非法操作。 可是在此款芯片上上面的方法却不太适用。虽然可以 watch 一个变量的地址,但是 watch 之后程序执行非常非常慢,可能要等非常久才能定位到问题,而我有不能减少中间执行的过程,这是一个常识性的问题,因此这中方式只能弃之不用。 有没有更好的方式呢? 我仔细的想了想,立刻就想到了一种非常简单的方式。我可以把这个变量设置为常量,常量一般都存储在代码段,而在我使用的这个芯片上,代码段是放在 flash 上面的,要通过普通的访存指令修改 flash 上面的数据会进入异常,这样我只需要查看异常发生的位置就能够成功定位到出问题的地方。 这样的方式果然好用,我立刻就发现了问题,可是让我不解的是它指向了一个不在代码区域内的位置,这可出乎我的意料了。 进一步的分析 当我发现问题发生的地方是一段程序区域外的位置,我觉得可能在中断处理流程中栈帧被修改了,这样恢复的时候才恢复到了一个错误的地址,这样的怀疑比较合理。我再回去看了看中断处理的汇编代码,发现我在中断中切换到了系统栈,将需要保存的现场存储到了系统栈中,而我的用户程序也使用了系统栈,这样旧的栈帧就被中断处理过程破坏了,恢复之后就表现出了一个异常的行为。 其实我切换栈指针这样的设计是正确的,只是我不应该在非任务环境下测试它。当第一个任务调度运行之后,中断打断的任务与系统栈有不同的栈指针,在这种条件下切换栈指针是正确的。我按照这样的思路创建了任务,启动实时操作系统,再次测试便没有问题了! 总结 在实际的测试中,对一些必要条件的忽略可能会造成严重的问题,我们不仅要关注程序执行的流程,更要关注程序执行的环境及程序执行对这一环境带来的改变。 |
|
|
|
只有小组成员才能发言,加入小组>>
857 浏览 0 评论
1185 浏览 1 评论
2561 浏览 5 评论
2894 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2757 浏览 6 评论
keil5中manage run-time environment怎么是灰色,不可以操作吗?
1183浏览 3评论
213浏览 2评论
481浏览 2评论
397浏览 2评论
M0518 PWM的电压输出只有2V左右,没有3.3V是怎么回事?
480浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-16 04:35 , Processed in 1.124807 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号