搜索
bottom↓
回复: 71

遇到STM32 A,B区 app升级困难,各路大神,帮忙看一下。

[复制链接]

出0入0汤圆

发表于 2019-6-19 16:56:45 | 显示全部楼层 |阅读模式
我正在做一个bootloader(boot+app1+app2)。

app1运行的时候,升级app2,校验合法后,然后重启直接运行APP2。
app2运行的时候,升级app1,校验合法后,然后重启直接运行APP1。。。。。。

目前的困难是,如何能够将APP1与APP2做成同一个固件?今天对比了下不同位置的固件,发现只有前480个字节的vector table不同。

今天做了些尝试,app的固件以地址0x8000000生成(RAM预留1k,以存放中断向量表)。
bootloader运行时,将vector table 整个复制到RAM的最前面(根据APP的不同地址,重新修正中断向量表,比如app2的运行地址是0x80005000,则将中断向量表统一加上0x5000);
但是发现这样子行不通,无法正常运行。是不是我哪里有缺漏的地方?

实在没办法的话,只能固件升级时,将中断向量表修改掉??

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2019-6-19 17:02:09 | 显示全部楼层
每个程序各自设置向量表地址, 你咋还用bootloader去复制向量表啊?

出0入0汤圆

发表于 2019-6-19 17:06:24 来自手机 | 显示全部楼层
我也觉得复制向量表太麻烦了,每个程序单独一个项目,单独一个地址配置

出0入0汤圆

 楼主| 发表于 2019-6-19 17:12:52 | 显示全部楼层
lyz3432 发表于 2019-6-19 17:02
每个程序各自设置向量表地址, 你咋还用bootloader去复制向量表啊?

我想将APP1,与APP2做成同一个固件,目标是这个。不然也不存在中断向量表的问题。

出0入8汤圆

发表于 2019-6-19 17:13:01 | 显示全部楼层
整个程序区分3部分 boot+app1+app2   都是单独的配置就行了,你复制向量表 干吗?

出0入0汤圆

发表于 2019-6-19 17:13:07 | 显示全部楼层
写个脚本,自动编译2次。

AB区麻烦,安全性并不比只有A区要好。
还是单A区,B区可以压缩 ,也可以放外部,更简单经济。

出0入8汤圆

发表于 2019-6-19 17:16:35 来自手机 | 显示全部楼层
app2作为接收缓存区,升级时放在2区,重启后,boot把2考到1,再重启,运行1

出0入0汤圆

 楼主| 发表于 2019-6-19 17:24:02 | 显示全部楼层
justdomyself 发表于 2019-6-19 17:16
app2作为接收缓存区,升级时放在2区,重启后,boot把2考到1,再重启,运行1

若是作为缓存区接收的话,没法做版本回退了。

出0入9汤圆

发表于 2019-6-19 17:36:14 | 显示全部楼层
aozima 发表于 2019-6-19 17:13
写个脚本,自动编译2次。

AB区麻烦,安全性并不比只有A区要好。

请教怎么实现自动编译两次呢?
也遇到这个问题过
都是分两次编译
生成两个bin文件
然后再把两个文件合并起来的

出40入42汤圆

发表于 2019-6-19 17:38:19 | 显示全部楼层
我来为楼主翻译一下:
楼主其实就是想做一个旧APP备份的功能,然后想开辟APP1区域和APP2区域,轮流进行备份旧的代码程序;
但楼主又想着代码功能是一样的,只想使用同一个升级固件,然后MCU可以自己实现在APP1和APP2之间跳转;
目前楼主觉得是中断向量表的问题,尝试把向量表拷到RAM里面,结果不行。
各位,明白了吧?

出0入0汤圆

发表于 2019-6-19 17:38:34 | 显示全部楼层
丢丢时光机 发表于 2019-6-19 17:12
我想将APP1,与APP2做成同一个固件,目标是这个。不然也不存在中断向量表的问题。 ...

两次编译完,写个脚本merge到一起就好了啊

出0入0汤圆

