Tiva C(TM4C)的bootloader和启动过程与stm32对比

2023-05-16

gossip:

        最近在咸鱼捡了个123GXL的板子,板子没到就先装好了环境,然后看了看资料,前天板子到了,先点了个灯,然后把板子扔到一边又继续看资料去了emmm...

        看资料的时候发现有些东西挺有意思的:比如它竟然出厂时在ROM中固化了库函数的二进制代码,用户程序可以直接跳转到ROM中去执行这些函数,那么Flash中就不必再存这些代码从而有更多的空间存其它数据了。

boot loader:

        这玩意学习stm32时根本没听说过,倒是以前给手机刷机时知道要进这个地方,好像叫做程序引导器。在看Tiva C的资料时总看到这个东西,于是深入研究了一下,竟然发现原来stm32也有这玩意。简单来说,它也是一个程序,用于接收上位机发来的程序数据并把数据烧写到Flash里面,完成用户程序的更新。至于究竟是怎么一回事,还得从ARM核MCU的启动过程说起。

启动过程:

        按照ARM的规定,系统的0x00处存放程序的栈顶指针,0x04开始就是中断向量表(加4是因为一个地址占32位),且第一个中断向量为reset中断向量。

        单片机上电后,首先初始化堆栈,然后读取0x00处的栈顶指针,接着将0x04处的reset中断服务函数地址载入PC寄存器,之后跳转执行reset的中断服务函数,并根据该中断服务函数内的指示跳转执行main函数。

stm32的boot loader:

         stm32是可以根据两个特定的引脚选择程序启动位置的,三个可以选择的启动区域分别是SRAM,FLASH和System Memory,如下所示:

         一般来说,用户程序存放到Flash当中,SRAM并不常用。选择从Flash启动程序就是选择执行用户程序。

        那么还有一个System Memory又是咋回事呢,其实从这个区域启动就会执行boot loader程序,当我们手头上没有调试器,要从串口给单片机烧写程序的时候,就得切换到这个模式。这时候我们可以用一些工具比如FlyMCU等,就可以将程序通过串口发送到单片机,此时单片机正执行的boot loader程序就会接收串口数据(也就是用户程序)并写到Flash当中,从而完成用户程序的更新。当切换回Flash启动方式后,就会运行新的用户程序了。

存储器重映射:

        stm32的boot loader的作用讲完了,但是还没弄清楚为什么切换引脚可以启动不同的程序,按照arm的规定,程序是从0x0000 0000处开始执行的,可这个位置的值不是固定的吗,不应该只能执行一个程序?这就涉及到地址的重映射了:

         如上图所示,stm32的0x0000 0000地址到0x07FF FFFF地址其实就是用来做重映射的,需要注意的是这里的地址是逻辑地址而不是物理地址,是人为规定出来的,因而完全可以再定义这段地址在逻辑上与Flash相连,这种定义,就是重映射。

        如果这么做,就是说将Flash的地址映射到了系统0x00处那段位置。当程序去读0x00时,实际上读的是Flash的首地址处的值,也就是用户程序的堆栈地址,接下来读0x04处的值,读的其实是0x0800 0004处的值,也就是用户程序的中断向量表的第一个中断向量。这么一来,单片机执行的就是用户程序了。

        同理,如果将system memory映射到0x00开始的那段位置,那么一开始就能读到System Memory的首地址的值了,这里存放的是boot loader这个程序的堆栈地址值,接着还能读到这个程序的第一个中断向量,从而执行了boot loader程序。

