目录

一、bootloader的任务

二、bootloader开发的基础知识

段的概念

重定位的概念

散列文件的概念

异常向量(待补充)

三、最简单的bootloader程序

四、使用汇编跳转

五、备注

一、bootloader的任务

本系列笔记主要记录我学习汽车电子的bootloader程序开发中做的笔记,我学习的芯片是英飞凌的aurix系列的tc377,tc234,tc222,这主要是涉及到两块的东西,驱动程序和协议栈(我学习的是uds协议),前面几篇笔记是我学习的stm32的bootloader。

bootloader的目的是OTA,即为了给板子上面的程序(app)进行升级,这个是bootloader的主要任务。ps:一般不会对bootloader本身进行更新。

有的程序中有双bootloader的设计,不过需要有硬件支持,比如板子上有rom空间,一上电后先执行rom中的程序,然后到指定的flash位置去判断执行哪一个bootloader,如果没有硬件支持,一上电就会只去第一个bootloader的位置执行程序,第二个bootloader就失去了意义。

Linux中的bootloader程序的任务有,1、初始化硬件:比如设置时钟、初始化内存;2、启动内核:从flash读出内核,存入内存,给内核设置参数,启动内核;3、调试作用:在开发产品时经常需要调试内核,使用bootloader可以方便地更新内核。

单片机以stm32f103使用keil举例,假设我们要把程序下载到0x08040000中去,那么我们单击下载后,程序就会被下载到这个地址中去。

二、bootloader开发的基础知识

这里有4个基础概念,需要我们了解了解,段的概念,重定位的概念,散列文件的概念,异常向量的概念。

段的概念

const修饰的全局变量和没有修饰的全局变量是有区别的,用const修饰过的变量是常量,会保存在rom中,没有用const修饰过的变量保存在ram中,对于stmf103来说就是,下图中的两个空间。

我们需要在设置完sp指针后(即第一条语句之后),进入main函数之前,应该要重定位,重定位分为两块,一是代码,代码可以放在rom上面运行;二是数据(可读可写的数据),我们要把rom上面定义为可读可写的数据复制到ram上面去。

所以我们的程序可以分为几个段:

  • 代码段(ro-code):就是程序本身,不会被修改
  • 可读可写的数据段(rw-data):有初始值的全局变量、静态变量,需要从rom复制到内存。
  • 只读的数据段(ro-data):可以放在rom上,不需要复制到内存。
  • bss段或zi段:

    初始值为0的全局变量或者静态变量,没必要放在rom上,使用之前清0就可以了

    未初始化的全局变量或者静态变量,没必要放在rom上,使用之前清0就可以了

  • 局部变量:保存在栈中,运行时生成
  • 堆:一个空闲空间,使用malloc函数来管理它,malloc函数可以自己写,堆并不是必须的

重定位的概念

  1. 保存在rom上的全局变量的值,在使用前要复制到内存,这就是数据段重定位。
  2. 想把代码移动到其他位置,这就是代码重定位。
  3. 重定位的本质就是移动数据

散列文件的概念

把代码段、只读数据段、数据段,移动到它的链接地址处,也就是复制。

我们需要注意,对于数据复制来说三要数是,源,目的,长度,

  • 数据保存在哪里?加载地址
  • 数据要复制在哪里?加载地址
  • 长度

在keil中使用散列文件来描述这些信息,分散排列,在STM32F103这类资源紧缺的单片机芯片中,代码段保存在Flash上,直接在Flash上运行(当然也可以重定位到内存),数据段保存在Flash上,使用前被复制到内存上。

可以从上面的图片中分析出三要素来,在加载域中有两个可执行域,第一个可执行域的源地址是0x0800 0000,目的是0x0800 0000,长度则是由这个可执行域中的所有具体文件大小之后决定的;第二个可执行域的源地址是紧随第一个之后,目的是0x2000 0000,长度则是由这个可执行域中的所有具体文件大小之后决定的。简述就是,要把可读可写的数据复制到内存ram上面去。

异常向量(待补充)

如果板子上面有bootloader程序,同时板子的ram 内存比较大,那么我们可以把应用程序放在外部的flash,bootloader放在内部flash,这样的设计,cpu的地址线和数据线可以访问到内部的flash、ram、spi控制器等等,而没办法直接访问到外部flash。

对于stm32来说,startup文件是bootloader程序的一部分。

