硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1226|回复: 27
收起左侧

[有问必答] stm32两段APP升级跳转问题

  [复制链接]

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2023-7-3 17:20:03 | 显示全部楼层 |阅读模式
自己写了个上位机通过串口发送bin文件来升级APP,但是有点小问题请教一下大佬们


流程是先将APP1下载到0x8008000;
bootloader检测备份寄存器的值选择运行APP1;
APP1运行时接收到升级指令,写备份寄存器,软件复位;
bootloader检测寄存器的值后开始擦除APP2区域,写入BIN文件;
然后自动跳转到APP2,此时是可以跳转到APP2且能够正常运行;
然后APP2接收到升级指令后,正常擦除APP1区域后跳转,就跳转不过去;;;
但是手动下载APP1后程序能够正常运行。。。


有没有大佬指导一下方向,可能是哪方面的问题。。。

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106726
QQ
发表于 2023-7-3 18:22:41 | 显示全部楼层
当前不管是更新APP1还是APP2,都是从boot跳转运行吧,而不是app1和app2互跳转。

然后就是你的app升级完毕后有做完整性校验没,这个有必要做下
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2023-7-14 10:02:04 | 显示全部楼层
说下结果吧
先说原因,烧录的BIN文件或HEX文件是包含程序的入口地址的,不能把编译的0x08008000地址的程序放在0x08010000的位置上,不然也进不去。
这样单片机做双APP交互升级很麻烦,后期进行固件升级时就需要准备两份文件。
虽然可以通过读elf文件读出程序的入口地址,但是在上位机方面要做的东西就很多,面对升级过程失败防止变砖的需求时还是没必要做得这么麻烦。
现在考虑在flash中设置标志位以检测掉电时程序是否正常,否则就跳转到备份APP,或者叫恢复出厂设置,只要保证备份APP可以实现接收更新指令,写更新标志位,复位的功能就可以。
回复

使用道具 举报

22

主题

67

回帖

133

积分

初级会员

积分
133
发表于 2023-7-14 10:17:55 | 显示全部楼层
山河 发表于 2023-7-14 10:02
说下结果吧
先说原因,烧录的BIN文件或HEX文件是包含程序的入口地址的,不能把编译的0x08008000地址的程序 ...

单bank的升级都必须从地址0x80000000代码开始执行 你放到别的位置当然是不能执行的,双app升级也必须是从boot开始执行跳转到一个app 对另外一个app进行升级 flash搞个标志位 作为跳转哪个app的标志
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2023-7-14 11:02:53 | 显示全部楼层
2360985396 发表于 2023-7-14 10:17
单bank的升级都必须从地址0x80000000代码开始执行 你放到别的位置当然是不能执行的,双app升级也必须是从 ...

对,但是想要两个app相互升级,后期升级的时候就很麻烦,要查看到当前运行的是哪个APP,尽管可以用flash标志位实现区分,但是对于下载的文件来说就需要准备两份,如若传错bin文件,程序的整体校验也都可以通过,但是会造成跳转不了变砖的情况。
回复

使用道具 举报

7

主题

21

回帖

42

积分

新手上路

积分
42
发表于 2023-7-14 13:38:36 | 显示全部楼层
中断向量表得问题吧
回复

使用道具 举报

22

主题

67

回帖

133

积分

初级会员

积分
133
发表于 2023-7-14 15:01:23 | 显示全部楼层
山河 发表于 2023-7-14 11:02
对,但是想要两个app相互升级,后期升级的时候就很麻烦,要查看到当前运行的是哪个APP,尽管可以用flash ...

写上位机更新的时候 建议输入本次checksum 并且上位机也计算chencksum 如何计算的结果和你输入的一致,又怎么会传错bin呢 我的项目的上位机就是这么做的, 更新之前必须知道这个bin的唯一性(自制checksum算法 防止别人蒙对)
回复

使用道具 举报

13

主题

52

回帖

91

积分

初级会员

积分
91
发表于 2023-7-26 11:15:43 | 显示全部楼层
2360985396 发表于 2023-7-14 15:01
写上位机更新的时候 建议输入本次checksum 并且上位机也计算chencksum 如何计算的结果和你输入的一致,又 ...

