关于M0内核MCU的Bootloader编写_m0内核的bootloader-程序员宅基地

技术标签: Bootloader  中断向量表映射  Cortex-M0  内核启动  51822  嵌入式  

      在使用MCU的时候如果要使用程序下载、程序升级或程序备份,那么都需要自己编写Bootloader。那么编写Bootloader使首先应该完成的是什么呢?没错,就是中断向量表。那如果操作中断向量表呢?这里就详细说一下:

      要操作中断向量表,首先要知道中断向量表是什么,它的作用是什么?在编写MCU程序的时候都会用到中断,然后会有中断回调函数。MCU是如何通过中断而转到中断回调函数呢?这就需要中断向量表了,可以简单的理解,中断向量表就是连接中断事件和中断回调函数的桥梁。当有中断产生的时候,MCU会到中断会向量表中找回调函数,进而去执行。如果想了解更多的可以看M0和M3内核手册。

      那知道了中断向量表是什么,现在要编写Bootloader的时候需要对中断向量表进行处理。在我的另一篇文章《STM32 IAP下载》篇中有介绍M3内核的相关操作,这里就不做过多介绍了,有兴趣的可以去看一下,附上链接:https://blog.csdn.net/qq_26226375/article/details/80158869

      这篇文章还是以一个特定的MCU来解释,因为最近都在玩Nordic的51822芯片,所以,就以51822为例来介绍。51822是一款可以跑蓝牙协议栈的芯片,这里并没有使用协议栈,用的裸机。言归正传,如何操作中断向量表,M0和M3内核有一定的区别,使用M3内核的STM32F1XX可以直接对中断向量表进行映射,而且这个操作只需要配置一个寄存器就好了。而使用M0的51822芯片却不能这么做,有兴趣的可以试一下,如果写两个工程,一个Boot程序,一个应用程序,两个工程的起始地址不一样。如果可以完成从Boot程序成功跳转到应用程序,那么恭喜,已经成功了四分之一了。如果这时候在应用程序中进入了中断回调函数,会发现好像中断回调函数的执行结果和自己在应用程序中写的中断回调函数结果不一样,但是却好像跟Boot的中断回调函数一样,这就很气了。这是为什么呢?这是因为所有程序的起始地址都是从0x00000000开始,从起始地址向后偏移一定的位置是中断向量表,MCU都是根据这个中断向量表来找到中断回调函数。虽然在应用程序中也定义了中断向量表,但是如果不做处理,这个向量表不能被MCU检测到。所以当在应用程序中调用回调函数的时候,程序会回到Boot的中断回调函数位置,然后调用Boot的回调函数。那么我们最关键的就是让应用程序能调用应用程序的回调函数。

    这里顺便介绍一下M0的启动流程。通常M0处理器都是从0x00000000开始的,内容如下图:

  

0x00000000的地址有个0x20008000的地址,这个地址就是(MSP)主栈指针的初始值,在往上的4个字节是复位后的程序执行的起始地址(会先执行复位)。从图上可以看到是0x000000c1,也就是说,程序在复位后,会从0x000000c1的位置开始。而0x00000000-0x000000c0的内容都被称之为“向量表”。那之后的是什么呢?见下图:

这个图就可以详细的看到向量表中存储的是什么。复位向量后是NMI向量,之后是硬件错误。。bulabula。。。这些看起来是不是有点眼熟。没错,这些就是在启动文件里的向量表内容。一般都会在.s文件里。这里依旧以51822为例:

可以看到这个启动文件里的东西,跟我们上边说的是对应的。我们看到的都是异常中断的中断回调函数,当程序出现异常的时候就会进入这些异常回调函数中。同样,图片下方的POWER_CLOCK_IRQHandler 、RADIO_IRQHandler..bulabula 也都是中断回调函数。既然M0内核没有办法进行中断向量表映射,那我们就需要让程序在boot和应用程序分别调用自己的中断回调函数。但是每次中断,程序都会回到0x00000008的位置开始寻找,所以必须在0x00000008的位置开始就区分开。

因为中断回调函数也是函数,也是调用一个地址的内容,所以我们可以把中断回调函数的内容都换成有序的、可以被我们控制的地址。那么当调用中断回调函数的时候,程序就会调用我们希望其调用的地址。可以这样做,如下附上代码:

/*
中断向量表重映射,映射到0x20000000的位置
*/
uint32_t my_vectors[48] __attribute__((at(0x20000000)));
void NMI_Handler()
{
    (*(void(*)(void))my_vectors[2])();
}
void HardFault_Handler()
{
    //(*(void(*)(void))my_vectors[3])();
}
void SVC_Handler()
{
    (*(void(*)(void))my_vectors[11])();
}
void PendSV_Handler()
{
    (*(void(*)(void))my_vectors[14])();
}

。。。。

这样,所有的中断回调函数全都会去调用my_vectors这个数组的内容的地址位置。我们把这个数组的地址定义到Boot程序和应用程序都能调用到的RAM区域,当然,这个地址要保护起来(Boot程序和应用程序都不会使用该地址)。然后我们在boot里将从0x00000000-0x000000c0的内容(向量表)拷贝到my_vectors数组中,这样就完成了boot向量表的拷贝。当程序在Boot区执行完成后,要跳转到应用程序之前,将应用程序的前0xc0的内容拷贝到my_vectors数组中,这样也就完成了应用程序的向量表重定义。这样,每次在执行boot程序的时候,执行的是boot的中断回调函数,而执行应用程序的时候,执行的是应用程序的中断回调函数。