看门狗会监控整个系统,如果系统崩溃,没人设置看门狗的话,看门狗会让整个程序复位。

bootloader获得新的app程序时,同时也会获得校验码,bootloader会对app程序重新计算校验码,校验码一样表示获得了正常的app。

bootloader做好以后可以使用串口升级,可以使用蓝牙升级,也可以使用can总线升级。

三、最简单的bootloader程序

第一种是最简单的bootloader,如果bootloader和app都在烧写在内部flash内存里面,app也在flash上直接运行,那么bootloader可以直接跳转到app的地址里面去执行程序,下面是c语言的版本。

void (*app) (void);
app = (void (*)(void))addrA;
app();

举个例子,如果跳转的地址是0x08040000,如果板卡的芯片使用的指令集是thumb指令(比如cortex-m3),那么代码应该是app=(void(*)(void)0x08040001),如果指令集是ARM指令集,代码为app=(void(*)(void)0x08040000)。

下面是汇编的版本

LDR PC = addrA

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

第三种情况,硬件支持重新设置vector地址,可以在应用程序中,设置对应的寄存器(cortex-m3对应的寄存器是SCB寄存器,SCB->VTOR,直接设置SCB->VTOR=app下载的地址),指定中断向量表的位置;如果硬件不支持重新设置异常地址,cpu永远只使用原来的vector,a判断有无新的vector,b老函数调用新vector的函数。

 四、使用汇编跳转

bootloader需要一个中断向量表,app也需要给他指定一个中断向量表。

在这里给出韦东山老师编写的最简单的bootloader程序(含汇编程序),即从bootloader中跳转到app程序中去,以stm32f系列为例,bootloader程序放在0x08000000,app程序放在0x08040000,下面这个是main.c的程序。


#include "uart.h"extern void start_app(unsigned int new_vector);int mymain()
{unsigned int new_vector = 0x08040000; uart_init();putstr("bootloader\r\n");/* start app */start_app(new_vector);return 0;
}

下面是start.s的代码

