【问题标题】:how to read atmega 32 signature row?如何读取 atmega 32 签名行?
【发布时间】:2012-09-10 11:38:29
【问题描述】:

我尝试使用boot_signature_byte_get(0); 读取 atmega32 的签名行,但我收到此错误:'SIGRD' undeclared (first use in this function),这似乎是因为我们只能使用 SPMCR 中具有 SIGRD 位的 AVR 读取签名(我想! )。
这是正确的吗?那么我该如何以另一种方式读取签名行?

【问题讨论】:

  • 错误不是在说那个位。相反,它表明您在某处缺少一些头文件。字符串“SIGRD”出现在该函数的源代码中,但是您缺少 SIGRD 为 #define d 的头文件,它是其他东西(如数字)。所以编译器遇到了字符串 SIGRD 并且无法识别它。从上下文来看,编译器假定它必须是函数的名称,并注意到它没有被声明。当然,它根本不是一个函数。如果包含#define,编译器将根本看不到字符串“SIGRD”。

标签: avr avr-gcc atmega avr-studio5


【解决方案1】:

早在 2007 年,任何头部都没有读取签名字节的功能,然后在同年引入。但看起来,它仍然存在一些问题。

数据表说:

All Atmel microcontrollers have a three-byte signature code which identifies the device.
This code can be read in both serial and parallel mode, also when the device is locked.
The three bytes reside in a separate address space.

意味着 ATMEGA32 可以读取该字节。同样在数据表中,它指定了如何读取该字节。在他们的大多数 MCU 中,它的读取方式相同,但由于某种原因,某些头文件中缺少 SIGRD 定义号,包括 ATMEGA32 之一。

但是,作为一种解决方法,我们可以手动定义SIGRD。我们只需要知道它的价值。当我在头文件中做一些findstr(或grep)搜索这个定义时,一致认为它的值为5。

因此,解决方法是:

#define SIGRD 5
#include <avr/boot.h>

我编译成功,但我只是尝试在模拟软件上测试程序,因为我现在没有 ATMEGA32。它返回一个字节,所以现在由您决定这是否是正确的字节...

关于你说的SPMCR这件事,好像签名行在另一个地址空间(据我了解,不知道对不对我无法确认),获取方式是使用一些指令,类似我们将一些程序上传到 MCU 时。

【讨论】:

  • Tnx 提供了这么大的帮助。我会尽力让你知道发生了什么。
  • @osyan,桥下流了很多水,怎么回事?
【解决方案2】:

当我今晚面临同样的问题时,我想加强一下并说明 Flávio 的答案。

那么我该如何以另一种方式读取签名行?

Flávio 的解决方法做得很好:

#define SIGRD 5
#include <avr/boot.h>

void read_signature_row(uint8_t sr[3])
{
  sr[0] = boot_signature_byte_get(0x0000);
  sr[1] = boot_signature_byte_get(0x0002);
  sr[2] = boot_signature_byte_get(0x0004);
}

void setup()
{
  Serial.begin(9600);
  delay(100);

  uint8_t sr[3] = {0xcc, 0xcc, 0xcc};
  read_signature_row(sr);

  char buff[100];
  snprintf(buff, sizeof buff, "Device signature: %02X %02X %02X", sr[0], sr[1], sr[2]);
  Serial.println(buff);
}

void loop()
{}

我没有 ATmega32,尽管此方法为我的 ATmega328P (1E 95 0F) 和 ATmega168PA (1E 94 0B) 检索正​​确的签名。

这似乎是因为我们只能使用 SPMCR 中具有 SIGRD 位的 AVR 读取签名(我想!)。 是这样吗?

不,它实际上在调用 LPM 之前将 SIGRD 设置为 SPMCR,如 avr/boot.h 所示:

#define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD))
#define boot_signature_byte_get(addr) \
(__extension__({                      \
      uint8_t __result;                         \
      __asm__ __volatile__                      \
      (                                         \
        "sts %1, %2\n\t"                        \
        "lpm %0, Z" "\n\t"                      \
        : "=r" (__result)                       \
        : "i" (_SFR_MEM_ADDR(__SPM_REG)),       \
          "r" ((uint8_t)(__BOOT_SIGROW_READ)),  \
          "z" ((uint16_t)(addr))                \
      );                                        \
      __result;                                 \
}))

【讨论】:

    【解决方案3】:

    我认为 atmega32 不支持读取用户程序中的签名字节。

    atmega32数据表显示该器件的SPMCR寄存器中没有SIGRD位,该寄存器的第五位被保留并标记为只读。 p>

    atmega640/1280/2560 处理器有一个类似的寄存器,称为 spmcSr,它有这个位 SIGRD(位 5)。但是数据表解释说这个位不应该被使用,因为这个操作是为将来使用而保留的(不过,那里解释了读取签名的过程)。

    您的编译器可以正常工作,因为 atmega32 没有此 SIGRD 位。

    【讨论】:

      【解决方案4】:

      SIGRD 存在并可用于 ATmega164A/164PA/324A/324PA/644A/644PA/1284/1284P 处理器。 “保留供将来使用”备注仅适用于 SPM 指令,除了 SPMCSR 的五个最低位之外,请参见第 285 页,第 26.9.1 节。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        • 2021-04-11
        • 2015-01-04
        • 2011-09-02
        • 2011-07-31
        相关资源
        最近更新 更多