Memory 为什么';写入闪存控制寄存器(STM32)时,闪存控制寄存器是否会更新?

Memory 为什么';写入闪存控制寄存器(STM32)时,闪存控制寄存器是否会更新?,memory,embedded,microcontroller,stm32,flash-memory,Memory,Embedded,Microcontroller,Stm32,Flash Memory,我正试图在STM32G0上写入更新我的工程字节,我被卡住了。我需要通过写入闪存键盘寄存器来解锁闪存。手册上说: 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. Th

我正试图在STM32G0上写入更新我的工程字节,我被卡住了。我需要通过写入闪存键盘寄存器来解锁闪存。手册上说:

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.
当我试图写的时候,我会确保我的BSY1位是清晰的,我相信这是唯一的条件

我就是这样写的:

#define KEY1  0x45670123
#define KEY2  0xCDEF89AB

... 

FLASH->KEYR = KEY1;
FLASH->KEYR = KEY2;
在这一点之后,我的闪光键寄存器仍然是0x0。有人知道为什么吗

编辑:这是我的代码

        #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;
下面是
程序\u 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);
}

编辑:这是一个只写寄存器,所以我不能读回它。我找到了如何成功写入内存的方法。

此代码使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执行str指令,GET32执行ldr指令

不同的STM32G0对其中一些寄存器有不同的默认值,我现在打开的FLASH_CR寄存器的默认值是:

Reset value: 0xC000 0000
这是两个锁定位,所以上面的每个解锁序列都绑定到一个位,所以两个序列都绑定到一个位,理论上两个位都解锁。可能会挖出一块电路板/芯片,尝试并编辑此答案以确认

看起来你是通过一个程序来做这件事的,这些芯片非常挑剔,闪存被擦除(就像在一个新的芯片中一样),你只需要一次引导加载程序加载的机会,一旦有东西存在,你就可以通过SWD进入(我想有一种方法可以阻止它),但是您不能使用swd来编写这些寄存器来执行这些您必须运行代码的任务,您可以从ram或flash运行它

根据您试图更改的内容,您可能需要重启芯片,以查看更改是否生效

编辑

uart输出

C0000000 
40000000 
00000000 
正如文件中所预期的那样


您是如何以及何时读取注册表的?您是否在解锁和读取之间触摸了任何寄存器?

我猜您没有启用dugital FLASH界面

RCC -> AHBENR |= RCC_AHBENR_FLASHEN;
然后

等待闪存外围设备

while (FLASH -> SR & FLASH_SR_BSY1) ;


FLASH\u CR默认值为0x0000 0080。检测到解锁序列后,硬件将重置位7。所以期望值是0x00。@Babajan您在哪里看到默认值是0x0000 0080?地址偏移量为0x008,其重置值为0x0000 0000,但我不确定默认值来自何处。默认寄存器值为0x8000 0000。这是一个链接,请参阅第2.8章。5@Babajan对于STM32F系列来说,使用地址和幻数毫无意义。此“伪代码”也是。
是两个锁位
第二个锁位不相关,因为它锁定与OPs无关的选项字节problem@P__J__代码中没有一个神奇的数字FLASH_CR是神奇的是,你必须挖掘代码层来找出它是什么,但这是100%来自文档,零魔法,零神秘,很容易理解。OP读数为零,要达到零,你需要根据文档清除两个位。这演示了零的路径,以及在解锁任何东西之前,解锁一个东西,然后解锁另一个东西。选项字节与读取零有关(或由于魔法隐藏头等原因没有正确的地址),OP读取零是因为他没有启用闪存外围设备。它不是闪存唯一的数字接口,用于编程和设置闪存。否则,他将在锁定位重置为非零的情况下读取该寄存器的默认值。顺便说一句,要读取该值,您不需要解锁它。请不要使用隐藏值,请使用文档中显示的值。这个问题是关于文档的,而不是关于某些库中的魔法隐藏值。@old_timer它们不是魔法数字。这些定义由STM提供(它不是库,只是头文件,具有与STM文档定义中使用的类似的可读性)。而且代码很容易阅读
RCC
是外围设备及其寄存器,称为
AHBENR
。您需要在此寄存器中设置位
flashn
。因此定义为
RCC\u AHBENR\u flashn
<代码>*(volatile uint32_t*)0x40005678 |=0x00010000对于人们来说很难解码。@P_uj_uu_u_u>为什么设置
RCC->AHBENR |=RCC_AHBENR_u闪烁解锁闪存的帮助?我尝试添加它,但它没有改变任何东西,因为它启用了闪存接口时钟。在此之后,您应该读取闪存->CR寄存器的默认值。如果您仍然读取零,则表示您在其他地方犯了错误,如果没有看到完整的代码,我将无法帮助您。@P_uj_u_u我刚刚将完整的代码添加到我的问题:)
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));