了解STM32参考手册中的写入flash流程
Posted
技术标签:
【中文标题】了解STM32参考手册中的写入flash流程【英文标题】:Understanding the writing to flash process in the STM32 reference manual 【发布时间】:2019-11-25 06:11:39 【问题描述】:我正在对 stm32l412kb 进行编程,有一次我会将数据写入闪存(从 UART)。从 stm32l41xx reference manual,我了解了在写入之前如何清除内存的步骤,但是在第 84 页上,有一个步骤我在写入实际数据时不知道该怎么做。这一步是
在想要的内存地址进行数据写入操作
它提到了什么数据写入操作?我看不到内存地址所在的任何寄存器,所以我假设它会使用指针?我该怎么做呢?
非常感谢您的帮助, 非常感谢,
哈利
【问题讨论】:
在我看来,这些术语有歧义:通常对 Flash 的写操作包括:1) 擦除扇区(如果需要) 2) 编程一个字(或 2 个字),意思是清除内存中的一位或几位。 【参考方案1】:除了一些事情(例如,仅在擦除后写入、时序、对齐、锁定/解锁)之外,写入 RAM 和写入 FLASH 存储器之间并没有太大区别。因此,如果您已按照参考手册中的步骤操作并且闪存已准备就绪(即已清除和解锁),那么您只需获取对齐的内存地址并写入即可。
STMs 自己的 HAL 库包含一个函数,它为您完成所有繁琐的样板文件并允许您“只写”:
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
这个函数在内部使用一个执行实际写入的子程序,它看起来像这样:
static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
/* Check the parameters */
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
/* Set PG bit */
SET_BIT(FLASH->CR, FLASH_CR_PG);
/* Program first word */
*(__IO uint32_t*)Address = (uint32_t)Data;
/* Barrier to ensure programming is performed in 2 steps, in right order
(independently of compiler optimization behavior) */
__ISB();
/* Program second word */
*(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);
如您所见,其中不涉及魔法。它只是一个取消引用的指针和一个赋值。
【讨论】:
你不能说写入 RAM 和 FLASH 没有太大区别。 Flash 扇区需要擦除,根据您必须注意在与您正在执行的扇区(或存储库)不同的扇区(或存储库)中进行编程的产品,在 STM32L4 上,您一次只能编程 64 位,您必须在对数据总线进行写访问之前,在 Flash 控制器寄存器中设置一个或多个位......但是你是对的,最后写入是由相同的 C(或汇编)指令引发的。【参考方案2】:它提到了什么数据写入操作?
“数据写入”只是对闪存中的内存地址的正常写入。它通常是STR 汇编指令。筛选您的数据表,我猜闪存地址在 0x08080000 和 0x00080000 之间。
例如。以下 C 代码会将值 42 写入第一个闪存地址:
*(volatile uint32_t*)0x00080000 = 42.
参考实现可以看stm32 hal drivers:
/* Set PG bit */
SET_BIT(FLASH->CR, FLASH_CR_PG);
/* Program the double word */
*(__IO uint32_t*)Address = (uint32_t)Data;
*(__IO uint32_t*)(Address+4) = (uint32_t)(Data >> 32);
【讨论】:
我认为您的第一个示例不起作用,因为只能编程双字(2 x 32 数据)。因此,您还需要写入接下来的四个字节:*(volatile uint32_t*)0x00080004 = 0;
以上是关于了解STM32参考手册中的写入flash流程的主要内容,如果未能解决你的问题,请参考以下文章