ARM Cortex-M嵌入式C基础编程(下)

ARM Cortex-M Embedded C Fundamentals/Tutorial

-Aviral Mittal

Load Region Vs Execution Region:

现在这意味着代码或代码的某些部分可能有不同的地址用于将它们加载到存储器中,例如,当它们加载到ROM中时,以及当它们被执行时。加载程序的地址称为其“加载地址”,执行程序的地址称为其执行地址。

现在很明显,如果程序的加载地址或程序的某一部分的加载地址与它们各自的执行地址不同,则必须将代码或代码的某一部分“重新定位”到不同的地址,即从其“加载地址”到“执行地址”

函数\uuu scatterload正是这样做的。

除了将代码或部分代码从加载区域重新定位到执行区域之外,此函数还将对某些区域(如堆栈区域)进行初始化。堆栈区域通常初始化为零,因为用于为堆栈内存保留空间的编译器指令“SPACE”也会导致其初始化为零。

虽然Keil通常会自动为用户插入所有的后台代码,以便重新定位代码,但它也允许用户定义称为散点加载文件的特定文件来定义不同的内存区域。但是,这超出了本文的范围。这里显示了散点加载文件的示例。使用自定义散点加载文件,用户可以有效地将代码和数据“散点”到内存中的多个区域。

这现在提出了一个有趣的观点:如果系统RAM不可用怎么办?在系统通电时,系统RAM很可能是可用的。XIP是这个场景的答案。

用户可以使用自己的“入口点”绕过默认执行流。这可以通过设置链接器选项“--entry My_Reset_Handler”来完成。

另一种方法是使用汇编指令'ENTRY'。

随机信息:

----------------

实际上,程序的完整执行顺序如下:

1. 堆栈指针从0x0000的内存内容加载

2. 处理器的程序计数器加载到Reset_Handler的位置,该位置将出现在内存位置0x0000_0004

3. Reset_Handler只不过是一个跳转到__main的程序(这是因为在startup.s文件中,Reset_Handler已被编码为这样做)

4.   __main calls __scatterload; Program jumps to
__scatterload

5.   __scatterload -> Initialization, Zero
Initialization regions to 0, load region relocation to execution addresses

6.   __scatterload_null

7.   __scatterload_zero_init

8.   __rt_entry

9.   __user_setup_stackheap (optional)

10. __user_libspace

11. __rt_entry_li 

12. __rt_lib_init

11. main()
-> User Code

12. __rt_lib_shutdown

上面编写的C程序包含应用程序代码和数据常量。当应用程序代码和数据的编译版本被放入微控制器的存储器中时,它可以被放入存储器的“根区域”或“非根区域”。根区域具有相同的加载时间和执行时间地址。非根区域具有不同的加载时间和执行时间地址。根区域包含ARM输出的区域表链接器region表包含需要初始化的非根代码和数据区域的地址。

但是根区域是什么?

根区域是内存空间中的一个区域,其中程序的“加载地址”只是其“执行地址”。

但是什么是“加载地址”和什么是“执行地址”?

加载地址只是用户代码将驻留在内存中的位置。例如,闪存或ROM或RAM。

但是,有时程序不能从它在内存中的位置“执行”,但在执行之前,必须将它重新定位到执行它的位置的内存区域中。这是“执行地址”。

Load Address Vs Execution Address: Why these
are different at all?

原因可能有很多,其中一个解释如下:

考虑一个例子,其中用户代码驻留在闪存中,并且由于闪存访问速度慢,因此可能需要从更靠近处理器的RAM执行代码以进行快速处理。存储程序的闪速存储器位置将是其“加载地址”,而复制并最终执行程序的RAM存储器位置将是其“执行地址”。

在任何嵌入式产品中,软件都很常见地驻留在非易失性存储器(如闪存)上,并在执行前将代码从闪存复制到RAM。

区域表还包含一个函数指针,该指针指示区域需要什么样的初始化,例如复制、归零或解压缩函数。

__scatterload遍历region表并初始化各个执行时间区域。功能:

将零初始化零,初始化(ZI)区域为零

将非根代码和数据区域从其加载时间位置复制或解压缩到执行时间区域。

__main总是在启动时调用此函数,然后再调用__rt_entry。

What is Scatter-Loading?

散点加载是使用户能够使用文本描述指定已编译二进制文件到链接器的内存映射的过程。

这是一种控制二进制文件的组件在内存映射中的位置的方法。

单词“scatter”的来源是这样一个事实:如果一个程序相当复杂,需要将编译后的代码的几个区域放在内存的几个区域中,那么它实际上是“scatter”在内存中。因此,这种机制通常适用于复杂程序,但也同样适用于简单程序。

