• 342查看
  • 0回复

[芯片硬件] 因STM32移植而引发的两个小疑问

[复制链接]


该用户从未签到

发表于 5-5-2024 20:02:05 | 显示全部楼层 |阅读模式

汽车零部件采购、销售通信录       填写你的培训需求,我们帮你找      招募汽车专业培训老师


因STM32移植而引发的两个小疑问w1.jpg

有STM32用户将基于STM32F0芯片的代码移植到STM32F4系列时遇到了些麻烦。其中有个问题跟中断处理有关。有个中断服务程序代码在STM32F0芯片里运行正常,移植到STM32F4芯片并使用同样的程序代码却明显异常,感觉每次中断都进了两次。

经过他一番网上搜索,大致找到了问题原因和解决办法。原因就是他在中断服务程序里做中断请求标志清零的代码放在服务程序的结尾处了,将其挪至服务程序的入口处就可以了。

问题是解决了,但依然还是有两个小疑问如鲠在喉。

第一个疑问,为什么同样的操作在F0系列正常,而在F4系列却异常呢?仅仅是因为F4系列跑得快?

其实,这里的主要原因是内核差异导致的。STM32F0系列芯片是基于ARM Cortex-M0内核的微处理器,STM32F4系列芯片是基于ARM Cortex-M4内核的微处理器,二者在内核上存在一些差异,其中一个差异就是,M4内核相比M0内核多了针对写操作的写缓冲以及相应执行机构,这里不妨称之为“缓冲写”单元。

因STM32移植而引发的两个小疑问w2.jpg

对于F0系列,由于没有“缓冲写单元”,CPU在做中断请求标志清零时需全程执行直到清零完成才能做中断返回。对于F4系列,由于有“缓冲写单元”协助,在做中断请求标志清零时CPU只需执行相应程序,交代清楚写些什么到哪里即可,具体的写操作就交给“缓冲写”单元完成,然后继续执行后续程序,后面跟F0系列就有点不一样了。由于清零操作代码执行时刻与准备出栈时刻太接近,“缓冲写”单元尚未完成对标志的清零,CPU因而再次进了一次中断服务程序。显然程序再运行一次后,一般来讲那个标志的清零都会完成了。因此,类似情况我们往往最多也就看到进了两次中断。

第二个疑问呢?

用户发现在使用STM32F4芯片时,即使清中断标志代码放在服务程序的结尾,一般只需在其后面追加3到4个NOP操作后就保证不会发生1次事件进入2次中断服务程序的情况。也就是说,在清中断标志代码后面稍加延时3~5个时钟就能保证清零完成。

对于Cortex-M内核的芯片,中断出栈不会少于12系统时钟。这样说来,即使不加那几个NOP操作延时,这12个时钟也足以让清零完成。这意味着出栈后中断请求标志早已完成清零,那么第2次再进中断是依据什么而响应的呢?

这里就涉及到ARM Cortex-M内核的中断响应咬尾机制。简单点说,当CPU刚执行完某中断服务程序准备出栈返回时,若内核硬件发现外边正有嗷嗷待哺的其它中断请求候着时,就果断决定不做出栈了,立马响应新的中断请求并执行相应服务程序。

具体到这里,当STM32F4的中断服务程序里最后一行清中断标志代码执行完后(具体写操作交给“缓冲写单元”了),CPU准备做出栈返回时,由于写缓冲单元尚未完成清零,硬件发现有个中断请求存在,于是乎果断决定放弃出栈,稍作准备后也不做压栈就执行当前中断请求所对应的服务程序,这里就是把刚才的中断服务程序再跑一次。

看到这里,我们应该明白了,中断再进一次的关键是CPU准备出栈时发现还有中断请求存在,至于出栈时间多长多短已经不重要,因为这时压根就不做出栈操作了。这也就可以解除上面提到的疑惑了。

下图就是示意中断前后两次执行的情况。【假定中断第一次是打断主程序或强占其它进来的】

因STM32移植而引发的两个小疑问w3.jpg

第一次进中断时,发生了压栈。第二次进中断是紧跟着第一次中断服务程序之后,未做出栈稍加准备后就开始执行服务程序,之后才做出栈操作。

看到这里,或许有人会问上面提到的稍加准备难道不要时间吗?也是要的,如果Flash访问取指延时为0等待的话,最短6个时钟。

因STM32移植而引发的两个小疑问w4.jpg

或许有人继续问,这个6个时钟跟平常压栈的10来个时钟是什么关系呢?

当有压栈时,这个6个时钟就包含于压栈时间里了,它大致用来做中断向量的提取、Exc_return值的拟定等,这些操作跟压栈操作是并行重叠的,有压栈时就不提这几个时钟的时间了,只说压栈时间。

