关于ARM Cortex-M0分散加载文件

1. 概念

分散加载文件是MDK用来将生成的可执行文件内存分散在ARM存储器上不同位置,达到充分利用存储器的功能。分散加载文件有以下两种用法:

1.1. 通用用法

通常情况下,如果不需要分散加载文件,或者是简单的分散加载,都可以在Keil的Linker中色选Use Memory Layout from Target Dialog,然后直接在Target界面进行配置。片内ROM可以设置两段代码。
在这里插入图片描述

1.2. 复杂用法

有时候需要更详细的分散加载文件,如将指定文件存放在指定存储位置上。此时就需要使用分散加载文件(Scatter-Loading Description File),即后缀为.sct的文件。sct文件是BNF标记语法,功能非常强大,一般情况下,不需要对此进行深入了解,足够使用即可。sct的基本结构如下:在这里插入图片描述

2. 示例

MDK链接器的一个重要作用是重定位代码和数据在内存中的地址。
如果选择使用Scatter File,则链接时,链接器会从sct文件中读取相关信息来进行代码和变量的内存位置重定位。嵌入式开发,非常注重削减成本,而SRAM是占成本的一个大头,所以IC设计时,SRAM是能省则省的。如64K的SRAM,32K用来存放代码,32K用来存放变量。如果我算法模块比较多,整个生成的BIN文件有40K,此时怎么办呢?
这里就需要用到分散加载文件中的一个重要属性——OVERLAP。它的作用是将几个不同模块的代码编译到一个相同的位置。那么有一个Main代码,几个Brance代码,需要哪个Brance代码的功能,将对应Branch代码加载到SRAM上即可。这样就可以在比较小的SRAM上,实际非常复杂的功能。

2.1. sct文件内容

以下内容来自M0内核的工程,Use *.o to match all object files. Use * to match all object files and libraries. 示例中主要将代码分模块,以及将模块指定到相同的位置。

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x20000000 0x00007000  {    ; load region size_region
  scan.bin 0x20000000 0x00007000  {  ; load address = execution address
   *.o (RESET, +First)				; *.o是指所有目标文件,RESET复位放在最前面+First指定此区域首先加载,
   *(InRoot$$Sections)				; 系统默认的
   .ANY (+RO)						; 包括其他目标文件、库文件。.ANY作用与*类似,但是*的优先级比.ANY高。
  }
  RW_IRAM1 0x20008000 UNINIT 0x00007000  {  ; RW data
   .ANY (+RW +ZI)							; .ANY指所有目标文件、库文件。+RW +ZI为指定的section attribute。
  }
}
; 以上加载域是Keil生成的,可以作为主加载域

LR_IROM2 0x20007000 OVERLAY 0x00001000  ; 第二个加载域,指定开始开始和大小, OVERLAY指定这个域可以和其他加载域重叠,让链接器不要报错误
{    ; load region size_region
  eeprom.bin 0x20007000 OVERLAY 0x00001000 ; eeprom.bin是指定此执行域的名字,名字最长不能超过31个字符
  {  ; load address = execution address
   EEpRom.o (+RO)						   ; 指定此执行域包括的目标文件 指定+RO属性存放此处,RO即表示代码。
   SANDISK.o (*)						   ; 指定SANDISK.o此目标文件中所有代码变量均存放此执行域
  }
}

LR_IROM3 0x20007000 OVERLAY 0x0000500 
{    ; load region size_region
  Hynix.bin 0x20007000 OVERLAY 0x0000500 
  {  ; load address = execution address
   Hynix.o (+RO+RW)						; 指定此执行域包括的目标文件 指定+RO +RW属性存放此处,因为RO RW都需要存放在ROM中。
  }
   RW_IRAM3 0x20007500 UNINIT 0x00000500  {  ; RW data
   Hynix.o (+ZI)							 ; 将ZI变量单独存放,可以减少代码空间浪费
  }
}

2.2. 生成Bin文件

  • sct文件中有3个加载域,对应3个执行域名,编译链接后生成scan.afx文件
  • axf文件相当于所有.o的汇总,.axf文件包括调试信息,所以比较大。
  • 在User的Run User Program After Build/Rebuild中配置如下命令:

fromelf.exe “.\Obj\scan.axf” --bin --output “.\out”

  • –output=destination
    This option specifies the name of the output file, or the
    name of the output directory if multiple output files are created.
  • Usage with --bin:
    You can specify a single input file and a single output filename.
    If you specify many input filenames and specify an output directory, then the output
    from processing each file is written into the output directory. Each output filename is derived from the corresponding input file. Therefore,specifying an output directory in this way is the only method of converting many ELF files to a binary or hexadecimal format in a single run of fromelf.
    If you specify a pattern in parentheses to select a subset of objects from an archive, fromelf only converts the subset. All the other objects are passed through to the output archive unchanged.
  • 如果设置了多个加载区域,则–output后面的会被认为是目录名,生成的文件名主要来自于.sct文件中每个加载区域中ROM的描述名。
  • 如果只有一个加载区域,则–output后面的会被认为是文件名。

