简体   繁体   English

为什么我的 Flash 控制寄存器在我写入时没有更新(STM32)?

[英]Why doesn't my Flash Control Register update when I write to it (STM32)?

I'm trying to write to update my engineering bytes on the STM32G0 and I'm getting stuck.我正在尝试写来更新我在 STM32G0 上的工程字节,但我被卡住了。 I need to unlock flash by writing to the FLASH_KEYR register.我需要通过写入 FLASH_KEYR 寄存器来解锁 flash。 The manual says this:手册是这样说的:

After reset, write into the FLASH control register (FLASH_CR) is not allowed so as to protect the Flash memory against possible unwanted operations due, for example, to electric disturbances. The following sequence unlocks these registers:

1. Write KEY1 = 0x4567 0123 in the FLASH key register (FLASH_KEYR)
2. Write KEY2 = 0xCDEF 89AB in the FLASH key register (FLASH_KEYR).

Any wrong sequence will lock the FLASH_CR registers until the next system reset. In the case of a wrong key sequence, a bus error is detected and a Hard Fault interrupt is generated.
The FLASH_CR registers can be locked again by software by setting the LOCK bit in one of these registers.

Note: The FLASH_CR register cannot be written when the BSY1 bit of the FLASH status register (FLASH_SR) is set. Any attempt to write to this register with the BSY1 bit set causes the AHB bus to stall until the BSY1 bit is cleared.

I making sure that my BSY1 bit is clear when I'm trying to write and I believe that's the only condition.当我尝试写作时,我确保我的 BSY1 位是清晰的,我相信这是唯一的条件。

This is how I'm writing:这就是我的写作方式:

#define KEY1  0x45670123
#define KEY2  0xCDEF89AB

... 

FLASH->KEYR = KEY1;
FLASH->KEYR = KEY2;

After this point, my FLASH_KEYR register is still 0x0.至此,我的 FLASH_KEYR 寄存器还是 0x0。 Does anyone know why?有谁知道为什么?

Edit: here's my code编辑:这是我的代码

        #define TEST_FLASH_BYTES    ((uint32_t)0x0801FF00)

        ...

        FLASH->CR &= FLASH_CR_LOCK;
        FLASH->KEYR = KEY1;
        FLASH->KEYR = KEY2;

        while(__HAL_FLASH_GET_FLAG(FLASH_SR_BSY1) != 0) {}

        program_flash(TEST_FLASH_BYTES, 0x1234567887654321);

        while (__HAL_FLASH_GET_FLAG(FLASH_SR_BSY1) != 0) {}

        FLASH->SR &= FLASH_SR_EOP;
        FLASH->CR &= FLASH_CR_PG;

here is program_flash :这是program_flash

static void program_flash(uint32_t address, uint64_t data)
{
    *(uint32_t *)address = (uint32_t)data;

    (independently of compiler optimization behavior) */
    __ISB();

    *(uint32_t *)(address + 4U) = (uint32_t)(data >> 32U);
}

Edit: it's a write only register so that's why I can't read it back.编辑:它是一个只写寄存器,所以这就是我无法读回它的原因。 I figured out how to write to my memory successfully.我想出了如何成功写入我的 memory。

This code enables the boot0 pin to work like a legacy stm32 chip.此代码使 boot0 引脚能够像传统 stm32 芯片一样工作。

    //enable BOOT0 pin
    while(GET32(0x40022010)&0x10000) continue;
    PUT32(0x40022008,0x45670123);
    PUT32(0x40022008,0xCDEF89AB);
    PUT32(0x4002200C,0x08192A3B);
    PUT32(0x4002200C,0x4C5D6E7F);
//from the manual:
//ST production value: 0xDFFF E1AA
    PUT32(0x40022020,0xDEFFE1AA);
    while(GET32(0x40022010)&0x10000) continue;
    PUT32(0x40022014,0x00020000);
    while(GET32(0x40022010)&0x10000) continue;

PUT32 does an str instruction and GET32 does an ldr instruction. PUT32 执行 str 指令, GET32 执行 ldr 指令。

The different STM32G0 have different default values for some of these registers, the one I have open right now for the FLASH_CR register is:不同的 STM32G0 对其中一些寄存器有不同的默认值,我现在为 FLASH_CR 寄存器打开的默认值是:

Reset value: 0xC000 0000

which is the two lock bit, so each of the unlock sequences above are tied to one bit, so do both sequences and in theory both bits unlock.这是两个锁定位,因此上面的每个解锁序列都绑定到一个位,两个序列也是如此,理论上两个位都解锁。 May dig out a board/chip and try this and edit this answer to confirm.可以挖出一块板/芯片并尝试这个并编辑这个答案以确认。

It looks like you are doing this from a program, these chips are quite picky, with the flash erased (as in a new chip) you get one shot at the bootloader approach to loading, once something is there, then you can come in through SWD (I assume there is a way to block that), but you can't use swd to write these registers to perform these kinds of tasks you have to run code, and you can run it from ram or flash.看起来您是从程序中执行此操作的,这些芯片非常挑剔,擦除了 flash(如在新芯片中),您可以通过引导加载程序进行加载,一旦有东西,您就可以通过SWD(我假设有一种方法可以阻止它),但是你不能使用 swd 来编写这些寄存器来执行你必须运行代码的这些类型的任务,你可以从 ram 或 flash 运行它。

Depending what you are trying to change you may need to power cycle the chip to see the change take effect.根据您要更改的内容,您可能需要重启芯片才能看到更改生效。

EDIT编辑

while(GET32(0x40022010)&0x10000) continue; //need this here?
ra=GET32(0x40022014); //FLASH_CR
while(GET32(0x40022010)&0x10000) continue;
PUT32(0x40022008,0x45670123);
PUT32(0x40022008,0xCDEF89AB);
rb=GET32(0x40022014); //FLASH_CR
PUT32(0x4002200C,0x08192A3B);
PUT32(0x4002200C,0x4C5D6E7F);
rc=GET32(0x40022014); //FLASH_CR
hexstring(ra);
hexstring(rb);
hexstring(rc);

uart output串口 output

C0000000 
40000000 
00000000 

Which as expected from the documentation.正如文档中所预期的那样。

How and when are you reading the register?您如何以及何时阅读注册表? Are you touching any registers in between unlock and read?您是否在解锁和读取之间触摸任何寄存器?

I guess you did not enable the dugital FLASH intrface.我猜你没有启用数字 FLASH 接口。

RCC -> AHBENR |= RCC_AHBENR_FLASHEN;

then然后

wait for the FLASH peripheral等待 FLASH 外设

while (FLASH -> SR & FLASH_SR_BSY1) ;
        RCC -> AHBENR |= RCC_AHBENR_FLASHEN;
        (*void)RCC -> AHBENR; // readback instead of delay to let this change to propagate throut the bus.
        while(FLASH -> SR & FLASH_SR_BSY1));
        //FLASH->CR &= FLASH_CR_LOCK; this line is worng. First of all it is not the way of reseting the bits, Secondly this bit is SET ONLY which meand that you can set it to enable the lock again
        FLASH->KEYR = KEY1;
        FLASH->KEYR = KEY2;

        while(FLASH -> SR & FLASH_SR_BSY1));

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM