【问题标题】:STM8 ASM safely execute WFESTM8 ASM 安全执行 WFE
【发布时间】:2016-07-22 11:35:48
【问题描述】:

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

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

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

while nbit(TIM1_SR1,CC3IF) asm("wfe");

即反汇编为:

000035    720252B602     BTJT      TIM1_SR1, #1, 0xB6
00003A    728F           WFE

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

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

我使用手册 PM0044,在第 26 页它包含漂亮的表格:

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

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

【问题讨论】:

  • 不清楚你在问什么。执行 WFE 指令后,CPU 已被事件唤醒,并执行以下指令。下面的指令应该是跳转回BTJT指令的JRA指令。序列是 1) 测试位并退出循环,如果设置 2) 等待唤醒事件 3) 跳转到步骤 1。如果您已正确编程 WFE 控制寄存器,那么它应该等同于序列 1) 测试位并退出loop if set 2) 跳转到第1步。WFE指令只是省电。
  • @Ross,真的如你所想吗? WFE 指令执行后,CPU 已经被事件唤醒并执行以下指令。 现在我认为这种错误的代码构造,正确的方法是仅在存在时才使用 WFE 指令是一个相当大的时间余量。在更复杂的情况下,不要在任何竞争对手的唤醒事件之后使用它。
  • 我确信它按照我描述的方式工作。在执行 WFE 指令期间,CPU 处于睡眠状态并等待事件。 WFE 指令执行完成后,CPU 不再处于睡眠状态,不再等待事件。然后它继续执行下一条指令,就像一条指令完成执行时通常发生的那样。但是,我仍然不明白你的问题是什么。所以我们可能不是在谈论同样的事情。大量的时间可以解决什么问题?
  • 如果在执行 BTJT 指令之后和执行 WFE 指令之前发生唤醒事件,我不确定 CPU 不会进入睡眠模式。当代码执行在几个周期被 fetch 过程停止时,就会发生这种情况,因为在 stm8 上,当代码从 RAM 运行时,8 位总线用于数据,16 位用于地址,而不是 32 位用于数据,24 位用于地址,以防代码从闪存运行。跨度>
  • @Ross 我已经更新了我的问题 - 现在更能解释我的问题了。

标签: c assembly embedded stm8


【解决方案1】:

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

errata provided by STMicroelectronics 内容如下:

可能会发生两种类型的故障:

案例 1:
如果 WFE 指令放在 内存中的 32 位字,在 WFE 期间发生的事件 执行周期或重新执行周期(从 ISR 返回时 handler) 将导致错误的代码执行。

案例 2:
中断请求,发生在 WFE 期间 执行周期会导致不正确的代码执行。这也是 对 WFE 重新执行周期有效,同时从 ISR 返回 处理程序

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

仅当 WFE 指令在内存中的 32 位字中处于某种对齐状态时,情况 1 才适用。因此,如果您可以确保 WFE 指令永远不会出现在以这种方式对齐的代码中,那么您将不会遇到此故障。如果您的汇编器支持 align 指令,您可以使用它来实现这一点,如果汇编器不插入 NOP,则可能与标签和跳转一起使用。然而,勘误表中给出了一个更简单的解决方案作为“专用解决方法”:

将 WFE 指令替换为

     WFE
     JRA next
next:

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

【讨论】:

  • 修改代码以确保正确的时机并不难,我认为这是更正确的方法。
【解决方案2】:

OP 找到的解决方案:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-20
    • 2014-01-14
    • 1970-01-01
    • 2020-01-03
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多