走在路上的时候,我想起了这个OTA的弊端,那我想有没有办法解决呢?其实是有的。
那就是我还是把app程序放在flash的最开始的位置,而把OTA的程序放到后面(flash的最后12k)去。
这样也带来新的弊端:(已经确认是可以在线调试和下载了。这个方法做其他参考吧)
1.是要小规模的修改单片机的应用程序,在串口增加一条命令,进入到下载模式。
2.如果升级失败,单片机将不能启动了,需要调试器的协助。这里倒是可以通过另外的方法解决。比如更新到备份区,升级的时候进行验证等。升级的时候断电就会比较致命。
3.OTA程序烧写不方便!!!好在这个程序基本不需要多次烧写,只要第一次烧写就好了。
这可能就需要大家权衡一下利弊了,一般来说,升级的时候是肯定不允许断电的。
本节的调整主要是方便应用程序的调试,和使用keil直接下载。同时也还是有串口升级的功能。
可能还是不太完善,后续再继续更新。
1.1 调试串口增加一条指令,我增加的是 y
1.2 对于y指令的跳转
1.3 goto_ota_program函数的实现
1.4 设置修改回去
1.5 main函数中设置中断向量偏移注释掉。
这里其实是链接地址,就是程序的实际运行的地址。见下图吧。
3.1 软件执行时,直接停在升级的程序部分
3.2 还有一些不需要使用设备需要关闭。
跳转后,出现单片机死机的问题,这里猜测gd32单片机触发了一些不必要的中断,所以要关闭不使用的设备。
这个地址是OTA升级应用的地址,需要注意的。
user选项卡
fromelf --bin -o ./output/@L.bin ./Objects/@L.axf
4.1 可以用ota(flash前端)升级ota(后端)的方法。
这个方法理论是可以的,但是我没有尝试,后面我发现可以用调试器,就没再纠结了。
4.2 能否借助调试器呢?
似乎是不行的,还想着用烧写软件STM32 ST-LINK Utility
但是我发现bin文件是可以的,呵呵
4.3 改单片机应用程序,让其增加升级OTA的功能。
这里可能需要增加的代码多,我暂时就不修改了!
当应用跳转到ota的时候,ota打印11个字符左右,单片机卡死
5.1.1 怀疑中断的问题
关闭所有外设和定时器,然后再跳转,故障依旧,现象相同
void gd32_disable_phy(void)
{SysTick->CTRL = 0; //关闭systickrcu_periph_clock_disable(RCU_GPIOA);rcu_periph_clock_disable(RCU_GPIOB);rcu_periph_clock_disable(RCU_GPIOC);rcu_periph_clock_disable(RCU_GPIOD);rcu_periph_clock_disable(RCU_GPIOE);rcu_periph_clock_disable(RCU_GPIOF);rcu_periph_clock_disable(RCU_GPIOG);rcu_periph_clock_disable(RCU_USART0);rcu_periph_clock_disable(RCU_USART1);rcu_periph_clock_disable(RCU_TIMER1);rcu_periph_clock_disable(RCU_TIMER0);rcu_periph_clock_disable(RCU_TIMER2);rcu_periph_clock_disable(RCU_TIMER3);rcu_periph_clock_disable(RCU_TIMER4);rcu_periph_clock_disable(RCU_TIMER5);rcu_periph_clock_disable(RCU_TIMER6);rcu_periph_clock_disable(RCU_TIMER7);}
5.1.2 加上 __disable_irq(); // 关闭总中断 就可以了
跳转之前关闭了所有的中断。(下图是单片机的应用程序!!!)
但是有一个问题,就是OTA下的systick也没有中断了。这个中断只是影响我led灯的闪烁,其他没有影响。
5.1.3 我又试了一下,我能关闭的所有中断,似乎只有关闭总中断才可以,难不成出了系统异常?
void gd32_disable_phy(void)
{
// SysTick->CTRL = 0; //关闭systick
// rcu_periph_clock_disable(RCU_GPIOA);
// rcu_periph_clock_disable(RCU_GPIOB);
// rcu_periph_clock_disable(RCU_GPIOC);
// rcu_periph_clock_disable(RCU_GPIOD);
// rcu_periph_clock_disable(RCU_GPIOE);
// rcu_periph_clock_disable(RCU_GPIOF);
// rcu_periph_clock_disable(RCU_GPIOG);
// rcu_periph_clock_disable(RCU_USART0);
// rcu_periph_clock_disable(RCU_USART1);
//
// rcu_periph_clock_disable(RCU_TIMER1);
// rcu_periph_clock_disable(RCU_TIMER0);
// rcu_periph_clock_disable(RCU_TIMER2);
// rcu_periph_clock_disable(RCU_TIMER3);
// rcu_periph_clock_disable(RCU_TIMER4);
// rcu_periph_clock_disable(RCU_TIMER5);
// rcu_periph_clock_disable(RCU_TIMER6);
// rcu_periph_clock_disable(RCU_TIMER7);//
// fwdgt_write_disable();
// nvic_irq_disable(USART0_IRQn);
// nvic_irq_disable(USART1_IRQn);
// nvic_irq_disable(TAMPER_IRQn);
// nvic_irq_disable(FMC_IRQn);
// nvic_irq_disable(EXTI0_IRQn);
// nvic_irq_disable(EXTI1_IRQn);
// nvic_irq_disable(EXTI2_IRQn);
// nvic_irq_disable(EXTI3_IRQn);
// nvic_irq_disable(EXTI4_IRQn);
// nvic_irq_disable(EXTI5_9_IRQn);
// nvic_irq_disable(EXTI10_15_IRQn);
// nvic_irq_disable(TIMER1_IRQn);
// nvic_irq_disable(TIMER2_IRQn);
// nvic_irq_disable(TIMER3_IRQn);
// nvic_irq_disable(TIMER4_IRQn);__disable_irq(); // 关闭总中断//__set_BASEPRI(WWDGT_IRQn);
}
因为我的单片机跑了freertos,这个问题估计还要研究一下才能清晰。
5.1.4 我升级了一下,提示成功了,但是无法继续执行新的单片机应用程序。
我想应该是关闭了中断的原因。我的应用程序需要中断才能继续。建议是升级后直接重启了。
启动程序 改为 NVIC_SystemReset(); 重启单片机就行。
三、总结一下:
3.1 第一版的功能优点:
3.1.1 升级时断电,重启还是可以使用串口继续升级
3.2 第一版的缺点:(请查看前文,经验证可以调试和下载。)
3.2.1 不方便使用keil直接下载应用程序,就要用串口,或者下载软件
3.2.2 不方便keil调试应用程序,不方便追踪问题
3.3 第二版的改进:(注意新的风险)
3.3.1 修正了第一版的研发不便。
3.4 又引进了新的问题:
3.4.1 升级的时候风险增加,比如升级过程中断电,或者被中断,都会导致单片机无法再启动了。
3.4.2 应用程序做了小部分修改。并且禁止了全部的中断。
似乎没有十全十美的办法。
本文发布于:2024-02-04 13:16:48,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170708132955915.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |