OpenEdv-开源电子网

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

如何获取当前运行程序所在flash地址及AB升级问题?

[复制链接]

3

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2022-3-13
在线时间
52 小时
发表于 2022-3-25 18:04:02 | 显示全部楼层 |阅读模式
1金钱
将STM32F407内置flash分成三个区域:bootloader + firmware_A + firmware_B
系统复位后,先运行的bootloader根据配置选择跳转到不同的firmware。在firmware中,实现对另一块firmware flash区域的烧写从而完成固件的升级
参考探索者开发板的IAP实验及网上的一些资源,已经大致完成了STM32 AB升级的部分功能。


但仍有问题
1. 升级的firmware是一个工程编译出来的(都是firmware_A的IROM1 start/size配置),但bin会随机写到firmware_A或firmware_B区域。
   目前暂时的解决方法是从bootloader跳转到firmware后,firmware根据bootloader配置判断当前跳转区域为A还是B,
   再在firmware main函数一开头,调用NVIC_SetVectorTable(NVIC_VectTab_FLASH, APP_A_FLASH_ADDRESS_OFFSET)或NVIC_SetVectorTable(NVIC_VectTab_FLASH, APP_B_FLASH_ADDRESS_OFFSET)
   尝试通过根据当前PC寄存器判断当前程序是跑在A还是B上,但发现无论bootloader跳转到A还是B,获取的PC寄存器值都落在A区域。
                AREA    ASMGETPC_PROC, CODE, READONLY

ASMGETPC        PROC
                EXPORT  ASMGETPC
                IMPORT g_currentPC
                PUSH    {R0-R8, LR}

                LDR     R0, =g_currentPC;
                MOV     R1, PC
                STR     R1, [R0]            // 将PC值写入全局变量g_currentPC,但没有预期的结果,都落在A区

                POP     {R0-R8, PC}
                ENDP
                ALIGN
                END

   问题是,如何在firmware运行中得知当前firmware是跑在A区还是B区?

2. 按firmwareA的flash配置编译出来的固件升级,从A升级到B是没问题的,但从B升级到A却有问题
   在firmware_B中,erase firmware_A flash区域时,FLASH_GetStatus()函数会返回错误

      if((FLASH->SR & FLASH_FLAG_RDERR) != (uint32_t)0x00)
      {
        flashstatus = FLASH_ERROR_RD;           // 单步调试走到这里,出现了这个错误,但查手册STM32F407的FLASH_SR没有RDERR,但STM32F42xxx and STM32F43xxx则有RDERR
      }
    然后keil单步跳到了void HardFault_Handler(void),是个while(1)死循环,

    同时keil窗口中出现如下打印
Cannot access Memory (@ 0x08028c86, Read, Acc Size: 2 Byte)
Cannot access Memory (@ 0x08028c88, Read, Acc Size: 4 Byte)
Cannot access Memory
Cannot access Memory (@ 0x08028c8c, Read, Acc Size: 4 Byte)
Cannot access Memory (@ 0x08028c8e, Read, Acc Size: 2 Byte)
Cannot access Memory (@ 0x08028c8e, Read, Acc Size: 2 Byte)

    keil memory窗口中,firmware_A区的值在erase时,全部跳变成了0xFF,说明flash erase firmware_A区是成功的。


       但,同时Keil的汇编窗口中的地址全部变成了0xFF,感觉虽然bootloader跳转到了B,但当前系统仍然是跑在A
       是不是keil编译出的bin不是位置无关的?即编译出的bin必须烧写在keil配置的flash起始地址上?


我bootloader里跳转的代码是:
    void iap_load_app(u32 appxaddr)
    {
        if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.
        {
            jump2app=(iapfun)*(vu32*)(appxaddr+4);      //用户代码区第二个字为程序开始地址(复位地址)

            RCC_DeInit();
            __disable_irq();

            MSR_MSP(*(vu32*)appxaddr);                  //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
            jump2app();                                 //跳转到APP.
        }
    }

我firmware里main函数开头的代码是
    void setupVectorTable2()
    {
        ...
        if (bconfig.firmware_A_or_B == BOOTLOADER_FIRMWARE_A) {
            NVIC_SetVectorTable (NVIC_VectTab_FLASH, FIRMWARE_A_FLASH_START_ADDRESS - 0x08000000);
        } else {
            NVIC_SetVectorTable (NVIC_VectTab_FLASH, FIRMWARE_B_FLASH_START_ADDRESS - 0x08000000);
        }
    }

    int main(void)
    {
        delay_init(168);   //初始化延时函数
        AT24CXX_Init();         //IIC初始化
        setupVectorTable2();    //根据bootloader配置设置中断向量表

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        __enable_irq();

        uart_init(115200);  //初始化串口波特率为115200
        ...
    }




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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2022-3-26 00:40:18 | 显示全部楼层
keil编译的bin本身是位置无关,但是它里面的内容是位置有关的啊,比如你函数A,在编译的时候就指定了地址,你放区域A和区域B,那就完全不一样了。地址对不上了。
回复

使用道具 举报

6

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2019-2-12
在线时间
28 小时
发表于 2022-4-13 15:10:18 | 显示全部楼层
没弄过AB升级,原因是切换太麻烦,虽然是一个工程,但A和B的向量表地址不同,生成的bin文件也不同,越简单的越可靠,只有一个firmware做好数据完整性MD5校验就行。
回复

使用道具 举报

3

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2022-3-13
在线时间
52 小时
 楼主| 发表于 2022-4-27 17:27:34 | 显示全部楼层
谢谢关注,早已经换升级方案了。AB升级不适用于单片机,改成了bootloader + firmware + 片外flash暂存区的实现
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-25 21:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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