keil如何设置stm32(STM32入门学习第三阶段Keil)

上期讲到此处:(doubixiaohanhan.sct中的内容后面会解释)

doubixiaohanhan.sct中的内容: ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x00010000 { ; load region size_region ER_IROM1 0x08000000 0x00010000 { ; load address = execution address *.o (RESET, First) *(InRoot$$Sections) .ANY ( RO) } RW_IRAM1 0x20000000 0x00005000 { ; RW data .ANY ( RW ZI) } }

扩展知识点:在链接的过程中,会用到一个描述文件,用来指定链接时的行为。这个描述文件叫做链接文件,如Linux下的.ld文件,keil中的分散加载文件(.sct文件)

armar.exe、fromelf.exe 及用户指令

armar 工具用于把工程打包成库文件(扩展知识点:在Linux下使用ar命令生成静态库文件

ar rc libxxx.a xxx.o

),fromelf.exe 可根据 axf 文件生成 hex、bin 文件,hex(51单片机常用的下载文件格式) 和 bin(Arm常用下载格式) 文件是大多数下载器支持的下载文件格式。在 keil MDK 中,针对 armar 和 fromelf 工具的选项几乎没有,仅集成了生成hex或 Lib 的选项如下图所示:控制 fromelf 生成 hex 及控制 armar 生成 lib 的配置 。

keil如何设置stm32(STM32入门学习第三阶段Keil)(1)

使用fromelf生成bin文件,可以在keil MDK 的“Option for Target->User”页中添加调用 fromelf 的指令,如下图所示,在 keil MDK 中添加指令 (默认是没有指令的)。

keil如何设置stm32(STM32入门学习第三阶段Keil)(2)

解释:

Before Compile C/C File:表示在编译C/C 文件之前生成

Before Build/Rebuild:表示在构建/重新构建工程前生成

After Build/Rebuild:表示在构建/重新构建工程后生成(使用最多的)

比如:我们在构建工程后,利用fromelf将.axf文件转为bin文件

keil如何设置stm32(STM32入门学习第三阶段Keil)(3)

上述语法格式:fromelf --bin --output 想要输出的.bin 具体的.axf文件

例子:fromelf --bin --output C:\Users\PC\Desktop\STM32F103C8T6\program\STM32F103C8T6升级版\USER\obj\doubixiaohanhan.bin C:\Users\PC\Desktop\STM32F103C8T6\program\STM32F103C8T6升级版\USER\obj\doubixiaohanhan.axf

keil如何设置stm32(STM32入门学习第三阶段Keil)(4)

扩展知识点:keil MDK工程中各种类型的文件解释:

keil如何设置stm32(STM32入门学习第三阶段Keil)(5)

keil如何设置stm32(STM32入门学习第三阶段Keil)(6)

keil如何设置stm32(STM32入门学习第三阶段Keil)(7)

以上三张图片摘自网上(本人难得建立表格重新输入,直接用网上的图片,侵权联系必删)

备注:

*.dep 和 *.d 文件 (dependency fifile) 记录的是工程或其它文件的依赖,主要记录了引用的文件路径,其中 *.dep 是整个工程的依赖,它以工程名命名,而 *.d 是单个源文件的依赖,它们以对应的源文件名命名。

*.crf 是交叉引用文件 (Cross-Reference fifile),它主要包含了浏览信息 (browse information),即源代码中的宏定义、变量及函数的定义和声明的位置。我们在代码编辑器中点击“Go To Defifinition Of ‘xxxx’”可实现浏览跳转,见图浏览信息 ,跳转的时候,keil MDK 就是通过 *.crf 文件查找出跳转位置的。

.axf 文件是由多个.o 文件链接而成的,而 *.o 文件由相应的源文件编译而成,一个源文件对应一个 *.o 文件。

