【嵌入式】stm32程序跳转实验

2023-05-16

【嵌入式】stm32程序跳转实验

菜老越

于 2019-04-23 17:54:56 发布

2888
 收藏 22
分类专栏: 嵌入式 文章标签: keil stm32 程序跳转 IAP BootLoader
版权

嵌入式
专栏收录该内容
32 篇文章4 订阅
订阅专栏
近期想研究下stm32基于BootLoader的IAP功能,要想实现这个,必须先搞明白程序跳转,在真正开搞前折腾了一下午,完成了程序跳转的简单测试。共用了两个程序,一个放在0x8000000开始的位置,暂称为Load程序;另一个放在0x8004000的位置,暂称为APP程序。两个程序分别包含以下功能:
1.Load程序:进入程序后首先向串口打印一句"This means START!”,然后在while(1)里循环打印“In While”,间隔为1秒;设立一个按键外部中断,中断发生后跳转到0x8004000的位置以运行APP程序。
2.APP程序:跳转过来后直接进到while(1)里循环打印“This is APP”,间隔为1秒,5秒后跳回Load程序。
下面先以最终的成功案例来介绍Load和APP程序。当然出于实验,也可以用在Load、APP程序中分别以不同形式操作led的方法,来检测Load和APP之间的跳转。

一、成功实验过程
1.Load程序
stm32代码下载到0x8000000开始的地址,程序跳转的意思也就是在程序运行时,通过一个跳转函数使得PC指针指到制定位置继续运行。看上去很简单但是重点需要注意跳转前后的中断的处理。
while(1)附近的程序如下

printf("This means START!\n");
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
        HAL_Delay(1000);
        printf("In While\n");

1
2
3
4
5
6
7
8
9
重点在于按键中断中的跳转函数Jump_test,程序如下

void Reset_test(void)
{
    typedef  void (*iapfun)(void);
    uint32_t JUMP_ADDR = 0x08004000;
    uint32_t STACK_ADDR = 0x20000000;
    uint32_t RESET_IRQ_ADDR = JUMP_ADDR + 4;
    iapfun jump2app;
    jump2app = (iapfun)*(volatile uint32_t *)RESET_IRQ_ADDR;
    __set_MSP(STACK_ADDR);
    __disable_irq();
    jump2app();
}
1
2
3
4
5
6
7
8
9
10
11
12
RESET_IRQ_ADDR 设置为JUMP_ADDR +4是因为stm32中断向量中,复位中断的相对地址为起始地址+4,如图所示;__set_MSP(STACK_ADDR)的作用为重新初始化堆栈;同时,在跳转前__disable_irq()是为了关闭所有中断,这似的在跳转过程中不会进入“很有缘分”的中断……