Tiva C的ROM中的Boot loader:

        按照官方文档所说,Tiva C系列可以有两个boot loader,一个是出厂固化在ROM中的,另外一个是在Flash中的。

        首先需要知道的是,Tiva C系列的逻辑地址分配与stm32不同,它没有像32一样预留给专门做重映射的空白区域,而是直接把Flash的地址安排在了0x00开始的一段区域,因此单片机一开始从0x00处读到的值就是Flash首地址里面的值。

        当芯片出厂的时候,ROM中固化了boot loader和库函数代码以及其它一些内容,而Flash是空的,那么就可以通过启动芯片的boot loader程序,然后利用串口或者其它的外设接口给Flash写入程序了。流程是这样的:当单片机启动时,它会去读0x00处的值,然后发现,欸,这个值好像不是一个地址欸,然后又发现0x04处的值好像也不是一个中断函数的函数地址,于是这时候就会把ROM的boot loader程序开始的位置直接重映射到0x00处,然后按照启动流程启动boot loader程序,接下来就可以使用LM Flash Programmer这个应用给芯片写入用户程序了。

        当下次重启时,系统发现0x00和0x04处的值都好像是一个地址的样子欸,于是就不去启动ROM中的boot loader程序了,而是按照正常流程去读取Flash中的堆栈地址以及中断函数地址,启动用户程序。

        在我看来,这个ROM的boot loader跟32中的那个比较相似,程序都是固化在了某一个只读存储区域,都只能使用某几个固定的外设接口来更新用户程序(比如串口0)。区别在于,stm32可以通过引脚来选择随时启动这个boot loader,而Tiva C系列的这个boot loader只有在以下情况能启动:

         需要注意的是,我看到的芯片手册里面,EN默认是置位的,引脚启动功能也是默认禁用的。因此只有情况3能启动这个boot loader,这个情况3简单地说就是用户程序不对劲的时候或者FLASH全为空的时候。如果不下心已经把程序写入了Flash,而程序中又没有去改变BOOTCFG这个寄存器的值,那么以后启动ROM中的boot loader程序就十分困难了。

 

Tiva C的Flash中的Boot loader:

        接下来说说FLASH中的boot loader。既然是Flash中的东西,就是可以修改的啦,因此可以比较灵活,比如说boot loader可以使用串口0,或者串口1,或者SSI3,或者以太网等来更新用户程序。这个boot loader不是自带的,官方给了代码,需要我们自己编译后弄到Flash里面。在Tivaware的例程目录下,有一个叫做boot_serial的文件夹,里面就是一个用串口更新的boot loader程序。

        如果使用这个boot loader的话,就得把Flash分成两个区域,每个区域存一个程序,分区大小需要根据boot loader这个程序的大小来设定,用户程序的首地址最好设置为除boot loader外第一个空白sector。如下图所示:

         首先,在boot loader程序中,要有一个APP_START_ADDRESS,这个变量存放的是用户程序的首地址,按照上图也就是0x2800。然后,boot loader程序中还有一个CheckForceUpdate()函数,它要来检测APP_START_ADDRESS开始的几个值正不正常,这跟ROM的boot loader差不多,只是地址多了一个偏移而已。如果APP_START_ADDRESS开始的值能够确定是堆栈地址和reset的中断函数地址,就认为用户程序存在,就跳转去执行用户程序,否则进入更新状态。当然,CheckForceUpdate()函数中也可以写一些根据引脚状态来确定是否进入更新的代码,官方例程也留下了接口如下:

         如果把boot loader弄到了Flash里面,相应的,用户程序也要更改一些地方,主要就是编译时候设置程序起始位置。正常来说,用户程序直接烧写到Flash开头就好了,比如stm32要设置程序位置为0x0800 0000(这是stm32的Flash的首地址),而Tiva C系列则设置为0x00(这是Tiva C的Flash首地址),但是现在Flash开头已经被boot loader占用了,因而需要把用户程序的起始地址改一下:

        上面那张图是keil里面的魔术棒的设置,下面这个是ccs的cmd文件的配置,根据自己的情况改一下程序的起始地址就行。

        都设置好之后,首先要把boot loader通过调试器烧写到Flash的起始位置。单片机重新上电,因为此时0x00是boot loader所以执行的是boot loader程序,该程序会执行一个CheckForceUpdate()去检测0x2800开始的一段位置,或者说检测设置的GPIO引脚的状态来确定是否执行更新,如果不执行,则跳转0x2800去执行用户程序,否则进入更新状态,配置特定外设并等待数据的到来。

