理解STM32参考手册中的Flash编程过程

3
我正在编程stm32l412kb,其中有一点是我将要从UART写入数据到flash。从stm32l41xx参考手册reference manual中,我了解到在写入数据之前如何清除存储器的步骤,但是在第84页中,当写入实际数据时,有一步我不知道该如何做。那一步是:

在所需的存储器地址执行数据写入操作

它提到了什么数据写入操作?我看不到任何寄存器与存储器地址相对应,所以我认为它将使用指针?我该怎么做?
非常感谢您的帮助, 谢谢, Harry

1
在我看来,这些术语存在歧义:通常对Flash的写操作包括:1)擦除一个扇区(如果需要)2)编程一个字(或两个字),编程意味着清除内存中的一个或多个位。 - Guillaume Petitjean
2个回答

7
除了一些细节(例如擦除后才能写入、时间、对齐和锁定/解锁),写入RAM和写入FLASH存储器之间没什么区别。如果你已经按照参考手册的步骤准备好了FLASH存储器(即清除并解锁),那么你可以直接使用对齐的内存地址进行写入。
ST公司的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);
}

正如您所看到的,这里并没有任何魔法。它只是一个取消引用的指针和一个赋值操作。


1
你不能说在写入RAM和FLASH之间没有太大的区别。根据产品需要擦除Flash扇区,必须注意在不同的扇区(或者bank)中编程以避免与执行时的扇区冲突,在STM32L4上每次只能编程64位,必须在数据总线上进行写访问之前设置Flash控制器寄存器中的一个或多个位... 然而,你是对的,最终写操作由相同的C(或汇编)指令触发。 - Guillaume Petitjean

3
它所提到的是哪种数据写操作?
“数据写入”只是在内存中写入地址为闪存存储器的普通写入。通常使用STR汇编指令。请查看您的数据手册,我猜测Flash存储器的地址应该在0x08080000和0x00080000之间。
例如,以下C代码将向第一个Flash存储器地址写入值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; - Codo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接