PRESERVE8THUMB; Vector Table Mapped to Address 0 at ResetAREA    RESET, DATA, READONLYEXPORT  __Vectors__Vectors       DCD     0                  DCD     Reset_Handler              ; Reset HandlerAREA    |.text|, CODE, READONLY; Reset handler
Reset_Handler   PROCEXPORT  Reset_Handler             [WEAK]IMPORT  mymainLDR SP, =(0x20000000+0x10000)BL mymainENDPstart_app   PROCEXPORT  start_app; set vector base address as 0x08040000ldr r3, =0xE000ED08str r0, [r3]ldr sp, [r0]      ; read val from addr 0x08040000ldr r1, [r0, #4]  ; read val from addr 0x08040004BX r1ENDPEND

在主函数中调用了start_app程序,这是一个编写在汇编文件中的函数,在c程序的函数中,函数的第一个参数保存在r0寄存器中,第二个参数保存在r1寄存器中,这里我们用到了一个参数,这个参数就在r0中;在start_app函数中主要做了三件事情,第一,重定位vector,即在跳转之前给app程序重新设置中断向量表的位置,第二,设置sp栈顶指针,即从要跳转的地址中取出第一个值赋给sp指针,第三,设置pc指针,即从要跳转的地址中取出第二个值赋给pc指针,实现跳转。设置栈顶的指针本来是由m3的硬件实现,在这里是我们是以软件的形式实现的。

如果在bootloader中没有设置中断向量表的值,可以在app程序中进行设置。

app的程序可以任意选取对应芯片程序即可,注意改掉对应的keil设置。

在这里我有问题还没有解决,1、多核单片机的bootloader怎么进行引导?和单核单片机类似吗?

2、其他芯片的第一条指令也是设置sp指针吗?如果不是,那是什么呢?

五、备注

本文的大部分内容是根据韦东山老师的视频整理编写的笔记从0写BootLoader(适用于单片机)

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

bootloader学习笔记---第一篇以stm32为例相关推荐

  1. 《鸟哥的Linux私房菜》个人学习笔记-第一篇

    <鸟哥的Linux私房菜>个人学习笔记-基础篇 这是一篇一个linux菜鸡自学的笔记 csdn上的各位大手子们好,本人实习生一枚最近想自己深入学习下linux,所以在社区里发博客,希望能记 ...

  2. bootloader学习笔记---第二篇

    目录 一.链接地址与跳转 二.bootloader疑难问题 1.应用程序中使用中断导致程序跑飞或者不能重新下载程序? 2.中断向量表具体是怎么重映射? 3.bootloader更新app过程中意外断电 ...

  3. 编程学习笔记(第一篇)面向对象技术高级课程:绪论-软件开发方法的演化与最新趋势(1)...

    软件工程的课程,对于从事大中型的软件开发是至关重要的一门课程. <面向对象技术高级课程>深入.系统.完整地讲解当今主流的面向对象软件开发方法的分析.设计.实现及重构方法,深入讲解UML语言 ...

  4. php百分比乘加,PHP学习笔记第一篇 基础知识

    基础知识 我将php语言学习里面最最基础的部分,需要第一个学的,必须牢牢掌握的,归类到一起. 大纲 1.数据类型 2.变量 3.常量 4.操作符 5.流程控制 6.数组 7.字符串操作 8.正则 基础 ...

  5. Cocos Studio学习笔记第一篇--界面

    大前天也就是周二被人问道:"对Cocos Studio2.0以后版本用法的了解."当时我一时之间没法回答,因为Cocos Studio1.6我以前用过很长时间,2.0改版以后我知道 ...

  6. python 学习笔记第一篇---下载网页内所有图片

    第一步:打开网址,进入开发者模式,选中 Network,选择 Img 然后刷新页面,静静等待页面加载 等待页面加载完成,你可以看到这边有很多图片的资源 随便点开一个图片选择 Headers 可以看到 ...

  7. MySQL学习笔记-第一篇-基础知识与命令

    目录 1 登录命令 1.1 主机域名登录 1.2 主机ip登录 2 库命令 2.1 显示库 2.2 创建数据库 2.3 删除数据库 2.4 MySQL-8.新特性 3 表命令 3.1 创建数据表 3. ...

  8. 华为HCIA-Datacom 学习笔记-------第一篇

    文章目录 一.前言 二.华为设备图标简介 三.通信与网络 1.网络通信基本概念 2.信息传递过程 3.常见术语 4.数据通信网络基本概念 5.网络设备 四.网络类型与网络拓扑 1.局域网.城域网.广域 ...

  9. es检索学习笔记第一篇

    文章目录 概念 倒排索引 分词器ik 创建mapping 查看索引,修改,删除 添加文档,查看文档,修改文档,查看文档 RestClient 一.映射分析 二.使用client创建索引等 创建Rest ...

最新文章

  1. c语言折半查找法程序,C语言基础:二分查找法演示代码
  2. 细粒度情感分析:还在用各种花式GNN?或许只用RoBERTa就够了
  3. elixir官方入门教程 模式匹配
  4. 汇编语言 用push指令将a段中的前8个字形数据,逆序存储到b段中
  5. 低代码开发平台_低代码开发平台测评——伙伴云
  6. gridview 实现排序 (在不是使用sqlDataSource控件,而在后台编码绑定gridview时,指定那个字段排序时使用。本例用了单层结构,可修改后应用于多层)
  7. Compact Normal Storage for Small G-Buffers
  8. VB.NET学习笔记:异步委托实现等待窗体(loading界面),执行任务超时可以取消操作
  9. matlab画图,均值±标准差
  10. C语言--求质数(详解)(筛选求质数)
  11. unity人物刚体移动_Unity3D 角色(物体) 移动方法 合集
  12. 自定义控件:Flag标签
  13. 易安居平安家园隐私政策
  14. 堆晶结构_堆晶岩形成条件
  15. 腾讯位置服务仿微信发送位置功能
  16. 安装nodejs时提示Leaving directory
  17. 手机界面显示无服务器,手机直接投屏电视,电视上显示投屏成功,却没有图像
  18. 基于SSM的停车场管理系统
  19. CentOS7.6搭建开源WCP知识管理系统
  20. 【ZCMU1930】帽子戏法(并查集)

热门文章

  1. 虎言新媒体训练营 助力初级会计成功转型新媒体运营
  2. C语言_链式栈结构+二进制计算器
  3. 说话人识别VAD算法概述
  4. 第四章 MCS-51单片机汇编语言程序设计
  5. HTML与CSS实现网页的超链接及美化
  6. html编码后台转换,HTML编码转换、HTML部分实体
  7. Android如何判断系统是否已经被Root
  8. 全球营商环境报告及数据(2004-2020年)
  9. 获取系统当前时间----sqlServer
  10. iOS 权限提示语国际化