(STM32) 擦除闪存和写入闪存给出 HAL_FLASH_ERROR_PGP 错误(使用 HAL)
(STM32) Erasing flash and writing to flash gives HAL_FLASH_ERROR_PGP error (using HAL)
正在尝试写入闪存以存储一些配置。我正在使用 STM32F446ze,我想将最后一个 16kb 扇区用作存储空间。
我在擦除我的扇区时指定了VOLTAGE_RANGE_3
。 VOLTAGE_RANGE_3
映射到:
#define FLASH_VOLTAGE_RANGE_3 0x00000002U /*!< Device operating range: 2.7V to 3.6V */
我在使用 FLASH_TYPEPROGRAM_WORD
写入闪存时遇到错误。错误是 HAL_FLASH_ERROR_PGP
。阅读参考手册,我读到这与使用错误的 parallelism/voltage 级别有关。
从参考手册我可以读到
此外,在参考手册中我可以读到:
Programming errors
It is not allowed to program data to the Flash
memory that would cross the 128-bit row boundary. In such a case, the
write operation is not performed and a program alignment error flag
(PGAERR) is set in the FLASH_SR register. The write access type (byte,
half-word, word or double word) must correspond to the type of
parallelism chosen (x8, x16, x32 or x64). If not, the write operation
is not performed and a program parallelism error flag (PGPERR) is set
in the FLASH_SR register
所以我想:
- 我擦除电压范围3的扇区
- 这给了我 2.7 到 3.6v 规格
- 这给了我 x32 并行度大小
- 我应该可以将 WORD 写入闪存。
但是,这一行给我一个错误(解锁闪光灯后)
uint32_t sizeOfStorageType = ....; // Some uint I want to write to flash as test
HAL_StatusTypeDef flashStatus = HAL_FLASH_Program(TYPEPROGRAM_WORD, address++, (uint64_t) sizeOfStorageType);
auto err= HAL_FLASH_GetError(); // err == 4 == HAL_FLASH_ERROR_PGP: FLASH Programming Parallelism error flag
while (flashStatus != HAL_OK)
{
}
但是当我开始写入字节时,一切正常。
uint8_t *arr = (uint8_t*) &sizeOfStorageType;
HAL_StatusTypeDef flashStatus;
for (uint8_t i=0; i<4; i++)
{
flashStatus = HAL_FLASH_Program(TYPEPROGRAM_BYTE, address++, (uint64_t) *(arr+i));
while (flashStatus != HAL_OK)
{
}
}
我的问题:
- 擦除一个扇区后,我只能写入一个
TYPEPROGRAM
,我理解的对吗?因此,擦除后我只能写字节,OR,半字,OR,字,OR双字?
- 在上述情况下我错过了什么/做错了什么。为什么我只能写字节,而我用
VOLTAGE_RANGE_3
擦除?
这看起来像是数据对齐错误,但不是参考手册中提到的与128位闪存行相关的错误。那个可能只与双字写入有关,与你的情况无关。
如果你想一次编程 4 个字节,你的 address
需要字对齐,这意味着它需要被 4 整除。此外,address
不是 uint32_t*
(指针),它是一个原始的 uint32_t
,所以 address++
将它递增 1,而不是 4。据我所知,Cortex M4 内核将总线上的未对齐访问转换为多个更小的对齐访问自动,但这违反了 flash 并行规则。
顺便说一句,执行字节、半字和字的混合写入是完全有效的,只要它们正确对齐即可。此外,与 F0、F1 和 F3 系列的闪存硬件不同,您可以尝试覆盖以前写入的位置而不会导致错误。 0->1 位变化被忽略。
正在尝试写入闪存以存储一些配置。我正在使用 STM32F446ze,我想将最后一个 16kb 扇区用作存储空间。
我在擦除我的扇区时指定了VOLTAGE_RANGE_3
。 VOLTAGE_RANGE_3
映射到:
#define FLASH_VOLTAGE_RANGE_3 0x00000002U /*!< Device operating range: 2.7V to 3.6V */
我在使用 FLASH_TYPEPROGRAM_WORD
写入闪存时遇到错误。错误是 HAL_FLASH_ERROR_PGP
。阅读参考手册,我读到这与使用错误的 parallelism/voltage 级别有关。
从参考手册我可以读到
此外,在参考手册中我可以读到:
Programming errors
It is not allowed to program data to the Flash memory that would cross the 128-bit row boundary. In such a case, the write operation is not performed and a program alignment error flag (PGAERR) is set in the FLASH_SR register. The write access type (byte, half-word, word or double word) must correspond to the type of parallelism chosen (x8, x16, x32 or x64). If not, the write operation is not performed and a program parallelism error flag (PGPERR) is set in the FLASH_SR register
所以我想:
- 我擦除电压范围3的扇区
- 这给了我 2.7 到 3.6v 规格
- 这给了我 x32 并行度大小
- 我应该可以将 WORD 写入闪存。
但是,这一行给我一个错误(解锁闪光灯后)
uint32_t sizeOfStorageType = ....; // Some uint I want to write to flash as test
HAL_StatusTypeDef flashStatus = HAL_FLASH_Program(TYPEPROGRAM_WORD, address++, (uint64_t) sizeOfStorageType);
auto err= HAL_FLASH_GetError(); // err == 4 == HAL_FLASH_ERROR_PGP: FLASH Programming Parallelism error flag
while (flashStatus != HAL_OK)
{
}
但是当我开始写入字节时,一切正常。
uint8_t *arr = (uint8_t*) &sizeOfStorageType;
HAL_StatusTypeDef flashStatus;
for (uint8_t i=0; i<4; i++)
{
flashStatus = HAL_FLASH_Program(TYPEPROGRAM_BYTE, address++, (uint64_t) *(arr+i));
while (flashStatus != HAL_OK)
{
}
}
我的问题:
- 擦除一个扇区后,我只能写入一个
TYPEPROGRAM
,我理解的对吗?因此,擦除后我只能写字节,OR,半字,OR,字,OR双字? - 在上述情况下我错过了什么/做错了什么。为什么我只能写字节,而我用
VOLTAGE_RANGE_3
擦除?
这看起来像是数据对齐错误,但不是参考手册中提到的与128位闪存行相关的错误。那个可能只与双字写入有关,与你的情况无关。
如果你想一次编程 4 个字节,你的 address
需要字对齐,这意味着它需要被 4 整除。此外,address
不是 uint32_t*
(指针),它是一个原始的 uint32_t
,所以 address++
将它递增 1,而不是 4。据我所知,Cortex M4 内核将总线上的未对齐访问转换为多个更小的对齐访问自动,但这违反了 flash 并行规则。
顺便说一句,执行字节、半字和字的混合写入是完全有效的,只要它们正确对齐即可。此外,与 F0、F1 和 F3 系列的闪存硬件不同,您可以尝试覆盖以前写入的位置而不会导致错误。 0->1 位变化被忽略。