STM8 ASM安全地执行WFE

imb*_*arr 4 c embedded assembly stm8

我在低功耗运行模式下从RAM 运行了 c代码(因此中断没有处理).此模式由代码序列启用:

  • 跳到RAM
  • SIM卡
  • 关闭内部闪光灯和电源调节器,切换到低速时钟源(LSE)
  • 在WFE模式下工作(低功耗等待模式)
  • 打开电源调节器和闪光灯,恢复时钟源
  • 轮缘
  • 跳到闪光灯

所以在勘误表中描述的WFE指令没有问题.这种结构的问题,可能是永远低功耗等待模式下 CPU锁定的原因:

while nbit(TIM1_SR1,CC3IF) asm("wfe");
Run Code Online (Sandbox Code Playgroud)

这是拆卸为:

000035    720252B602     BTJT      TIM1_SR1, #1, 0xB6
00003A    728F           WFE
Run Code Online (Sandbox Code Playgroud)

来自定时器的事件具有概率性质,并且此代码不保证在WFE指令执行后它将发生:

  • BTJT指令在2个周期内完成,长度为5;
  • 从RAM执行的代码可能不连续,因为"fetch"状态会在几个周期内暂停执行

我使用手册PM0044,在第26页它内容漂亮的表:

RAM中的示例代码执行

有两种情况,代码执行在3个周期停止.所以我不确定在BTJT和WFE指令之间不会发生异步唤醒事件.

有没有办法确保严格的逻辑顺序(检查条件> wfe>唤醒事件)?

Ros*_*dge 5

If your lockup problems are caused by the WFE errata I mentioned then there should be an easier solution than trying to achieve "proper application timing".

The errata provided by STMicroelectronics reads:

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

Case 2 shouldn't apply in your case as you say "Interrupts are not handled because I use low power run mode". If interrupts can't occur during the WFE instruction only the failure described in the first case could be causing your lockups.

Case 1 only applies if the WFE instruction is in a certain alignment within a 32-bit word in memory. So if you can ensure the WFE instruction never appears in code aligned this way then you won't encounter this failure. If your assembler supports an align directive you could use it achieve this, maybe along with a label and a jump if the assembler doesn't insert NOPs. However an easier solution is given as a "dedicated workaround" in errata:

Replace the WFE instruction with

     WFE
     JRA next
next:
Run Code Online (Sandbox Code Playgroud)

This appears to work around the failure by putting what amounts to a 2-byte NOP after the WFE instruction. My guess is the failure results in the CPU not executing the instruction immediately following the WFE instruction, instead skipping ahead two bytes to the instruction (if any) at the start of the next 32-bit world. Putting a 2-byte NOP in the space skipped over means it doesn't matter if the failure occurs or not.