ARM Cortex-M嵌入式C基础编程(下)
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基础编程(下)的更多相关文章
- ARM Cortex-M嵌入式C基础编程(上)
ARM Cortex-M嵌入式C基础编程(上) ARM Cortex-M Embedded C Fundamentals/Tutorial -Aviral Mittal 此技术是关于从编写简单的嵌入式 ...
- 【转】Shell编程基础篇-下
[转]Shell编程基础篇-下 1.1 条件表达式 1.1.1 文件判断 常用文件测试操作符 常用文件测试操作符 说明 -d文件,d的全拼为directory 文件存在且为目录则为真,即测试表达式成立 ...
- 前端开发工程师 - 03.DOM编程艺术 - 第1章.基础篇(下)
第1章.基础篇(下) Abstract: 数据通信.数据存储.动画.音频与视频.canvas.BOM.表单操作.列表操作 数据通信(HTTP协议) HTTP事务: 客户端向服务器端发送HTTP请求报文 ...
- 《Python编程第4版 下》高清PDF|百度网盘免费下载|Python基础编程
<Python编程第4版 下>高清PDF|百度网盘免费下载|Python基础编程 提取码:tz5v 当掌握Python的基础知识后,你要如何使用Python?Python编程(第四版)为这 ...
- 嵌入式系统基础知识(一): 系统结构和嵌入式Linux
目录 一. 嵌入式体系结构 二. 开发过程中的分工 三. 嵌入式软件体系结构 四. 嵌入式Linux 一. 嵌入式体系结构 <嵌入式系统设计师教程>这本书的前三章脉络很清晰, 按照嵌入式系 ...
- 灵动微电子ARM Cortex M0 MM32F0010 GPIO 的配置驱动LED灯
灵动微电子ARM Cortex M0 MM32F0010 GPIO的配置 目录: 1.前言 2.学习方法简要说明 3.要点提示 4.注意事项 5.MM32F0010系统时钟的配置 6.MM32F001 ...
- 嵌入式LINUX基础教程 第2版
嵌入式LINUX基础教程 第2版 目录 第1章 入门 11.1 为什么选择Linux 11.2 嵌入式Linux现状 21.3 开源和GPL 21.4 标准及相关组织 31.4.1 Linux标准基 ...
- 【ARM-Linux开发】ARM7 ARM9 ARM Cortex M3 M4 有什么区别
ARM7 ARM9 ARM Cortex M3 M4 区别 arm7 arm9 可以类比386和奔腾, 不同代,arm9相比arm7指令集和性能都有所增强,arm7和arm9都有带mmu和无mmu的版 ...
- 灵动微电子ARM Cortex M0 MM32F0010 UART1和UART2中断接收数据
灵动微电子ARM Cortex M0 MM32F0010 UART1和UART2中断接收数据 目录: 1.MM32F0010UART简介 2.MM32F0010UART特性 3.MM32F0010使用 ...
随机推荐
- Ribbon、Feign和OpenFeign的区别
Spring Cloud 微服务架构学习记录与示例 Ribbon Ribbon 是 Netflix开源的基于HTTP和TCP等协议负载均衡组件 Ribbon 可以用来做客户端负载均衡,调用注册中心的服 ...
- 基于路由器的VRRP技术--VRRP的应用
目录 无Vlan的VRRP 有Vlan的VRRP 今天要讲的VRRP都是基于路由器的VRRP. 一:无Vlan的VRRP 如图,PC1和PC2是企业内网主机,AR1和AR2是企业访问外网的路由器,有一 ...
- Intel汇编语言程序设计学习-第四章 数据传送、寻址和算术运算-下
4.3 和数据相关的操作符和伪指令 操作符和伪指令并非机器可执行的指令,相反,它们是由汇编器进行解释的.开发者可以使用一系列的MASM操作符或伪指令获取数据的地址以及大小等特征信息: OFFSET操 ...
- 【js】Leetcode每日一题-数组异或操作
[js]Leetcode每日一题-数组异或操作 [题目描述] 给你两个整数,n 和 start . 数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == ...
- typecho+宝塔搭建
在这个互动视频中很详细的讲解到了 https://www.bilibili.com/video/BV1o4411r7x5?spm_id_from=pageDriver
- $ git push -u origin master 报错
输入$ git push -u origin master报permission denied(publickey) 如下: 原因是没有与gitee上的账号成功建立密钥对,所以需要配对密钥 解决方法( ...
- Codeforces Round #713 (Div. 3)AB题
Codeforces Round #713 (Div. 3) Editorial 记录一下自己写的前二题本人比较菜 A. Spy Detected! You are given an array a ...
- C++ primer plus读书笔记——第8章 函数探幽
第8章 函数探幽 1. 对于内联函数,编译器将使用相应的函数代码替换函数调用,程序无需跳到一个位置执行代码,再调回来.因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存. 2. 要使用内 ...
- FHD 4K 8K分辨率
4K(2160P,即4096×2160的像素分辨率)和8K(4320P,即7,680 × 4,320的像素分辨率)属于UHDTV. FHD是FULL HD(Full High Definition)的 ...
- Spring Cloud Gateway之全局异常拦截器
/** * @version 2019/8/14 * @description: 异常拦截器 * @modified: */ @Slf4j public class JsonExceptionHand ...