操作BASEPRI特殊功能寄存器时无效解决方法(下)

这里优先级分组选择的是将优先级的4位控制位全部用作抢占优先级的配置,响应优先级都一样,即不做特别配置。那么上图中systick/tim2/tim3/tim4的中断的抢占优先级数据0、2、3、4其实是站在中断优先级寄存器的高4位而言的,那么放到整个8位优先级寄存器来看的话,他们的优先级应该是0x00,0x20,0x30,0x40【其实,低4位值是多少无关紧要,反正无效位】。
前面提过了,现在basepri寄存器也只用到高4位,低4位保留。显然,如果在给basepri寄存器赋值时按照基于高4位得到数字往里面写的话肯定都是无效的。
比方,我们期望在主程序里将上面tim2/tim3/tim4的几个中断都屏蔽掉,若代码像下面截图里这样写肯定达不到目的。我这里开启了tim2/tim3/tim4的周期性更新中断。【本文代码编译、调试基于arm
mdk ide】
经过测试也的确没有达到目的。我写__set_basepri(2)的本意是想屏蔽掉那几个定时器的中断响应,结果发现根本没作用。basepri寄存器也没正确写入,因为数据2只能写到basepri寄存器的低4位,这几位恰好是无效位。不难理解,当我们改写成__set_basepri(0x20)时就可以达到目的了。
此时,basepri被正确写入,tim2/tim3/tim4的中断不能得到响应,倒是systick中断可以不被影响地得到响应,因为它的优先级是0,basepri的配置屏蔽不了它。也就是说,通过配置basepri寄存器来设置中断响应门槛的话,是阻止不了优先级为0或更高优先级的中断的响应的。如果对basepri写0表示放弃其设置的中断门槛的功能。
如果希望对包括0优先级在内的所有可配置中断进行关闭或屏蔽,能否做得到呢?若可以,如何操作?
stm32芯片里的中断如果按中断源是来自st外设还是arm核处理器可以分为异常和中断,比方下图中灰色部分的就是异常,其它为中断。【截图来自stm32g4系列参考手册】
平常我们统称二者为中断,不做区分。如果说把所有中断按其优先级是否可以配置,又可以将中断分为优先级固定和优先级可配置的中断。其中,优先级固定的中断在上面表格中都明确标示了fixed字样,优先级可配置的都加注了settable字样。结合前面提到的优先级寄存器的特性,可配置的优先级是不会高于0级,即配置的数字不会小于0的。
若我们期望对所有可配置中断进行关闭或屏蔽,可以操作另一个叫primask的寄存器,它只有1位有效控制位。
我们通过对parmask写1,令cpu对所有优先级可配置的中断不做响应;若对其写0表示放弃屏蔽功能。比方,我们还是接着前面的演示代码来看看效果。
这时,前面提到的4个定时器中断都不能得到响应了,虽打了断点但过不去。我们还可以借助调试工具看到这几个中断的响应情况【systick位置离得远,单独截取后插进图中的】。
对于上图的部分信息我这里稍微解释下。
图形上方的字母e、p、a是下方eable/pending/active单词的首字母。enable表示相应中断是否在nvic端得到响应允许;pending表示中断等待cpu的执行;active表示中断服务程序正在被执行。从图中可以看出,systick/tim2/tim3/tim4的中断响应都虽得到允许,但都处于pending期待执行状态。既然没有得到执行,active位自然也是0。
上图中优先级的数字显然是按照高4位结合优先级分组后来看的,那个s表示subpriority的意思。为了看得更清晰点,我不妨将优先级分组采用下面的做法重新配置下,保持原抢占优先级都不动,增加1位响应优先级【即子优先级】配置。目前4位优先级配置位拆分为3位抢占优先级配置位和1位响应优先级配置位。当前测试代码也保持不动。
显然,上图中的抢占优先级编号2、3、4是站在分组后的高3位单独来看的,响应优先级是站在分组后剩下的1位单独来看的。如果我们把两类优先级的配置合在高4位一起看,优先级数字应该分别是十进制数1、5、6、9。【这个地方要弄清楚,否则下面调试结果看不明白。】
基于前面测试代码和现有配置,我们看看运行后的中断响应情况。
刚才虽然调整了优先级的分组配置,但这几个中断的抢占优先级都没改变,所以在primask为1的情况下都不能得到响应。我们可以发现这几个中断的优先级站在高4位的角度来看而得出的优先级数字跟我上面分析的基本一致,除了systick的。
按理此时此处systick的优先级应该是1而不是0。为什么会这样呢?原因就在于我基于cubemx组织的代码,这个过程中如果使用systick做库代码的tick时钟,其中断优先级的配置使用默认配置,没有理睬cubemx这边针对它子优先级的配置。cube库在配置systick优先级时,默认使用全部4位用作抢占优先级的配置,同时将子优先级配置为0。当然,我们可以针对性地调整来适应我们的需求。主要是下面这个weak特性的初始函数,我们可以手动修改这个函数里关于中断优先级的配置。
关于使用primask屏蔽所有可配置中断的做法还有其它等效动作,比如使用cpsid指令和cpsie指令或调用相关cmsis函数。【参见下图】
它们的作用一样,也就是我们平常所说的开、关总中断,准确点说是屏蔽所有优先级可配置中断的响应或者放弃屏蔽功能。对于开、关总中断的说法,从实现屏蔽效果来看勉强可以说能关总中断。但整体上讲,个人觉得这个说法不太合适,还很容易给人带来误解,颇具误导性。其实,不论是操作primask还是basepri寄存器,并没有对被屏蔽中断的原有参数和配置做任何改变。即那些暂时被屏蔽的中断的中断响应允许位、中断请求使能位、中断触发事件等都不会因为暂时的被屏蔽而发生改变。打个形象而不是特别贴切的比方。当你开着豪车愉快地跑在某条道上,听着歌哼着曲。突然前方有交警在对道路做临时管制,你和其它一干人车都被拦停下来。原因是有一行高级别的人物要保障优先通行。你等虽被拦停下来,既没人说你无证驾驶、也没人告知你无权走这条道,证照都在,行路权也有,就是此刻级别不够。一旦放行,你依然可以一如既往地行使。
我倒觉得arm技术手册提到的优先级提升更好理解和接受些。即通过对basepri、primask这些寄存器编程提升当前执行程序的优先级,使得低于当前优先级的中断暂时得不到响应。适当时候放弃优先级升级功能,恢复原状。
可能有人知道,还有个可以关闭或屏蔽优先级高至-1级的hardfault异常的控制寄存器,就是faultmask,也是1位有效位,操作跟primask类似。有兴趣的话,可以自行进一步研究下。

车规级AEC-Q100、AEC-101、AEC-200标准解读
TIA 对于5G网络的安全有多重要
国产通信巨头倒下曾与中兴华为齐名如今为了4.5亿卖掉科研大楼
新基建的提出将促进自动驾驶的落地应用
用电阻设定增益的单端至差分转换器
操作BASEPRI特殊功能寄存器时无效解决方法(下)
最新调查:越贵的手机打车越贵
索尼回音壁HT-MT300:音频控制惟妙惟肖
稳中向好的宁德时代是否会造车?官方回应:不会造车
DisplayPort 在电视中的应用
DARPA为推进制造毫米级到厘米级微型机器人所需的技术制定了一项新计划
配置很高但又涨价了!华为P10据说定价3499元
电流表测量电流的原理及方法
中国还在“互联网+”,美国已悄悄进入“新硬件时代”!发人深省
PIC单片机循环程序实例
文心一言率先全面开放 百度放大招
ITECH无人机测试解决方案,UP你的续航极限!
TUV南德与北方华创联合发布《氢氦工艺气体爆炸性研究及测试》论文
随着汽车工业的发展越来越完善,车载冰箱会成为未来的主流方向吗
一种实时检测变压器绝缘油中微水含量的传感器