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

  13. main()
    -> User Code

  14. __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. [转] 高性能嵌入式处理器时代来临!多家中国芯片设计公司选择ARM® Cortex™-A9和Mali™图形处理器技术

    ARM公司(伦敦证交所:ARM:纳斯达克:ARMH)近日宣布,在过去一年多时间内,海思(Hisilicon).晶晨半导体(Amlogic).中天联科(Availink).海尔(Haier)等多家中国知 ...

  3. 外网访问arm嵌入式linux_嵌入式Linux系统编程——文件读写访问、属性、描述符、API

    Linux 的文件模型是从 Unix 的继承而来,所以 Linux 继承了 UNIX 本身的大部分特性,然后加以扩展,本章从 UNIX 系统接口来描述 Linux 系统结构的特性. 操作系统是通过一系 ...

  4. linux 返回非法指令,linux – ARM Cortex A7在内核模式下返回PMCCNTR = 0,在用户模式下返回非法指令(即使在PMUSERENR = 1之后)...

    我想在Raspberry Pi 2上读取循环计数寄存器(PMCCNTR),它有一个ARM Cortex A7内核.我为它编译了一个内核模块,如下所示: #include #include int in ...

  5. 【嵌入式】非操作系统下GPIO口控制器及LED灯编程

    非操作系统下GPIO口控制器及LED灯编程 GPIO控制器 概述 内部架构 端口寄存器 GPIO控制寄存器 GPIO数据寄存器 GPIO上拉寄存器 非操作系统LED灯闪烁 开发步骤 开发板上二极管 读 ...

  6. 配置eclipse为ARM嵌入式开发板编程

    配置eclipse为ARM嵌入式开发板编程 1-计算机环境 操作系统:window10 编程软件:Eclipse IDE for C and C++ Developers - 2022-09 Wind ...

  7. 嵌入式Linux编程基础ppt,嵌入式LinuxC高级编程.ppt

    <嵌入式LinuxC高级编程.ppt>由会员分享,可在线阅读,更多相关<嵌入式LinuxC高级编程.ppt(45页珍藏版)>请在装配图网上搜索. 1.嵌入式Linux C高级编 ...

  8. ARM Cortex -M 体系结构————————ARM微控制器与嵌入式系统(清华大学慕课记录)

    ARM的发展过程 对于ARM公司来讲,ARM公司只做CPU设计,采用出售IP的方式运营,半导体产商无需自己设计CPU,是生产关系的革命,提高了生产力.下面这张图ARM核的多个系列,我们可以看到ARM从 ...

  9. 非零基础自学Golang 第18章 HTTP编程(下) 18.2 HTTP服务端 18.2.2 启动HTTP服务器 18.2.3 启动HTTPS服务器

    非零基础自学Golang 文章目录 非零基础自学Golang 第18章 HTTP编程(下) 18.2 HTTP服务端 18.2.2 启动HTTP服务器 18.2.3 启动HTTPS服务器 第18章 H ...

最新文章

  1. MySQL更新命令_UPDATE
  2. JS原始类型:数值的运用技巧
  3. JVM(4)——对象访问
  4. 流浪地球开机动画包zip_影视日报|合家欢动画电影quot;许愿神龙quot;定档1.15;流浪地球加长版定档11.26...
  5. drupal 7在一个form新增或者修改一个字段
  6. 吐嘈OpenCV的图像旋转功能 _7
  7. 自带python库的环境软件_pyenv虚拟环境管理python多版本和软件库
  8. Android WebRTC 音视频开发总结
  9. 记事本编写java_如何使用记事本编写java程序
  10. Android 选择国家对应区号 中英双版
  11. 简单工厂模式、工厂模式以及抽象工厂模式(具体)
  12. 如何扩展硬盘以及删除恢复分区?
  13. Steam网页版/手机端显示“短期内来自您网络的失败登陆过多,请稍后再试”
  14. 「论文阅读」Rethinking Network Design and Local Geometry in Point Cloud:A Simple Residual MLP Framework
  15. UI设计现状与发展趋势是什么
  16. HIDS逐渐的成为主流
  17. 【机器学习】决策树(Decision Tree)
  18. 在线时间戳计算时间差
  19. 【文献阅读】Commission Fee is not Enough: A Hierarchical Reinforced Framework for Portfolio Management
  20. 俄版“支付宝”来了 俄互联网巨头Yandex推出全新支付服务

热门文章

  1. List元素互换,List元素转换下标,Java Collections.swap()方法实例解析
  2. 2022-2028年中国硅藻土产业发展态势及市场发展策略报告
  3. 2022-2028年中国社区体育产业深度调研及投资前景预测报告
  4. 2022-2028年中国内衣行业研究及前瞻分析报告
  5. 2019-4:自考总结
  6. 北京大学开源分词工具pkuseg 初试与使用感受
  7. java.lang.NullPointerException异常原因及解决
  8. Python 扩展 Op
  9. BEP 7:CUDA外部内存管理插件(下)
  10. 用小神经网络和光谱仪优化关键词识别