他的意思是一份工程生成的bin文件,从bootloader启动跳转的问题。因为工程里面有设置中断向量表位置,boot跳转的时候跳转两个地址是不行的。
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2023-7-29 12:06:31 来自手机 | 显示全部楼层
山河 发表于 2023-7-14 11:02
对,但是想要两个app相互升级,后期升级的时候就很麻烦,要查看到当前运行的是哪个APP,尽管可以用flash ...

先说一下双bank的APP的意义:设备可以不停机,实现设备升级程序,也就是APP1在运行过程中,同时接收并写入固件APP2,完整接收并校验通过正确写入后,然后直接从APP1跳转到APP2,无缝执行APP2。反之,依然。这个好处,以前单APP是没有的,以前是要嘛执行BL,要么执行APP,升级程序过程中,设备是不运行APP的,只是停留在BL中。

说一下如何实现双bank的APP的跳转:首先必须明白一点,设备重现上电或看门狗复位或其他硬件复位后,程序还是先运行在BL中,可以判断flash中的一个标志,判断这个标志,决定是跳转到APP1或APP2中,或停留在BL中(没有APP的情况下)等待接收APP。APP1在正确接收并写入APP2后,改变flash标志为APP2,APP1保存现场,然后跳转到APP2并执行之,反之,过程相同。一定要记住这个flash标志,BL只判断而不改写,APP1或APP2在正确升级程序后改写。保证设备不会变砖,总有一个APP可以运行,最坏情况下,没有APP运行,停留在BL中,等待接收正确完整的APP。

你的思路是正确的,只是跳转过程或整个BL和APP联合起来运行的流程而没搞清楚。
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2023-7-29 21:05:04 | 显示全部楼层
山河 发表于 2023-7-14 11:02
对,但是想要两个app相互升级,后期升级的时候就很麻烦,要查看到当前运行的是哪个APP,尽管可以用flash ...

是的,现场升级程序时必须要查询flash标志,用来确定单片机中正在运行的是APP1或APP2,但是只需要准备一份升级程序的bin就够了。如果查询到当前是APP1,就把新bin烧写到APP2的位置;如果查询到当前是APP2,就把新bin烧写到APP1的位置。
需要注意的是BL中不要使用中断,大部分单片机厂家都是这样建议的,因为中断向量表需要重映射,不是不可以做,会很麻烦,程序复杂了;如果单片机装备有备用的硬件中断向量表,也就是BL和APP有各自独立的中断向量,就非常容易在BL中使用中断了。
做双bank的APP时,也要注意中断向量的问题。
总之,准备一份新bin就足够了。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2023-7-31 15:50:10 | 显示全部楼层
lb1057907736 发表于 2023-7-29 21:05
是的,现场升级程序时必须要查询flash标志,用来确定单片机中正在运行的是APP1或APP2,但是只需要准备一 ...

感谢大佬指导,因为设计的产品现场查询不方便,如果客户不懂选错app,产品也是直接变砖了,最好还是往“傻瓜式”更新操作方向设计,整理了两个方案,一是设置app缓存区,不管是接收app时掉电还是copy到执行区域时掉电,都能防止硬件变砖;另一种方案是固化另一个app,掉电升级失败跳转到这里,也可以说是恢复出厂设置,只要保证程序能够正常接收更新指令就好。这次栽到了不了解程序BIN文件的入口地址,以为BIN文件随便放就可以
回复

使用道具 举报

6

主题

88

回帖

106

积分

初级会员

积分
106
发表于 2023-7-31 17:00:42 | 显示全部楼层
山河 发表于 2023-7-31 15:50
感谢大佬指导,因为设计的产品现场查询不方便,如果客户不懂选错app,产品也是直接变砖了,最好还是往“ ...

变砖就变夸了,只要程序能保证进BOOT就能再次升级,让它多变几次砖也好让用户操作小心点。
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2023-7-31 17:46:50 来自手机 | 显示全部楼层
山河 发表于 2023-7-31 15:50
感谢大佬指导,因为设计的产品现场查询不方便,如果客户不懂选错app,产品也是直接变砖了,最好还是往“ ...

