打印

GD32 IAP固件升级跳转 (Bootloader --> APP)踩坑解答

[复制链接]
1129|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
GD32升级进入HardFaultHandler()原因分析
大家好!随着全球芯片紧缺,许多企业纷纷选择了国产芯片。今天我就GD32(兆易创新)MCU的固件升级所遇到的问题给大家说说我的看法。相信使用GD芯片的工程师,都看过GD给出的Demo例程,关于IAP的,有一个BOOT(LED慢闪),按下按键跳转至APP(LED快闪)的例程。 这里看似没啥问题,大家注意其中有2个坑

第一个坑
BOOT程序(或者叫IAP程序) 和 APP FLASH划分

BOOT通常来说比较小 最多也就10K多,大家看看我的配置

BOOT程序起始地址:0x8000000
SIZE我分配了0x2000 ,也就是8k字节 , BOOT程序编译下来需要比8k小

app程序起始地址:0x8010000

SIZE我分配了0x80000(最大) , 实际上APP程序不会有这么大,没关系就写这个。
————————————————
版权声明:本文为CSDN博主「黑牛程序员」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39502111/article/details/124256629

使用特权

评论回复
沙发
泡椒风爪|  楼主 | 2023-1-29 17:25 | 只看该作者
JumpAddress = *( __IO uint32_t* )( ApplicationAddress + 4 );            //用户代码区第二个字存储为新程序起始地址(新程序复位向量指针)
Jump_To_Application = ( pFunction ) JumpAddress;
__set_MSP( *( __IO uint32_t* ) ApplicationAddress );                    //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)


Jump_To_Application();                                                  //设置PC指针为新程序复位中断函数的地址
这一步都没啥问题,把跳转地址填对(就是APP程序的起始地址)
第二个坑
跳转问题:
1.BOOT跳转至APP时,调用这个代码即可
__disable_irq(); // 可以使用这个函数 关闭总中断


2.APP跳转至BOOT
这里问题就大了,用BOOT的方法,将地址替换成BOOT的起始地址0x8000000,你会发现,也可以成功,但是,再从BOOT跳转至APP的时候 就有问题了, 进入APP程序后,初始化外设时,会进入HardFaultHandler();硬件错误中断函数,一直停留在while(1); 这是为啥???、

使用特权

评论回复
板凳
泡椒风爪|  楼主 | 2023-1-29 17:27 | 只看该作者
2.APP跳转至BOOT
这里问题就大了,用BOOT的方法,将地址替换成BOOT的起始地址0x8000000,你会发现,也可以成功,但是,再从BOOT跳转至APP的时候 就有问题了, 进入APP程序后,初始化外设时,会进入HardFaultHandler();硬件错误中断函数,一直停留在while(1); 这是为啥???

使用特权

评论回复
地板
泡椒风爪|  楼主 | 2023-1-29 17:30 | 只看该作者
函数指针跳转 和 系统复位 的区别
大家看到没有,BOOT跳转至APP的方法是,使用函数指针,调用时,使得PC指针指向APP所在位置,但是这个方法用在 APP跳向BOOT的时候,却不严谨。

使用特权

评论回复
5
泡椒风爪|  楼主 | 2023-1-29 17:31 | 只看该作者
函数指针跳转
函数指针跳转,仅仅是将PC指针 指向 目标地址,MCU是有堆栈的呀,光跳转过去,不清除堆栈.有可能出现RAM溢出(你的APP程序占用RAM比较大就会出现这个情况), 进入HardFault硬件错误中断的情况之一:堆栈溢出。 就会出现 BOOT第一次跳转至APP,都正常 ,APP跳转BOOT之后 , 第二次再从BOOT使用函数指针跳转APP,进入 HardFault硬件错误中断 , 因为第一次从BOOT跳转APP时,BOOT并没有占用太多的RAM, 所以哪怕不清除堆栈, 依然够用, 那么第二次再跳转APP的时候,. 之前在APP时已经初始化太多变量和函数,消耗了太多的RAM,这时不清除堆栈,再次进入APP, MCU就会因为堆栈不够,发生溢出,导致进入了硬件错误中断。

使用特权

评论回复
6
泡椒风爪|  楼主 | 2023-1-29 17:31 | 只看该作者
系统复位
前面我已经说了跳转导致进入硬件错误中断的原因, 知道了原因问题就已经解决了一半,怎么解决? 我清除堆栈不就行了麻。 怎么清除? 大家麻烦去百度一下 这个函数 NVIC_SystemReset(); 看名字就知道,是系统复位函数, 是的,这个函数会将相关标志位清除,具体是哪一行我不知道,但是这个函数确实能清除堆栈,使用这个函数,实现 APP跳转至 BOOT, 就能够避免因为堆栈溢出,而导致进入硬件错误中断。 上源码

使用特权

评论回复
7
泡椒风爪|  楼主 | 2023-1-29 17:47 | 只看该作者
        __disable_irq();  // 可以使用这个函数 关闭总中断
        __set_FAULTMASK(1);        //关闭中断,确保跳转过程中 不会进入中断,导致跳转失败
        NVIC_SystemReset();          //系统复位,复位后默认从MCU的起始地址开始, 也就是BOOT的起始地址开始, 这样程序就从APP回到了BOOT,再从BOOT跳转至APP的时候, 堆栈已经清除了,也就不会发生溢出









        上面是我写给自己的, 避免以后再犯错, 在下能力有限 如有不对之处,恳请大佬指点,感激不尽!

使用特权

评论回复
8
caizhiwei| | 2023-3-22 13:11 | 只看该作者
很不错,我也是同样的程序,mdk能正常跳转,iar不能跳转,很奇怪。

使用特权

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

本版积分规则

39

主题

253

帖子

0

粉丝