【问题标题】:What can cause the LPM instruction to always fail?什么会导致 LPM 指令总是失败?
【发布时间】:2012-08-08 07:52:54
【问题描述】:

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

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

但是,当我尝试使用 LPM 指令检查内容时,它始终显示为零。

LPM无法读取时,我确定了以下原因:

  1. 当锁定位被设置时,禁止读取闪存。这里不是这种情况,因为没有设置锁定位。
  2. 由于先前的写入指令,闪存的读取被锁定。这里不是这种情况,因为我设置了RWWSRE 并等到while (SPMCSR & 0b01000000) {} 亮起绿灯
  3. 我算错了地址(Z 指针的分段可能很棘手)。这里不是这样,因为我也用第一个单词(地址 0)尝试了它,但它仍然不起作用。

我使用以下代码进行测试,读取flash的前两个字节(写入指令成功完成,因为该位置的程序内存不为零,用调试器检查)

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

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

但是,r2r3 将始终为零,无论闪存中有什么。

还有LPM读取失败的情况吗?

【问题讨论】:

  • 这适用于哪种 Atmel 处理器?
  • @Ian:致所有具有自编程能力的人。请注意,如果闪存大小 > 64 KB,则必须使用 elpm 而不是 lpm
  • 我看到现在问题上有一个 AVR 标签。这涵盖了8位AVR的各个系列和完全不同的AVR32系列。 Atmel 还生产一系列 8051 和 ARM 处理器,所有这些处理器都可以将数据写入闪存。至少,指出您所指的处理器系列是有用的。
  • 我将它添加到标签中,它是 8 位 AVR,但没有标签。我添加了 ATmega,但我认为如果有自编程的 ATtiny,它也适用于它们。

标签: assembly embedded avr atmel atmega


【解决方案1】:

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

代码部分

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 2011-04-04
    • 2012-02-25
    • 2014-03-10
    相关资源
    最近更新 更多