硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4965|回复: 2
收起左侧

[Flash] STM32H750连续编程FALSH失败问题,花了半天时间才找到HAL库函数的BUG

[复制链接]

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
发表于 2019-10-4 01:41:14 | 显示全部楼层 |阅读模式
调试H7-TOOL产品的BOOT固件升级程序,大数据连续编程flash时会出现编程失败问题,扇区中只有部分数据会成功写入。
写入失败的现象是:硬件报错 PGSERR1或PGSERR2
PGSERR1存储区 1 编程顺序错误标志
PGSERR12存储区2 编程顺序错误标志



ST固件库中的范例是可以正常运行的,它太简单了,擦除128K扇区,写入32字节数据。只有连续写入8K以上数据才会出问题。
STMH750只有128KB容量,但是强行按H743编程算法使用2MB空间一直未发现运行问题。出现些flash问题后以为芯片问题,毕竟128KB以外的区域是不保证OK的。
但是编程器仿真下载程序正常,只是代码中执行编程会失败。尝试过增加连续编程语句之间的延迟,无法解决。后跟踪库函数代码,添加1条DSB执行解决问题。


库文件:stm32h7xx_hal_flash.c 问题函数:HAL_FLASH_Program
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint64_t Data)
{
    ... 省略
    __DSB(); /* 2019-10-04 armfly : 数据同步指令,等待上面指令执行完毕才执行下面的指令,否则大批量连续编程会失败 */

    /* Program the 256 bits flash word */
    do
    {
       *dest_addr++ = *src_addr++;
    } while (--row_index != 0);
    __DSB();
   ... 省略
}

添加红色代码行解决问题。

测试代码如下:
   #if 1   /* 测试写flash */
    {
        uint32_t addr = 0x08100000;
        uint16_t i;
        uint16_t j;
        uint8_t buf0[1024];
        uint8_t buf1[1024];
        uint8_t err = 0;
        
        for (i = 0; i < 1024; i++)
        {
            buf0 = i;
        }
        
        addr = 0x08100000;
        err = 0;
        for (i = 0; i < 8; i++)
        {
            if (bsp_EraseCpuFlash(addr + i * 128 * 1024) != 0)
            {
                err = 1;
                break;
            }
            
            for (j = 0; j < 128; j++)
            {
                if (bsp_WriteCpuFlash(addr + j * 1024, buf0, 1024) != 0)
                {
                    err = 2;
                    break;
                }
            }
            
            for (j = 0; j < 128; j++)
            {
                memcpy(buf1, (uint8_t *)(addr + j * 1024), 1024);
               
                if (memcmp(buf0, buf1, 1024) != 0)
                {
                    err = 3;
                    break;
                }
            }           
            
            if (err != 0)
            {
                break;
            }
        }
        
        while(1);
    }
    #endif

评分

参与人数 1金币 +6 收起 理由
龙之谷 + 6 赞一个!

查看全部评分

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107046
QQ
发表于 2019-10-4 10:52:49 | 显示全部楼层
那看来是1.3版本HAL库的bug,在新的1.5版本里面修了个这个地方,不过函数变化也很大

HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
{
  HAL_StatusTypeDef status;
  __IO uint32_t *dest_addr = (__IO uint32_t *)FlashAddress;
  __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
  uint32_t bank;
  uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;


  /* Check the parameters */
  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
  assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));


  /* Process Locked */
  __HAL_LOCK(&pFlash);


  if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
  {
    bank = FLASH_BANK_1;
  }
  else
  {
    bank = FLASH_BANK_2;
  }


  /* Reset error code */
  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;


  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);


  if(status == HAL_OK)
  {
    if(bank == FLASH_BANK_1)
    {
      /* Set PG bit */
      SET_BIT(FLASH->CR1, FLASH_CR_PG);
    }
    else
    {
      /* Set PG bit */
      SET_BIT(FLASH->CR2, FLASH_CR_PG);
    }


    __ISB();
    __DSB();


    /* Program the 256 bits flash word */
    do
    {
      *dest_addr = *src_addr;
      dest_addr++;
      src_addr++;
      row_index--;
    } while (row_index != 0U);


    __ISB();
    __DSB();


    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);


    if(bank == FLASH_BANK_1)
    {
      /* If the program operation is completed, disable the PG */
      CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
    }
    else
    {
      /* If the program operation is completed, disable the PG */
      CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
    }
  }


  /* Process Unlocked */
  __HAL_UNLOCK(&pFlash);


  return status;
}

回复

使用道具 举报

2

主题

569

回帖

575

积分

金牌会员

积分
575
发表于 2019-10-4 20:48:50 | 显示全部楼层
深刻…
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-15 12:57 , Processed in 0.261414 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表