As per Joseph Yui:

不同的开发工具有不同的方式来指定微控制器系统中程序和数据存储器的布局。在ARM工具链中,可以使用名为散点加载文件的文件类型,或者在Keil MDK-ARM的情况下,散点加载文件可以由mVision开发环境自动生成。

When to use Scatter-Loding?

根据ARM文档:

实现嵌入式系统通常需要分散加载,因为它们使用ROM、RAM和内存映射外设。

需要或非常有用分散加载的情况:

Complex memory maps 

必须放在许多不同内存区域中的代码和数据需要详细说明将数据段放在内存空间的何处。

不同类型的存储

许多系统包含各种物理内存设备,如flash、ROM、SDRAM和fast SRAM。散点加载描述可以将代码和数据与最合适的内存类型相匹配。例如,可以将中断代码放入快速SRAM中以提高中断响应时间,但可能会将不经常使用的配置信息放入较慢的闪存中。

内存映射外设

散点加载描述可以将数据部分放在内存映射中的精确地址,以便可以访问内存映射的外围设备。

在固定位置的函数

即使修改并重新编译了周围的应用程序,也可以将函数放在内存中的同一位置。这对于跳转表的实现很有用。

使用符号标识堆和堆栈

当应用程序链接时,可以为堆和堆栈位置定义符号。

What is a debug-adaptor: 

为了将程序代码下载到微控制器,并执行诸如暂停和单步执行等调试操作,您可能需要调试适配器将PC上的USB连接转换为微控制器使用的调试通信协议。大多数C编译器供应商都有自己的调试适配器产品。例如,Keil有ULINK产品系列,IAR提供I-Jet产品。

一些开发包已经在板上内置了USB调试适配器。

软件设备驱动程序:

用于读/写外设寄存器的软件。

目标对象文件:

在大多数情况下,项目包含许多单独编译的文件。编译过程完成后,每个源文件都会有一个对应的目标文件。为了生成最终组合的可执行映像,需要单独的链接过程。在链接阶段之后,IDE还可以生成其他文件格式的程序图像,以便将图像编程到设备。

闪存编程:

几乎所有的Cortex -M微控制器都使用闪存来存储程序。创建程序图像后,我们需要将程序下载到微控制器的闪存中。要做到这一点,你需要一个调试适配器,如果你使用的微控制器板没有一个内置。实际的flash编程过程可能相当复杂,但这些通常由IDE完全处理,您只需单击鼠标即可执行整个编程过程。注意,如果您愿意,也可以将应用程序下载到SRAM并从中执行它们

执行程序并调试:

编译好的程序下载到微控制器后,您可以运行该程序并查看它是否工作。您可以使用IDE中的调试环境来停止处理器(通常称为halt),并检查系统的状态以确保其正常工作。如果它不能正常工作,您可以使用各种调试功能(如单步执行)详细检查程序操作。所有这些操作都需要一个调试适配器(或者一个内置在开发工具包中的适配器,如果有的话)来连接正在测试的IDE和微控制器。如果发现一个软件错误,那么您可以编辑程序代码,重新编译项目,将代码下载到微控制器,然后再次测试

在编译程序的执行过程中,可以通过各种I/O机制(如UART接口或LCD模块)输出信息来检查程序的执行状态和结果。本书中的一些例子将展示如何实现其中一些方法。

上面的流程与基于GNU'gcc'的流程不同,它看起来如下:

主要区别在于连接过程。基于GNU的过程是单步的,而第一步有单独的链接过程。

