我正在尝试在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页):
- 通过检查闪存状态寄存器(FLASH_SR)中的BSY位,检查是否正在进行闪存主存储器操作。
- 检查并清除由于之前的编程而导致的所有错误编程标记。如果没有,则设置PGSERR。
- 设置Flash控制寄存器(FLASH_CR)中的PG位。
- 在所需的存储器地址,主存储器块或OTP区域内执行数据写操作。只有双字可以 程序。 - 在与double对齐的地址中写入第一个单词 单词 - 写下第二个单词
- 等到FLASH_SR寄存器中的BSY位清零。
- 检查FLASH_SR寄存器中是否设置了EOP标志(表示编程操作已成功),并通过软件将其清除。
- 如果不再有编程请求,则清除FLASH_SR寄存器中的PG位。
醇>
我无法理解步骤 3中的 PG位是什么。但是当我尝试设置它时,不允许写入。
我使用ST-Link Utility进行写入,使用命令-w32
,根据手册,我应该允许我在寄存器上写入。
-w32支持写入闪存,OTP,SRAM和R / W寄存器
此外,步骤 4。似乎描述了我正在反对的确切问题,但我无法理解它提出的解决方案。
关于如何用任何解决方案解决问题的任何暗示都将是一种祝福。此外,由于我对嵌入式低级词汇不是很熟悉,所以请不要犹豫,编辑我的问题以使其更清晰。
答案 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中。