赞
踩
我们下载arm编译工具后,需要将目录添加到环境变了中。
fromelf --bin --output ..\Output\F407_Demo.bin ..\Output\F407_Demo.axf
Build started: Project: F407_Demo
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'D:\Keil_v5\ARM\ARM_Compiler_5.06u7\Bin'
Build target 'F407_Demo'
After Build - User command #1: fromelf --bin --output ..\Output\F407_Demo.bin ..\Output\F407_Demo.axf
"..\Output\F407_Demo.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:01
在工程的编译提示输出信息中有一个语句“Program Size:Code=xx RO-data=xx RW-data=xx ZI-data=xx”, 它说明了程序各个域的大小,编译后,应用程序中所有具有同一性质的数据(包括代码)被归到一个域,程序在存储或运行的时候, 不同的域会呈现不同的状态,这些域的意义如下:
RW-data和ZI-data它们仅仅是初始值不一样而已,为什么编译器非要把它们区分开?这就涉及到程序的存储状态了,应用程序具有静止状态和运行状态。 静止态的程序被存储在非易失存储器中,如STM32的内部FLASH,因而系统掉电后也能正常保存。但是当程序在运行状态的时候,程序常常需要修改一些暂存数据, 由于运行速度的要求,这些数据往往存放在内存中(RAM),掉电后这些数据会丢失。因此,程序在静止与运行的时候它在存储器中的表现是不一样的。
图中的左侧是应用程序的存储状态,右侧是运行状态,而上方是RAM存储器区域,下方是ROM存储器区域。
编译生成的RW-data的数据属于图中的RW节,ZI-data的数据属于图中的ZI节。是否需要掉电保存,这就是把RW-data与ZI-data区别开来的原因, 因为在RAM创建数据的时候,默认值为0,但如果有的数据要求初值非0,那就需要使用ROM记录该初始值,运行时再复制到RAM。
STM32的RO区域不需要加载到SRAM,内核直接从FLASH读取指令运行。
在MDK中,我们建立的工程一般会选择芯片型号,选择后就有确定的FLASH及SRAM大小,若代码超出了芯片的存储器的极限, 编译器会提示错误,这时就需要裁剪程序了,裁剪时可针对超出的区域来优化。
STM32F407ZGT6微控制器的SRAM和Flash大小如下:
此外,STM32F407系列的芯片可以通过FSMC(灵活的静态存储控制器)扩展外部SRAM,例如使用型号为IS62WV51216的SRAM芯片,其容量为1MB(1024KB)。这为需要更多运行时数据存储空间的应用程序提供了扩展选项。
所以,
其中ZI_data包括初始值为0的全局变量、局部变量和动态分配的空间,局部变量属于栈空间,动态分配的空间属于堆空间。这两块空间也是可以单独配置的,在启动文件startup_stm32f40xx.s中。
在Listing目录下包含了*.map及*.lst文件,它们都是文本格式的。map文件是由链接器生成的,它主要包含交叉链接信息,查看该文件可以了解工程中各种符号之间的引用以及整个工程的Code、RO-data、 RW-data以及ZI-data的详细及汇总信息。它的内容中主要包含了“节区的跨文件引用”、“删除无用节区”、“符号映像表”、 “存储器映像索引”以及“映像组件大小”。
map文件的最后一部分是包含映像组件大小的信息(Image component sizes),这也是最常查询的内容。
Image component sizes Code (inc. data) RO Data RW Data ZI Data Debug Object Name 140 56 128 0 128 1362 bsp_dma.o 60 26 0 0 0 531 bsp_exti.o 88 16 0 0 0 1389 bsp_led.o 12 4 0 0 0 465 bsp_pwm2.o 276 70 0 16 0 962 bsp_timer.o 350 32 0 10 0 4498 bsp_usart.o 16 0 0 0 0 506 bsp_wwdg.o 64 28 0 0 0 531 main.o 124 16 0 0 0 1887 misc.o 36 8 392 0 1024 952 startup_stm32f40xx.o 142 28 0 0 0 3647 stm32f4xx_dma.o 32 10 0 0 0 1260 stm32f4xx_exti.o 168 0 0 0 0 3286 stm32f4xx_gpio.o 20 0 0 0 0 4082 stm32f4xx_it.o 216 24 0 16 0 4626 stm32f4xx_rcc.o 38 0 0 0 0 3354 stm32f4xx_tim.o 308 8 0 0 0 5440 stm32f4xx_usart.o 28 10 0 0 0 1107 stm32f4xx_wwdg.o 276 34 0 0 0 306193 system_stm32f4xx.o ---------------------------------------------------------------------- 2410 370 552 44 1152 346078 Object Totals 0 0 32 0 0 0 (incl. Generated) 16 0 0 2 0 0 (incl. Padding) ---------------------------------------------------------------------- Code (inc. data) RO Data RW Data ZI Data Debug Library Member Name 0 0 0 0 0 0 entry.o 0 0 0 0 0 0 entry10a.o 0 0 0 0 0 0 entry11a.o 4 0 0 0 0 0 entry12b.o 8 4 0 0 0 0 entry2.o 4 0 0 0 0 0 entry5.o 0 0 0 0 0 0 entry7b.o 0 0 0 0 0 0 entry8b.o 8 4 0 0 0 0 entry9a.o 30 0 0 0 0 0 handlers.o 36 8 0 0 0 68 init.o 0 0 0 0 0 0 iusefp.o 30 0 0 0 0 68 llshl.o 36 0 0 0 0 68 llsshr.o 32 0 0 0 0 68 llushr.o 26 0 0 0 0 80 memcmp.o 2218 90 0 0 0 464 printfa.o 0 0 0 4 0 0 stdout.o 44 0 0 0 0 80 uidiv.o 98 0 0 0 0 92 uldiv.o 48 0 0 0 0 68 cdrcmple.o 56 0 0 0 0 88 d2f.o 334 0 0 0 0 148 dadd.o 222 0 0 0 0 100 ddiv.o 186 0 0 0 0 176 depilogue.o 48 0 0 0 0 68 dfixul.o 26 0 0 0 0 76 dfltui.o 228 0 0 0 0 96 dmul.o 38 0 0 0 0 68 f2d.o 110 0 0 0 0 168 fepilogue.o ---------------------------------------------------------------------- 3874 106 0 4 0 2044 Library Totals 4 0 0 0 0 0 (incl. Padding) ---------------------------------------------------------------------- Code (inc. data) RO Data RW Data ZI Data Debug Library Name 2574 106 0 4 0 988 mc_w.l 1296 0 0 0 0 1056 mf_w.l ---------------------------------------------------------------------- 3874 106 0 4 0 2044 Library Totals ---------------------------------------------------------------------- ============================================================================== Code (inc. data) RO Data RW Data ZI Data Debug 6284 476 552 48 1152 342938 Grand Totals 6284 476 552 48 1152 342938 ELF Image Totals 6284 476 552 48 0 0 ROM Totals ============================================================================== Total RO Size (Code + RO Data) 6836 ( 6.68kB) Total RW Size (RW Data + ZI Data) 1200 ( 1.17kB) Total ROM Size (Code + RO Data + RW Data) 6884 ( 6.72kB) ==============================================================================
当工程按默认配置构建时,MDK会根据我们选择的芯片型号,获知芯片的内部FLASH及内部SRAM存储器概况, 生成一个以工程名命名的后缀为*.sct的分散加载文件(Linker Control File,scatter loading), 链接器根据该文件的配置分配各个节区地址, 生成分散加载代码,因此我们通过修改该文件可以定制具体节区的存储位置。
文件内容如下:
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x00100000 { ; load region size_region ER_IROM1 0x08000000 0x00100000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) .ANY (+XO) } RW_IRAM1 0x20000000 0x00020000 { ; RW data .ANY (+RW +ZI) } RW_IRAM2 0x10000000 0x00010000 { .ANY (+RW +ZI) } }
我们的sct示例文件配置如下:程序的加载域为内部FLASH的0x08000000,最大空间为0x00100000;程序的执行基地址与加载基地址相同, 其中RESET节区定义的向量表要存储在内部FLASH的首地址,且所有o文件及lib文件的RO属性内容都存储在内部FLASH中; 程序执行时RW及ZI区域都存储在以0x20000000为基地址,大小为0x00020000的空间(128KB),这部分正好是STM32内部主SRAM的大小。
链接器根据sct文件链接,链接后各个节区、符号的具体地址信息可以在map文件中查看。
了解sct文件的格式后,可以手动编辑该文件控制整个工程的分散加载配置,但sct文件格式比较复杂,所以MDK提供了相应的配置选项可以方便地修改该文件, 这些选项配置能满足基本的使用需求,其实就是我们在上文中配置的RAM和ROM大小。
在弹出的对话框中有一个“Memory Assignment”区域(存储器分配),在该区域中可以针对文件的各种属性内容进行分配, 如Code/Const内容(RO)、Zero Initialized Data内容(ZI-data)以及Other Data内容(RW-data), 点击下拉菜单可以找到在前面Target页面配置的IROM1、IRAM1、IRAM2等存储器。 例如图中我们把这个bsp_led.c文件的OtherData属性的内容分配到了IRAM2存储器(在Target标签页中我们勾选了IRAM1及IRAM2), 当在bsp_led.c文件定义了一些RW-data内容时(如初值非0的全局变量),该变量将会被分配到IRAM2空间,配置完成后点击OK,然后编译工程, 查看到的sct文件。
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x00100000 { ; load region size_region ER_IROM1 0x08000000 0x00100000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) .ANY (+XO) } RW_IRAM1 0x20000000 0x00020000 { ; RW data .ANY (+RW +ZI) } RW_IRAM2 0x10000000 0x00010000 { bsp_led.o (+RW) .ANY (+RW +ZI) } }
虽然MDK的这些存储器配置选项很方便,但有很多高级的配置还是需要手动编写sct文件实现的, 例如MDK选项中的内部ROM选项最多只可以填充两个选项位置,若想把内部ROM分成多片地址管理就无法实现了; 另外MDK配置可控的最小粒度为文件,若想控制特定的节区也需要直接编辑sct文件。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。