cortex_m7有多个内核版本,在r0p1版本中有一个bug。该bug已在r0p1之后的版本修复,此后的版本可不再使用该bug的围堵策略。也参考freerots的官方论坛中的“Use of barriers when setting BASEPRI on Cortex M7”
CPUID寄存器会存储cortex_m7的内核版本,bit23:bit20用于指示处理器版本,bit3-bit0用于指示修订版本,针对r0p1,则bit23-bit20为0,bit3-bit0的值为1。
ARM官方存在相关的手册,例如“cortex_m7_software_developers_errata_notice_r0_v4”,里面记录了bug内容。围堵此bug的方法,为在关闭中断的情况下,来对basepri抬升(basepri的寄存器值减小,即优先级提高)。
可能出现的异常现象:中断服务中获取到basepri后,发现中断的优先级值大于或等于basepri寄存器的值,不应该产生中断,却产生了中断。
根据官方对bug的描述,推测内核实现的机理应是“在执行basepri修改的期间若发生了中断,应禁止响应中断”
针对此bug原文描述如下:
837070: Increasing priority using a write to BASEPRI does not take effect immediately
Category B
Products Affected: Cortex-M7, Cortex-M7 with FPU.
Present in: r0p1
Description
An MSR to BASEPRI or BASEPRI_MAX can be used to boost current execution priority.
This update is required to be serialised to the instruction stream meaning that after this update completes, it takes effect immediately and no exceptions of lower priority than the new boosted priority can pre-empt execution.
Because of this erratum, the priority boosting does not take place immediately, allowing the instruction after the MSR to be interrupted by an exception of lower priority than the new boosted priority.
This effect is only limited to the next instruction. Subsequent instructions are guaranteed to see the new boosted priority.
Configurations affected
This erratum affects all configurations of the processor.
Conditions
The following scenario is required to hit this erratum:
1) An MSR to BASEPRI or BASEPRI_MAX is executed to increase current execution priority.
2) An asynchronous exception (interrupt, asynchronous bus fault, SysTick, PendSV) becomes pending around the time that the MSR is being executed. The priority of this exception is higher than the execution priority before the MSR and lower than the priority after it.
Under these conditions, the asynchronous exception might be taken after the MSR completes. In this situation, the return address stacked will point to the instruction after the MSR.
The window for this erratum ends when the instruction after the MSR completes. After this, this erratum cannot occur.
Implications
This erratum means that the instruction after an MSR to boost BASEPRI might incorrectly be pre-empted by an insufficiently high priority exception.
Note that this erratum only affects MSR to BASEPRI or BASEPRI_MAX.
MSR or CPS to PRIMASK or FAULTMASK work correctly.
Workaround
To work around this problem, the MSR to boost BASEPRI can be replaced by the following code sequence:
CPSID i
MSR to BASEPRI
CPSIE i
<critical region code>