bootloader学习笔记---第二篇

目录

一、链接地址与跳转

二、bootloader疑难问题

1、应用程序中使用中断导致程序跑飞或者不能重新下载程序?

2、中断向量表具体是怎么重映射?

3、bootloader更新app过程中意外断电,怎么处理?流程是先备份后擦出然后烧写吗?

4、botloader烧写app程序过程中突然断电或者断开连接导致bootloader无法使用,必须重新烧写,这是什么原因呢?

5、怎么将BOOT程序和APP程序一起烧进板子?

6、第一,多核芯片是否给每个核编写一个bootloader,并分别放在每个核相应的flash里?第二,上位机软件下发的信息是否可以通过ID来区分送到哪个核里?第三,上位机软件是不是必须和CAN盒子配套?

 7、bootloader升级过程很慢,100k左右的s19文件需要十多分钟?

8、boot程序,对于app的跳转地址有什么要求?boot程序比较大,跳转地址是0x25000,跳转总是失败?

9、可以直接从APP区域跳转到到BOOT区域直接升级,而不用经过一个重启的过程吗?正常项目都是APP启动升级的

10、boot 更新app的时候,将flash drv(擦除,写入等风险操作函数)临时通过can从上位机下载到ram中并运行,通过修改链接文件指定自定义的一块ram,可以把收到的flash drv的数据放到这块地址,在执行擦除或者写入操作时,1.怎么找到擦除或写入函数的ram地址并执行?2.如果可以找到地址,怎么往擦除或写入函数传递参数(这两个函数知道ram地址,不是函数,怎么传递参数)?

11、将地址强制转换为函数指针调用,会造成hard fault interrupt?

三、备注


一、链接地址与跳转

这里讨论第一篇文章中提到的第二种情况,即第二种常见的情况就是app烧写在flash上,app应该在ram内存里运行,app或者是bootloader需要把app拷贝到内存ram中去,1、如果是bootloader拷贝的,那么bootloader要跳转到内存ram中去执行app;2、如果是app自己把自己复制到内存中去的,那么bootloader直接跳转到app的位置就可以了。

这里有三个问题,1、谁把app从flash复制到ram中去?2、具体是复制到哪里?3、如果bootloader要跳转到ram中去怎么跳?

第一个问题,app自我复制,bootloader帮忙复制;第二个问题,这个地址我们可以预先设置好;第三个问题,用函数指针跳转。

下面介绍两种跳转方式
第一、相对跳转,BL main; 这是条汇编语句,这条语句会让pc=当前pc+相对位移。不管我们程序放在哪里,相对跳转都能成功。编译器是默认优先使用相对跳转。

 

