代码之家  ›  专栏  ›  技术社区  ›  bas

(STM32)擦除闪存并写入闪存会产生HAL_flash_ERROR_PGP错误(使用HAL)

  •  0
  • bas  · 技术社区  · 3 年前

    正在尝试写入闪存以存储某些配置。我正在使用 STM32F446ze 其中我想使用最后一个16kb扇区作为存储。

    我指定了 VOLTAGE_RANGE_3 当我 已擦除 我的部门。 电压范围3 映射到:

    #define FLASH_VOLTAGE_RANGE_3        0x00000002U  /*!< Device operating range: 2.7V to 3.6V                */
    

    当我使用时,向flash写入时出错 FLASH_TYPEPROGRAM_WORD 。错误为 HAL_FLASH_ERROR_PGP 。阅读参考手册我读到这与使用错误的平行度/电压水平有关。

    从我可以阅读的参考手册

    enter image description here

    此外,在参考手册中,我可以阅读:

    编程错误

    不允许将数据编程到Flash 将跨越128位行边界的存储器。在这种情况下 不执行写入操作,并且程序对齐错误标志 (PGAERR)被设置在FLASH_SR寄存器中。写入访问类型(字节, 半单词、单词或双单词)必须对应于的类型 选择的并行度(x8、x16、x32或x64)。如果没有,写入操作 不执行,并且设置了程序并行性错误标志(PGPERR) 在FLASH_SR寄存器中

    所以我想:

    • 我擦除了电压范围3中的扇区
    • 这给了我2.7到3.6伏的规格
    • 这给了我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、字或双字?
    • 在上述情况下,我遗漏了什么/做错了什么。为什么我只能写字节,而我用擦除 电压范围3 ?
    0 回复  |  直到 3 年前
        1
  •  2
  •   Tagli    3 年前

    这看起来像是一个数据对齐错误,但是 与参考手册中提到的128位闪速存储器行有关。这可能只与双字写作有关,在你的情况下无关紧要。

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

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