打印
[应用相关]

STM32F4单片机bootloader及在线升级IAP基本原理

[复制链接]
手机看帖
扫描二维码
随时随地手机跟帖
61

使用特权

评论回复
62
发给她更好fh|  楼主 | 2023-9-30 23:59 | 只看该作者
偏移设置原位置在启动文件中对应的系统初始化void SystemInit(void)中,因此在每一份程序的main函数要要增加一行代码设置向量表偏移,如下所示在flash基地址0x0800 0000 基础上偏移0x20000:

使用特权

评论回复
63
发给她更好fh|  楼主 | 2023-9-30 23:59 | 只看该作者
SCB->VTOR = FLASH_BASE | Flag_Table.ull_vetofflen; /* Vector Table Relocation in

使用特权

评论回复
64
发给她更好fh|  楼主 | 2023-9-30 23:59 | 只看该作者
示例如下:
int main(void)
{
        ReadFlagTable(&Flag_Table);//将标志位的表读       
        SCB->VTOR = FLASH_BASE | Flag_Table.ull_vetofflen; /* Vector Table Relocation in Internal FLASH */               
        Sysint();//系统初始化
        while(1)
        {
        }

使用特权

评论回复
65
发给她更好fh|  楼主 | 2023-9-30 23:59 | 只看该作者
APP中升级方案如下:

使用特权

评论回复
66
发给她更好fh|  楼主 | 2023-9-30 23:59 | 只看该作者

使用特权

评论回复
67
发给她更好fh|  楼主 | 2023-9-30 23:59 | 只看该作者
前半部分为正常逻辑流程,后半部分为升级流程,当单片机收到升级指令后,将升级文件写到另外一个APP区,最后根据发送的校验信息完成最终flag标志位的写入然后进行复位操作。

使用特权

评论回复
68
发给她更好fh|  楼主 | 2023-10-1 00:00 | 只看该作者
测试代码如下:
单片机中将bin形式的升级文件接收到数组auch_UartRxBuf[]中,接收完成将标志位uch_updateflag置位,主循环中判断成功后,将数组auch_UartRxBuf[]写入另外一个APP对应的flash区域内。写入成功后将运行标志ull_updaterun_flag以及偏移长度ull_vetofflen写入flag分区中。然后关中断重启即可。
————————————————
版权声明:本文为CSDN博主「蜗牛Jay」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43058521/article/details/125355343

使用特权

