Keil uVision - Atmel SAM3U 读取唯一标识符

时间:2021-01-27 11:18:44

标签: arm embedded microcontroller keil atmel

我一直在尝试从 Atmel SAM3U MCU 读取唯一标识符 (UID),但事实证明它比实现它所需要的更困难。有没有人有任何例子或可以建议如何正确阅读它?每当我这样做时,我都会在 do while 循环(如文档状态)中等待 EEFC(闪存 ROM)状态寄存器更改状态,但它从未这样做,因此 MCU 会陷入循环。

Atmel Read Unique Identifier Document

这是我正在使用的代码

// must run this from SRAM
__attribute__((section(".ARM.__at_0x20080000"))) void Get_Unique_ID(unsigned int *pdwUniqueID)
{
    Efc *p_efc;
    unsigned int status;
    
    // clear the array
    pdwUniqueID[0] = 0;
    pdwUniqueID[1] = 0;
    pdwUniqueID[2] = 0;
    pdwUniqueID[3] = 0;
    
    // send the Start Read Unique Identifier command (STUI) by writing the Flash Command Register with the STUI command
    p_efc->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_STUI;
    
    // wait for the Flash Programming Status Register (EEFC_FSR) to fall
    do { status = p_efc->EEFC_FSR; }
    while ((status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY);
    
    // the Unique Identifier is located in the first 128 bits of the Flash memory mapping
    pdwUniqueID[0] = *(unsigned int *)IFLASH0_ADDR;
    pdwUniqueID[1] = *(unsigned int *)(IFLASH0_ADDR + 4);
    pdwUniqueID[2] = *(unsigned int *)(IFLASH0_ADDR + 8);
    pdwUniqueID[3] = *(unsigned int *)(IFLASH0_ADDR + 12);
    
    // to stop the Unique Identifier mode, the user needs to send the Stop Read unique Identifier
    // command (SPUI) by writing the Flash Command Register with the SPUI command
    p_efc->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SPUI;
    
    // when the Stop Read Unique Unique Identifier command (SPUI) has been performed
    // the FRDY bit in the Flash Programming Status Register (EEFC_FSR) rises
    do { status = p_efc->EEFC_FSR; }
    while ((status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
}

请注意,__attribute__((section(".ARM.__at_0x20080000"))) 不是通过链接器将此函数动态分配给 SRAM 的最佳方法,我们将不胜感激任何有关如何使其更具动态性的建议。

已解决 问题是我拥有的芯片是假的,所以 SAM-BA 会返回它指定的 SRAM 缓冲区地址中的任何内容。这是 SAM-BA 中的一个错误,因为如果它收到 0x00000000,它应该给出错误或警告消息,然后停止读取。 不要从中国购买假芯片!

谢谢。

1 个答案:

答案 0 :(得分:0)

我认为 p_efc 没有正确初始化。 您创建了一个指向 Efc 数据结构的指针,该数据结构因此指向某物

然后您将某事写到某处并期望它起作用。

Efc *p_efc;
p_efc->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_STUI;

我的猜测是您需要将其初始化为正确的 EEFC 基址。 datasheet 有以下内容:

<块引用>

SAM3U4(256 KB 内部闪存 版本)嵌入了两个 EEFC(EEFC0 用于 Flash0,EEFC1 用于 Flash1) 而 SAM3U2/1 嵌入了一个 EEFC。

因此,根据您的 MCU 版本,您需要解决 EEFC0 或 EEFC1。我假设您使用 libopencm3 但这适用于任何其他库。寻找 EEFC location define。按照定义/文件/链接我们到达 this page,它告诉我们将 Efc 指针指向 EEFC0_BASEEEFC1_BASE。我建议您使用 EEFC0EEFC1 定义,因为它使您的代码更便携。

因此,如果您的 Efc 位于 EEFC0,那么您的代码应该可以工作:

Efc *p_efc = EEFC0;