首先bin文件是不包含地址信息的,但考虑到你的上位机是普通串口,通信协议估计也是自定义的,传bin时肯定要加上地址,不然怎么知道烧写到app1还是app2呢?你的app估计肯定会用到中断,烧写到两个不同位置app的中断入口的绝对物理地址肯定不同。确实需要准备两个bin,app1或app2的bin因为中断问题是两个不同的。除非你有版本记录而清晰地知道每台设备运行的是app1或app2,这样只准备一个bin就行了,这样做绝对是不可能的;总之,就是要准备两个bin,通过查询当前设备而选择其中的一个。这部分工作上位机工程师来做,串口查询,然后告知客户选择哪个bin,选错了直接变砖头,bin就是二选一。
可以这样做客户查询需要哪一个,你们发给他哪一个,但是下位机工程师必须准备两个bin。上下位机加上一个查询命令很容易。
程序越简单越好,bug越少。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2023-8-1 10:47:45 | 显示全部楼层
啊对,就是BIN文件中断入口的问题,感谢大佬,现在很清楚了
回复

使用道具 举报

0

主题

13

回帖

13

积分

新手上路

积分
13
发表于 2023-10-27 10:55:12 | 显示全部楼层
lb1057907736 发表于 2023-7-31 17:46
首先bin文件是不包含地址信息的,但考虑到你的上位机是普通串口,通信协议估计也是自定义的,传bin时肯定 ...

为啥不能做到一个bin呢,bin里面加起始地址信息即可,boot判断这个地址并写入相应的app分区
回复

使用道具 举报

3

主题

122

回帖

131

积分

初级会员

积分
131
发表于 2023-10-27 13:39:34 | 显示全部楼层
quar 发表于 2023-10-27 10:55
为啥不能做到一个bin呢,bin里面加起始地址信息即可,boot判断这个地址并写入相应的app分区

同样一个工程,完全一样的程序,改了程序中断入口,比如keil里就是target设置IROM的地址,0x08000000改成0x08001000,前后得到的bin是不一样的,改了地址以后的bin再烧到原来的地址,程序大概率是运行不起来的,所以需要一个地址对应改为相应地址的bin,比如0x08000000就只能烧录keil工程里设置成0x08000000地址的bin,0x08001000就只能烧录keil工程里设置成0x08001000地址的bin
回复

使用道具 举报

0

主题

13

回帖

13

积分

新手上路

积分
13
发表于 2023-10-27 15:15:59 | 显示全部楼层
本帖最后由 quar 于 2023-10-27 15:38 编辑
skyshine 发表于 2023-10-27 13:39
同样一个工程,完全一样的程序,改了程序中断入口,比如keil里就是target设置IROM的地址,0x08000000改成 ...

这是两个版本的bin了吧,你只要在bin里面加入起始地址的信息,bootloader接收到后去判断应该写到哪个分区。改一个功能,就版本+1呗。另外,如果遇到升级的bin与运行的某个APP(比如APP1)地址是同一个的话,需要把APP1拷贝到APP2备份,防止新版本出问题,如果出问题,则需要拷回运行旧版本的APP1
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2023-10-27 15:34:50 来自手机 | 显示全部楼层
skyshine 发表于 2023-10-27 13:39
同样一个工程,完全一样的程序,改了程序中断入口,比如keil里就是target设置IROM的地址,0x08000000改成 ...

正解。因为中断向量表是不同的,除非BL和APP都不使用任何中断。APP哪能不用中断呢?我做的BL和双APP是用在PIC单片机的8位机上的。其实更复杂,因为较老的单片机没有备用中断向量表,又因为硬件中断的地址是固定的,例如只有高低两级中断,高优先级中断的固定硬件地址是0x08,低的是0x18,并且这两个地址都在BL中,为了简化设计软件设计BL不使用任何中断,全部是轮询的方式。以上两个地址各放置一条goto语句,分别跳转到APP的高低优先级服务程序的地址。没办法,这比STM32还要复杂。较新的PIC的8位机配备了备用硬件中断向量地址。BL和APP可以各自使用自己的中断了,最起码不需要BL goto跳转中断向量地址了。现在工程师太幸福了……
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2023-10-27 15:44:19 来自手机 | 显示全部楼层
quar 发表于 2023-10-27 15:15
这是两个版本的bin了吧,你只要在bin里面加入起始地址的信息,bootloader接收到后去判断应该写到哪个分区 ...

你没明白,因为中断向量的问题,APP1和APP2是不同的。bin就是不同的,不能只修改bin的起始地址就行了。如果让你的办法可行,就需要APP不使用任何中断,全部是轮询的方式。保证两个bin是完全相同的,仅起始地址不同。如果不信的话,你可以做个实验,你的程序是不能运行的,可以试试。
回复