对于前面提到的第2次基于咬尾机制进中断的情形,如果希望得到较为直观地体验、感受,可以借助断点,观察栈帧的变化来满足。我们可以明显地观察到中断服务程序运行了两次,压栈只发生一次。

好,今天的话题就分享到这里,供君参考。下次再聊。




该用户从未签到

发表于 11-3-2025 20:12:01 | 显示全部楼层
回复帖子:

关于您提到的STM32F0与STM32F4芯片在中断处理上的差异,主要有以下几点需要考虑:

首先,不同系列的STM32芯片可能存在硬件架构和中断处理机制上的差异。虽然它们都是ARM Cortex-M系列内核,但具体的实现细节可能会有所不同。因此,在某些情况下,相同的代码在F0系列运行正常,在F4系列可能表现出异常行为。这可能是因为在某些特定场景下,不同的芯片内部逻辑在处理中断请求时的响应和时序有所不同。因此,建议您详细查阅相应芯片的技术手册和相关文档,以了解其硬件架构和中断管理机制。其次,关于为什么将中断请求标志清零的代码放在服务程序的不同位置会产生影响的问题,这可能与中断处理的优先级和嵌套机制有关。当发生嵌套中断时,标志清零的位置可能会影响中断处理的顺序和流程。因此,在实际应用中需要根据具体的硬件特性和需求来合理设计中断服务程序的结构。至于如何正确进行代码移植,需要充分了解不同芯片的差异并进行针对性的优化调整。在进行代码移植时,除了注意硬件差异外,还应关注编译器版本、外设驱动差异等因素。通过详细分析和调试代码,确保代码在不同芯片上的兼容性和稳定性。建议您查阅相关技术文档并进行充分的测试验证。如有疑问或需要进一步帮助,请随时交流。

[内容由汽车工程师之家人工智能总结,欢迎免费使用,见贴尾]
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 11-3-2025 20:12:02 | 显示全部楼层
针对您提出的问题,关于STM32F0与STM32F4系列在中断处理上的差异,可以这样解释:

首先,STM32F0和STM32F4虽然都属于STM32系列,但它们在内部架构、性能以及中断处理机制上存在一些差异。关于您的疑问,可能是由于STM32F4系列在处理中断时,对中断的响应和优先级分配有所不同。将中断请求标志清零的代码放在服务程序结尾可能导致在特定条件下,第二次进入该中断服务程序的可能性增加。这可能是由于某些内部状态或标志在中断处理过程中发生了变化。

其次,将中断请求标志清零的代码移至服务程序入口处是一个有效的解决方法,因为它确保了每次进入中断服务程序时都能及时清除中断标志,避免了重复进入的情况。这种做法在STM32F4系列中更加有效,符合其处理中断的逻辑和架构。而STM32F0系列可能因为设计或实现上的差异并未出现这个问题。这解释了为什么同样的操作在两个系列中表现不同。为了更准确地了解差异和背后的原因,建议查阅两个系列的中断处理相关文档或参考手册。

[内容由汽车工程师之家人工智能总结,欢迎免费使用,见贴尾]
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 11-3-2025 20:12:02 | 显示全部楼层
回复帖子:

关于您提到的疑问,我明白您的困惑。在将基于STM32F0的代码移植到STM32F4系列时出现的中断处理问题,很可能是由于不同芯片系列在中断管理和处理方面的细微差异导致的。虽然STM32F0和STM32F4都属于STM32系列,但它们在一些特定性能、寄存器配置和中断优先级管理等方面可能存在差异。这可能是您在F0系列中正常工作的中断服务程序在F4系列出现异常的原因。

关于将中断请求标志清零的代码位置问题,通常建议将此类操作放在中断服务程序的入口处。这是因为中断服务程序应当尽快处理完中断相关操作并退出,以避免影响其他中断的响应。将标志清零放在入口处可以确保即使发生异常或再次触发中断,也不会对之前的标志状态造成影响。

针对您的第一个疑问,具体差异可能涉及到中断向量表、中断优先级配置或者中断嵌套等方面的差异。要深入了解这些差异并解决类似问题,建议查阅STM32F4系列的相关技术文档和参考手册,并与STM32F0系列进行对比分析。此外,不同芯片系列的差异也可能与编译器版本、库函数版本等因素有关,这些因素都可能影响到代码移植的兼容性。在进行代码移植时,建议仔细测试和验证以确保代码在不同芯片系列上的稳定性和可靠性。

[内容由汽车工程师之家人工智能总结,欢迎免费使用,见贴尾]
回复 支持 反对

使用道具 举报

快速发帖

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

本版积分规则

QQ|手机版|小黑屋|Archiver|汽车工程师之家 ( 渝ICP备18012993号-1 )

GMT+8, 19-8-2025 04:02 , Processed in 0.606358 second(s), 37 queries .

Powered by Discuz! X3.5

© 2001-2013 Comsenz Inc.