发表于 2019-6-19 17:40:21 | 显示全部楼层
istars2005 发表于 2019-6-19 17:36
请教怎么实现自动编译两次呢?
也遇到这个问题过
都是分两次编译

cmake 写的 就是当两个工程啊 编完一个在遍另一个啊  当是脚本自动调的啊

出0入0汤圆

发表于 2019-6-19 17:46:38 | 显示全部楼层
istars2005 发表于 2019-6-19 17:36
请教怎么实现自动编译两次呢?
也遇到这个问题过
都是分两次编译

工程文件都一样的,就链接脚本里面地址不同而已。
写个脚本之类的来做呗,全自动才能不出错。
错后 得到 a.bin b.bin
再像上面网面说的合并成一个。

但你上传到云端时,可能也可以打成一个,还要对bin做一下校验,防止损坏。
因为现在各个云都是只让上传一个文件,没见过2个的。

反正,AB就是坑。

出40入42汤圆

发表于 2019-6-19 18:00:28 | 显示全部楼层
楼主不应该在bootloader运行的时候把中断向量表复制到RAM

应该在APP运行的时候把Flash里面的中断向量表复制到RAM,然后APP的代码根据当前是运行在APP1还是APP2,修改RAM里面相应的地址偏置,最后把MCU中断向量表的寄存器指到RAM里

出0入0汤圆

 楼主| 发表于 2019-6-19 18:11:33 | 显示全部楼层
落叶知秋 发表于 2019-6-19 18:00
楼主不应该在bootloader运行的时候把中断向量表复制到RAM

应该在APP运行的时候把Flash里面的中断向量表复 ...

效果是一样的啊。因为boot里面已经读取了分区信息,想着直接用了得了,不想再app里面再判断这些玩意。

出0入0汤圆

 楼主| 发表于 2019-6-19 18:13:22 | 显示全部楼层
落叶知秋 发表于 2019-6-19 18:00
楼主不应该在bootloader运行的时候把中断向量表复制到RAM

应该在APP运行的时候把Flash里面的中断向量表复 ...

boot及app的ram起始1K的空间,单独存放向量表的。boot里操作跟app里操作,效果应该是一样的。

出40入42汤圆

发表于 2019-6-19 18:22:28 | 显示全部楼层
丢丢时光机 发表于 2019-6-19 18:13
boot及app的ram起始1K的空间,单独存放向量表的。boot里操作跟app里操作,效果应该是一样的。 ...

没考虑过boot跳转到APP执行时,APP的初始化流程会复位RAM?

出40入42汤圆

发表于 2019-6-19 18:24:11 | 显示全部楼层
丢丢时光机 发表于 2019-6-19 18:13
boot及app的ram起始1K的空间,单独存放向量表的。boot里操作跟app里操作,效果应该是一样的。 ...

如果你APP里面没改过.s汇编文件的话,一般都会在运行到main之前把RAM初始化为0的

出0入0汤圆

 楼主| 发表于 2019-6-19 18:32:00 | 显示全部楼层
落叶知秋 发表于 2019-6-19 18:24
如果你APP里面没改过.s汇编文件的话,一般都会在运行到main之前把RAM初始化为0的 ...

这个有测试,RAM没有被清空; ld文件里面改了RAM的起始地址。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2019-6-19 18:37:20 | 显示全部楼层
坛友帮帮忙。这个问题解决了的话,我把这个A,B升级方案的工程分享到论坛给大家参考。

出0入0汤圆

发表于 2019-6-19 18:54:03 | 显示全部楼层
中断向量表偏移过去就行啦

出0入0汤圆

发表于 2019-6-19 19:06:27 来自手机 | 显示全部楼层
我觉得不止中断向量表,函数地址这些也要改,否则跳转的时候还是跳到编译器编译那个地址

出0入0汤圆

发表于 2019-6-19 19:08:41 来自手机 | 显示全部楼层
lyz3432 发表于 2019-6-19 17:38
两次编译完,写个脚本merge到一起就好了啊

merge到一起怎么理解呢?

出0入9汤圆

