在STM32的OTP中写入64位数据

时间:2017-06-14 07:52:59

标签: embedded stm32 cpu-registers flash-memory

我正在尝试在STM32L4芯片的内存闪存中写入数据。这是在编程上下文中完成的,我在其中使用对ST-Link实用程序命令行的C调用

所以这是一个闪存的例子:

               0             4             8             C
0x1FFF7000  FFFFFFFF     FFFFFFFF       FFFFFFFF       FFFFFFFF

到目前为止,我只能在 64位数据空间上写 32bits

               0             4             8             C
0x1FFF7000  AAAAAAAF     FFFFFFFF       BBBCCCDD       FFFFFFFF

在前32位写入时,第二个32位被锁定。因此,如果内存处于先前状态,则不允许进行以下写入:

               0             4             8             C
0x1FFF7000  AAAAAAAF     00000001       BBBCCCDD       FFFFFFFF
                            ^^                            ^^
                         Not allowed                     Locked

我只能在64位数据空间中写入大小受32位限制的数据。 我发现这非常特殊,因为没有理由以这种方式处理内存。

编辑:这是真的,因为我想写一个OTP,当我在其他地方写的时候似乎正常工作

第一种可能的解决方案

我前一个问题answer引用了这个:

  

第2级:无需调试
  在此级别中,保证级别1得到保证。   此外,还有Cortex®-M4调试端口,从RAM启动(启动RAM   模式)和从系统内存(引导加载程序模式)启动不再   可用。在用户执行模式(boot FLASH mode)中,进行所有操作   允许在Flash主内存上。 ...
  2级根本无法删除:这是不可逆转的操作。

有没有办法让 2级允许我在64位内存空间上写两次32位?

第二种可能的解决方案

查看芯片的documentation,我找到了闪存编程序列(第102页):

  
      
  1. 通过检查闪存状态寄存器(FLASH_SR)中的BSY位,检查是否正在进行闪存主存储器操作。
  2.   
  3. 检查并清除由于之前的编程而导致的所有错误编程标记。如果没有,则设置PGSERR。
  4.   
  5. 设置Flash控制寄存器(FLASH_CR)中的PG位。
  6.   
  7. 在所需的存储器地址,主存储器块或OTP区域内执行数据写操作。只有双字可以   程序。 - 在与double对齐的地址中写入第一个单词   单词 - 写下第二个单词
  8.   
  9. 等到FLASH_SR寄存器中的BSY位清零。
  10.   
  11. 检查FLASH_SR寄存器中是否设置了EOP标志(表示编程操作已成功),并通过软件将其清除。
  12.   
  13. 如果不再有编程请求,则清除FLASH_SR寄存器中的PG位。
  14.   

我无法理解步骤 3中的 PG位是什么。但是当我尝试设置它时,不允许写入。

我使用ST-Link Utility进行写入,使用命令-w32,根据手册,我应该允许我在寄存器上写入。

  

-w32支持写入闪存,OTP,SRAM和R / W寄存器

此外,步骤 4。似乎描述了我正在反对的确切问题,但我无法理解它提出的解决方案。

关于如何用任何解决方案解决问题的任何暗示都将是一种祝福。此外,由于我对嵌入式低级词汇不是很熟悉,所以请不要犹豫,编辑我的问题以使其更清晰。

1 个答案:

答案 0 :(得分:5)

您观察到此行为的原因如下(来自STM32L4x5 STM32L4x6 RM):

  

用户的1 KB(128双字)OTP(一次性可编程)字节   数据。 OTP区域仅在Bank 1中可用。 OTP数据不可能   擦除,只能写一次。如果只有一位为0,那么   即使有了价值,整个双字也不能再写了   0x0000 0000 0000 0000。

这意味着OTP区域被组织为64位值,并且对它的写入应该是" atomic",这意味着您一次写入所有64位。在64位中的任何一位设置0将锁定整个双字以进行进一步写入。在您的示例中,这意味着,如果您尝试使用-w8以8位批量写入值,则只能在给定的双字(64位)中写出8个中的第一个字节。

反过来,这意味着即使ST-Link实用程序手册指出-w32允许编程OTP区域,它也只意味着可以将OTP指定为要写入的目标地址,而不一定是你将能够正确编程每个双字的所有位。这看起来像是一种疏忽,尽管你无能为力。

我个人会尝试使用-P命令对其进行编程:

Description: Loads binary, Intel Hex or Motorola S-record file into device memory without
verification. For hex and srec format, the address is relevant.
Syntax: -P <File_Path> [<Address>]
Examples: -P C:\file.srec
-P C:\file.bin 0x08002000
-P C:\file.hex

我自己还没有对它进行测试,但目前对我来说,这似乎是唯一可能允许你以原子方式进行测试的可能性。通过ST-Link将64位值编程到OTP中。