什么可能导致LPM指令总是失败?

时间:2012-08-08 07:52:54

标签: assembly embedded avr atmel atmega

我有一个自修改程序写入程序闪存区域(它不会破坏程序流程,因为我写入另一个闪存扇区,而不是我的程序运行的闪存扇区 - 它运行在受保护的引导程序部分)。 。

复杂的部分,写入闪存,工作。我可以在调试器中检查它,我发送的值已成功写入闪存。

但是,当我尝试使用LPM指令检查内容时,它总是读为零。

LPM无法阅读时,我发现了以下原因:

  1. 设置锁定位时,禁止读取闪存。这不是这种情况,因为没有设置锁定位。
  2. 由于先前的写入指令,闪存的读取被锁定。不是这里的情况,因为我设置了RWWSRE并等到while (SPMCSR & 0b01000000) {}
  3. 的绿灯
  4. 我错误地计算了地址(Z指针的分割可能很棘手)。不是这里的情况,因为我也用第一个字(地址0)尝试了它,但它仍然没有用。
  5. 我使用以下代码进行测试,读取闪存的前两个字节(写入指令成功完成,因为该位置的程序存储器不为零,使用调试器检查)

      lpm r0,Z+
      lpm r1,Z+
      movw r2, r0
    

    在此之前,我将Z指针设置为零,并使用调试器检查它是否为零(r30r31)。

    但是,r2r3始终为零,无论闪光灯中是什么。

    还有另一种情况LPM无法阅读吗?

1 个答案:

答案 0 :(得分:2)

我在逐步运行它并检查所有受影响的寄存器的内容时​​找到了解决方案。事实证明这个问题与LPM无关,但我保留了这个问题以供将来参考。

代码部分

  lpm r0,Z+
  lpm r1,Z+
  movw r2, r0

在C for循环中,Z指针在该循环之前设置。但是,循环比较恰好被编译为使用r30作为临时寄存器,因此它损坏了Z指针。通过将Z指针和带有LPM的部分初始化到同一#asm ... #endasm块中来解决问题。