发表于 2019-6-19 19:55:35 | 显示全部楼层
aozima 发表于 2019-6-19 17:46
工程文件都一样的,就链接脚本里面地址不同而已。
写个脚本之类的来做呗,全自动才能不出错。
错后 得到  ...

通过修改工程的.sct文件可以实现
但是源文件中还需要执行NVIC_SetVectorTable
否则程序运行肯定会出错

这样写脚本就得把这部分考虑进去了
有什么好办法能解决这个问题吗?

出0入9汤圆

发表于 2019-6-19 19:57:19 | 显示全部楼层
823032003 发表于 2019-6-19 19:08
merge到一起怎么理解呢?

就是把两次生成的a.bin和b.bin直接连接起来
因为两个文件字节数是完全相同的
升级时候程序判断自己是a还是b,然后自己从merge完的文件中找到需要升级的文件偏移就行了

出0入0汤圆

发表于 2019-6-19 20:01:26 | 显示全部楼层
我记得f0没有偏移量  就是将向量表放在内存实现啊

出0入0汤圆

 楼主| 发表于 2019-6-19 20:02:20 | 显示全部楼层
823032003 发表于 2019-6-19 19:06
我觉得不止中断向量表,函数地址这些也要改,否则跳转的时候还是跳到编译器编译那个地址 ...

对的,中断向量表里面的函数地址不同,APP放在不同的位置,中断向量表里面的地址也应随之发生改变。

出0入0汤圆

 楼主| 发表于 2019-6-19 20:03:18 | 显示全部楼层
huangqi412 发表于 2019-6-19 20:01
我记得f0没有偏移量  就是将向量表放在内存实现啊

我这个是STM32F105.应该跟M0不一样

出0入0汤圆

发表于 2019-6-19 20:05:38 | 显示全部楼层
丢丢时光机 发表于 2019-6-19 20:03
我这个是STM32F105.应该跟M0不一样

我的意思是 f0就是将向量表放在内存做的  boot将aopp的表搬运到内存   没道理你放在内存不能用

出0入8汤圆

发表于 2019-6-19 20:29:24 | 显示全部楼层
直接工具合成两个app的bin文件不行吗

出0入0汤圆

发表于 2019-6-19 20:33:55 | 显示全部楼层
但是源文件中还需要执行NVIC_SetVectorTable
否则程序运行肯定会出错


可以让boot来处理

出0入9汤圆

发表于 2019-6-19 20:45:23 来自手机 | 显示全部楼层
aozima 发表于 2019-6-19 20:33
可以让boot来处理

赞,这样确实可以解决问题

出0入8汤圆

发表于 2019-6-19 21:25:37 来自手机 | 显示全部楼层
丢丢时光机 发表于 2019-6-19 17:24
若是作为缓存区接收的话,没法做版本回退了。

版本回退是伪需求,只是为了掩盖测试不充分

出0入8汤圆

发表于 2019-6-19 21:43:56 来自手机 | 显示全部楼层
canspider 发表于 2019-6-19 21:25
版本回退是伪需求,只是为了掩盖测试不充分

严重赞同,,,

出0入0汤圆

发表于 2019-6-19 21:52:35 来自手机 | 显示全部楼层
A,B两个交互用,会整死人。可靠升级是把B当存储区,接收完成从B搬到A,A运行

出0入8汤圆

发表于 2019-6-19 22:17:37 来自手机 | 显示全部楼层
丢丢时光机 发表于 2019-6-19 20:02
对的,中断向量表里面的函数地址不同,APP放在不同的位置,中断向量表里面的地址也应随之发生改变。 ...

对,我们最近也有个这种项目要开发,我也在想工程里面那些函数指针咋办,应该要把工程搞成地址无关的,或者可以设置整体偏移值。

出0入0汤圆

 楼主| 发表于 2019-6-19 23:23:30 | 显示全部楼层
了无 发表于 2019-6-19 22:17
对,我们最近也有个这种项目要开发,我也在想工程里面那些函数指针咋办,应该要把工程搞成地址无关的,或 ...

