一个关于STM32 在线升级的神秘事件
时间:12-13
整理:3721RD
点击:
本周工作遇到的问题分享给大家
http://blog.sina.com.cn/s/blog_16d87300e0102xsno.html
同事小伙伴遇到的问题,他在做stm在线升级,即程序Bootloader+App模式
非常诡异的是,如果从正常电源口给产品供电,那么只能在线升级一次,第一次升级完后​,跳APP运行正常,再次跳回Bootloader也正常,但是再刷Flash则必定会程序跑飞;但是如果用Jlink插着给STM32供电,但是JLINK的USB口哪怕插在充电器上,都可无限次刷新App部分code
小伙伴困扰了6个小时,最终锁定在供电电压上,因为直接供电的电压比仿真器口供电电压高0.02V,仅此差异而已,而且该现象复现在所有板子上,无一例外​
此时已经是晚上9点,6小时前小伙伴求助与我我正在忙,无暇顾及,临下班发现他任然被该问题困扰,于是和他一起分析
他的0.02V电压影响推断我并不赞同,我说如果电压会如此影响一颗数字芯片的这样普通的功能,那这个芯片就别卖了​
​首先我了解到,APP回跳到Bootloader,不是通过复位的方式来实现的,而是通过汇编语句之类的软件方法来实现的,于是我在猜测,两种供电方式的差异是不是因为插入JLINK后Jlink由于某种触发实现了Reset,但是被告知如果两种供电方式同时供着,即既有供电口正常又有Jlink供电,仍然表现出不正常,于此同时,我们做了实验,只是在Jtag口供3.3V不接其他信号也可以正常无限次烧写升级,故可分析出这个现象本身和Jlink里的信号并无关系,只是说如果只有JTAG口供电,则可以正常烧写
进一步分析,JTAG口供电,只给板上STM32供电,而产品标准供电口供电,则会给板上所有芯片供电,怀疑到这里后,首先尝试断掉DSP供电​,一试,果然可以无限烧录了,再次尝试,给DSP供电,但是用仿真器拉住DSP不让DSP Run,再试,仍然成功,到此,已经比较明了了,肯定是DSP吃了太多的点导致STM32供电不足(呵呵呵呵小伙伴真的就说这么想的)
我严肃的告诉小伙伴,这就是因为你不按照我的要求,APP跳Bootloader不应该用跳转代码而应该用复位造成的!不信听我娓娓道来:
第一次进到Bootloader时,所有工作用到的外设(CAN,UART等等)都没有初始化,所以这个时候烧录APP是没有问题的;然后跳转到APP正常工作,外设初始化后开始接受数据,也可以进入中断,此时,上位机发命令要求跳回bootloader,但是所有外设寄存器任然保留着正常工作时的值,而且中断向量任然存在,此时bootloader已经无法正常工作了,因为一旦收到中断,程序就会跑飞,而DSP此时的的确确就说在和STM32通讯,所以这就是为什么回跳bootloader后无法正常烧写的原因!
分析至此,我进一步告诉小伙伴,不要去打补丁在bootloader里初始化掉用到的通讯口,老老实实的按照我推荐的方法,app收到烧录命令后置一个flag在BatterayRam里然后产生复位,让芯片硬件自己把所有的外设初始化掉​,这样是可以兼容以后的各种外设使用的!问题得以完美解决!
http://blog.sina.com.cn/s/blog_16d87300e0102xsno.html
同事小伙伴遇到的问题,他在做stm在线升级,即程序Bootloader+App模式
非常诡异的是,如果从正常电源口给产品供电,那么只能在线升级一次,第一次升级完后​,跳APP运行正常,再次跳回Bootloader也正常,但是再刷Flash则必定会程序跑飞;但是如果用Jlink插着给STM32供电,但是JLINK的USB口哪怕插在充电器上,都可无限次刷新App部分code
小伙伴困扰了6个小时,最终锁定在供电电压上,因为直接供电的电压比仿真器口供电电压高0.02V,仅此差异而已,而且该现象复现在所有板子上,无一例外​
此时已经是晚上9点,6小时前小伙伴求助与我我正在忙,无暇顾及,临下班发现他任然被该问题困扰,于是和他一起分析
他的0.02V电压影响推断我并不赞同,我说如果电压会如此影响一颗数字芯片的这样普通的功能,那这个芯片就别卖了​
​首先我了解到,APP回跳到Bootloader,不是通过复位的方式来实现的,而是通过汇编语句之类的软件方法来实现的,于是我在猜测,两种供电方式的差异是不是因为插入JLINK后Jlink由于某种触发实现了Reset,但是被告知如果两种供电方式同时供着,即既有供电口正常又有Jlink供电,仍然表现出不正常,于此同时,我们做了实验,只是在Jtag口供3.3V不接其他信号也可以正常无限次烧写升级,故可分析出这个现象本身和Jlink里的信号并无关系,只是说如果只有JTAG口供电,则可以正常烧写
进一步分析,JTAG口供电,只给板上STM32供电,而产品标准供电口供电,则会给板上所有芯片供电,怀疑到这里后,首先尝试断掉DSP供电​,一试,果然可以无限烧录了,再次尝试,给DSP供电,但是用仿真器拉住DSP不让DSP Run,再试,仍然成功,到此,已经比较明了了,肯定是DSP吃了太多的点导致STM32供电不足(呵呵呵呵小伙伴真的就说这么想的)
我严肃的告诉小伙伴,这就是因为你不按照我的要求,APP跳Bootloader不应该用跳转代码而应该用复位造成的!不信听我娓娓道来:
第一次进到Bootloader时,所有工作用到的外设(CAN,UART等等)都没有初始化,所以这个时候烧录APP是没有问题的;然后跳转到APP正常工作,外设初始化后开始接受数据,也可以进入中断,此时,上位机发命令要求跳回bootloader,但是所有外设寄存器任然保留着正常工作时的值,而且中断向量任然存在,此时bootloader已经无法正常工作了,因为一旦收到中断,程序就会跑飞,而DSP此时的的确确就说在和STM32通讯,所以这就是为什么回跳bootloader后无法正常烧写的原因!
分析至此,我进一步告诉小伙伴,不要去打补丁在bootloader里初始化掉用到的通讯口,老老实实的按照我推荐的方法,app收到烧录命令后置一个flag在BatterayRam里然后产生复位,让芯片硬件自己把所有的外设初始化掉​,这样是可以兼容以后的各种外设使用的!问题得以完美解决!
我猜所有硬件工程师都问过这个问题:仿真的时候好好的怎么现在不行了。