STM8 ASM安全地执行WFE

时间:2016-04-02 18:12:39

标签: c assembly embedded stm8

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

  • 跳转到RAM
  • SIM
  • 关闭内部闪光灯和电源调节器,切换到低速时钟源(LSE)
  • 使用WFE模式(低功耗等待模式)进行一些工作
  • 打开电源调节器和闪光灯,恢复时钟源
  • RIM
  • 跳转到闪光灯

所以在勘误表中描述的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页它内容很漂亮:

example code execution from RAM

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

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

2 个答案:

答案 0 :(得分:5)

如果您的锁定问题是由我提到的WFE勘误引起的,那么应该有一个比尝试实现“正确的应用程序计时”更简单的解决方案。

errata provided by STMicroelectronics读取:

  

可能会发生两种类型的失败:

     

情况1:
如果WFE指令被放置在两个MSB中   内存中的32位字,即WFE期间发生的事件   执行周期或重新执行周期(从ISR返回时)   处理程序)将导致代码执行错误。

     

情况2:中断请求,在WFE期间发生   执行周期将导致代码执行错误。这也是   从ISR返回时,对WFE重新执行周期有效   处理

案例2不适用于您的情况,因为您说“由于我使用的是低功率运行模式,因此不会处理中断”。如果在WFE指令期间不能发生中断,则只有第一种情况中描述的故障可能导致锁定。

情况1仅在WFE指令在内存中的32位字内处于特定对齐时才适用。因此,如果您可以确保WFE指令永远不会出现在以这种方式对齐的代码中,那么您将不会遇到此故障。如果汇编程序支持align指令,你可以使用它实现这一点,如果汇编程序没有插入NOP,可能还会附带标签和跳转。然而,更简单的解决方案是勘误表中的“专用解决方法”:

  

替换WFE指令
     WFE
     JRA next
next:

这似乎可以通过在WFE指令之后放入相当于2字节NOP的数据来解决此问题。我的猜测是失败导致CPU在WFE指令之后不立即执行指令,而是在下一个32位世界开始时向前跳过两个字节到指令(如果有的话)。在空格中放置一个2字节的NOP意味着无论是否发生故障都无关紧要。

答案 1 :(得分:1)

OP发现的解决方案:

  

我已经多次仔细阅读勘误表(感谢Ross Ridge),这是主要的想法:

     

一般解决方案是确保在正确的应用程序计时期间,在WFE指令执行或重新执行周期期间不会发生中断请求或事件。