【[STM32]标准库-自定义BootLoader】
[STM32]标准库-自定义BootLoader
- Bootloader
- Bootloader的实现
- BOOTloader工程
- APP工程
Bootloader
bootloader其实就是一段启动程序,它在芯片启动的时候最先被执行,可以用来做一些硬件的初始化或者用作固件热更新,当初始化完成之后跳转到对应的应用程序中去。
bootloader程序需要通过下载器烧写到芯片中,而APP则可以通过有线方式的UART、IIC、USB、SPI等总线来通过bootloader来更新,视所设计的bootloader程序而定。另外,对于无线方式热更新APP,一般是用WiFi、bluetooth通过UART透传的方式烧写芯片APP程序。
Bootloader的实现
本次采用STM32F429IGT6单片机,Flash共有1MB大小,SRAM共有256KB。
本次设计一个Bootloader和一个APP程序,空间分别如下:
BOOTloader程序起始地址0x0800 0000分配大小为0xA000,40KB,
注意按照扇区对齐(比如4KB一个扇区)
APP程序起始地址0x0800 A000分配的大小为0xF6000,984KB。
STM32的中断向量表和栈顶地址
STM32Fx有一个中断向量表,这个中断向量表存放代码开始部分的后4个字节处(即0x08000004),代码开始的4个字节存放的是栈顶地址。
栈是从高到低分配,高地址到低地址
堆是从低到高分配,低地址到高地址
排列格式如下
我们知道一般情况下,我们下载的代码放在0x08000_000这个位置,为了实现bootloader,我们可以将下载代码的位置整体往后挪一段空间,比如我们挪到0x0800_3000,那么这之前挪动空出来的一段空间,我们就可以用来存放我们的bootloader程序。系统上电后先运行bootloader,bootloader决定是否要更新app,最后跳转到0x0800 3000这个位置执行。
上图为SystemInit中修改用户app存放位置(0x0800 3000)的地方,SystemInit在启动文件中用到,它会在复位后,在main函数运行之前运行;

