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. 【Spring】Spring中Bean的生命周期

    Spring中Bean的生命周期依赖于Spring的容器,大致可分为以下4个阶段: 1.Bean的初始化阶段 2.Bean属性赋值的阶段,获取上下文关联 3.Bean初始化的阶段 4.Bean销毁的阶 ...

  2. POJ1422 最小路径覆盖

    题意:      一个战场,往战场上投放伞兵,每个伞兵不能后退,只能往前走,问你最少多少个伞兵可以吧所有的点都占领. 思路:      这个题是最小路径覆盖,最小路径覆盖 = n - 最大匹配数,首先 ...

  3. OpenStack+kvm虚拟机xml格式解析

    配置说明 首先介绍一下配置结构: xml配置遵循<keyword> xxxxxx </keyword>的格式,即一个配置段以<keyword>开头,以</ke ...

  4. pr中打开Audition编辑剪辑?

    前景 现在一般的adobe全家桶都是一键安装破解. 天翼网盘链接,下载不限速,没有账号就现注册一个即可. https://cloud.189.cn/t/UZRjuqAZ3E7r (访问码:8ago) ...

  5. 03.21 ICPC训练联盟周赛:UCF Local Programming Contest 2018正式赛

    B Breaking Branches 题意:两个人比赛折枝,谁剩下最后1,无法折出整数即为输 思路:树枝长n,若是奇数,则Bob胜出,若是偶数,则Alice胜出,且需要输出1: 1 #include ...

  6. Spring Boot 允许跨域设置失败的问题深究

    在公司开发过程中,一个前后端分离的项目遇见了跨域的问题. 前端控制台报错:No 'Access-Control-Allow-Origin' header is present on the reque ...

  7. 字体:等宽字体与比例字体 - Monospaced font & Proportional font

    字体:等宽字体与比例字体 - Monospaced font & Proportional font 量子波儿 2013-08-24 16:54:12 7101 收藏 1分类专栏: 计算机常识 ...

  8. python实现UDP通讯

    Environment Client:Windows Server:KaLi Linux(VM_virtul) Network:Same LAN Client UDPClient.py #-*- co ...

  9. setting>SSH>sessions setting>勾选ssh Keepalive[ MobaXterm】设置保持SSH连接

    [ MobaXterm]设置保持SSH连接 ssh远程连接会在无操作时自动断开连接.为了保持程序运行和连接,需要设置保持连接. 1.MobaXterm如果使用了MobaXterm客户端,那么需要在设置 ...

  10. libvirtd 启动成功,但却没有监听

    现象: 执行 systemctl start libvirtd在其它机器上进行测试是否监听:virsh -c qemu+tcp://host/system libvirtd启动成功,没有报错,但却没有 ...