第二、绝对跳转,是让pc=要跳转的地址。比如,LDR r5 , [pc, #24]     BLX r5。函数指针的方式也是绝对跳转的方式。对于绝对跳转,在对应的地址上面必须有对应的代码。stm32上电后第二件事情就是跳转到Reset_Handler中去,这也是绝对跳转。如果是长距离调用,也会使用绝对跳转。如果是绝对跳转,我们程序烧录的位置如果发生变化,即我们烧录的地址和链接文件(散列文件)中指定的地址不一致,那么跳转过去的地址就会出现错误,因为跳转的绝对地址的那块内存可能没有初始化,程序会崩溃。

散列文件

 

如果我们如上图那样使用散列文件修改了app程序的链接地址,那么app程序会把指令和数据放在0x20000000。那么这相当于,bootloader跳转到app中,app自己把自己复制到0x20000000。可以看到散列文件中,链接地址和加载地址都是同一个地址,链接地址就是运行时的地址,我们可以使用烧录工具来决定程序的烧录地址,在这里加载地址没有用,只有链接地址有用。

 上面的代码是app自己复制自己到内存的

第二种情况,需要bootloader把app复制到内存中去时,app文件的头部一般会包含以下几种信息,1、加载地址:即要拷贝到内存的那个地址,2、入口地址:即第一条指令地址,3、长度,4、CRC。

这就需要bootloader启动后需要去app的烧录地址读取这些头部信息,接着解析这些头部信息,然后读取app.bin存入内存,最后跳转到内存中去执行app程序。

解析头部信息,需要注意的是,存储方式是大字节序还是小字节序,

这里我补充一个知识点:我们在对flash进行读写操作时,flash中对应的应用程序文件将不能运行,所以必须将flash driver拷贝到ram区域,这是由flash的硬件性质决定的,为什么呢?

因为,flash只有一套自己的crossbar(类似交叉开关,同一时刻只能执行一种操作)访问总线,当其被用作写数据时,不能同时读取数据(譬如CPU取指执行程序)。但在支持RWW partition的flash中是不必如此操作的,它支持在不同flash分区同时进行读和写。

二、bootloader疑难问题

1、应用程序中使用中断导致程序跑飞或者不能重新下载程序?

这个要看具体的MCU(内核),一个原则是使能中断和异常发生之前必须确保其中断向量表和中断/异常ISR已经ready。

2、中断向量表具体是怎么重映射?

更改向量表基地址寄存器,也叫中断向量表偏移量寄存器,中断向量表的重定向可以是在bootloader进入用户程序之前改,也可以在用户程序里面改,对于在Cortex-M3内核的MCU上可以通过设置SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET,关于这个寄存器的描述可以见下图;该寄存器的值来实现中断向量表的重定义。如果没有这类的寄存器可以参考这位博主的办法尝试解决STM32F0芯片IAP实现之中断向量表重映射(没有中断向量表偏移寄存器SCB->VTOR的应对方法)_a只如初见的博客-CSDN博客_中断重映射

3、bootloader更新app过程中意外断电,怎么处理?流程是先备份后擦出然后烧写吗?

一般是双应用程序分区,更新完新的应用程序之后才擦除老的应用程序分区并设置跳转标志,以保证时钟有一个分区中的应用程序正确可用。

4、botloader烧写app程序过程中突然断电或者断开连接导致bootloader无法使用,必须重新烧写,这是什么原因呢?

如果应用程序新过程中断电或者意外复位,则应用程序更新失败,相应的应用程序完整性校验通不过,当然得重新下载,为了避免这种情况下应用程序丢失,常常BootLoader需要对应用程序进行双备份,即使用两个不同的NVM分区来保存应用程序,只有新的应用程序更新成功之后,才擦除老的应用程序。

5、怎么将BOOT程序和APP程序一起烧进板子?

用任意文本编辑器打开bootloader和app工程生成的S19文件拷贝即可合并,然后使用调试器通过SWD/JTAG接口下载即可。

6、第一,多核芯片是否给每个核编写一个bootloader,并分别放在每个核相应的flash里?第二,上位机软件下发的信息是否可以通过ID来区分送到哪个核里?第三,上位机软件是不是必须和CAN盒子配套?

多核MCU只需要为其boot CPU core开发一个bootloader就可以了,可以通过ID或者地址来判断,可以复用我们的上位机软件,但其只有简单功能,要用这个上位机软件需要使用匹配的CAN适配器,否则需要修改底层dll以适用于其他CAN适配器

 7、bootloader升级过程很慢,100k左右的s19文件需要十多分钟?

Flash擦除本身很耗时间,另外,可以在将S19文件每行的数据设置为更长(比如128字节或者512字节)或者把bootloader里面改为接收10行s19再烧写,提高Flash烧写效率,再或者就是提高通信速率

8、boot程序,对于app的跳转地址有什么要求?boot程序比较大,跳转地址是0x25000,跳转总是失败?

这个要看跳转具体是如何实现的?要反汇编看看具体的汇编跳转指令,不同的汇编跳转指令支持的跳转地址范围不同。

9、可以直接从APP区域跳转到到BOOT区域直接升级,而不用经过一个重启的过程吗?正常项目都是APP启动升级的

可以在APP中接收到boot请求后使用函数指针直接跳转到bootloader的reset_handler,但需要在跳转之前反初始化/复位APP使用的所有时钟和外设,以避免APP与bootloader的相互影响。当然,我们推荐的方式还是软件复位或者看门狗溢出复位进入bootloader。

10、boot 更新app的时候,将flash drv(擦除,写入等风险操作函数)临时通过can从上位机下载到ram中并运行,通过修改链接文件指定自定义的一块ram,可以把收到的flash drv的数据放到这块地址,在执行擦除或者写入操作时,1.怎么找到擦除或写入函数的ram地址并执行?2.如果可以找到地址,怎么往擦除或写入函数传递参数(这两个函数知道ram地址,不是函数,怎么传递参数)?

第1个问题,使用函数查找表,类似中断向量表的工作原理;第2个问题使用函数指针,因为函数名本身就是地址,我们可以定义一个和flash drv相同格式的函数指针,然后向这个函数指针传递的参数就是传递给了flash drv函数;

11、将地址强制转换为函数指针调用,会造成hard fault interrupt?

typedef void(*pfun_t)(void);
 pfun_t pfun = (pfun_t)0x00500000; 
pfun(); 

注意是把中断向量(中断ISR函数地址,存在中断向量表地址的内容)而不是中断向量地址本身转换成函数指针执行。

三、备注

本文部分内容是根据韦东山老师的视频整理编写的笔记从0写BootLoader(适用于单片机),还有部分公众号中汽车电子expert成长之路的文章评论,部分图片来自于cortex-m3权威指南。

=文档信息=
本学习笔记由博主整理编辑,仅供非商用学习交流使用
由于水平有限,错误和纰漏之处在所难免,欢迎大家交流指正
如本文涉及侵权,请随时留言博主,必妥善处置
版权声明:非商用自由转载-保持署名-注明出处

  • 0
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值