keil如何设置stm32(STM32入门学习第三阶段Keil)(8)

  • ELF 文件头:用来描述整个文件的组织,例如数据的大小端格式,程序头、节区头在文件中
  • 的位置等。
  • 程序头:告诉系统如何加载程序,例如程序主体存储在本文件的哪个位置,程序的大小,程
  • 序要加载到内存什么地址等等。
  • 节区:是 *.o 文件的独立数据区域,它包含提供给链接视图使用的大量信息,如指令 (Code)、数据 (RO、RW、ZI-data)、符号表 (函数、变量名等)、重定位信息等。
  • 节区头:存储在最后的节区头则包含了本文件节区的信息,如节区名称、大小等等。

使用 fromelf 文件可以查看 *.o、.axf 及.lib 文件的 ELF 信息

步骤:

1,在工程模板中的obj目录下打开命令行: shift 鼠标右键

keil如何设置stm32(STM32入门学习第三阶段Keil)(9)

2,点击 "在此处打开Powershell窗口(S)"

3,使用fromelf命令:比如:fromelf --text -v doubixiaohanhan.axf > doubixiaohahan.txt

keil如何设置stm32(STM32入门学习第三阶段Keil)(10)

doubixiaohahan.txt中内容:

======================================================================== ** ELF header Information File Name: .\doubixiaohanhan.axf Machine class: ELFCLASS32 (32-bit) ;注释:32位机,我们使用的是STM32 Data encoding: ELFDATA2LSB (Little endian) ;小端格式 Header version: EV_CURRENT (Current version) Operating System ABI: none ABI Version: 0 File Type: ET_EXEC (Executable) (2) ;可执行文件 Machine: EM_ARM (ARM) ;机器版本:arm芯片 Image Entry point: 0x080000ed ;映像image入口地址 Flags: EF_ARM_HASENTRY EF_ARM_ABI_FLOAT_SOFT (0x05000202) ARM ELF revision: 5 (ABI version 2) Conforms to Soft float procedure-call standard Built with Component: ARM Compiler 5.06 update 3 (build 300) Tool: armasm [4d35c6] Component: ARM Compiler 5.06 update 3 (build 300) Tool: armlink [4d35c9] Header size: 52 bytes (0x34) Program header entry size: 32 bytes (0x20) ;程序头 Section header entry size: 40 bytes (0x28) ;段头 Program header entries: 1 ;程序头入口1个 Section header entries: 16 ;段头入口16个 Program header offset: 308688 (0x0004b5d0);程序头在文件中的位置 Section header offset: 308720 (0x0004b5f0);节区头在文件中的位置 Section header string table index: 15 ======================================================================== ** Program header #0 Type : PT_LOAD (1) ;表示这是可加载的内容 File Offset : 52 (0x34) ;在文件中的偏移 Virtual Addr : 0x08000000 ;虚拟地址 Physical Addr : 0x08000000 ;物理地址 Size in file : 4220 bytes (0x107c) ;程序在文件中占据的大小 Size in memory: 4932 bytes (0x1344);若程序加载到内存,占据的内存空间 Flags : PF_X PF_W PF_R PF_ARM_ENTRY (0x80000007) Alignment : 8;地址对齐 ======================================================================== ** Section #1 Name : ER_IROM1 Type : SHT_PROGBITS (0x00000001) Flags : SHF_ALLOC SHF_EXECINSTR (0x00000006) Addr : 0x08000000 File Offset : 52 (0x34) Size : 4156 bytes (0x103c) Link : SHN_UNDEF Info : 0 Alignment : 4 Entry Size : 0 ==================================== ** Section #2 Name : RW_IRAM1 ;节区(段)名 Type : SHT_PROGBITS (0x00000001) Flags : SHF_ALLOC SHF_WRITE (0x00000003) 此节区在进程执行过程中占用内存。 节区包含可执行的机器指令。 Addr : 0x20000000 File Offset : 4208 (0x1070) Size : 64 bytes (0x40) Link : SHN_UNDEF Info : 0 Alignment : 4 Entry Size : 0 ==================================== ** Section #3 Name : RW_IRAM1 Type : SHT_NOBITS (0x00000008) Flags : SHF_ALLOC SHF_WRITE (0x00000003) Addr : 0x20000040 File Offset : 4272 (0x10b0) Size : 712 bytes (0x2c8) Link : SHN_UNDEF Info : 0 Alignment : 8 Entry Size : 0 ==================================== ** Section #4 Name : .debug_abbrev Type : SHT_PROGBITS (0x00000001) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 4272 (0x10b0) Size : 1476 bytes (0x5c4) Link : SHN_UNDEF Info : 0 Alignment : 1 Entry Size : 0 ==================================== ** Section #5 Name : .debug_frame Type : SHT_PROGBITS (0x00000001) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 5748 (0x1674) Size : 2012 bytes (0x7dc) Link : SHN_UNDEF Info : 0 Alignment : 1 Entry Size : 0 ==================================== ** Section #6 Name : .debug_info Type : SHT_PROGBITS (0x00000001) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 7760 (0x1e50) Size : 26784 bytes (0x68a0) Link : SHN_UNDEF Info : 0 Alignment : 1 Entry Size : 0 ==================================== ** Section #7 Name : .debug_line Type : SHT_PROGBITS (0x00000001) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 34544 (0x86f0) Size : 6972 bytes (0x1b3c) Link : SHN_UNDEF Info : 0 Alignment : 1 Entry Size : 0 ==================================== ** Section #8 Name : .debug_loc Type : SHT_PROGBITS (0x00000001) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 41516 (0xa22c) Size : 2480 bytes (0x9b0) Link : SHN_UNDEF Info : 0 Alignment : 1 Entry Size : 0 ==================================== ** Section #9 Name : .debug_macinfo Type : SHT_PROGBITS (0x00000001) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 43996 (0xabdc) Size : 221552 bytes (0x36170) Link : SHN_UNDEF Info : 0 Alignment : 1 Entry Size : 0 ==================================== ** Section #10 Name : .debug_pubnames Type : SHT_PROGBITS (0x00000001) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 265548 (0x40d4c) Size : 1306 bytes (0x51a) Link : SHN_UNDEF Info : 0 Alignment : 1 Entry Size : 0 ==================================== ** Section #11 Name : .symtab Type : SHT_SYMTAB (0x00000002) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 266856 (0x41268) Size : 7328 bytes (0x1ca0) Link : Section 12 (.strtab) Info : Last local symbol no = 293 Alignment : 4 Entry Size : 16 ==================================== ** Section #12 Name : .strtab Type : SHT_STRTAB (0x00000003) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 274184 (0x42f08) Size : 7340 bytes (0x1cac) Link : SHN_UNDEF Info : 0 Alignment : 1 Entry Size : 0 ==================================== ** Section #13 Name : .note Type : SHT_NOTE (0x00000007) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 281524 (0x44bb4) Size : 28 bytes (0x1c) Link : SHN_UNDEF Info : 0 Alignment : 4 Entry Size : 0 Section Segment ==================================== 1 0 2 0 3 0 ==================================== ** Section #14 Name : .comment Type : SHT_PROGBITS (0x00000001) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 281552 (0x44bd0) Size : 26980 bytes (0x6964) Link : SHN_UNDEF Info : 0 Alignment : 1 Entry Size : 0 Component: ARM Compiler 5.06 update 3 (build 300) Tool: armlink [4d35c9] ArmLink --strict --callgraph --map --symbols --xref --diag_suppress=9931 --cpu=Cortex-M3 --list=.\obj\doubixiaohanhan.map --output=.\obj\doubixiaohanhan.axf --scatter=.\obj\doubixiaohanhan.sct --info=summarysizes,sizes,totals,unused,veneers E:\keilmdk5Setup\ARM\ARMCC\Bin\..\lib\armlib\c_w.l E:\keilmdk5Setup\ARM\ARMCC\Bin\..\lib\armlib\fz_ws.l E:\keilmdk5Setup\ARM\ARMCC\Bin\..\lib\armlib\h_w.l E:\keilmdk5Setup\ARM\ARMCC\Bin\..\lib\armlib\m_ws.l E:\keilmdk5Setup\ARM\ARMCC\Bin\..\lib\armlib\vfpsupport.l Input Comments: 篇幅太长,部分删除 Component: ARM Compiler 5.06 update 3 (build 300) Tool: ArmCC [4d35f0] ArmCC --c99 --split_sections --debug -c -o.\obj\usart.o --depend=.\obj\usart.d --cpu=Cortex-M3 --apcs=interwork -O0 --diag_suppress=9931 -I..\CORE -I..\STM32F10x_StdPeriph_Driver\inc -I..\APP\led -I..\APP\button -I..\BIT_Operation -I..\CORE -I..\delay -I..\APP\timer -I..\USART -I..\APP\pwm -I..\APP\capture -I..\APP\ADC -I..\APP\I_temperature -I..\APP\LCD1602 -I..\APP\iwdg -I..\APP\AT24C0X -I..\APP\MPU60X0 -I..\APP\DHT11 -I..\APP\DHT11_2 -I..\APP\myiic -IC:\Users\PC\Desktop\STM32F103C8T6\program\STM32F103C8T6升级版\USER\RTE -IE:\keilmdk5Setup\Keil\STM32F1xx_DFP\2.3.0\Device\Include -IE:\keilmdk5Setup\ARM\CMSIS\Include -D__UVISION_VERSION=521 -DSTM32F10X_MD -DSTM32F10X_MD -DUSE_STDPERIPH_DRIVER --omf_browse=.\obj\usart.crf ..\USART\usart.c ==================================== ** Section #15 Name : .shstrtab Type : SHT_STRTAB (0x00000003) Flags : None (0x00000000) Addr : 0x00000000 File Offset : 308532 (0x4b534) Size : 156 bytes (0x9c) Link : SHN_UNDEF Info : 0 Alignment : 1 Entry Size : 0 ====================================

