(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_3VOLTAGE_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

所以我想:

但是,这一行给我一个错误(解锁闪光灯后)

    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)
        {
        }
    }

我的问题:

这看起来像是数据对齐错误,但不是参考手册中提到的与128位闪存行相关的错误。那个可能只与双字写入有关,与你的情况无关。

如果你想一次编程 4 个字节,你的 address 需要字对齐,这意味着它需要被 4 整除。此外,address 不是 uint32_t*(指针),它是一个原始的 uint32_t,所以 address++ 将它递增 1,而不是 4。据我所知,Cortex M4 内核将总线上的未对齐访问转换为多个更小的对齐访问自动,但这违反了 flash 并行规则。

顺便说一句,执行字节、半字和字的混合写入是完全有效的,只要它们正确对齐即可。此外,与 F0、F1 和 F3 系列的闪存硬件不同,您可以尝试覆盖以前写入的位置而不会导致错误。 0->1 位变化被忽略。