【问题标题】:Why can't write internal flash of same address twice为什么不能两次写入相同地址的内部闪存
【发布时间】:2016-07-14 15:33:55
【问题描述】:

我正在尝试写入 STM32F1xxC 的内部闪存(每页 2KB),我可以在页面擦除后写入闪存,这会将页面的每个字节转换为 0xFF。

很奇怪,我不能将相同的flash地址写两次,只有当那个地址之前的值为“0xFFFF”时才有可能。 p>

这个限制的原因是什么? 而且我想知道为什么我不能写到奇数地址? (例如 0x803F0A1)

我认为我的问题不是特定于平台(或供应商)的,所以我没有添加任何代码。

感谢您的帮助。

【问题讨论】:

  • 虽然闪存技术施加了您所描述的许多限制,但 STM32 片上闪存在您应该非常注意的方式方面受到进一步限制,因为它们严重影响其在应用中的实用性。从这个意义上说,您的问题是“特定于供应商的”,但您是对的,不需要代码来回答。
  • 这是特定于供应商的,而不是通用的......

标签: embedded stm32 flash-memory


【解决方案1】:

这不是很奇怪,但是flash的规则,因为底层技术(我不敢解释,我不是物理学家)。看看这里:

https://en.wikipedia.org/wiki/Flash_memory#Block_erasure

不过,只要新值为 0,就可以重写位置 位是覆盖值的超集。例如,咬一口 值可能会被擦除为 1111,然后写入 1110。连续写入 到那个半字节可以将其更改为 1010,然后是 0010,最后是 0000。 本质上,擦除将所有位设置为 1,而编程只能 清除位为 0。

至于:

我还想知道为什么我不能写到奇数地址?

这是您的 CPU 的内存对齐限制 - 一个非常常见的限制,不要因此而责怪它!这里有一个很好的解释:

https://stackoverflow.com/a/3025225/5257515

因此,要写入未对齐的地址,您还必须先写入对齐的地址:

  • 加载 16 位(或 32 位,取决于您的对齐粒度限制)位内存对齐地址值,其中包括您感兴趣的部分,

  • 更改此部分,其余部分保持不变,

  • 将新的 16(或 32)位值写回内存对齐地址。

编辑:

有关 STM32F1xx 更严格设计的具体见解,请务必查看@Clifford 评论。

【讨论】:

  • 在 STM32F1xx 上,读-修改-写技术将不起作用。 ST 的实现比您描述的更严格。它可以用 16 位字写入,如果 任何 个位为零(即该字之前是否已写入),则该字可能不会被写入。
  • @Clifford 感谢您对 STM32F1xx 的深入了解,我的回答非常广泛/全面。
  • 是的,STM32 闪存有点“陷阱”——这不是唯一的问题——通常你可以在写入/擦除另一页的同时读取一页,但在 STM32 中,整个闪存总线停止,因此在 Flash 运行中没有代码 - 在很长一段时间内(数十毫秒)停止执行。
  • @Clifford STM32 闪存允许您在写入值后将全零写入闪存字。他们甚至在他们的应用笔记之一中使用它来模拟闪存中的 EEPROM:STM32F0xx 微控制器 (AN4061) 中的 EEPROM 仿真
  • @NZD 您的评论可能更好地应用于 my 答案,我已经详细描述了 STM32 的行为。这是否特别是将整个单词限制为零,因此可能的 word 转换是 all-ones->non -zero->zero?它是 F0 特有的,还是所有 STM32 都如此?
【解决方案2】:

闪存的本质是 write 操作只允许一个位从 1 到 0 的转换。要将一个位从 0 设置为 1 需要一个 erase操作和擦除操作适用于整个擦除块。擦除块的大小因设备而异。

在大多数闪存实现中,如果唯一的位变化是从 1 到 0,则可以修改已经写入的字。然而,在 STM32F1xx 上,即使这样也是不可能的,因为字大小是 16 位,如果已经写了另一半字,就不能写一个字节。

STM32F2xx(以及 F4 和 F7 范围)通过允许以 8、16 和 32 位模式写入闪存来部分解决此问题,但仍然无法将位从 1 写入 0 位在同一个词中已经是零。

您可能需要注意的 STM32 片上闪存的另一个问题是,在写入或擦除操作期间,总线会停顿很长一段时间。在传统的闪存部件上,您可以在写入另一页的同时从一页读取,但在 STM32 上,整个闪存被阻塞。由于通常从闪存中获取指令,因此这种读阻塞意味着在闪存擦除/写入操作期间不处理任何指令 - 整个处理器内核处于等待状态 (外围设备继续运行 - 除非使用 DMA 从闪存读取)。对于擦除,延迟取决于页面大小;在 STM32F1xx 上,这个延迟可以高达 40 毫秒,在 F2 上是 800 毫秒!这使得实时系统中的片上闪存写入/擦除操作存在问题。

虽然闪存通常对写入/擦除操作施加限制,但 ST 的实现会施加其自身的附加限制,如上所述。您总是需要将您的非易失性存储器技术与应用程序相匹配,或者编写您的应用程序以使用可用的非易失性存储器。外部(片外)设备可能适合您的情况。大多数技术都以某种方式在速度、可用性、耐用性、密度和成本方面做出某种妥协,但您可以考虑使用外部闪存、EEPROM、FRAM 或电池支持的 SRAM。如果您的处理器缺少外部存储器接口,或者您负担不起使用地址总线访问设备所需的引脚数,则大多数可用技术是通过 SPI 或 I2C 进行串行访问设备。

另请注意,STM32F1xx 闪存实现的详细信息在通用用户手册的单独文档中进行了描述。参考PM0075 Programming manual - STM32F10xxx Flash memory microcontrollers

为了公平起见,限制性的 STM32 闪存实现并非完全随意。毫无疑问,与“完整”实现相比,该实现需要更少的裸片空间,从而为更多外围设备、更大的内存或更小的裸片尺寸提供空间(以降低成本)。芯片设计涉及许多妥协,ST 似乎选择为大型外设集妥协闪存灵活性。

【讨论】:

  • 请注意,ST 提供代码来模拟闪存中的 EEPROM 行为。它使用滚动内存方法,将写入分布在可擦除扇区中。这种方法减轻了上面没有直接提到的另一个限制:擦除/编程周期的数量被限制在大约 10k(请参阅参考手册),之后闪存被损坏的风险越来越大。 STM32F103 的示例代码可以在这里找到:github.com/STMicroelectronics/STM32CubeF1/blob/…
  • @gg99 : EEPROM 仿真仅适用于 STM32 设备的子集(闪存页小且大小相同的设备。但它确实适用于本问题中的 STM32F1xx。(请参阅AN2594)对于其他一些 STM32 部件,另请参阅AN4894
猜你喜欢
  • 2021-05-26
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多