.map(结合上篇文章中doubixiaohanhan.map进行学习) 文件是由链接器生成的,它主要包含交叉链接信息,查看该文件可以了解工程中各种符号之间的引用以及整个工程的 Code、RO-data、RW-data 以及 ZI-data 的详细及汇总信息。它的内容中主要包含了“节区的跨文件引用”、“删除无用节区”、“符号映像表”、“存储器映像索引”以及“映像组件大小”。

  1. 节区的跨文件引用:详细列出了各个 *.o 文件之间的符号引用。由于 *.o 文件是由 asm 或 c/c 源文件编译后生成的,各个文件及文件内的节区间互相独立,链接器根据它们之间的互相引用链接起来。
  2. 删除无用节区:部分列出了在链接过程它发现工程中未被引用的节区,这些未被引用的节区将会被删除 (指不加入到 *.axf 文件,不是指在 *.o 文件删除),这样可以防止这些无用数据占用程序空间。
  3. 符号映像表:列出了被引用的各个符号在存储器中的具体地址、占据的空间大小等信息。
  4. 存储器映像索引:相对于符号映像表,这个索引表描述的单位是节区,而且它描述的主要信息中包含了节区的类型及属性,由此可以区分 Code、RO-data、RW-data 及 ZI-data。
  5. 映像组件大小:这部分包含了各个使用到的 *.o 文件的空间汇总信息、整个工程的空间汇总信息以及占用不同类型存储器的空间汇总信息,它们分类描述了具体占据的 Code、RO-data、RW-data 及 ZI-data 的大小,并根据这些大小统计出占据ROM的总空间。