使用道具 举报

0

主题

13

回帖

13

积分

新手上路

积分
13
发表于 2023-10-27 16:08:45 | 显示全部楼层
lb1057907736 发表于 2023-10-27 15:44
你没明白,因为中断向量的问题,APP1和APP2是不同的。bin就是不同的,不能只修改bin的起始地址就行了。如 ...

为啥编译的时候,修改中断向量表的地址不用根据起始地址智能设置呢?Image$$ER_IROM1$$Base
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2023-10-27 16:32:27 来自手机 | 显示全部楼层
quar 发表于 2023-10-27 16:08
为啥编译的时候,修改中断向量表的地址不用根据起始地址智能设置呢?Image$$ER_IROM1$$Base

我不会写脚本。如果你能做到固件正常运行就行了,你的脚本方法很好。我都是在IDE的编译器设置里修改,笨方法。
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2023-10-27 16:34:09 来自手机 | 显示全部楼层
quar 发表于 2023-10-27 16:08
为啥编译的时候,修改中断向量表的地址不用根据起始地址智能设置呢?Image$$ER_IROM1$$Base

我咨询一下,STM32的BL中可以使用中断吗?
回复

使用道具 举报

0

主题

13

回帖

13

积分

新手上路

积分
13
发表于 2023-10-27 17:18:55 | 显示全部楼层
lb1057907736 发表于 2023-10-27 16:34
我咨询一下,STM32的BL中可以使用中断吗?

可以啊,有其他什么考虑吗?
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2023-10-27 23:02:39 来自手机 | 显示全部楼层
quar 发表于 2023-10-27 17:18
可以啊,有其他什么考虑吗?

PIC几年前的8位单片机,做BL还不建议使用中断,中断留给APP用。不是不能用,将会把固件写的更复杂。因为硬件中断源地址是固定的。不能同时用,最新的片子配备了一个备用中断源,都可以用了。
回复

使用道具 举报

0

主题

13

回帖

13

积分

新手上路

积分
13
发表于 2023-10-30 15:13:27 | 显示全部楼层
lb1057907736 发表于 2023-10-27 23:02
PIC几年前的8位单片机,做BL还不建议使用中断,中断留给APP用。不是不能用,将会把固件写的更复杂。因为 ...

有个疑问,这个硬件中断源地址(中断向量)是在boot中的吗?这个中断函数是写在app的吗,那中断向量(boot里的)怎么拿到的中断函数(app里的)的地址
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2023-10-30 22:09:06 来自手机 | 显示全部楼层
quar 发表于 2023-10-30 15:13
有个疑问,这个硬件中断源地址(中断向量)是在boot中的吗?这个中断函数是写在app的吗,那中断向量(boot ...

0x08和0x18是两个固定的硬件中断源,在BL中。假如APP从地址0x2000开始,那么0x2008和0x2018就是APP中断函数的地址,这是确定的规则。假如发生中断了,0x08 goto到0x2008,0x18goto到0x2018。执行APP的中断。
回复

使用道具 举报

0

主题

13

回帖

13

积分

新手上路

积分
13
发表于 2023-10-31 11:16:19 | 显示全部楼层
lb1057907736 发表于 2023-10-30 22:09
0x08和0x18是两个固定的硬件中断源,在BL中。假如APP从地址0x2000开始,那么0x2008和0x2018就是APP中断函 ...

那为啥不设置一个标志位呢,boot的时候,标志为0,就goto到boot的处理函数,跳转APP后标志为1,就goto到APP的处理。不就可以两个都用中断了
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2023-10-31 12:56:09 来自手机 | 显示全部楼层
quar 发表于 2023-10-31 11:16
那为啥不设置一个标志位呢,boot的时候,标志为0,就goto到boot的处理函数,跳转APP后标志为1,就goto到AP ...

懂你的意思,例如在flash某个不用的地方,放个标志,BL和APP都可以访问,用于区分到底是谁的中断服务程序。BL这样就复杂了。可以做,但复杂了,要维护好这个标志,用于区分到底该执行谁的中断服务程序。我说的这种类型的MCU,连原厂都建议BL中不用中断,必定BL功能单一且明确,就是升级程序以及上电时验证一下APP的完整以及合法性。然后跳转执行APP,使命结束。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-2 09:46 , Processed in 0.255269 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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