STM8 ASM 安全执行 WFE
STM8 ASM safely execute WFE
我在 低功耗 运行 模式下从 RAM 运行 中获取了 c 代码(因此不处理中断)。此模式由代码序列启用:
- 跳转到RAM
- SIM卡
- 关闭内部闪存和电源调节器,切换到低速时钟源(LSE)
- 使用 WFE 模式(低功耗等待模式)做一些工作
- 开启电源调节器和闪光灯,恢复时钟源
- RIM
- 跳转到闪光灯
因此勘误表 sheet 中描述的 WFE 指令没有问题。此构造的问题,可能是 CPU 永远锁定在 低功耗等待模式 的原因:
while nbit(TIM1_SR1,CC3IF) asm("wfe");
即反汇编为:
000035 720252B602 BTJT TIM1_SR1, #1, 0xB6
00003A 728F WFE
来自计时器的事件具有概率性质,此代码不保证它会在执行 WFE 指令后发生:
- BTJT指令执行2个周期,长度为5;
- 从 RAM 执行的代码可能不连续,因为 "fetch" 声明在几个周期内暂停执行
我使用手册 PM0044,第 26 页的内容很漂亮 table:
代码执行在 3 个周期停滞的情况有 2 例。所以我不确定我的异步唤醒事件不会发生在 BTJT 和 WFE 指令之间。
有没有办法保证严格的逻辑顺序(检查条件 > wfe > 唤醒事件)?
OP 找到的解决方案:
I have read errata (thanks to Ross Ridge) few times more attentively, and this is main idea:
General solution is to ensure no interrupt request or event occurs during WFE instruction execution or re-execution cycle by proper application timing.
如果您的锁定问题是由我提到的 WFE 勘误表引起的,那么应该有比尝试实现 "proper application timing".
更简单的解决方案
errata provided by STMicroelectronics 内容为:
Two types of failures can occur:
Case 1:
In case WFE instruction is placed in the two MSB of the
32-bit word within the memory, an event which occurs during the WFE
execution cycle or re-execution cycle (when returning from ISR
handler) will cause an incorrect code execution.
Case 2:
An interrupt request, which occurs during the WFE
execution cycle will lead to incorrect code execution. This is also
valid for the WFE re-execution cycle, while returning from an ISR
handler
情况 2 不适用于您所说的情况 "Interrupts are not handled because I use low power run mode"。如果在 WFE 指令期间不会发生中断,则只有第一种情况中描述的故障可能会导致您的锁定。
情况 1 仅适用于 WFE 指令在内存中的 32 位字内处于特定对齐方式的情况。因此,如果您可以确保 WFE 指令永远不会出现在以这种方式对齐的代码中,那么您就不会遇到这种故障。如果您的汇编器支持 align 指令,您可以使用它实现此目的,如果汇编器不插入 NOP,则可能连同标签和跳转。然而,勘误表中的 "dedicated workaround" 给出了一个更简单的解决方案:
Replace the WFE instruction with
WFE
JRA next
next:
这似乎通过在 WFE 指令后放置相当于 2 字节 NOP 的内容来解决故障。我的猜测是失败导致 CPU 没有立即执行 WFE 指令之后的指令,而是向前跳过两个字节到下一个 32 位世界开始处的指令(如果有的话)。在跳过的space中放一个2字节的NOP意味着是否发生故障无关紧要。
我在 低功耗 运行 模式下从 RAM 运行 中获取了 c 代码(因此不处理中断)。此模式由代码序列启用:
- 跳转到RAM
- SIM卡
- 关闭内部闪存和电源调节器,切换到低速时钟源(LSE)
- 使用 WFE 模式(低功耗等待模式)做一些工作
- 开启电源调节器和闪光灯,恢复时钟源
- RIM
- 跳转到闪光灯
因此勘误表 sheet 中描述的 WFE 指令没有问题。此构造的问题,可能是 CPU 永远锁定在 低功耗等待模式 的原因:
while nbit(TIM1_SR1,CC3IF) asm("wfe");
即反汇编为:
000035 720252B602 BTJT TIM1_SR1, #1, 0xB6
00003A 728F WFE
来自计时器的事件具有概率性质,此代码不保证它会在执行 WFE 指令后发生:
- BTJT指令执行2个周期,长度为5;
- 从 RAM 执行的代码可能不连续,因为 "fetch" 声明在几个周期内暂停执行
我使用手册 PM0044,第 26 页的内容很漂亮 table:
代码执行在 3 个周期停滞的情况有 2 例。所以我不确定我的异步唤醒事件不会发生在 BTJT 和 WFE 指令之间。
有没有办法保证严格的逻辑顺序(检查条件 > wfe > 唤醒事件)?
OP 找到的解决方案:
I have read errata (thanks to Ross Ridge) few times more attentively, and this is main idea:
General solution is to ensure no interrupt request or event occurs during WFE instruction execution or re-execution cycle by proper application timing.
如果您的锁定问题是由我提到的 WFE 勘误表引起的,那么应该有比尝试实现 "proper application timing".
更简单的解决方案errata provided by STMicroelectronics 内容为:
Two types of failures can occur:
Case 1:
In case WFE instruction is placed in the two MSB of the 32-bit word within the memory, an event which occurs during the WFE execution cycle or re-execution cycle (when returning from ISR handler) will cause an incorrect code execution.Case 2:
An interrupt request, which occurs during the WFE execution cycle will lead to incorrect code execution. This is also valid for the WFE re-execution cycle, while returning from an ISR handler
情况 2 不适用于您所说的情况 "Interrupts are not handled because I use low power run mode"。如果在 WFE 指令期间不会发生中断,则只有第一种情况中描述的故障可能会导致您的锁定。
情况 1 仅适用于 WFE 指令在内存中的 32 位字内处于特定对齐方式的情况。因此,如果您可以确保 WFE 指令永远不会出现在以这种方式对齐的代码中,那么您就不会遇到这种故障。如果您的汇编器支持 align 指令,您可以使用它实现此目的,如果汇编器不插入 NOP,则可能连同标签和跳转。然而,勘误表中的 "dedicated workaround" 给出了一个更简单的解决方案:
Replace the WFE instruction with
WFE JRA next next:
这似乎通过在 WFE 指令后放置相当于 2 字节 NOP 的内容来解决故障。我的猜测是失败导致 CPU 没有立即执行 WFE 指令之后的指令,而是向前跳过两个字节到下一个 32 位世界开始处的指令(如果有的话)。在跳过的space中放一个2字节的NOP意味着是否发生故障无关紧要。