分散加载文件(链接文件).sct语法

当工程按默认配置构建时,keil MDK 会根据我们选择的芯片型号,获知芯片内部的FLASH 及内部SRAM 存储器概况,生成一个以工程名命名的后缀为 *.sct 的分散加载文件 (Linker Control File,scatter loading),链接器根据该文件的配置分配各个节区地址,生成分散加载代码,因此我们通过修改该文件可以定制具体节区的存储位置。一个分散加载文件由一个或者多个加载域(load regions)组成。每个加载域由一个或者多个执行域(execution regions)组成。执行域中又包含很多个输入段描述(Input section description)。

格式:

加载域名 (基地址 | (" " 地址偏移)) [属性列表] [最大容量]

{

执行区域

}

加载域名:名称,在 map 文件中的描述会使用该名称来标识空间。用户自定义。

基地址(或称为起始地址): 本加载域的起始地址。分为两种方式:

  • 1),base_address:直接指明本加载域的起始地址。
  • 2),base_address offset:表示此加载域的起始地址为前一个加载域的结束地址 offset字节。offset必须对齐。

属性列表:属性列表说明了加载域的是否为绝对地址、N 字节对齐等属性,该配置是可选

的。具体取值如下:

  • ABSOLUTE: 绝对地址。默认属性。
  • PI: 与位置无关。
  • RELOC: 可重定位。
  • OVERLAY: 覆盖。
  • NOCOMPRESS: 不能进行压缩。

