硬汉嵌入式论坛

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

[STM32H7] STM32H723 读Flash进hardfault

[复制链接]

1

主题

2

回帖

5

积分

新手上路

积分
5
发表于 6 天前 | 显示全部楼层 |阅读模式
最近在做H723的bootloader,现在发现一个问题,就是将内部flash的内容copy 一段(备份区)到另外一段内部flash(运行区)的过程中,异常掉电,然后重新上电重新走copy过程。copy完之后会去校验运行区的Crc,校验Crc的过程中会去读运行区flash里的值,但是在读运行区flash的某一个位置的过程中会进hardfault,用memmory browser看那个位置的flash的值显示是“??”
Note:copy的过程是先擦除运行区的flaah,然后把备份区的flash的数据读到RAM中,然后在把ram里的值写入到运行区的flash
写入Flash 是参考论坛一位网友的 没有用官方的库函数[mw_shl_code=c,true]void stmflash_write(uint32_t waddr, uint32_t *pbuf, uint32_t length)


有没有大神能提供下思路,卡了好几天了

回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 6 天前 | 显示全部楼层
代码
[C] 纯文本查看 复制代码
void stmflash_write(uint32_t waddr, uint32_t *pbuf, uint32_t length)
{
    FLASH_EraseInitTypeDef FlashEraseInit;
    HAL_StatusTypeDef FlashStatus = HAL_OK;
    uint32_t SectorError = 0;
    uint32_t  addrx = 0;
    uint32_t  endaddr = 0;
    uint32_t bankFlag = 0;

    if (waddr < STM32_FLASH_BASE || waddr % 32 ||       /* 写入地址小于 STM32_FLASH_BASE, 或不是32的整数倍, 非法. */
        waddr > (STM32_FLASH_BASE + STM32_FLASH_SIZE))  /* 写入地址大于 STM32_FLASH_BASE + STM32_FLASH_SIZE, 非法. */
    {
        return;
    }

    HAL_FLASH_Unlock();                         /* 解锁 */
    addrx = waddr;                              /* 写入的起始地址 */
    endaddr = waddr + length * 4;               /* 写入的结束地址 */

	if(IS_FLASH_PROGRAM_ADDRESS_BANK1(addrx))
	{
		bankFlag = FLASH_BANK_1;
	}
//	else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(addrx))
//	{
//		bankFlag = FLASH_BANK_2;
//	}

    if (addrx < 0X1FF00000)
    {
        while (addrx < endaddr)                 /* 扫清一切障碍.(对非FFFFFFFF的地方,先擦除) */
        {
            if (stmflash_read_word(addrx) != 0XFFFFFFFF)                        /* 有非0XFFFFFFFF的地方,要擦除这个扇区 */
            {

            	FlashEraseInit.Banks = bankFlag;
                FlashEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;             /* 擦除类型,扇区擦除 */
                FlashEraseInit.Sector = FLASH_If_addr_to_setor(addrx);       /* 要擦除的扇区 */
                FlashEraseInit.NbSectors = 1;                                   /* 一次只擦除一个扇区 */
                FlashEraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3;            /* 电压范围,VCC=2.7~3.6V之间!! */
                if (HAL_FLASHEx_Erase(&FlashEraseInit, &SectorError) != HAL_OK)
                {
                    break;                      /* 发生错误了 */
                }

//                SCB_CleanInvalidateDCache();    /* 清除无效的D-Cache */
            }
            else
            {
               addrx += 4;
            }
            FLASH_WaitForLastOperation(FLASH_WAITETIME, bankFlag);          /* 等待上次操作完成 */
        }
    }

    FlashStatus = FLASH_WaitForLastOperation(FLASH_WAITETIME, bankFlag);    /* 等待上次操作完成 */

    if (FlashStatus == HAL_OK)
    {
        while (waddr < endaddr)                 /* 写数据 */
        {
            if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, waddr, (uint64_t)pbuf) != HAL_OK)    /* 写入数据 */
            {
                break;                          /* 写入异常 */
            }

            waddr += 32;
            pbuf += 8;
        }
    }
    HAL_FLASH_Lock();                           /* 上锁 */
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 6 天前 | 显示全部楼层
看下写入Flash后,Flash的ECC是不是触发错误了
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-12 00:04 , Processed in 0.042046 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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