你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

运行一段时间后“死机”,再深入观察,看到定时器4中断服务程序不再执行,看了《Cortex-M3权威指南(中文)》仍无法定位原因?

[复制链接]
13530875826 提问时间:2024-8-11 00:08 / 未解决

1、sw.rar

2、芯片STM32F103C8T6。

3、程序意图:(1)用TIM4产生1ms定时,在其TIM4_IRQHandler()中计数并设置70ms、500ms等定时器标记。(2)在main()的死循环子函数中,每70ms,读取编码器数值并显示在LCD上;每500ms,读取ADC数值并显示在LCD上,同时为了方便观察,闪烁LED灯。

4、故障现象:刚开始运行,正常,LED灯闪正常;一阵子后,LED灯不闪,“死机”了。

5、用debug方式运行,复现“死机”后,按Stop,cpu模式为Handler,异常中断号为46(TIM4),程序在0000 125A到0000 12A6之间循环, 访问内存地址2000 0032到2000 0035。 查map文件,并正常运行时,单步跟踪,2000 0032到2000 0035 对应 g_10msOK到g_500msOK; 正常运行时,单步跟踪,0800 125A到0800 12A6,是while(1){}中判断g_10msOK到g_500msOK的地方。 猜测,Thread模式时,地址是0800 125A,切换到Handler模式后,地址是0000 125A。

说明,“死机”后,while(1){}中判断是否70ms、500ms的代码还一直在跑,只是70ms、500ms的标记一直为0,所以没有执行点灯。 死机后,在TIM4_IRQHandler()加断点,并不触发。为什么?

收藏 评论18 发布时间:2024-8-11 00:08

举报

18个回答
13530875826 回答时间:2024-8-13 23:12:36

xmshao 发表于 2024-8-13 14:38
不用着急。</p>
<p>看看你到底开启了哪些中断,看看是否有在中断里需被使用的变量,因为中断优先级方面的原 ...

[md]SV,PendSV,SysTick系统自动设置其使能且优先级为0s0。 我自己的代码,优先级组2,USART1为3s3,TIM4为0s3,EXTI9_5_IRQn为1s1,EXTI15_10_IRQn为1s1。 TIM4中断程序中,更新70ms变量标记;EXTI中断程序中,更新编码器数值;main中,读取70ms变量标记值和编码器数值。都只是变量读写,没有看出死锁。 死马当活马医,尝试把上面几个中断的优先级统一设为0s0,居然不死机了! 再试,优先级统一设为1s0,还是死机。 再试,我虽然USART1、EXTI设置有使能中断,但没插串口、没插编码器,不会有中断吧?打断点,确实没有USART1、EXTI的中断,只有TIM4中断在跑。 中断的优先级统一设为0s0不死机,设为1s0会死机,这是为什么呢?

13530875826 回答时间:2024-8-12 21:06:45

butterflyspring 发表于 2024-8-12 10:07
既然Tim4 中断不执行,那么试试在 debug 下看看该中断的配置是否有变化,进而找出故障的线索和发生的原因。 ...

1723467626719.png

1723467645724.png

另外,TIM4这边只是看中断出门了没。我还查看NVIC这边,看中断进门了没。如上,中断使能ISER0、中断活动IABR0都是对的,说明NVIC对TIM4中断,是允许进门的,并且正在响应处理(活动)中。

13530875826 回答时间:2024-8-12 20:54:22

butterflyspring 发表于 2024-8-12 10:07
既然Tim4 中断不执行,那么试试在 debug 下看看该中断的配置是否有变化,进而找出故障的线索和发生的原因。 ...

1723466601131.png 查看过,TIM4相关的寄存器,PSC, ARR控制频率的,没变化,CNT也在循环计数中。CR1使能计数器的,都正常中。DIER.UIE=1,允许更新中断的,而且状态SR.UIF=1,说明有计数到溢出产生更新,硬件把这个标志位置1了。以上说明,TIM4是正常计数,并产生了中断标记的。

13530875826 回答时间:2024-8-11 00:13:24

sw.rar是我的代码工程压缩包,有7M多,怎么上传不了吗?

butterflyspring 回答时间:2024-8-12 10:07:28
既然Tim4 中断不执行,那么试试在 debug 下看看该中断的配置是否有变化,进而找出故障的线索和发生的原因。
xmshao 回答时间:2024-8-12 10:55:34
首先,确保系统时钟和供电没有问题。这两种原因导致的死机基本没啥可追踪的,怎么死的往往并无正常逻辑。


你可以借助断点看看是否落在那个Hardfault中断里了。


重点检查哪些地方涉及数组访问的,看看有无可能发生越界的情形,当然这也是常发生问题的地方。


再就是有无可能堆栈溢出了,尤其中断嵌套较多时。
13530875826 回答时间:2024-8-12 21:35:54