ARM Cortex-M嵌入式C基础编程(下)的更多相关文章

  1. ARM Cortex-M嵌入式C基础编程(上)

    ARM Cortex-M嵌入式C基础编程(上) ARM Cortex-M Embedded C Fundamentals/Tutorial -Aviral Mittal 此技术是关于从编写简单的嵌入式 ...

  2. 【转】Shell编程基础篇-下

    [转]Shell编程基础篇-下 1.1 条件表达式 1.1.1 文件判断 常用文件测试操作符 常用文件测试操作符 说明 -d文件,d的全拼为directory 文件存在且为目录则为真,即测试表达式成立 ...

  3. 前端开发工程师 - 03.DOM编程艺术 - 第1章.基础篇(下)

    第1章.基础篇(下) Abstract: 数据通信.数据存储.动画.音频与视频.canvas.BOM.表单操作.列表操作 数据通信(HTTP协议) HTTP事务: 客户端向服务器端发送HTTP请求报文 ...

  4. 《Python编程第4版 下》高清PDF|百度网盘免费下载|Python基础编程

    <Python编程第4版 下>高清PDF|百度网盘免费下载|Python基础编程 提取码:tz5v 当掌握Python的基础知识后,你要如何使用Python?Python编程(第四版)为这 ...

  5. 嵌入式系统基础知识(一): 系统结构和嵌入式Linux

    目录 一. 嵌入式体系结构 二. 开发过程中的分工 三. 嵌入式软件体系结构 四. 嵌入式Linux 一. 嵌入式体系结构 <嵌入式系统设计师教程>这本书的前三章脉络很清晰, 按照嵌入式系 ...

  6. 灵动微电子ARM Cortex M0 MM32F0010 GPIO 的配置驱动LED灯

    灵动微电子ARM Cortex M0 MM32F0010 GPIO的配置 目录: 1.前言 2.学习方法简要说明 3.要点提示 4.注意事项 5.MM32F0010系统时钟的配置 6.MM32F001 ...

  7. 嵌入式LINUX基础教程 第2版

    嵌入式LINUX基础教程  第2版 目录 第1章 入门 11.1 为什么选择Linux 11.2 嵌入式Linux现状 21.3 开源和GPL 21.4 标准及相关组织 31.4.1 Linux标准基 ...

  8. 【ARM-Linux开发】ARM7 ARM9 ARM Cortex M3 M4 有什么区别

    ARM7 ARM9 ARM Cortex M3 M4 区别 arm7 arm9 可以类比386和奔腾, 不同代,arm9相比arm7指令集和性能都有所增强,arm7和arm9都有带mmu和无mmu的版 ...

  9. 灵动微电子ARM Cortex M0 MM32F0010 UART1和UART2中断接收数据

    灵动微电子ARM Cortex M0 MM32F0010 UART1和UART2中断接收数据 目录: 1.MM32F0010UART简介 2.MM32F0010UART特性 3.MM32F0010使用 ...

随机推荐

  1. Git 常用命令总结,将会持续更新

    平常在windows电脑上使用Git Extensions 工具比较多,大部分的常用指令都可以通过点点点就可以完成.在mac电脑上的话使用sourcetree工具.但有时候也会直接通过git命令,很多 ...

  2. 缓冲区溢出分析第05课:编写通用的ShellCode

    前言 我们这次的实验所要研究的是如何编写通用的ShellCode.可能大家会有疑惑,我们上次所编写的ShellCode已经能够很好地完成任务,哪里不通用了呢?其实这就是因为我们上次所编写的ShellC ...

  3. SSM中事务的配置模板

    Spring-tx.xml 配置思路: 1. 声明事务管理器DataSourceTransactionManager,并注入数据源dataSource属性 2.配置事务增强<tx:advice& ...

  4. xml数据解析和生成

    java中xml的解析方式有许多,有java自带的DOM.SAX,android中的PULL,其它的还有DOM4J.JDOM等. 本文简要讲述DOM.SAX.PULL三种方式. 1.DOM方法 缺点: ...

  5. 【BUAA 软工博客作业】个人博客作业

    项目 内容 课程:2020春季软件工程课程博客作业(罗杰,任健) 博客园班级链接 作业:热身作业,阅读并撰写博客 作业要求 课程目标 学习大规模软件开发的技巧与方法,锻炼开发能力 作业目标 阅读教材, ...

  6. Swagger简明教程

    一.什么是swagger Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化RESTful风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法, ...

  7. 基于pyqt5和openpyxl和Pyinstaller的青年大学习检查未学习人数的脚本

    前几天接到团支书的一个需求,因为学校给的名单是青年大学习已学习的名单,然而要知道未学习的名单只能从所有团员中再排查一次,过程相当麻烦.团支书跟我抱怨后,刚好我也学过一些操作办公软件的基础.打包pyth ...

  8. [Python] 命名空间&作用域

    Python的类语句不会创建实例 类会创建命名空间,通过对象访问类的属性和方法 类不会创建作用域,对方法和属性的引用必须加以限定(如在方法中必须通过self引用实例的属性) class My1(): ...

  9. Linux PATH环境变量及作用(初学者必读)

    Linux PATH环境变量及作用(初学者必读) < 什么是环境变量,Linux环境变量有哪些?Linux打包(归档)和压缩 > <Linux就该这么学>是一本基于最新Linu ...

  10. centos 7 启动和关闭zabbix 服务

    systemctl start zabbix-server  启动服务端 systemctl stop zabbix-server  停止服务端 systemctl start zabbix-agen ...