评论回复
69
发给她更好fh|  楼主 | 2023-10-1 00:00 | 只看该作者
int main(void)
{       
        ReadFlagTable(&Flag_Table);//将标志位的表读       
        SCB->VTOR = FLASH_BASE | Flag_Table.ull_vetofflen; /* Vector Table Relocation in Internal FLASH */               
        Sysint();//系统初始化
        for(int i=0;i<5;i++)
        {
                delay_ms(500);
                GPIO_ToggleBits(GPIOF, GPIO_Pin_9);       
        }               
        while(1)
        {
                delay_ms(1000);       
                GPIO_ToggleBits(GPIOF, GPIO_Pin_9);                               
                if(uch_updateflag==1)
                {
                        uch_updateflag=0;                       
                        if(Flag_Table.ull_updaterun_flag==0x00000011)
                        {
                                ull_vetselect = 0x40000;//更换BIN文件中的偏移                               
                                if(WriteAppBinToFlash2(STM32_FLASH_APP2_BASE,auch_UartRxBuf,uch_updataLen))
                                {
                                        Flag_Table.ull_updaterun_flag=0x00000022;
                                        Flag_Table.ull_vetofflen = 0x40000;
                                        WriteFlagTable(&Flag_Table);//将标志位的表写入       
                                        INTX_DISABLE();//close interupt
                                        NVIC_SystemReset();//重启                                                               
                                }       
                        }
                        else if(Flag_Table.ull_updaterun_flag==0x00000022)
                        {
                                ull_vetselect = 0x20000;//更换BIN文件中的偏移
                                if(WriteAppBinToFlash2(STM32_FLASH_APP1_BASE,auch_UartRxBuf,uch_updataLen))
                                {               
                                        Flag_Table.ull_updaterun_flag=0x00000011;
                                        Flag_Table.ull_vetofflen = 0x20000;                                       
                                        WriteFlagTable(&Flag_Table);//将标志位的表写入       
                                        INTX_DISABLE();//close interupt                                       
                                        NVIC_SystemReset();//重启                                                                       
                                }       
       
                        }
                }
}

使用特权

评论回复
70
发给她更好fh|  楼主 | 2023-10-1 00:00 | 只看该作者
因为不同烧写地址偏移对应的bin文件不同(最大不同是向量表地址都是固定的),所以在升级文件写入flash时要更改源码文件。
更改程序烧写首地址如图所示。

使用特权

评论回复
71
发给她更好fh|  楼主 | 2023-10-1 00:00 | 只看该作者

使用特权

评论回复
72
发给她更好fh|  楼主 | 2023-10-1 00:00 | 只看该作者
相同源码更改烧写地址后bin文件的不同。

使用特权

评论回复
73
发给她更好fh|  楼主 | 2023-10-1 00:00 | 只看该作者
通过对比发现固定不同的是偏移,图中左边偏移为0x40000右边为0x20000,如果想要将不同的bin文件从APP1移动到APP2所在的flash区域,只需要将bin文件中的偏移更改掉即可。更改方式如下:

使用特权

评论回复
74
发给她更好fh|  楼主 | 2023-10-1 00:00 | 只看该作者
//将升级代码写入临时存储区 
u32 WriteAppBinToFlash2(u32 appxaddr,u8 *appbuf,u32 appsize)
{
        u32 t;
        u32 iapbuf[UpdatePacketMaxLen/4];//缓存
        u16 i=0;
        u32 temp;
        u32 fwaddr=appxaddr;//当前写入的地址
        u8 *dfu=appbuf;
        memset(&iapbuf,0xff,sizeof(iapbuf));
        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个字节
                if((((temp)&0xFFFF0000)==(FLASH_BASE | Flag_Table.ull_vetofflen))&&(((temp)&0x0000FFFF)!=0X00000000))
                {
                        temp = ((temp)&0x0000FFFF)|(FLASH_BASE|ull_vetselect);               
                }
                iapbuf[i++]=temp;            
                if(i==UpdatePacketMaxLen/4)
                {
                        i=0;
                        if(STMFLASH_Write(fwaddr,iapbuf,UpdatePacketMaxLen/4))
                          fwaddr+=UpdatePacketMaxLen;//偏移  UpdatePacketMaxLen=N*4
                        else
                                return FALSE;
                }
        }
        if(i)
        {
                if(!STMFLASH_Write(fwaddr,iapbuf,i))//将最后的一些内容字节写进去.
                        return FALSE;
        }
  return fwaddr;
}

使用特权

评论回复
75
Henryko| | 2023-10-10 13:21 | 只看该作者
bootloader该怎么自己写啊

使用特权

评论回复
76
AloneKaven| | 2023-10-10 17:34 | 只看该作者
地址映射是怎么实现的啊

使用特权

评论回复
77
Stahan| | 2023-10-11 20:38 | 只看该作者
main地址放在哪里合适啊

使用特权

评论回复
78
发给她更好fh|  楼主 | 2024-1-31 20:30 | 只看该作者
在读取每个4字节数据时判断偏移量是否为当前APP区域的偏移,等于就改写偏移。

                if((((temp)&0xFFFF0000)==(FLASH_BASE | Flag_Table.ull_vetofflen))&&(((temp)&0x0000FFFF)!=0X00000000))
                {
                        temp = ((temp)&0x0000FFFF)|(FLASH_BASE|ull_vetselect);               
                }

使用特权

评论回复
79
发给她更好fh|  楼主 | 2024-1-31 20:30 | 只看该作者
最后补充一下boot表以及bin文件生成的知识点。
bin文件的生成需要设置一下

使用特权

评论回复
80
发给她更好fh|  楼主 | 2024-1-31 20:31 | 只看该作者
红色圈中文件需要对应你们工程目录中的.axf文件。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则