最大容量(或称为加载域大小(max_size))(可选):指定加载域的最大范围。默认取值0xFFFFFFFF.

执行区域:可以有一个或者多个执行域.

格式:

执行域名 (基地址 | " " 地址偏移) [属性列表] [最大容量 ]

{

输入节区描述

}

执行域名:名称。

基地址(或称为起始地址): 本加载域的起始地址。分为两种方式:

  • 1),base_address:直接指明本加载域的起始地址。
  • 2),base_address offset:表示此加载域的起始地址为前一个加载域的结束地址 offset字节。offset必须对齐。

属性列表:属性列表说明了加载域的是否为绝对地址、N 字节对齐等属性,该配置是可选

的。具体取值如下:

  • ABSOLUTE: 绝对地址。默认属性。
  • PI: 与位置无关。
  • RELOC: 可重定位。
  • OVERLAY: 覆盖。
  • NOCOMPRESS: 不能进行压缩。

最大容量(或称为加载域大小(max_size))(可选):指定加载域的最大范围。默认取值0xFFFFFFFF.

输入节区:可以有一个或者多个输入段描述.

配合加载域及执行域的配置,在相应的域配置“输入节区描述”即可控制该节区存储到域中,其语法格式如下:通用格式:目标文件过滤器 [ 属性]

模块选择样式"(" 输入节区样式","" " 输入节区属性")" 模块选择样式"(" 输入节区样式","" " 节区特性")" 模块选择样式"(" 输入符号样式","" " 节区特性")" 模块选择样式"(" 输入符号样式","" " 输入节区属性")" 输入节区属性:通过在模块选择样式后面加入输入节区属性,可以选择样式中不同的内容, 每个节区属性描述符前要写一个“ ”号,使用空格或“,”号分隔开

目标文件过滤器(模块选择样式)。支持通配符*、?。不区分大小写。如main.o,user*.o等。可匹配的文件可以为目标文件名、库名(不带前导路径名)、库完整路径名。可以使用*.o匹配所有的目标文件。用*匹配所有文件,包括目标文件和库。可以使用.ANY进行任意的匹配。它的优先级低于*。

属性,不区分大小写:

  • RO-CODE:(或TEXT)只读代码段
  • RO-DATA:(或CONST)只读数据段
  • RO :(或TEXT)即RO-CODE RO-DATA
  • RW-DATA:可读写数据段
  • RW-CODE:可读写代码段
  • RW:(或DATA) 即RW-DATA RW-CODE
  • ZI:(或BSS)初始化为0的可读写数据段
  • XO:可执行的区域
  • ENTRY 即包含ENTRY的段,节区入口点
  • FIRST存储到区域的头部,LAST 存储到尾部。通常重要的节区会放在头部,而 CheckSum(校验和)之类的数据会放在尾部。

举例:*.o (RESET, First) 表示任何目标文件中的RESET段放在起始位置。

文章讲解部分 完结

欢迎关注逗比小憨憨

后面将是视频教程,视频教程讲解的内容要比文章部分讲的多

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页