BOOTloader工程
bootloader和App都是完整的STM32工程,区别在于工程所实现的功能和占用Flash的大小。由于Bootloader的功能比较单一,并且为了节约Flash留给用户App,Bootloader一般不带操作系统,所占用的Flash较小。APP是完整的用户程序,按照正常的设计流程进行设计,只需要在工程配置和部分初始化代码处进行修改。
设置工程起始地址,及其大小
中断向量表的地址偏移
调用函数NVIC_SetVectorTable()进行配置。BOOT工程一般不需要配置
执行BOOT后,跳转到APP程序中
注意点:
检查堆栈地址是否有效,单片机的RAM大小为0x30000,0x3000 0000 - 0x3000 = 0x2FFD 0000,也可以用其他方法来计算RAM是否超过单片机的范围
关闭全局中断,__set_PRIMASK(1);仅只剩下NMI 和硬 fault 可以响应,记得在APP工程设置__set_PRIMASK(0);
复位BOOT工程中用到的外设
函数指针赋值为Reset_Handler向量的地址
设置堆栈地址
跳转到APP中
typedef void (*Run_APP_t)(void);
/**
-
@brief 跳转并执行到APP程序
-
@param APPProgramAddr : APP程序的地址
-
@retval None
/
static void Jump_to_APP(uint32_t APPProgramAddr)
{
Run_APP_t run_app = (Run_APP_t)((uint32_t*)(APPProgramAddr + 4));/* 检查堆栈地址(RAM地址)是否有效,然后跳转到用户应用程序 /
if(((uint32_t*)APPProgramAddr & 0x2FFD0000) == 0x20000000)
{
/*
关闭所有中断,
在它被置 1 后,就关掉所有可屏蔽的异常,只剩下NMI 和硬 fault 可以响应。
它的缺省值是 0,表示没有关中断。
*/
__set_PRIMASK(1);/* 复位所有已经开启的外设 */ GPIO_DeInit(GPIOH); GPIO_DeInit(GPIOA); GPIO_DeInit(GPIOC); EXTI_DeInit(); CRC_ResetDR(); USART_DeInit(USART1);/* 设置堆栈指针 */
// __set_PSP((uint32_t)APPProgramAddr);
// __set_CONTROL(0);
__set_MSP((uint32_t)APPProgramAddr);
/* 跳转到APP程序中执行 */run_app();
}
else
{USART1Printf("BOOT_ERROR1!\r\n");
}
}
APP工程
Flash的起始地址,大小
中断向量表偏移地址和开启全局中断
/* 设置中断向量表 /
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0xA000);//中断向量表偏移
/
关闭所有中断,
在它被置 1 后,就关掉所有可屏蔽的异常,只剩下NMI 和硬 fault 可以响应。
它的缺省值是 0,表示没有关中断。
*/
__set_PRIMASK(0);
Keil5生成BIN文件
fromelf --bin -o “$L@L.bin” “#L”
注意点:上电应检查标志位,不能初始化任何外设,根据该标志位来决定是否进入APP
通过软件复位给 APP 一个干净的系统
这里的标志位存在RTC备份寄存器0中,占用4个字节
相关文章:
【[STM32]标准库-自定义BootLoader】
[STM32]标准库-自定义BootLoader BootloaderBootloader的实现BOOTloader工程APP工程 Bootloader bootloader其实就是一段启动程序,它在芯片启动的时候最先被执行,可以用来做一些硬件的初始化或者用作固件热更新,当初始化完成之后跳转到对应的…...
Spring Boot项目中不使用@RequestMapping相关注解,如何动态发布自定义URL路径
一、前言 在Spring Boot项目开发过程中,对于接口API发布URL访问路径,一般都是在类上标识RestController或者Controller注解,然后在方法上标识RequestMapping相关注解,比如:PostMapping、GetMapping注解,通…...
Vue中有哪些优化性能的方法?
Vue是一款流行的JavaScript框架,用于构建交互性强的Web应用程序。在前端开发中,性能优化是一个至关重要的方面,尤其是当应用程序规模变大时。Vue提供了许多优化性能的方法,可以帮助开发人员提升应用程序的性能,从而提升…...
Python pandas遍历行数据的2种方法
背景 pandas在数据处理过程中,除了对整列字段进行处理之外,有时还需求对每一行进行遍历,来处理每行的数据。本篇文章介绍 2 种方法,来遍历pandas 的行数据 小编环境 import sysprint(python 版本:,sys.version.spli…...
Spring之@Transactional源码解析
前言 我们在日常开发的时候经常会用到组合注解,比如:EnableTransactionManagement Transactional、EnableAsync Async、EnableAspectJAutoProxy Aspect。今天我们就来抽丝剥茧,揭开Transactional注解的神秘面纱 EnableTransactionManagement注解的作用 当我们看到类似Ena…...
第三届国际亲子游泳学术峰会,麒小佑为亲游行业提供健康解决方案
第三届国际亲子游泳学术峰会大合影 2024年2月26—28日,第三届国际亲子游泳学术峰会在中国青岛成功召开。 第三届国际亲子游泳学术峰会是中国婴幼游泳行业最高标准的学术性会议,由亲游圈主办,旨在为本行业搭建一个高端圈层,帮助机…...
Python光速入门 - Flask轻量级框架
FlASK是一个轻量级的WSGI Web应用程序框架,Flask的核心包括Werkzeug工具箱和Jinja2模板引擎,它没有默认使用的数据库或窗体验证工具,这意味着用户可以根据自己的需求选择不同的数据库和验证工具。Flask的设计理念是保持核心简单,…...
C/C++ 说说引用这玩仍是干啥的
引用的本质就是给某个实例对象起个外号。生活中李逵,也叫黑旋风。诸葛亮,又叫孔明。 引用的方式: 类型& 引用名对象名 举个例子 int i0; int& ki;//这种方式就是引用----->i有了自己的小名,从次叫k了 std::cout<…...
swoole
php是单线程。php是靠多进程来处理任务,任何后端语言都可以采用多进程处理方式。如我们常用的php-fpm进程管理器。线程与协程,大小的关系是进程>线程>协程,而我们所说的swoole让php实现了多线程,其实在这里来说,就是好比让php创建了多个进程,每个进程执行一条…...
kubectl基础命令详解
管理名称空间资源 查看名称空间 [rootceshi-130 conf]# kubectl get ns [rootceshi-130 conf]# kubectl get namespace NAME STATUS AGE default Active 7d17h kube-node-lease Active 7d17h kube-public Active 7d17h kube-system …...
collection的遍历方式
增强for遍历 增强for的底层就是迭代器,为了简化迭代器的代码书写的。 他是jdk5之后出现的,其内部原理就是一个Iterator迭代器。 所有的单列集合和数组才能用增强for进行遍历。 package myCollection;import java.util.ArrayList; import java.util.C…...
SpringBoot中@Async使用注意事项
前言 Async这个注解想必大家都用过,是用来实现异步调用的。一个方法加上这个注解以后,当被调用时会使用新的线程来调用。但其实这里面也有一个坑。 问题 这个注解使用时存在如下问题:在没有自定义线程池的场景下,默认会采用Sim…...
IEEE 802.11 RTS/CTS/BA/Management
RTS/CTS IEEE 802.11 RTS/CTS即RTS/CTS协议(Request To Send/Clear To Send)即请求发送/清除发送协议是被802.11无线网络协议采用的一种用来减少由隐藏节点问题所造成的冲突的机制。 相当于一种握手协议,主要用来解决"隐藏终端"问题。"隐藏终端"(Hid…...
【风格迁移】对比度保持连贯性损失 CCPL:解决图像局部失真、视频帧间的连贯性和闪烁
对比度保持连贯性损失 CCPL:解决图像局部失真、视频帧间的连贯性和闪烁 提出背景解法:对比度保持连贯性损失(CCPL) 局部一致性假设 对比学习机制 邻域调节策略 互信息最大化对比学习:在无需标签的情况下有效学习区分…...
【C++】贪心算法
贪心算法(Greedy Algorithm)是一种基于贪心策略的算法,它在每一步选择中都采取当前状态下最优的选择,以希望最终得到全局最优解。贪心算法通常适用于满足最优子结构性质的问题,即问题的最优解可以通过其子问题的最优解…...
记一次dockerfile无法构建问题追溯
我有一个dockerfile如下: ENTRYPOINT ["/sbin/tini","-g", "--"] CMD /home/scrapy/start.sh 我原本的用意是先启动tini,再执行下面的cmd命令启动start.sh。 为啥要用tini? 因为我的这个docker…...
React使用 useImperativeHandle 自定义暴露给父组件的实例方法(包括依赖)
关键词 React useImperativeHandle 摘要 useImperativeHandle 是 React 提供的一个自定义 Hook,用于在函数组件中显式地暴露给父组件特定实例的方法。本文将介绍 useImperativeHandle 的基本用法、常见应用场景,以及如何处理其依赖项,以帮…...
yolov5v7v8目标检测增加计数功能--免费源码
在yolo系列中,很多网友都反馈过想要在目标检测的图片上,显示计数功能。其实官方已经实现了这个功能,只不过没有把相关的参数写到图片上。所以微智启软件工作室出一篇教程,教大家如何把计数的参数打印到图片上。 一、yolov5目标检测…...
JPA常见异常 JPA可能抛出的异常
1、EntityNotFoundException(实体不存在异常): 通过 JPA 查找一个不存在的实体。 2、NonUniqueResultException(非唯一结果异常): 查询返回了多个结果,但期望只有一个结果。 3、TransactionRequiredExcep…...
Dockerfile的艺术:构建高效容器镜像的指令详解与实战指南
在容器化技术风靡全球的今天,Dockerfile作为构建 Docker 镜像的蓝图,其编写技巧与理解深度直接影响着应用部署的效率与稳定性。本文将深入剖析Dockerfile中的核心指令,以实战角度为您呈现一份详尽的解读与操作指南,并在文末抛出一…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
《Offer来了:Java面试核心知识点精讲》大纲
文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...
Mac flutter环境搭建
一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...
WEB3全栈开发——面试专业技能点P8DevOps / 区块链部署
一、Hardhat / Foundry 进行合约部署 概念介绍 Hardhat 和 Foundry 都是以太坊智能合约开发的工具套件,支持合约的编译、测试和部署。 它们允许开发者在本地或测试网络快速开发智能合约,并部署到链上(测试网或主网)。 部署过程…...
c++算法学习3——深度优先搜索
一、深度优先搜索的核心概念 DFS算法是一种通过递归或栈实现的"一条路走到底"的搜索策略,其核心思想是: 深度优先:从起点出发,选择一个方向探索到底,直到无路可走 回溯机制:遇到死路时返回最近…...
