bootloader学习笔记---第一篇以stm32为例

2023-05-16

目录

一、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的代码


                PRESERVE8
                THUMB


; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
				EXPORT  __Vectors
					
__Vectors       DCD     0                  
                DCD     Reset_Handler              ; Reset Handler

				AREA    |.text|, CODE, READONLY

; Reset handler
Reset_Handler   PROC
				EXPORT  Reset_Handler             [WEAK]
                IMPORT  mymain

				LDR SP, =(0x20000000+0x10000)
				BL mymain

                ENDP

start_app   PROC
				EXPORT  start_app

				; set vector base address as 0x08040000
				ldr r3, =0xE000ED08
				str r0, [r3]
				
				ldr sp, [r0]      ; read val from addr 0x08040000
				ldr r1, [r0, #4]  ; read val from addr 0x08040004

				BX r1

                ENDP
                

                 END

在主函数中调用了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(适用于单片机)

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

bootloader学习笔记---第一篇以stm32为例 的相关文章

  • 【SLAM】VINS-fusion,VINS-Mono 编译,使用T265测试

    安装 VINS fusion VINS Mono 将vins mono 下载到ros工作空间catkin ws里面 span class token builtin class name cd span home jiangz catkin
  • 总结使用layui-laydate日历控件遇到的问题

    一 利用layui laydate日历控件选择月份 1 问题 选择月份时不能实现鼠标直接点击选择 xff0c 选择之后需要按 确定 原来的代码 html文件 xff1a span class token operator lt span d
  • 【pytorch】torch1.7.1安装、查看torch版本、GPU是否可用

    在conda 虚拟环境下安装torch 61 61 1 7 1 43 GPU版本 本机环境 CUDA 11 0Python 3 7 安装torch1 7 1 官网搜索确认需要下载的对应本机cuda的torch版本 xff0c 使用在线下载即
  • S.BUS协议

    内容 本篇文章主要是S BUS协议原理介绍 xff0c 并实现了arduino输出S BUS数据 S BUS简介 SBUS是一个接收机串行总线输出 xff0c 通过这根总线 xff0c 可以获得遥控器上所有通道的数据 目前很多模型及无人机电
  • window10+TensorRT-8.2.5.1+yolov5 v6.2 c++部署

    一 准备工具 1 1 visual studio下载安装 参考 xff1a vs2019社区版下载教程 xff08 详细 xff09 Redamancy 06的博客 CSDN博客 vs2019社区版 1 2 显卡驱动 43 cuda 43
  • openstack创造实例报:找不到有效有效主机,没有足够主机,而且点击实例还报500

    第一次接触openstack时候 xff0c 再创建实例时候右上方就弹出创建失败 实例 xxx 执行所请求操作失败 xff0c 实例处于错误状态 请稍后再试 错误 找不到有效主机 xff0c 原因是 没有足够的主机可用 这个问题是因为你的o
  • Kubernetes v1.21 发布,新版本主要特性

    美国时间 4 月 8 日 xff0c Kubernetes v1 21 正式发布 xff0c 这是 Kubernetes 在 2021 年发布的第一个版本 此版本包含 51 项增强功能 xff1a 13 项增强功能已进入稳定阶段 xff0c
  • 基于51单片机的火焰报警器

    基于51单片机的火焰报警器 一 模块描述 1 可以检测火焰或者波长在760纳米心1100纳米范围内的光源 2 探测角度60度左右 xff0c 对火焰光谱特别灵敏3灵敏度可调 图中蓝色数字电位器调节 3 对火焰的探测距离 跟灵敏度和火焰强度有
  • STM32的大小端模式——什么是大小端模式?

    目录 1 什么是大小端模式2 为什么会有大小端模式之分3 什么情况需要考虑大小端模式4 常见的设备的大小端模式5 测试大小端模式例程6 大小端转化例程 1 什么是大小端模式 大端模式Big Endian xff1a 高字节存于内存低地址 x
  • MDK KEIL 烧录STM32下载错误:Flash Timeout.Reset the Target and try it again.解决办法(芯片解锁 解除读报护)

    使用keil开发STM32点下载时出现下面的报错 xff1a 点确定后 xff1a 出现如上情况很可能是该芯片锁死 xff0c 即设置了读写保护 解决方法是想办法解锁芯片 xff0c 可以使用ST Link配合stlink utility软
  • Visual Studio 如何创建C/C++项目

    这里不说Visual Studio安装过程 xff0c 默认已经安装好软件 对Visual Studio安装有疑问的可以参考 xff1a Visual Studio安装教程 1 打开软件Visual Studio xff0c 点击创建新项目
  • Visual Studio安装教程

    本文章主要记录Visual Studio2019的安装过程 xff0c 由于只用于开发C C 43 43 xff0c 因此关于其它语言支持将不安装 xff0c 仅供参考 一 下载 1 下载地址在微软官网 xff1a 微软官网 2 选择菜单栏
  • CAN波形解析实例(1)

    这里的CAN数据波形抓取的是两个STM32F103设备通过CAN通信一方发送另一方接收 xff0c CAN收发器使用的是TJA1051 xff08 扩展帧发送数据ID 61 0x18DAF110 Data 61 0x06 0x08 xff0
  • GPIO推挽输出和开漏输出模式区别详解

    以STM32参考手册中的GPIO输出配置图为例 xff1a 看到输出驱动器虚线框中的内容 xff0c 输出驱动器中的P MOS和N MOS两个MOS管就是实现推挽输出和开漏输出的关键 推挽输出模式下 xff0c P MOS和N MOS都正常
  • 树莓派新手入门教程

    截至目前 20210405 xff0c 树莓派最新版本为4B xff0c 如下图所示 xff1a 树莓派3B 43 的主要的部件位置 xff1a 下载最新Raspbian系统镜像 1 首先进入树莓派官网 xff1a https www ra
  • 公司研发工具链体系化建设,帮助公司从混乱走向正规

    一 软件发布平台 没办法对外提供二进制库下载便捷方式不方便部署 xff0c 不同版本之间预览和说明性欠缺问题 可以参考的解决方案 xff1a https www cnblogs com djlsunshine p 11164770 html
  • 关于写代码的几个看法

    最近在新公司负责bug的修复 xff0c 发现很多的代码逻辑理解起来有些困难 现在将其中观察到的现象列出来 xff0c 谈谈自己的看法 1 类过大 对于代码来说 xff0c 我们在编写的时候最好做到SRP Single Responsibi
  • 树莓派VNC server设置开机自启动

    目前已测试OK的几个方法 xff1a 方法1 xff08 作为服务自启动 xff09 xff1a 在 etc init d 中创建一个文件 例如tightvncserver xff1a span class token function s
  • 一个结构体 = 另一个结构体(同类型结构体之间可直接赋值操作)

    两个同类型结构体变量可以直接赋值 xff0c 不同类型结构体不能直接赋值 span class token macro property span class token directive hash span span class tok
  • FreeRTOS任务切换过程深层解析

    FreeRTOS 系统的任务切换最终都是在 PendSV 中断服务函数中完成的 xff0c uCOS 也是在 PendSV 中断中完成任务切换的 为什么用PendSV异常来做任务切换 PendSV 可以像普通中断一样被 Pending xf

随机推荐

  • QT C++入门学习(1) QT Creator安装和使用

    Qt官方下载 Qt 官网有一个专门的资源下载网站 xff0c 所有的开发环境和相关工具都可以从这里下载 xff0c 具体地址是 xff1a http download qt io 进入链接后 xff0c 是一个文件目录 xff0c 依次进入
  • QT初体验:手把手带你写一个自己的串口助手

    前言 本文记录一下用QT Creator 写一个基本功能齐全的串口助手的过程 xff0c 整个工程只有几百行代码 xff0c 跟着做下来对新手来说可以更快了解整个QT项目的开发过程和一些常用控件的使用方法 对新手学习QT能增强信心 xff0
  • QT如何打包生成独立可执行.exe文件

    一 将QT程序使用Release编译 二 新建一个文件夹 xff0c 将Release编译生成的exe文件复制到新建文件夹中 先找到Release编译生成的exe文件夹位置 xff0c 与项目创建的文件夹有关 xff1a 临时文件夹 rel
  • 利用OpenCV识别不规则图形轮廓并找其中心点和角度

    关于寻找图形的轮廓 xff0c 想来大家都不陌生 但平常寻找并进行识别的轮廓都是较为标准的图形 xff0c 如圆形 xff0c 矩形等 但在一些特殊情况下 xff0c 我们所检测的图形并不是理想的标准图形 比如说我们检测元件的引脚 xff0
  • 神经网络学习小记录21——InceptionV3模型的复现详解

    神经网络学习小记录21 InceptionV3模型的复现详解 学习前言什么是InceptionV3模型InceptionV3网络部分实现代码图片预测 学习前言 Inception系列的结构和其它的前向神经网络的结构不太一样 xff0c 每一
  • Ubuntu的快乐学习3——ros的launch用法

    Ubuntu的快乐学习3 ros的launch用法 学习前言launch是什么launch的使用方法一 简单使用二 常用标签1 launch标签2 node标签3 include标签4 remap标签5 param标签6 rosparam标
  • 三周年创作纪念日

    机缘 不知不觉已经开始分享三周年了 xff0c 最开始什么都不懂 xff0c 作为自动化的学生 xff0c 以为学点算法就可以变得厉害一些 xff0c 于是学了点C 43 43 相关就开始分享 后来立志于研究深度学习算法 xff0c 感觉强
  • win10+vs2017+opencv4.0.1+opencv_contrib-4.0.1详细教程

    最近想好好认真学习一下opencv4 0 xff0c 需要用到contrib扩展库 xff0c 配置完记录下 先写一下版本信息 xff1a opencv4 0 1 xff0c vs2017和 win10 其他opencv版本安装和配置原理一
  • OpenHD---低成本开源高清数字图传

    转载注明出处 文章目录 一 前言二 OpenHD简单介绍三 图传材料准备1 树莓派2 摄像头 排线 SD卡 读卡器4 网卡 四 硬件连接五 镜像刷写六 通电测试七 系统参数设置八 连接飞控九 关于二次开发十 最后 一 前言 这篇文章是对树莓
  • PS2手柄通讯协议解析---附资料和源码

    文章目录 一 PS2介绍二 PS2通讯协议介绍 xff08 1 xff09 PS2端口介绍 xff08 2 xff09 PS2通讯过程 三 基于STM32的PS2通信源码四 文档与源码下载链接 一 PS2介绍 今天就带大家来认识一下PS2的
  • Stm32延时与计时方法(HAL库)

    文章目录 一 延时的3种方法1 循环延时2 定时器中断延时与非中断延时 三 定时器中断式计时与延时二 定时器非中断式延时四 代码例程五 同系列博客 一 延时的3种方法 首先 xff0c 先了解一下什么延时 顾名思义 xff0c 延时即是延长
  • CAN通信知识梳理及在Stm32上的应用(HAL库)

    文章目录 一 CAN通信简介二 硬件连接三 CAN总线上的电平信号四 CAN帧的种类 xff08 1 xff09 遥控帧 xff08 2 xff09 数据帧 五 CAN的仲裁方法六 CAN在Stm32上的应用 xff08 1 xff09 C
  • C语言标准库函数大全(ctype、time 、stdio、stdlib、math、string)

    文章目录 C语言函数库 一 lt ctype h gt 二 lt math h gt 三 lt stdio h gt 四 lt stdlib h gt 五 lt time h gt 六 lt string h gt 文档资料 C语言函数库
  • 作品分享:基于STM32的温度报警器含源码、原理图、PCB文件、作品报告

    文章目录 一 前言二 材料准备三 硬件部分四 软件部分1 底层封装库2 中间层3 应用层 五 外壳设计六 资料链接 一 前言 该作品是我在华工电工开放实习的作品 xff0c 本作品由七部分组成 中央为Stm32F405RG芯片 xff0c
  • 基于时延法的麦克风阵列声源定位分析

    文章目录 一 关于麦克风阵列二 关于声源定位三 基于广义互相关 GCC 计算时延四 基于时延差的声源定位法1 近场模型2 远场模型 五 三维空间阵列的声源定位系统实现1 推导过程 六 六元圆形麦克风阵列声源定位七 相关链接 一 关于麦克风阵
  • STM32实现PWM输出与PWM输入捕获(HAL库)

    文章目录 一 前言二 STM32 定时器2 1 基本定时器2 1 1 功能与框图2 1 2 CubeMX配置 2 2 通用定时器2 2 1 功能与框图2 2 2 CubeMX配置 2 3 高级定时器2 3 1 功能与框图2 3 2 Cube
  • 宇树A1电池拆解分享

    文章目录 一 关于A1电池二 拆解过程2 1 结构设计2 2 电路方案2 3 电芯设计 三 相关链接 一 关于A1电池 今天的主角是宇树的A1电池 该电池主要用在宇树的A1机器狗上 xff0c A1主打的是运动性能 xff0c 最大持续奔跑
  • 大疆Mini1充电管家拆解分享

    文章目录 一 关于充电管家二 拆解过程 一 关于充电管家 御Mini充电管家外观简洁优雅 xff0c 最多可容纳三块电池进行充电 xff0c 在一块电池充满电后会自动进行下一块电池的充电 xff0c 支持电池的电量显示 除此之外 xff0c
  • 磁盘高级管理工具VDO (redhat8版本以上或者centos8以上)

    1 vdo简述 Virtual Data Optimizer 通过数据去重 压缩的方式来优化存储空间 VDO层放置在现有块存储设备上 xff0c 例如Raid设备 本地磁盘设备 LVM 或文件系统 放置在VDO层之上 xff0c 也可以将V
  • bootloader学习笔记---第一篇以stm32为例

    目录 一 bootloader的任务 二 bootloader开发的基础知识 段的概念 重定位的概念 散列文件的概念 异常向量 xff08 待补充 xff09 三 最简单的bootloader程序 四 使用汇编跳转 五 备注 一 bootl