在这里插入图片描述
2.App程序
App程序在这里就更简单了,直接上代码

 

 int main(void)
{
  __enable_irq();
  SCB->VTOR = 0x8004000;
  
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  
  int count = 0;
  while (1)
  {
    HAL_Delay(1000);
    HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_7);
    printf("This is APP\n");
    if(count >= 5)
        HAL_NVIC_SystemReset();
    count++;
 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
其中头两行的__enable_irq()和SCB->VTOR = 0x8004000要在进入main函数一开始就执行,这是为了打开跳转前关闭的中断,并且重定位向量表,否则APP程序里的与中断相关的程序会炸。重定位中断向量时,往VTOR寄存器中写入的值即为APP程序的起始地址,具体为什么要这样,请参考《ARM Cortex-M3与M4权威指南》。经过用stm32Cube自动生成的一些列初始化后,就到了APP程序的主体。可以看到当定义的count变量大于5时,直接运行HAL_NVIC_SystemReset()使系统软重启,程序又从0x8000000的位置开始执行,即为跳回了Load程序。
这里需要注意的是在APP跳回Load程序时,本以为可以类比于Load跳到APP,即用Jump_test函数,跳到0x8000000的位置,结果发现这样操作时,虽然能跳回去,但Load程序中跟中断相关的代码会出现异常。如定时器中断一直处于活跃状态,无论怎么清标志位都出不来;同时,外部按键中断也因为中断优先级的问题偶尔挂起,无论怎么清除中断挂起状态都不行。DeBug了半天,看寄存器值看的都眼花了,还是无果。干脆直接重启系统,反正重启系统也是从0x8000000开始运行……

3.程序下载
3.1.Load程序下载
Load程序就是下载在0x8000000开始的位置,这个和普通下载程序一样,直接用默认值下载就好了,打开keil的Options for Target,选择Target选型卡,可以看到下图,红框里就是默认位置,只不过我将Size设置成了0x4000,也就是16k,因为Load程序很小,16k足够了,同时APP下在0x8004000的位置,正好紧邻着Load程序。

在这里插入图片描述
在选择Utilities选项卡,点击Settings,在点击Flash Download选项卡,如下图所示,Start和Size同上,这样一来。设置好后就可以先下载Load程序到单片机了。

 在这里插入图片描述

 

3.2.APP程序下载
同理的,APP设置过程同上,只是记得把Start设置为0x8004000,size随便设置,只要放得下你的程序就好了。设置好后点击下载,程序就被下到了0x8004000开始的位置。下面就可以测试啦。

4.程序测试
链接好ttl转串口线,打开串口助手后,可以观察到Load程序的运行结果

在这里插入图片描述

 

按下外部中断对应的按键后,跳入APP程序,打印结果如下。可以观察到打印6次This is APP后系统复位,重新进入Load程序。测试成功。

在这里插入图片描述

 

二、总结
1.跳转函数里要重新初始化堆栈,并禁用中断;
2.APP程序一进main函数首先要开启中断,并重定位中断向量;
3.APP跳回Load时直接用软复位就好了。如果用Jump_test类似的函数,跳回Load后整个中断系统会出现异常,不如直接复位重启所有,古人云出了Bug先重启,是有一定道理的……

通过这次实验实现了Load与APP间的互跳,接下的任务就是打造一个自己的BootLoader以及IAP程序啦
————————————————
版权声明:本文为CSDN博主「菜老越」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/spiremoon/article/details/89460441

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

【嵌入式】stm32程序跳转实验 的相关文章

  • C语言除法运算符“/”和求余运算符“%”

    看似两个很简单的运算符 xff0c 却也真要掌握用好它也不容易 xff0c 本文作为关于此类运算符的各方面的问题的汇总 xff0c 希望对你我都有一些帮助 除法运算符 二元运算符 xff0c 具有左结合性 参与运算的量均为整型时 xff0c
  • 冒泡排序

    include lt stdio h gt define LENGTH 8 void main int tmp number LENGTH 61 95 45 15 78 84 51 24 12 for i 61 0 i lt LENGTH
  • 金山词霸C++笔试(北邮11月23号)

    金山词霸笔试题 xff08 北邮11月23号 xff09 xff08 一 xff09 以下输出什么 xff1f char ptr 61 34 hello world 34 cout lt lt ptr h ptr指向字符串的首地址 xff0
  • 关于计算机研究和写作的链接收集

    研究相关的资源 What is Research in Computer Science 计算科学的研究是什么 xff1f 翻译 Basic Research Skills in Computer Science 计算科学的基本研究方法 R
  • 实战笔记之C++里面双冒号和冒号及点号引用符

    标题党了额 xff0c mark一下 xff0c 有时间再整理 以下节选自多人博客 推荐博文一篇http blog csdn net gyymen article details 4962873 箭头 xff08 gt xff09 xff1
  • 在Linux中如何修改root帐户的登录用户名

    vi etc passwd 按i键进入编辑状态 修改第1行第1个root为新的用户名 按esc键退出编辑状态 xff0c 并输入 x保存并退出 vi etc shadow 按i键进入编辑状态 修改第1行第1个root为新的用户名 按esc键
  • Linux elasticsearch 安装超详细教程

    1 下载elasticsearch 7 11 2 linux x86 64 tar gz 之所以下载7 11 2版本是因为我使用了中文分词器 xff0c 对应中文分词器的版本号 2 可以官方下载 xff0c 会比较慢 xff0c 这里提供我
  • 程序员做一辈子?

    首先 xff0c 程序员真有必要干一辈子吗 xff1f 如果你是个搬砖的 xff0c 你会考虑一辈子搬砖吗 xff1f 你肯定会想着过几年挣钱了 xff0c 买个车跑运输 xff0c 或者自己做工头 对程序员来说 xff0c 真心没有必要干
  • ubuntu系统怎么使用ifconfig和开启远程连接

    在ubuntu系统刚安装好之后ifconfig命令和开启远程连接都是不起作用的 xff0c 如果需要使ifconfig起作用需要安装一个小工具 xff0c 如果想开启远程连接的话也需要安装open ssh工具 开启ifconfig xff1
  • LDMIA、LDMIB、LDMDB、LDMDA、STMIA、LDMFD、LDMFA、LDMED、LDMEA等指令详解

    关于多寄存器加载存储指令 1 LDMIA指令 LDMIB指令 LDMDB指令 LDMDA指令 xff08 1 xff09 LDMIA指令 xff0c IA表示每次传送后地址加4 xff08 2 xff09 LDMIB指令 xff0c 每次传
  • FreeRTOS-互斥信号量

    原文地址 xff1a http blog csdn net xukai871105 article details 43456985 0 前言 在嵌入式操作系统中互斥型信号量是任务间资源保护的重要手段 下面结合一个具体例子说明FreeRTO
  • 执行体线程--ETHREAD

    typedef struct ETHREAD KTHREAD Tcb 内嵌了KTHREAD对象作为第一个数据成员 LARGE INTEGER CreateTime 包含了线程创建时间 xff0c 他是在线程创建时被赋值的 union LAR
  • 显卡驱动的作用(本质作用)

    确切资料表明显卡不需要驱动也可以进行显示 xff0c 只需要将显示的内容存到对应的显存地址就可以 xff08 通过cpu直接或者间接的硬连线实现 xff09 也就是说单纯的显示像素的话不需要使用显卡驱动 xff0c 但是单纯的显示像素甚至某
  • 智能指针之make_unique与make_shared

    make unique的实现 std make shared是C 43 43 11的一部分 xff0c 但是std make unique很可惜不是 它是在C 43 43 14里加入标准库的 xff0c 但我们可以自己实现make uniq
  • NVIDIA Jetson TX1 系列开发教程之十二:libcurl、RapidJSON安装

    NVIDIA Jetson TX1 系列开发教程之十二 xff1a libcurl RapidJSON安装 转载请注明作者和出处 xff1a http blog csdn net u011475210嵌入式平台 xff1a NVIDIA J
  • 用户标签体系的搭建方法

    一 标签体系的困境 每一个需求背后都有对应的痛点和问题 xff0c 在讲具体的方法之前 xff0c 笔者想简单阐述一下标签体系搭建和实践过程中企业一般会遇到的问题 困境 xff0c 方便读者理解本文的搭建思路 目的和未来的优化方向 用户标签
  • Windows 安装TVM 及各种报错解决!无GPU版本

    这篇先来一个不用GPU的下次 xff0c 再整一个带GPU的 xff01 系统基本信息 Windows 11 Anaconda 4 12 Python 3 8 13 Visual Studio 2022 这几天在Windows 下安装TVM
  • C++变量前面加下划线的含义

    C 43 43 变量前面加下划线和不加下划线都不会影响对变量的定义 xff0c 只是风格问题 xff0c 更喜欢将成员变量或者私有成员变量的前面加上下划线 以表示该变量是某个类的属性 比如 xff1a int size int getsiz
  • tensorflow中GPU相关设置解决显存不足

    1 显存不足时报错如下 xff1a E tensorflow stream executor cuda cuda dnn cc 359 could not create cudnn handle CUDNN STATUS INTERNAL
  • freertos 学习笔记——第一章、裸机进阶RTOS

    第一章 前言 1 1裸机的软件写法 1 xff0c 轮询系统 void main sys init while 1 task 1 task 2 任务处理在循环中依次执行 2 xff0c 前后台系统 中断被成为前台 xff0c 无限循环被成为

随机推荐

  • freertos学习笔记——第三章、任务控制——3.1 全局变量造成的困扰

    裸机中经常使用全局变量 xff0c 但在RTOS中大量使用全局变量会造成很多问题 在RTOS中也可以使用全局变量但使用时一定要注意有哪些任务会写这个变量 xff0c 哪些任务会读这个变量 尤其切记在使用这个变量的过程中变量的数值发生改变 x
  • MTK项目总结

    一 sensor路径 vendor mediateck propri sensor校准 xff1a 加速度校准 adb shell 34 echo 1 gt sys bus platform drivers gsensor test cal
  • JAVA简述和JDK环境搭建

    一 Java 语言背景介绍 1 什么是 Java 语言 xff1f Java 语言是美国 Sun 公司 xff08 Stanford University Network xff09 在 1995 年推出的计算机语言 2009年 xff0c
  • Java变量、标识符以及类型转换详解

    本篇文章为本人学习笔记 xff0c 如有错误 xff0c 希望指正 一 进制 进制详细概念以及转换 xff1a https blog csdn net diyu122222 article details 80692904 这篇写的很好 x
  • Java运算符的使用和规则

    本篇文章为本人学习笔记 xff0c 如有错误 xff0c 希望指正 Java中运算符大致分为以下几类 xff1a 算数运算符赋值运算符自增自减运算符关系运算符逻辑运算符三元运算符 1 算数运算符 算数运算符包括 xff1a 作用 43 加法
  • Java的内存分配理解

    本篇文章为本人学习笔记 xff0c 如有错误 xff0c 希望指正 Java 程序在运行时 xff0c 需要在内存中分配空间 为了提高运算效率 xff0c 就对空间进行了不同区域的划分每一片区域都有特定的处理数据方式和内存管理方式 区域名称
  • IntelliJ IDEA的Debug教程

    1 什么是Debug模式 它是供程序员使用的程序调试工具 xff0c 它可以用于查看程序的执行流程 xff0c 也可以用于追踪程序执行过程来调试程序 2 Debug模式操作流程 如何加断点 选择要设置断点的代码行 xff0c 在行号的区域后
  • opencv获取相机图像并发布为ROS节点

    仅记录工程中的使用 完整代码请查看 xff1a https github com chx725 cv and ros ROS是最普遍使用的机器人系统之一 xff0c 提供了各种功能包 xff0c 仿真环境 xff0c 模型 xff0c 可视
  • Java中两种方法实现栈和队列(面试)

    学到LinkedList xff0c 上课时老师提了一下代码实现栈和队列 xff0c 面试可能会用上 xff0c 就码了栈和队列两种实现方案 如有问题 xff0c 希望指出 一 栈 1 数组实现栈 span class token comm
  • docker容器迁移教程

    前言 被领导要求部署一个和测试环境一样的演示环境 xff0c 并且数据库也要同步过去 xff0c 服务器上的各种服务都是docker部署的 xff0c 由于之前docker玩的比较少 xff0c 所以还是踩了不少坑的 xff0c 在此记录一
  • Java多sheet模板导出表格

    前言 需求是这样的 xff0c 需要在页面导出列表表格时同时导出每项的详情数据 xff0c 而且详情表格并不是一个常规的二维表格 xff0c 就像图中这样的效果 xff0c 所以要解决的最主要两个问题就是 xff1a 多sheet实现 异形
  • docker容器时间不同步导致在java应用中获取的时间不正确问题

    一 前言 在把Java应用部署到docker容器时 xff0c 发现应用获取到的时间和现实时间相差了8个小时 xff0c 会导致一系列不必要的麻烦 二 解决方案 1 首选需要确保宿主机的时区和时间的准确 现在宿主机上用 date R 看一下
  • Caffeine一级缓存介绍和应用

    Caffeine介绍 redis和caffeine的区别 相同点就不用说 xff0c 广义上都是缓存的方式 咱们就说说不同 redis是将数据存储到内存里 xff1b caffeine是将数据存储在本地应用里caffeine和redis相比
  • Java中使用es条件构造器BoolQueryBuilder

    前言 由于es在java中查询没法像mybatis那样方便 xff0c 而且es的构造器使用也比较繁琐 xff0c 理解不是很方便 xff0c 所以写一篇文章来记录es构造器BoolQueryBuilder查询时各种条件的构造的正确姿势 教
  • 群晖docker容器内mysql部署和远程连接

    群晖docker容器内mysql部署和远程连接 1 docker内Mysql部署2 Mysql远程访问配置 1 docker内Mysql部署 首先在群晖docker内安装ubuntu镜像 xff0c 启用镜像时注意对容器和宿主机的端口映射进
  • eclipse的安装及配置PyDev插件(win10)

    原博文 xff1a Windows下安装Eclipse 43 python2 7 43 Pydev 一 安装eclipse 学习Java第一步就是装eclipse 我每学习一门语言都会先死在安装程序上 这个也一样 一 去eclipse官网下
  • 小微企业技术人员面试流程及常见问题整理分析

    技术人员面试流程 在同一个小的企业做久了 xff0c 当有人员离职后 xff0c 招聘中的面试的工作就落在了资历老一点的员工上 虽然不是专业的HR xff0c 但还是在此记录一下一些人员面试的基本流程步骤及主要内容 一 面试流程 1 接待应
  • Ubuntu 解决触摸板不识别问题

    Ubuntu 解决触摸板不识别问题 span class hljs built in sudo span vi etc default grub span class hljs comment 把GRUB CMDLINE LINUX 61
  • 图像的灰度化、二值化

    目录 1 图像像素点 2 灰度化 3 二值化 4 使用open cv库进行图片的灰度化 二值化 4 1 将图片转换为灰度图 4 2 将灰度图转换为二值化图图片 1 图像像素点 在图像处理中 xff0c 用RGB三个分量 xff08 R xf
  • 【嵌入式】stm32程序跳转实验

    嵌入式 stm32程序跳转实验 菜老越 于 2019 04 23 17 54 56 发布 2888 收藏 22 分类专栏 xff1a 嵌入式 文章标签 xff1a keil stm32 程序跳转 IAP BootLoader 版权 嵌入式