打算固件升级时,把固件中的中断向量表部分直接修改后,存入相应的flash。

出0入8汤圆

发表于 2019-6-20 00:24:34 来自手机 | 显示全部楼层
丢丢时光机 发表于 2019-6-19 23:23
打算固件升级时,把固件中的中断向量表部分直接修改后,存入相应的flash。 ...

你试试,把结果与问题发上来讨论讨论,我会持续关注这个帖子,咱们一块把这个问题解决了,你的问题解决了,我的也就解决了

出0入0汤圆

 楼主| 发表于 2019-6-20 10:09:24 | 显示全部楼层
了无 发表于 2019-6-20 00:24
你试试,把结果与问题发上来讨论讨论,我会持续关注这个帖子,咱们一块把这个问题解决了,你的问题解决了 ...

我准备放弃AB方案了。今天用工具对比了下两个不同位置的bin,发现不同的地方不仅仅是VECTOR TABLE.固件从头到尾都有不同的地方。

出870入263汤圆

发表于 2019-6-20 10:34:21 | 显示全部楼层
丢丢时光机 发表于 2019-6-20 10:09
我准备放弃AB方案了。今天用工具对比了下两个不同位置的bin,发现不同的地方不仅仅是VECTOR TABLE.固件从 ...

这算不算出尔反尔?当你之前说出链接到两个不同地址时,只是向量表不同的时候,我就很怀疑了。

出0入9汤圆

发表于 2019-6-20 10:46:10 | 显示全部楼层
丢丢时光机 发表于 2019-6-20 10:09
我准备放弃AB方案了。今天用工具对比了下两个不同位置的bin,发现不同的地方不仅仅是VECTOR TABLE.固件从 ...

AB升级我觉得问题不大
有两个项目用到AB方案升级

主要是人为的需要控制好固件生成和merge
而且有时候生成的AB固件是不一样大的
二者最大有4个字节的差别
我吃过一次亏后来写了个批处理自动检查二者大小
然后再决定是不是merge

如果能通过脚本实现自动生成AB文件
并且检查大小 确保都没问题
那就大胆的使用

出0入4汤圆

发表于 2019-6-20 10:57:30 | 显示全部楼层
其实,一用一备更方便。

出0入0汤圆

发表于 2019-6-20 11:17:20 | 显示全部楼层
弄同样的app,中断向量一样, 存放到不同的位置,决定复制一个app到程序区运行

出0入0汤圆

发表于 2019-6-20 11:58:19 | 显示全部楼层
之前用1768,做ab区升级,最后发现,a b 的全局变量和函数要一样,不然,升级成功,也不能运行。最后放弃了使用一主一备。如果要a b都可以,需要用分散加载。

出0入0汤圆

 楼主| 发表于 2019-6-20 13:12:09 | 显示全部楼层
armstrong 发表于 2019-6-20 10:34
这算不算出尔反尔?当你之前说出链接到两个不同地址时,只是向量表不同的时候,我就很怀疑了。 ...

昨天只生成了两个2K的flash。自认为很小,人工对比了下。结果自己犯了个错误。。。还得工具对比。

出0入0汤圆

 楼主| 发表于 2019-6-20 13:17:59 | 显示全部楼层
落叶知秋 发表于 2019-6-19 17:38
我来为楼主翻译一下:
楼主其实就是想做一个旧APP备份的功能,然后想开辟APP1区域和APP2区域,轮流进行备份 ...

我的主要问题是,生成一个固件,无论放在APP1的位置,还是APP2位置,boot都能跳转过去正确执行。

出40入42汤圆

发表于 2019-6-20 13:39:32 | 显示全部楼层
丢丢时光机 发表于 2019-6-20 13:17
我的主要问题是,生成一个固件,无论放在APP1的位置,还是APP2位置,boot都能跳转过去正确执行。 ...

OJBK,讨论的前提出错了,后面白忙活

出0入8汤圆

发表于 2019-6-21 08:06:13 来自手机 | 显示全部楼层
在外面放个大的flash,boot的时候判断要不要升级就可以了。把boot做成出厂时的app固件,新版的app从网上自动下载,新版的app更新到另一个偏移量去

