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

关于程序总跳回启动文件的话题

[复制链接]
zero99 发布时间:2017-6-27 10:36
某STM32应用客户反映:
他用STM32f407芯片开发产品,使用ADC并开启了DMA中断。中断服务函数经过反复检查并没有发现配置错误,优先级也配置得当,可为什么每次仿真时程序都跳回启动文件呢?

9 [2 |+ A) d- Q- C# ]
后面,经过进一步沟通与反馈,发现只要开启DMA中断就跳回启动文件,并死在下面位置。
  y+ {8 F% u7 Q% A

2 w2 A2 f/ L  `0 [* ~& Q. O
一般来讲,在做STM32开发调试时,如果发现程序频繁跳进启动文件的话,可能有以下几种情况及相关特征:

/ [. H% i' U1 J' o4 D
1、运行程序时发生异常访问,导致硬件错误、总线错误等
比如堆栈溢出啊、数组越界、执行非法指令、非法访问等。这时,程序指针可能会跳进启动文件里事先准备好了的相应异常服务程序,并进入死循环。比如下面这些:
/ ]* F3 M; E2 r# Y( m) f
2、芯片因为时钟问题、电源问题、WDG等原因,导致芯片频繁复位
比如时钟异常、电源波动厉害、电源驱动不足、WDG未重置等,导致芯片频繁运行复位程序。此时相对比较容易发现程序频繁回到启动文件里执行复位代码以及调用SystemInit()函数。当然,类似问题在芯片复位脚上也能观察到电平频繁跳变。
3、用户没有编写中断服务程序或其函数名与启动文件里的不一致
此时往往表现在开启了某些中断功能,但用户没有编写自己的中断服务程序,或者用户编写的中断服务函数名跟启动文件里事先定义的不一致。这样的话,当产生相关中断时,就会进入启动文件里事先使用汇编指令编写的中断服务函数,该函数除了一条原地死循环的代码外,再无其它。

( ]1 V* T/ c4 R1 u6 n2 B  l
在启动文件里,除了前面提到的几种特殊异常服务函数外,其它中断服务函数都共用同一执行代码,B .,即原地死循环,类似51系列MCU里的JMP $指令。

7 u8 j1 n0 m' ^5 p( W$ t0 S
具体结合到本案例,经过多次排查、验证,发现问题就出在中断服务程序的函数名的书写上。他写的中断服务函数名跟启动文件里事先定义的就差一个字母。比如把DMA1_Stream0_IRQHandler()写错成DMA_Stream0_IRQHandler()。

9 {) Z3 c* H2 Q, G& B
该问题很隐蔽,尤其这种以为编写了中断服务函数,但中断函数名写得跟启动文件里的不一致时,编译器并不会给出任何提示,这就不容易发现问题。之前,也碰到过有人因中断函数名写得跟启动文件里定义的不一致导致中断不响应或者抱怨进不了相关中断的问题。

. X% |! @4 z& |% ]  Z
从客户提供的截图也可以看出,程序进入了启动文件里默认的中断服务程序,即那条死循环汇编指令 B . 。

/ Q2 Z+ ~. ^& A( i7 D; p
这里以基于CORTEX-M4内核的STM32F4芯片为例,顺便提下基于CORTEX-Mx内核的中断矢量表的话题。
在每片基于CORTEX-Mx内核的芯片里,都有一张硬件中断矢量表。在这张表里按固定的顺序、以字【4个字节】为单位依次存放着各类异常响应的入口地址,其中第一个字是个例外,它存放的是栈顶地址。& W5 W  E5 `7 v/ _! L) V# u
, i- u4 \, H' r( Z. Z# Y
下面是STM32F405/407和STM32F415/417系列芯片内部中断矢量表的一部分。其中Address是相对于该表起始地址的偏移量。该矢量表自身的地址由寄存器VTOR决定【注:M0系列没有这个寄存器】。不同的STM32系列,甚至同一系列的不同产品线【比如STM32F1系列的低容量产品线、高容量产品线、互联型产品线】,其中断矢量表的内容往往会有些差异。
8 t/ D& }6 [4 p# x
当内核响应了某异常或中断后,对应的异常或中断服务程序就会得到执行。为了得到相应服务程序的入口地址,内核就使用上述的中断矢量表并建立查表机制。

6 D% ^3 d0 r* y. J7 y
通常来讲,STM32的工程项目里的启动文件已经事先帮我们预备好了所有异常及中断的服务函数,并将各个服务函数名所对应的地址按固定顺序填入到中断矢量表中。不过,这里的各个服务函数体非常简单,上面提过,就是一句原地死循环代码。# {- I: u! L; A! G

6 Z" Y9 _( x# P) X& O
9 Z! ?: v  ?" k& f1 v
这样做的目的就是先给各异常及中断服务函数挂个号,留个地址,把中断矢量表搭建起来。真正的用户中断服务程序还得靠用户在外部具体实现,并使用与启动文件里相对应的相同函数名。毕竟,启动文件不可能知道用户在各种服务函数里需要做什么。0 j6 C! |" r# J
结合上面的介绍,我们知道不同的STM32产品线,其中断矢量表的内容及位置顺序都可能不同;相应地启动文件中准备的矢量表内容和顺序也就可能不一样。
由于STM32系列众多,产品线丰富,所以在做移植时要注意启动文件跟所选芯片型号是一致的。经常有人在做不同产品间的移植时,因忽略启动文件的差异,工程启动文件选择不合适导致中断响应方面出问题。
也许有人会问,启动文件里已经定义了全套各个异常及中断服务函数,用户自己再定义同名的函数不会有重复定义的问题吗?不会的。君不见,启动文件里定义的各个异常服务函数名后面都跟了[weak]弱定义符号吗?意味着在进行代码编译时它可以被其它非弱定义的同名函数覆盖取代。
8 [' }3 E; h. E" P2 \) c: F& p
转自:ST MCU 信息交流0 M1 \3 S& t: e5 \: X
赞 收藏 评论3 发布时间:2017-6-27 10:36

举报

3个回答
MrJiu 回答时间:2017-6-27 11:50:50
这个,我的第一感觉,就像是启动文件和中断服务函数不匹配,换句话说就是,其实是没有中断实现函数!!!不过,我记得以前好像是直接进入那个硬件中断函数里面!!!然后进行死循环。。。
子曰好人 回答时间:2017-6-29 13:10:49
恩,不错的分析,值得初学者学习借鉴
arenas 回答时间:2017-6-29 13:49:25
经常遇到的是跳入到中断出不来。
$ |3 @4 A$ B' j5 A0 [1 h3 q9 g
, q8 Y& Q+ n3 o& |6 Y7 c改中断函数名称的机会很少,所以一般遇不到
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版