总结:

        简而言之,无论boot loader在哪里,当它被触发启动后,就可以发送程序到单片机的特定外设,boot loader程序会接收俺们的程序并帮我们写入Flash。boot loader的触发启动方式各不相同,stm32通过两个引脚的电平情况触发,而Tiva C是根据某些地址的值或者IO的值来触发执行。

        这么看来,Tiva C的触发条件还是比较苛刻得,一般只有全新芯片才能触发ROM的boot loader,如果没有调试器,如果第一次不小心写了个程序进0x00处,那么很难再启动ROM的boot loader,此时Flash的boot loader也没有被存进去Flash,更加启动不了了。想不通Ti这么做的意义何在。

        所以还是调试器大法好啊阿巴阿巴......

        看了好久资料,看得迷迷糊糊,现在把自己对boot loader和启动过程的理解写出来,也不知道能写清楚,还望大家前来指正与交流啦~

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

Tiva C(TM4C)的bootloader和启动过程与stm32对比 的相关文章

  • /bin/sh^M: 坏的解释器: 没有那个文件或目录

    在windows上面notepad 43 43 写的shell文件 xff0c 复制带Linux上面提示错误 bin sh M 坏的解释器 没有那个文件或目录 在命令行执行下面语句 xff1a span class token commen
  • 相机内参矩阵、外参矩阵、畸变矩阵

    1 相机针孔模型 图中 xff0c X坐标系是针孔所在坐标系 xff0c Y坐标系为成像平面坐标系 xff0c P为空间一点 xff0c 小孔成像使得P点在图像平面上呈现了一个倒立的像 齐次形式 xff1a 在此 xff0c 我们先暂时舍弃
  • STM32—驱动GY85-IMU模块

    GY85是一个惯性测量模块 xff0c 内部集成了三轴加速度计 三轴陀螺仪 电子罗盘 气压传感器等芯片 xff0c 用于测量和报告设备速度 方向 重力 xff0c 模块可以将加速度计 陀螺仪 电子罗盘等传感器的数据进行综合 xff0c 在上
  • MPU6050原始数据分析——学习笔记

    MPU6050原始数据分析 学习笔记 个人学习笔记MPU6050简介 原始数据分析加速度计陀螺仪代码 个人学习笔记 用于记录自己学习的成果 xff0c 并且分享给大家一起看看 希望对看到这篇的朋友有所帮助 MPU6050简介 MPU 605
  • DAY15 异常捕获

    DAY15 异常捕获 一 文件操作细节问题 1 1 参数encoding open file mode 61 r encoding 61 None encoding 设置文本文件的编码或者解码方法 xff08 将数据写入到文件之前会自动编码
  • x86-从实模式到保护模式(总结)

    总结主要针对最后一章的内容 xff0c 最后一张的程序使用的是平坦模式 代码段和数据段都是从0x00000000到0xffffffff xff0c 能够访问4GB的地址空间 使用平坦模式的好处 xff1a 不用频繁的在段与段之间进行切换 代
  • Docker 部署 Prometheus & Grafana (监控主机进程)

    目录 1 环境介绍 xff1a 2 部署 主机进程 监控1 使用 Docker 部署 Grafana2 部署并启动 prometheus3 下载 process exporter4 创建并编辑文件 process name yaml5 在
  • 【Docker】报错:Got permission denied while trying to connect to the Docker daemon socket at unix:///var/

    报错原因 在VMWARE中安装的centos中查看容器Docker所安装的镜像命令时即执行 docker images 时虚拟机报错 xff0c 该用户没有此类权限 错误 xff1a Got permission denied while
  • linux ubuntu 彻底卸载包,清理linux软件卸载残留

    使用以下命令清理残留配置 xff0c 其实就是删除残留的 rc文件 dpkg span class token parameter variable l span span class token operator span span cl
  • list和array 访问不连续index

    python中内置数据类型list与numpy array都是常会用到的两种数据结构 二者在访问变量中不连续index时处理方式有所不同 array array访问不连续index的方式非常简单 xff0c 只需要用定义好的索引直接截取ar
  • TVM Windows conda 安装

    TVM Windows 安装 简介 本篇博客主要目的是帮助大家在windows平台上安装好tvm xff0c 并且可以顺利使用 因为有项目需要使用tvm xff0c 同时自己需要用windows做一些测试 xff0c 因此想要在window
  • 探讨ros下的cmakelists文件的编写

    文章目录 cmakelists文件整体架构分块讲解1 CMake版本2 软件包名称3 查找相关的CMake包4 消息 服务 动作生成器 cmakelists文件整体架构 所需CMake版本 xff08 cmake minimum requi
  • git 克隆指定分支

    git clone b 分支名 仓库地址
  • 【NVIDIA】Jetson Xavier NX镜像烧录

    设备信息 我的设备是Jetson Xavier NX xff1b 准备工作 鼠标 键盘 显示器SD卡 32GB至少 网线 xff08 也可以wifi xff09 官方教程 xff1a https developer nvidia com e
  • Android GPS学习 (二) :GPS 服务启动以及初始化流程

    扫码关注 xff0c 一起学习 1 GPS 服务启动 SystemServer java的startOtherServices方法中添加LocationManagerService方法的代码如下 frameworks base servic
  • docker运行ubuntu22.04出现异常(转载)

    原文链接 xff1a https xyz uscwifi xyz post PRTc2ZYZx 参考 xff1a docker Why I cannot run 96 apt update 96 inside a fresh ubuntu
  • 为什么执行同一个程序每次输出的变量地址是不一样的

    首先看一下下面的代码 include lt stdio h gt int main int a 61 1 printf 34 p n 34 amp a return 0 然后我就很疑惑 xff0c 为什么每次的地址都是不一样的 为什么会有这
  • 中断的基本概念

    异常和中断 概念 xff1a 程序执行过程中CPU会遇到一些特殊情况 xff0c 是正在执行的程序被 中断 xff0c cpu中止原来正在执行的程序 xff0c 转到处理异常情况或特殊事件的程序去执行 xff0c 结束后再返回到原被中止的程
  • 8086CPU结构与功能

    微处理器的外部结构 微处理器的外部结构如下图所示 8086CPU片有40个管脚 微处理器通过这些引脚与外部的逻辑部件连接 完成信息的交换 CPU的这些引脚称为微处理器级的总线 功能 与存储器之间交换信息 指令及数据 与I O设备之间交换信息
  • 8086微处理器的寄存器组织

    8086CPU内部有14个16位的寄存器 按功能可以分为8个通用寄存器 4个段寄存器和两个控制寄存器 通用寄存器 通用寄存器可以分为两类 数据寄存器 AX BX CX DX 和地址寄存器 变址寄存器 SI DI SP BP 8086CPU有