出0入8汤圆

发表于 2019-6-21 08:08:44 来自手机 | 显示全部楼层
也就是每次升级都把固件先保存在外置的flash,可以保存很多份app固件,升级完进去app后要判断该app估计是否正常运行,如果不能正常运行就要做标记。判断:我是我还是我是我的影子,哈哈

出0入0汤圆

发表于 2019-6-21 08:13:14 来自手机 | 显示全部楼层
向量表是个要注意的地方,前几天帮我客户处理过类似的问题,在仿真看到存放向量表数据是偏移之后的数据

出0入0汤圆

发表于 2019-6-21 08:37:01 | 显示全部楼层
你得在APP1 和APP2 前加一段bootloader, 用它实现跳转升级APP1还是APP2

出0入8汤圆

发表于 2019-6-21 08:46:19 | 显示全部楼层
本帖最后由 kebaojun305 于 2019-6-21 08:50 编辑
丢丢时光机 发表于 2019-6-20 13:17
我的主要问题是,生成一个固件,无论放在APP1的位置,还是APP2位置,boot都能跳转过去正确执行。 ...


你这个 前提确实错了 除非你能修改app1  或者app2得内部所有得地址。   这个功能 最简单的就是编译2个起始地址不同的app ,可以实现,你想编译一个app  在2个不同flash地址中运行,是不可能的。

出0入9汤圆

发表于 2019-6-21 08:46:33 来自手机 | 显示全部楼层
丢丢时光机 发表于 2019-6-20 13:17
我的主要问题是,生成一个固件,无论放在APP1的位置,还是APP2位置,boot都能跳转过去正确执行。 ...

你这个要求有点复杂吧,我一直是生成两个固件,然后合并在一起,然后根据当前运行的固件开判断从哪部分截取合并的固件

出0入0汤圆

发表于 2019-6-21 08:51:35 | 显示全部楼层
A\B来回切换想想很好,其实就会碰到楼主的问题,就是能实现也会遇到编译同一个文件的问题,想实现回退版本功能,不如分成四个区,BOOT引导区,APP区,代码备份区1,代码备份区2,升级后由BOOT实现把备份区的代码复制到APP区运行,备份区1和2交替存放最新升级文件。

出0入0汤圆

发表于 2019-6-21 09:05:28 | 显示全部楼层
丢丢时光机 发表于 2019-6-20 13:17
我的主要问题是,生成一个固件,无论放在APP1的位置,还是APP2位置,boot都能跳转过去正确执行。 ...

感觉应该是编译出来2个app固件,编译的时候要在不同的基地址上编译,要不里面的跳转,函数定位都不一样的地址,然后合并到到一起,boot跳转到哪个都行

出0入0汤圆

 楼主| 发表于 2019-6-21 10:17:59 | 显示全部楼层
istars2005 发表于 2019-6-21 08:46
你这个要求有点复杂吧,我一直是生成两个固件,然后合并在一起,然后根据当前运行的固件开判断从哪部分截 ...

A,B合成一个固件,对存储空间要求就高了,得外挂flash。

出0入0汤圆

发表于 2019-6-21 10:35:08 | 显示全部楼层
A,B确实没必要,不如App和Store。
回退的实现本身就需要很多条件,如果你更新完了A有和回退相关的bug,还是死路一条。如果任何情况下你能通过Bootloader重新update firmware,则完全没必要存储旧的image。

出0入0汤圆

 楼主| 发表于 2019-6-21 10:43:31 | 显示全部楼层
dalige 发表于 2019-6-21 10:35
A,B确实没必要,不如App和Store。
回退的实现本身就需要很多条件,如果你更新完了A有和回退相关的bug,还 ...

嗯,目前已经启用A运行B存储的方案了。

出0入9汤圆

发表于 2019-6-21 10:45:05 | 显示全部楼层
丢丢时光机 发表于 2019-6-21 10:17
A,B合成一个固件,对存储空间要求就高了,得外挂flash。

