网站首页 > 技术教程 正文
前言
嵌入式的设备,或多或少都需要对设备进行更新已适配更多的需求,如果未出货的设备还可以使用下载线去下载,但是如果出货之后到了客户那里,客户没有下载线而且不是专业人员,无法对设备进行升级,这时候,bootLoader 的重要性就凸显出来了,bootLoader 的设计就是为了设备能够进行远程升级或者只用指令升级,极大简便了升级需要的步骤,做到傻瓜式升级,极大增强了产品的后续维护性。
下面我来介绍写如何快速实现 STM32 BootLoader 的引导,帮助正在读文章的您更快将此技术运用起来!
一、Bootloader 是什么?
Bootloader是在应用程序开始前运行的一个小程序,里面可以进行一些初始化操作,升级引用程序等,在嵌入式设备中很常见。
二、BootLoader 的实现
我这里做了一个简单的 BootLoader 程序,只能进行引导,还没有对升级进行编写,升级是对约定好的应用程序的 Flash 进行擦+写,比较常用的升级方式是通过 TFTP 的方式进行升级,您可以在 STM32官方的这个例程找到答案: 基于LwIP TCP/IP栈通过以太网进行STM32F4x7应用内编程(IAP)(AN3968)
2.1 生成 bin 文件
- 使用 Cube 生成出来后,打开工程的设置选项,填入如下命令
fromelf --bin -o ".\bin_file\@L.bin" "#L"
编译之后,可以看到 bin_file 文件夹里面生成了 bin 文件,并可以知道其大小,我们根据其大小约定应用程序在 Flash 的起始位置
2.2 确认应用程序的起始位置
- 升级的过程被称为 IAP(In Application Programming) ,每个芯片的 Flash 的扇区不同,我这里使用的是 STM32F767,上官网查看有关资料:STM32F76xxx and STM32F77xxx advanced Arm?-based 32-bit MCUs.pdf 里面有关于 Flash 扇区的地址信息:
- 在步骤2.1已经知道 BootLoader 的 bin文件大小是22 KB,我们可以根据上面的 Flash 扇区进行分配,我将应用程序的起始位置定在 扇区1,起始地址为 0x0800 8000
2.3 编写引导程序
#include "stm32f7xx.h"
typedef void (*pFunction)(void);
/*!
* @brief 跳转到应用程序段
* 执行条件:无
* @param[in1] : 用户代码起始地址.
*
* @retval: 无
*/
void jump_to_app(uint32_t app_addr)
{
pFunction jump_to_application;
uint32_t jump_address;
/* Check if valid stack address (RAM address) then jump to user application */
if (((*(__IO uint32_t*)app_addr) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
jump_address = *(__IO uint32_t*) (app_addr + 4);
jump_to_application = (pFunction) jump_address;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) jump_address);
jump_to_application();
}
}
#define FLASH_JUMP_ADDR (0x08008000)
int main(void)
{
/*
初始化程序省略.....
*/
if(((FLASH_JUMP_ADDR+4)&0xFF000000)==0x08000000) //Judge if start at 0X08XXXXXX.
{
jump_to_app(FLASH_JUMP_ADDR); // Jump to APP
}
while(1)
{
}
}
三、App 的实现
3.1 修改 IROM1 的位置
根据约定好的 Flash 起始位置进行更改,上面步骤 2.2 已经确定好是 0x08008000
3.2 修改向量表
搜索宏定义 VECT_TAB_OFFSET,将 0x00 改为距离 0x08000000 的偏移量
/*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x8000 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
3.3 加入 App 循环打印提示
void StartDefaultTask(void const * argument)
{
/* USER CODE BEGIN StartDefaultTask */
segger_rtt_init("APP enter!");
/* Infinite loop */
for(;;)
{
print_log("You are in App now !!\n");
osDelay(1000);
}
/* USER CODE END StartDefaultTask */
}
四、演示效果
- 确认烧录过程是 Erase Sectors!
- 打开 RTT 窗口,连接 RTT 到 STM32 ,依次烧录 BootLoader 和 App 的程序;
如何使用 JLink 实现 Segger log 可以按参考我之前的文章: 【嵌入式小技巧】stm32 实现 Segger RTT 打印(超详细) - 烧录完 App 程序之后,可以在 RTT窗口 看到正确引导到 App,成功!!!
总结
以上是使用 快速搭建 STM32 Bootloader 的引导程序,希望能够帮助正在读文章的您更快将此技术运用起来!
完整代码可进群免费领取!!!
嵌入式物联网的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而错失高薪offer。不过别担心,我为大家整理了一份150多G的学习资源,基本上涵盖了嵌入式物联网学习的所有内容。点击下方链接,0元领取学习资源,让你的学习之路更加顺畅!记得点赞、关注、收藏、转发哦!
点击这里找小助理0元领取:扫码进群领资料
猜你喜欢
- 2024-10-23 基于S12 MagniV系列的LIN Bootloader设计
- 2024-10-23 怎么使用USBasp给arduino烧写bootloader?
- 2024-10-23 腾讯 ROG 游戏手机 6 / Pro 公开内核源码并支持解锁 bootloader
- 2024-10-23 浅谈基于uds的bootloader设计(简要概述u-boot的主要功能)
- 2024-10-23 Bootloader引导程序uboot(bootice 引导)
- 2024-10-23 基于CAN总线的Bootloader设计与实现
- 2024-10-23 Rust语言开发操作系统-第二章(最小化内核)
- 2024-10-23 基于RT-Thread完整版搭建的极简Bootloader
- 2024-10-23 海信阅读手机A9现可解锁bootloader并获取root权限
- 2024-10-23 三星警告Galaxy Z Fold 3解锁bootloader将失去相机功能
你 发表评论:
欢迎- 最近发表
-
- linux日志文件的管理、备份及日志服务器的搭建
- Linux下挂载windows的共享目录操作方法
- Linux系统中的备份文件命令(linux系统中的备份文件命令有哪些)
- 麒麟KYLINOS|通过不同方法设置用户访问文件及目录权限
- 「Linux笔记」系统目录结构(linux目录的结构及含义)
- linux中修改归属权chown命令和chgrp命令
- 工作日报 2021.10.27 Android-SEAndroid权限问题指南
- Windows和Linux环境下,修改Ollama的模型默认保存路径
- 如何强制用户在 Linux 上下次登录时更改密码?
- 如何删除Linux文件夹中除某些扩展名之外的所有文件?
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)
本文暂时没有评论,来添加一个吧(●'◡'●)