OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4433|回复: 6

关于IAP写入Flash时擦除扇区的疑问

[复制链接]

7

主题

14

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2022-10-13
在线时间
9 小时
发表于 2023-5-8 15:13:10 | 显示全部楼层 |阅读模式
1金钱
看了很久这个原子哥写入Flash的代码:
里面的STMFLASH_Write如下:


假如要写入的Flash区域原本有数据(可能是以前的app代码),那么每一次进入STMFLASH_Write都会擦除一次整个扇区,那么第二次调用STMFLASH_Write的时候,第一次写进来的2K数据岂不是会被擦除掉?因为这两个2K数据都在同一个扇区。求告知是这样吗?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

7

主题

14

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2022-10-13
在线时间
9 小时
 楼主| 发表于 2023-5-8 15:14:41 | 显示全部楼层
卧槽图片掉了,直接补代码吧。
void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize)
{
        u32 t;
        u16 i=0;
        u32 temp;
        u32 fwaddr=appxaddr;//当前写入的地址
        u8 *dfu=appbuf;
        for(t=0;t<appsize;t+=4)
        {                                                  
                temp=(u32)dfu[3]<<24;   
                temp|=(u32)dfu[2]<<16;   
                temp|=(u32)dfu[1]<<8;
                temp|=(u32)dfu[0];          
                dfu+=4;//偏移4个字节
                iapbuf[i++]=temp;            
                if(i==512)
                {
                        i=0;
                        STMFLASH_Write(fwaddr,iapbuf,512);
                        fwaddr+=2048;//偏移2048  512*4=2048
                }
        }
        if(i)STMFLASH_Write(fwaddr,iapbuf,i);//将最后的一些内容字节写进去.  
}


void STMFLASH_Write(uint32_t WriteAddr,uint32_t *pBuffer,uint32_t NumToWrite)       
{
    FLASH_EraseInitTypeDef FlashEraseInit;
    HAL_StatusTypeDef FlashStatus=HAL_OK;
    uint32_t SectorError=0;
        uint32_t addrx=0;
        uint32_t endaddr=0;       
    if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return;        //非法地址
   
        HAL_FLASH_Unlock();             //解锁       
        addrx=WriteAddr;                                //写入的起始地址
        endaddr=WriteAddr+NumToWrite*4;        //写入的结束地址
   
    if(addrx<0X1FF00000)
    {
        while(addrx<endaddr)                //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
                {
                        if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区
                        {   
                                FlashEraseInit.Banks=FLASH_BANK_1;                                                //操作BANK1
                                FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;       //擦除类型,扇区擦除
                                FlashEraseInit.Sector=STMFLASH_GetFlashSector(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,FLASH_BANK_1);    //等待上次操作完成
        }
    }
    FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME,FLASH_BANK_1);       //等待上次操作完成
        if(FlashStatus==HAL_OK)
        {
                while(WriteAddr<endaddr)//写数据
                {
            if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD,WriteAddr,(uint64_t)pBuffer)!=HAL_OK)//写入数据
                        {
                                break;        //写入异常
                        }
                        WriteAddr+=32;
                        pBuffer+=8;
                }
        }
        HAL_FLASH_Lock();           //上锁
}
回复

使用道具 举报

11

主题

2140

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4837
金钱
4837
注册时间
2015-1-10
在线时间
606 小时
发表于 2023-5-9 13:37:10 | 显示全部楼层
可以根据实际的芯片类型直接擦除单扇区然后全写入,也可以先全擦除后再做不擦除的写入,原子哥只是给个思路,适用于单扇区2K的芯片,比如STM32F103ZET6
回复

使用道具 举报

7

主题

14

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2022-10-13
在线时间
9 小时
 楼主| 发表于 2023-5-9 14:26:16 | 显示全部楼层
阿侑kevin 发表于 2023-5-9 13:37
可以根据实际的芯片类型直接擦除单扇区然后全写入,也可以先全擦除后再做不擦除的写入,原子哥只是给个思路 ...

您好,我发上来的代码是h7的,它的扇区是128KB,而写入Flash的数组大小一次是2K,所以我才会对整个扇区擦除有疑问
回复

使用道具 举报

11

主题

2140

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4837
金钱
4837
注册时间
2015-1-10
在线时间
606 小时
发表于 2023-5-10 15:57:16 | 显示全部楼层
菜鸟9号 发表于 2023-5-9 14:26
您好,我发上来的代码是h7的,它的扇区是128KB,而写入Flash的数组大小一次是2K,所以我才会对整个扇区擦 ...

128K的建议全擦除后用地址偏移写入,写满后再全擦除
回复

使用道具 举报

5

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
358
金钱
358
注册时间
2018-9-29
在线时间
146 小时
发表于 2023-5-10 16:00:49 | 显示全部楼层
一样的问题 因为FLASH 写入的 被擦除了  总是失败
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13079
金钱
13079
注册时间
2012-11-26
在线时间
3809 小时
发表于 2023-5-10 16:12:18 | 显示全部楼层
不懂你意思  如果是同一次升级,你的地址会往后面偏移啊。如果不是同一次,擦除不是应该的吗
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-19 21:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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