butterflyspring 发表于 2024-8-12 10:07
既然Tim4 中断不执行,那么试试在 debug 下看看该中断的配置是否有变化,进而找出故障的线索和发生的原因。 ...

再者,我也查看了中断向量表,TIM4是46号异常,对应向量表地址0000 00B8存放的入口地址是0800 3EAD,也就是TIM4_IRQHandler()的地址。说明向量表没有破坏。

13530875826 回答时间:2024-8-12 21:50:49

butterflyspring 发表于 2024-8-12 10:07
既然Tim4 中断不执行,那么试试在 debug 下看看该中断的配置是否有变化,进而找出故障的线索和发生的原因。 ...

根据《权威指南》说的,中断的活动状态寄存器IABR是硬件自动维护的,执行了ISR的第一条指令,活动状态置1,到ISR返回时,活动状态清0。我这里观察到活动状态为1,说明ISR没返回?但是单步跟踪,执行的是main()里面的while(1){}循环。这就怪了?

13530875826 回答时间:2024-8-12 22:00:49

butterflyspring 发表于 2024-8-12 10:07
既然Tim4 中断不执行,那么试试在 debug 下看看该中断的配置是否有变化,进而找出故障的线索和发生的原因。 ...

但是这里也有一个线索:死机后,stop,单步执行,执行代码地址是0000 125A;正常时,单步执行,执行代码地址是0800 125A。实际对应就是main()里面while(1){}判断70ms、500ms标志的代码。这部分代码应该是thread模式执行的,怎么到了handler模式?

13530875826 回答时间:2024-8-12 22:18:26

xmshao 发表于 2024-8-12 10:55
首先,确保系统时钟和供电没有问题。这两种原因导致的死机基本没啥可追踪的,怎么死的往往并无正常逻辑。</p>
<p>...

1、供电和时钟目前看不是主因。因为我对软件做些改动的话,就不会出现死机。 2、在HardFault、MemManageFault、BusFault、UsageFault都加了断点,出现死机时,没有进入这些Fault,而且这些Fault的相关寄存器,也看起来是正常的。 3、我只用了TIM4和USART1这2个中断,而且TIM4优先级高。不应有嵌套的情况。

13530875826 回答时间:2024-8-12 22:26:40
简化代码:
void TIM4_IRQHandler(void)
{
i70msCnt++;
if (i70msCnt == 70)
{
i70msCnt = 0;
g_70msOK = 1;
}

i500msCnt++;
if (i500msCnt == 500)
{
i500msCnt = 0;
g_500msOK = 1;
}
}

main()
{
while(1)
{
if (g_70msOK == 1)
{
g_70msOK = 0;
Timer_70ms_Proc();
}
if (g_500msOK == 1)
{
g_500msOK = 0;
Timer_500ms_Proc();
}
}
}
13530875826 回答时间:2024-8-12 22:30:28

卧槽,这论坛,贴代码格式都很难,发压缩包又上不去。是程序猿论坛吗?

13530875826 回答时间:2024-8-12 22:58:12

13530875826 发表于 2024-8-12 22:26
简化代码:
void TIM4_IRQHandler(void)
{

问题目前的小结: 1、死机时,TIM4相关寄存器正常,并置位了中断标记。NVIC允许TIM4中断进门,且表示TIM4正在处理中(活动状态置1)。 2、但是stop后单步跟踪,实际代码执行的是main() while(1){}的。这部分代码正常执行时是thread模式的,但现在是handler模式。 3、查看向量表,TIM4异常向量位置所放的地址就是TIM4_IRQHandler()地址,向量表没有被破坏。 4、所以,本应是执行TIM4_IRQHandler()的,怎么实际执行main() while(1){}?

13530875826 回答时间:2024-8-12 23:12:03

13530875826 发表于 2024-8-12 22:58
问题目前的小结:
1、死机时,TIM4相关寄存器正常,并置位了中断标记。NVIC允许TIM4中断进门,且表示 ...

[md]核心就是:死机后,stop并单步执行,看到是handler模式,且表示正在处理TIM4中断,中断向量表也没有被破坏,按理应执行TIM4_IRQHandler(),但执行代码实际对应的是main() while(1){},这是怎么回事啊?

xmshao 回答时间:2024-8-13 14:38:18

13530875826 发表于 2024-8-12 23:12
核心就是:死机后,stop并单步执行,看到是handler模式,且表示正在处理TIM4中断,中断向量表也没有 ...

[md]不用着急。

看看你到底开启了哪些中断,看看是否有在中断里需被使用的变量,因为中断优先级方面的原因导致变量信息的获取出现死锁。

比方,在中断A里调用B延时服务函数,B服务函数又需用到另一定时中断,可该定时中断优先级又低于A的,这时就会出现死锁。

还有,对于那些在中断和主程序里都使用的变量,记得加上volatile。

12下一页
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版