2.3. 测试结果

生成的.map文件
在这里插入图片描述

U32 uTest = 0x12345678;
U32 uTest2[128] = 0;
  • 这两个变量是hynix.c中的全局变量,前者属于RW类型,后者属于ZI类型,分别生成进入对应的执行域,符合预期。
  • Ov表示OVERLAY的属性,有*的符号就表示是重叠的。
  • HAL_IIC_Start和HY_CfgEnhanceMode分别属于不同的目标文件,以这两个接口进行测试。
  • 将生成的eeprom.bin加载进入RAM,触发HY_CfgEnhanceMode函数,串口打印信息如下:
    [2020-05-19 11:17:45.646]# RECV ASCII>
    HY_CfgEnhanceMode:20007001
  • 将生成的hynix.bin加载进入RAM,触发HAL_IIC_Start函数,串口打印信息如下:
    [2020-05-19 11:17:53.577]# RECV ASCII>
    HAL_IIC_Start:2000701
  • 通过串口打印的函数名及地址可以看出,确实是重叠地,并且调用也正常。
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《The Definitive Guide to ARM Cortex-M0 and Cortex-M0+ Processors (2nd Edition)》是一本权威的指南,旨在深入介绍ARM Cortex-M0和Cortex-M0+处理器的原理和应用。 这本书的第二版对第一版进行了全面修订和更新,以反映最新的技术发展。它面向的读者包括学生、工程师和嵌入式系统开发人员,完全涵盖了ARM Cortex-M0和Cortex-M0+处理器的所有方面。 第二版首先从处理器的基础知识开始,介绍了ARM架构和处理器核心的基本概念。它详细解释了指令集、寄存器、内存管理单元和中断处理等关键组件的功能和作用。 接下来,该书深入探讨了由ARM Cortex-M0和Cortex-M0+处理器支持的编程模型和开发工具。它提供了大量的示例代码和实际应用案例,帮助读者更好地理解如何编写高效的嵌入式软件。 此外,该书还介绍了处理器的性能特征、能源管理、调试技术和硬件外设等方面的内容。读者可以了解到如何最大限度地利用ARM Cortex-M0和Cortex-M0+处理器的特性,提升系统的性能和效率。 总的来说,这本书是学习和使用ARM Cortex-M0和Cortex-M0+处理器的最佳指南。它通过清晰的解释、丰富的示例和实用的技巧,帮助读者掌握这些处理器的核心知识和开发技能。无论是初学者还是有经验的开发人员,都会从中受益,并能够更好地应用ARM Cortex-M0和Cortex-M0+处理器来开发高质量的嵌入式系统。 ### 回答2: 《The Definitive Guide to ARM Cortex-M0 and Cortex-M0 Processors》(第二版)是一本关于ARM Cortex-M0和Cortex-M0处理器的权威指南。它提供了深入的理解和学习这些处理器的各个方面和功能。 本书首先介绍了ARM Cortex-M0和Cortex-M0处理器的基础知识,包括其体系结构、指令集和寄存器等。读者可以通过这些基本概念来建立对这些处理器的整体理解。 接着,书中详细讲解了ARM Cortex-M0和Cortex-M0处理器的内部工作原理和特性。它解释了处理器的各个组成部分,例如ALU、寄存器文件、内存管理单元等,以及它们如何协同工作来执行指令和管理资源。读者可以通过深入理解处理器的内部机制,从而更好地编写和优化相关的代码。 此外,本书还介绍了软件开发工具和环境,为读者提供了使用ARM Cortex-M0和Cortex-M0处理器进行软件开发的基本知识。它涵盖了编程语言、编译器、仿真器和调试器等方面的内容,使读者能够充分利用这些工具来开发高效且可靠的嵌入式系统。 《The Definitive Guide to ARM Cortex-M0 and Cortex-M0 Processors》(第二版)还提供了大量的实例和案例研究,帮助读者更好地应用所学知识。此外,还提供了一些实用的技巧和技术,帮助读者避免常见的错误和问题,并提供了优化代码和系统性能的建议。 总之,本书是一本非常有价值的学习资料,适用于对ARM Cortex-M0和Cortex-M0处理器感兴趣的学生、工程师和研究人员。通过阅读本书,读者可以获得深入的理解和应用这些处理器的能力,从而更好地进行嵌入式系统开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值