1

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

4

4 回答 4

2

早在 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 时。

于 2012-09-19T22:14:05.727 回答
2

当我今晚面临同样的问题时,我想加强一点并说明弗拉维奥的答案。

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

Flavio 的解决方法做得很好:

#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;                                 \
}))
于 2017-08-24T00:02:53.190 回答
0

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

atmega32 Datasheet 显示该器件在其寄存器 SPMCR 中没有称为 SIGRD的位,该寄存器的第五位保留并标记为只读。

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

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

于 2014-09-27T11:32:10.313 回答
0

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

于 2020-04-04T02:59:27.433 回答