随机推荐

  • python dict setdefault()方法

    描述 Python 字典 setdefault 函数和 get 方法 类似 如果键不存在于字典中 xff0c 将会添加键并将值设为默认值
  • CPU原生支持的任务切换方式

    CPU 厂商原本计划的一种任务切换方法 xff0c 并不是操作系统实例中任务切换的方法 未采用的原因是此方法效率不高 xff0c 现代操作系统很少用这种方法切换任务 为了支持多任务 xff0c CPU 厂商提供了 LDT TSS 这两种原生
  • linux内核2.6.16版本启动分析(1)

    电脑的启动流程详见这篇博文电脑开机过程 简述一下就是按下电源键后 cs ip置位到0xffff0的位置 而这个位置是固化的 上面都刻录好了BIOS程序 BIOS执行基本的硬件自检以及建立中断向量表 初始化BIOS中断等 接下来会把第一块磁盘
  • linux内核目录分析

    最近准备开始研读linux的内核了 今天在deepin内核版本为4 8 15上编译安装了内核4 19 6 本来是先装2 6 16版本的 但2 6 16版本的内核版本要求gcc的版本为4 6之下 装4 6版本的gcc的时候出了点问题 还没解决
  • AT&T语法

    在linux内核编写中 为了维持与gcc输出汇编程序的兼容性 as汇编器使用AT amp T系统的V的汇编语法 下面简称为AT amp T语法 这种语法与Intel汇编程序使用的语法 简称Intel语法 很不一样 他们之间的主要区别有以下几
  • eBPF入门

    BPF和eBPF是什么 简单来说 BPF提供了一种在和各种内核和应用程序事件发生时运行一段小程序的机制 BPF是一项灵活而高效的技术 由指令集 存储对象和辅助函数等几部分组成 由于它采用了虚拟指令集规范 因此也可将它视作一种虚拟机的实现 这
  • make详解

    Make 1 学习make的必要性 在Linux中 有一个用来维护程序模块关系和生成可执行程序的工具 xff0d make 他可以根据程序模块的修改情况重新编译链接生成中间代码或最终的可执行程序 执行make 命令 xff0c 需要一个名为
  • Linux:网络编程——UDP代码及其封装

    Linux xff1a 网络编程 UDP代码及其封装 UDP代码封装UDP 前面我们了解了 UDP的编程步骤为 xff1a 客户端 xff1a 创建套接字 接收消息 发送消息 接收消息 服务端 xff1a 创建套接字 绑定地址信息 接收消息
  • 卷积神经网络CNN笔记(Tensorflow)

    卷积神经网络学习笔记 一 卷积神经网络相关定义二 基本步骤三 数据增强1 基本原理2 keras实现3 卷积神经网络中的应用 四 常用代码五 实验代码六 使用预训练的卷积神经网络结语 一 卷积神经网络相关定义 卷积层 xff08 Convo
  • 基于GTSRB数据集的交通标志识别实验(Tensorflow)

    基于GTSRB的交通标志识别实验 一 数据数据读取 二 搭建网络三 模型预测四 附录模块导入Code 结语 一 数据 官网下载太慢 xff0c 然后我找到了一个整理好的数据集 链接 GTSRB 德国交通标志识别图像数据 数据集很干净 xff
  • 贝叶斯分类器原理——学习笔记

    贝叶斯分类器原理 简介一 逆概率推理与贝叶斯公式1 确定性推理与概率推理2 贝叶斯公式 二 贝叶斯分类的原理三 概率估计1 先验概率的估计2 类条件概率的估计 四 贝叶斯分类的错误率五 常用贝叶斯分类器1 最小错误率贝叶斯分类器2 最小风险
  • python format

    str format 基本语法是通过 和 来代替以前的 位置 format 函数可以接受不限个参数 xff0c 位置可以不按顺序 gt gt gt span class token string 34 34 span span class
  • 钢材表面缺陷检测分类不同图像增强方式的对比研究

    带钢表面缺陷检测分类不同图像增强方式的对比研究 1 直接使用图像数据进行深度学习2 图像增强图像分析形态学top hat变换图像锐化 3 图像增强后的深度学习总结 基于钢材表面缺陷库进行多种缺陷检测分类实验 xff0c 对比分析了使用卷积神
  • YOLO系列论文精读

    YOLO系列论文精读 YOLOV11 xff09 实现2 xff09 详细解读总结 YOLOV2 90001 xff09 Better xff1a 2 xff09 Faster xff1a 3 xff09 Stronger xff1a 总结
  • Git使用技巧

    Git使用技巧 基本操作 1 版本控制 版本控制 xff1a 进入文件夹 xff0c 右键点git bash here初始化 xff0c 输入git init管理 xff0c git add 文件名生成版本 xff0c git commit
  • Aruco检测Marker原理及代码详解(c++)

    Aruco检测Marker原理及代码详解 xff08 c 43 43 xff09 detectmarker主要流程 这个函数写在aruco cpp里 detectMarkers convertToGrey detectCandidates
  • pytorch学习

    Pytorch学习 一些简单记录 一 基本语法 1 Tensor 创建Tensor xff1a 创建未初始化矩阵 x 61 torch empty 5 3 创建零初始化矩阵 x 61 torch zeros 5 3 dtype 61 tor
  • 卡尔曼滤波及数据融合:PX4-EKF源码分析

    卡尔曼滤波及数据融合 xff1a PX4 EKF源码分析 卡尔曼滤波PX4 EKF predictState 状态预测L 259calculateOutputStates xff1a L 323存进Buffer的内容 xff1a 修正算法
  • Ubuntu18.04安装Gazebo并与ROS连接

    Ubuntu18 04安装Gazebo并与ROS连接 Gazebo安装Gazebo与ROS连接 Gazebo安装 注意 xff1a Ubuntu18 04需要下载Gazebo9这个版本 xff0c Gazebo的版本不要弄错 如果已经下载了
  • Tiva C(TM4C)的bootloader和启动过程与stm32对比

    gossip 最近在咸鱼捡了个123GXL的板子 xff0c 板子没到就先装好了环境 xff0c 然后看了看资料 xff0c 前天板子到了 xff0c 先点了个灯 xff0c 然后把板子扔到一边又继续看资料去了emmm 看资料的时候发现有些