你是通过什么升级?
我都是把固件放在远端服务器
然后设备判断应该升级哪个固件
下载的时候直接就截断了
不需要把合并的固件都下载下来

出0入0汤圆

发表于 2019-6-21 11:13:24 | 显示全部楼层
justdomyself 发表于 2019-6-19 17:16
app2作为接收缓存区,升级时放在2区,重启后,boot把2考到1,再重启,运行1

这个是  正解!!!
再没比这个简单的了?

出0入8汤圆

发表于 2019-6-21 20:06:44 | 显示全部楼层
istars2005 发表于 2019-6-21 10:45
你是通过什么升级?
我都是把固件放在远端服务器
然后设备判断应该升级哪个固件

这位兄弟说的方法可行,不过也是妥协没办法的办法了

出0入0汤圆

发表于 2019-8-5 11:24:41 | 显示全部楼层
stm32  m0和m3的中断向量机制不一样,m3可以通过寄存器实现中断向量重映射,但是M0好像只能从ram拷贝实现中断重映射。还有一个问题就是你的boot1引脚是从flash启动还是从

出0入0汤圆

发表于 2019-8-5 11:25:17 | 显示全部楼层
sram启动

出0入0汤圆

发表于 2019-8-5 14:18:06 | 显示全部楼层
丢丢时光机 发表于 2019-6-19 17:24
若是作为缓存区接收的话,没法做版本回退了。

你都能直接识别出版本了!为什么还不能做版本回退? 用个优先级更高的变量,让APP1 判断备份区的这个变量。

出0入0汤圆

发表于 2019-8-9 11:26:27 | 显示全部楼层
这是在做OTA吗?

出0入0汤圆

发表于 2023-12-25 16:16:26 来自手机 | 显示全部楼层
istars2005 发表于 2019-6-20 10:46
AB升级我觉得问题不大
有两个项目用到AB方案升级


(引用自41楼)

好几年了,大哥你的AB分区好用吗?

出0入9汤圆

发表于 2023-12-25 16:58:07 | 显示全部楼层
startwar0418 发表于 2023-12-25 16:16
好几年了,大哥你的AB分区好用吗?
(引用自66楼)

很好用啊
需要注意的事项上面也提到了
需要控制一下
不然会有风险
不过从bootloader里面做好校验也不怕
我上次吃亏是boot里面没有处理

出0入0汤圆

发表于 2023-12-25 17:09:28 | 显示全部楼层
能否分享一下方案细节

出0入0汤圆

发表于 2023-12-26 08:38:27 来自手机 | 显示全部楼层
istars2005 发表于 2023-12-25 16:58
很好用啊
需要注意的事项上面也提到了
需要控制一下

(引用自67楼)

看之前的回复,你是按AB两个分区分别编译完然后合成一个文件,Mcu自己判断用A还是B的然后刷进去?

出0入9汤圆

发表于 2023-12-26 08:42:05 | 显示全部楼层
startwar0418 发表于 2023-12-26 08:38
看之前的回复,你是按AB两个分区分别编译完然后合成一个文件,Mcu自己判断用A还是B的然后刷进去? ...
(引用自69楼)

是的
MCU会把当前的一些信息存在flash里面
根据这些信息来确定应该升级A还是B

出0入0汤圆

发表于 2023-12-26 11:08:05 来自手机 | 显示全部楼层
istars2005 发表于 2023-12-26 08:42
是的
MCU会把当前的一些信息存在flash里面
根据这些信息来确定应该升级A还是B ...

(引用自70楼)

不知你是否试过只生成一个app就能AB通用的。我看有的编译器有PIC (position-independent code)选项,似乎能实现一个App通刷AB区

出0入9汤圆

发表于 2023-12-26 21:19:10 | 显示全部楼层
startwar0418 发表于 2023-12-26 11:08
不知你是否试过只生成一个app就能AB通用的。我看有的编译器有PIC (position-independent code)选项,似乎 ...
(引用自71楼)

没有试过
如果有这个方法的话希望你能开一个帖子分享一下
会非常有用
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 00:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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