起始,方法还有很多,这个只是其中的一种而已。欢迎留言评论,如果有说的不对的地方,也欢迎大佬指正。

 

 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_26226375/article/details/100080998

智能推荐

TortoiseGit解决TortoiseGitPlink要求输入密码-程序员宅基地

文章浏览阅读3.2k次,点赞4次,收藏10次。解决TortoiseGitPlink要求输入密码_tortoisegitplink

什么是大端存储和小端存储-程序员宅基地

文章浏览阅读4.7k次,点赞2次,收藏5次。详细了解大端和小端的存储_大端存储和小端存储

【共读】企业信息安全建设与运维指南(一)_信息安全运营服务实施指南研究-程序员宅基地

文章浏览阅读6.3k次,点赞5次,收藏49次。一、从零开始建设企业信息安全系统:企业信息安全体系分为:信息安全技术体系和信息安全管理体系 信息安全技术体系: 两个层面: 1.需建设安全相关基础设施和系统,以具备解决相关安全问题的能力。 2.需具备安全运营能力,只有正确部署和使用设备,才能真正保障信息安全。 信息安全管理体系: 两个层面: 1.具备信息安全相关的制度、规范、流程及策略。 2.具..._信息安全运营服务实施指南研究

python遍历文件夹轻松拷贝所有固定格式的文件_python遍历所有文件复制指定文件?tn=02003390_71_hao_pg-程序员宅基地

文章浏览阅读455次。import osimport shutil def select_file(dir, dir_out): # dir为查询文件路径,dir_out为拷贝路径 if os.path.isfile(dir): if(dir[-4:] == '.bmp' or '.jpg' or 'png'): #拷贝所有以上格式的文件,也可以修改为其他格式 filename = dir.split('\\')[-1] # 提取文件名称 s_python遍历所有文件复制指定文件?tn=02003390_71_hao_pg

Win cuda11+cudnn11网盘下载_win11 cudatookit安装包 百度云-程序员宅基地

文章浏览阅读5.1k次,点赞17次,收藏10次。https://pan.baidu.com/s/1IV_lBCeFFM712xx_iXnhqQ 提取码:0pr5_win11 cudatookit安装包 百度云

springboot集成thymeleaf时css js加载不出来的问题_springboot thymeleaf 不显示css js-程序员宅基地

文章浏览阅读2.1k次。springboot项目的css 和js默认位置是在static中,所以如果没有另外的修改的话,直接创建一个static文件夹,把css和js放入即可。这里放一个实例<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>儿童随访记录表</title> <!-- 引入 echarts.js --> <script src="ht._springboot thymeleaf 不显示css js

随便推点

【教程】CDQ套CDQ——四维偏序问题【转载】-程序员宅基地

文章浏览阅读128次。转自前言 上一篇文章已经介绍了简单的CDQ分治,包括经典的二维偏序和三维偏序问题,还有带修改和查询的二维/三维偏序问题。本文讲介绍多重CDQ分治的嵌套,即多维偏序问题。四维偏序问题给定N(N<=20000)个有序四元组(a,b,c,d),求对于每一个四元组(a,b,c,d),有多少个四元组(a2,b2,c2,d2)满足a2<a &..._cdq处理四维偏序

Unity两个相机设置_unity设置两个摄像机-程序员宅基地

文章浏览阅读571次,点赞8次,收藏10次。Culling Mask:bg(将背景图片的layer设置为bg,层级在最后面,比如这里设置为9,背景图片一般放在2DObject-sprite里)main Camera:用来照物体的,CameraUI:用来照背景的。_unity设置两个摄像机

瑞_VMware虚拟机安装Linux纯净版(含卸载,图文超详细)_虚拟机安装linuxqq和卸载的图片-程序员宅基地

文章浏览阅读3.7k次,点赞90次,收藏24次。VMware虚拟机安装Linux纯净版(含卸载,图文超详细)_虚拟机安装linuxqq和卸载的图片

即时通讯开发平台AnyChat的开发流程及应用_axchat的使用过程-程序员宅基地

文章浏览阅读1.1k次。AnyChat开发流程指南下面列出AnyChatPlatform Core SDK基本开发流程,适用于开发视频会议系统、语音视频聊天系统、远程教育平台以及即时通讯平台(IM)等。 一、初始化该部分是首先要完成的,用于设置SDK的一些行为,包括设置对应的回调函数、设置SDK组件路径、设置是否产生日志文件等,通常初始化AnyChat SDK的代码如下(C++): 01.// 打_axchat的使用过程

计算机毕设Python+Vue疫情期间学生作业线上管理系统(程序+LW+部署)_在线作业管理系统测试用例-程序员宅基地

文章浏览阅读190次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:SSM + mybatis + Maven + Vue 等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。_在线作业管理系统测试用例

Unicode与FFFE(记一个蛋疼的项目)-程序员宅基地

文章浏览阅读758次。好久没更新博客了。近期忙着一个项目, 还要应付各种考试就顾不上博客了。今天遇到了一个蛋疼的问题, 通过BLE4.0与蓝牙外设通信。按照客户给的协议文档发送的数据, 可是外设不能正确识别。折腾了一下午。最后问了客户才知道... 数据头fffe, 他们在外设里面已经做规定了。 所以不须要发送。真是蛋疼。也怪自..._unicode fffe

推荐文章

热门文章

相关标签