分散加载,嵌入式程序结构_第1页
分散加载,嵌入式程序结构_第2页
分散加载,嵌入式程序结构_第3页
分散加载,嵌入式程序结构_第4页
分散加载,嵌入式程序结构_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、ARM中的RO、RW和ZI DATA说明 【整理者】【提供者】zzzh【详细说明】ARM中的RO、RW和ZI DATA说明ARM中的RO、RW和ZI DATA说明感觉这几段还蛮有用的发上来备份一下osboyRO段、RW段和ZI段Posted by gavinkwoe一直以来对于ARM体系中所描述的RO,RW和ZI数据存在似是而非的理解,这段时间对其仔细了解了一番,发现了一些规律,理解了一些以前书本上有的但是不理解的东西,我想应该有不少人也有和我同样的困惑,因此将我的一些关于RO,RW和ZI的理解写出来,希望能对大家有所帮助。要了解RO,RW和ZI需要首先了解以下知识:ARM程序的组成此处所说的

2、“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的bin映像(image)文件,这一点清注意区别。一个ARM程序包含3部分:RO,RW和ZIRO是程序中的指令和常量RW是程序中的已初始化变量ZI是程序中的未初始化的变量由以上3点说明可以理解为:RO就是readonly,RW就是read/write,ZI就是zeroARM映像文件的组成所谓ARM映像文件就是指烧录到ROM中的bin文件,也成为image文件。以下用Image文件来称呼它。Image文件包含了RO和RW数据。之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域

3、一律清零即可。包含进去反而浪费存储空间。 Q:为什么Image中必须包含RO和RW?A:因为RO中的指令和常量以及RW中初始化过的变量是不能像ZI那样“无中生有”的。ARM程序的执行过程从以上两点可以知道,烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。因此就有必要了解ARM程序是如何从ROM中的image到达实际运行状态的。实际上,RO中的指令至少应该有这样的功能:1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM

4、区域清零。ZI中也是变量,同理:变量不能存在ROM中在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。说了上面的可能还是有些迷糊,RO,RW和ZI到底是什么,下面我将给出几个例子,最直观的来说明RO,RW,ZI在C中是什么意思。1; RO看下面两段程序,他们之间差了一条语句,这条语句就是声明一个字符常量。因此按照我们之前说的,他们之间应该只会在RO数据中相差一个字节(字符常量为1字节)。 Prog1:#include <stdio.h>void main(void);Prog2:#include <stdio.h>c

5、onst char a = 5;void main(void);Prog1编译出来后的信息如下:=Code RO Data RW Data ZI Data Debug948 60 0 96 0 Grand Totals=Total RO Size(Code + RO Data) 1008 ( 0.98kB)Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)=Prog2编译出来后的信息如下:=Code RO Data RW Data ZI Data

6、 Debug948 61 0 96 0 Grand Totals=Total RO Size(Code + RO Data) 1009 ( 0.99kB)Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)=以上两个程序编译出来后的信息可以看出:Prog1和Prog2的RO包含了Code和RO Data两类数据。他们的唯一区别就是Prog2的RO Data比Prog1多了1个字节。这正和之前的推测一致。如果增加的是一条指令而不是一个常量,则结果应该

7、是Code数据大小有差别。2; RW同样再看两个程序,他们之间只相差一个“已初始化的变量”,按照之前所讲的,已初始化的变量应该是算在RW中的,所以两个程序之间应该是RW大小有区别。 Prog3:#include <stdio.h>void main(void);Prog4:#include <stdio.h>char a = 5;void main(void);Prog3编译出来后的信息如下:=Code RO Data RW Data ZI Data Debug948 60 0 96 0 Grand Totals=Total RO Size(Code + RO Data

8、) 1008 ( 0.98kB)Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)=Prog4编译出来后的信息如下:=Code RO Data RW Data ZI Data Debug948 60 1 96 0 Grand Totals=Total RO Size(Code + RO Data) 1008 ( 0.98kB)Total RW Size(RW Data + ZI Data) 97 ( 0.09kB)Total ROM Size(C

9、ode + RO Data + RW Data) 1009 ( 0.99kB)=可以看出Prog3和Prog4之间确实只有RW Data之间相差了1个字节,这个字节正是被初始化过的一个字符型变量“a”所引起的。3; ZI再看两个程序,他们之间的差别是一个未初始化的变量“a”,从之前的了解中,应该可以推测,这两个程序之间应该只有ZI大小有差别。Prog3:#include <stdio.h>void main(void);Prog4:#include <stdio.h>char a;void main(void);Prog3编译出来后的信息如下:=Code RO Data

10、 RW Data ZI Data Debug948 60 0 96 0 Grand Totals=Total RO Size(Code + RO Data) 1008 ( 0.98kB)Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)=Prog4编译出来后的信息如下:=Code RO Data RW Data ZI Data Debug948 60 0 97 0 Grand Totals=Total RO Size(Code + RO Data

11、) 1008 ( 0.98kB)Total RW Size(RW Data + ZI Data) 97 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)=编译的结果完全符合推测,只有ZI数据相差了1个字节。这个字节正是未初始化的一个字符型变量“a”所引起的。注意:如果一个变量被初始化为0,则该变量的处理方法与未初始化华变量一样放在ZI区域。即:ARM C程序中,所有的未初始化变量都会被自动初始化为0。 总结:1; C中的指令以及常量被编译后是RO类型数据。2; C中的未被初始化或初始化为0的变量编译后是ZI类型数据

12、。3; C中的已被初始化成非0值的变量编译后市RW类型数据。附:程序的编译命令(假定C程序名为tst.c):armcc -c -o tst.o tst.carmlink -noremove -elf -nodebug -info totals -info sizes -map -list aa.map -o tst.elf tst.o编译后的信息就在aa.map文件中。ROM主要指:NAND Flash,Nor FlashRAM主要指:PSRAM,SDRAM,SRAM,DDRAM/=Image$?$Limit 的含义对于刚学习ARM的人来说,如果分析它的启动代码,往往不明白下面几个变量的含义:

13、|Image$RO$Limit|、|Image$RW$Base|、|Image$ZI$Base|。首先申明我使用的调试软件为ADS1.2,当我们把程序编写好以后,就要进行编译和链接了,在ADS1.2中选择MAKE按钮,会出现一个Errors and Warnings 的对话框,在该栏中显示编译和链接的结果,如果没有错误,在文件的最后应该能看到Image component sizes,后面紧跟的依次是Code,RO Data ,RW Data ,ZI Data ,Debug 各个项目的字节数,最后会有他们的一个统计数据:Code 163632 ,RO Data 20939 ,RW Data 5

14、3 ,ZI Data 17028Tatal RO size (Code+ RO Data) 184571 (180.25kB)Tatal RW size(RW Data+ ZI Data) 17081(16.68 kB)Tatal ROM size(Code+ RO Data+ RW Data) 184624(180.30 kB)后面的字节数是根据用户不同的程序而来的,下面就以上面的数据为例来介绍那几个变量的计算。在ADS的Debug Settings中有一栏是Linker/ARM Linker,在output选项中有一个RO base选项,下面应该有一个地址,我这里是0x0c100000,后

15、面的RW base 地址是0x0c200000,然后在Options选项中有Image entry point ,是一个初始程序的入口地址,我这里是0x0c100000 。有了上面这些信息我们就可以完全知道这几个变量是怎么来的了:|Image$RO$Base| = Image entry point = 0x0c100000 ;表示程序代码存放的起始地址|Image$RO$Limit|=程序代码起始地址+代码长度+1=0x0c100000+Tatal RO size+1= 0x0c100000 + 184571 + 1 = 0x0c100000 +0x2D0FB + 1= 0x0c12d0fc

16、|Image$RW$Base| = 0x0c200000 ;由RW base 地址指定|Image$RW$Limit| =|Image$RW$Base|+ RW Data 53 = 0x0c200000+0x37(4的倍数,0到55,共56个单元)=0x0c200037|Image$ZI$Base| = |Image$RW$Limit| + 1 =0x0c200038|Image$ZI$Limit| = |Image$ZI$Base| + ZI Data 17028=0x0c200038 + 0x4284=0x0c2042bc也可以由此计算:|Image$ZI$Limit| = |Image$

17、RW$Base| +TatalRWsize(RWData+ZIData) 17081=0x0c200000+0x42b9+3(要满足4的倍数)=0x0c2042bc/=Part1 简介一 概述Scatter file (分散加载描述文件)用于armlink的输入参数,他指定映像文件内部各区域的download与运行时位置。Armlink将会根据scatter file生成一些区域相关的符号,他们是全局的供用户建立运行时环境时使用。(注意:当使用了scatter file 时将不会生成以下符号 Image$RW$Base, Image$RW$Limit, Image$RO$Base, Image

18、$RO$Limit, Image$ZI$Base, and Image$ZI$Limit)二 什么时候使用scatter file当然首要的条件是你在利用ADS进行项目开发,下面我们看看更具体的一些情况。1 存在复杂的地址映射:例如代码和数据需要分开放在在多个区域。2 存在多种存储器类型:例如包含 Flash,ROM,SDRAM,快速SRAM。我们根据代码与数据的特性把他们放在不同的存储器中,比如中断处理部分放在快速SRAM内部来提高响应速度,而把不常用到的代码放到速度比较慢的Flash内。3 函数的地址固定定位:可以利用Scatter file实现把某个函数放在固定地址,而不管其应用程序是否

19、已经改变或重新编译。4 利用符号确定堆与堆栈:5 内存映射的IO:采用scatter file可以实现把某个数据段放在精确的地指处。因此对于嵌入式系统来说scatter file是必不可少的,因为嵌入式系统采用了ROM,RAM,和内存映射的IO。三 scatter file 实例1 简单的内存映射LOAD_ROM 0x0000 0x8000EXEC_ROM 0x0000 0x8000*( RO)RAM 0x10000 0x6000*( RW, ZI)LOAD_ROM(下载区域名称) 0x0000(下载区域起始地址) 0x8000(下载区域最大字节数)EXEC_ROM(第一执行区域名称) 0x0

20、000(第一执行区域起始地址) 0x8000(第一执行区域最大字节数)*( RO(代码与只读数据)RAM(第二执行区域名称) 0x10000(第二执行区域起始地址) 0x6000(第二执行区域最大字节数)*( RW(读写变量), ZI(未初始化变量)2 复杂内存映射LOAD_ROM_1 0x0000EXEC_ROM_1 0x0000program1.o( RO)DRAM 0x18000 0x8000program1.o ( RW, ZI)LOAD_ROM_2 0x4000EXEC_ROM_2 0x4000program2.o( RO)SRAM 0x8000 0x8000program2.o (

21、 RW, ZI)LOAD_ROM_1 0x0000(下载区域一起始地址)EXEC_ROM_1 0x0000(第一执行区域开始地址)program1.o( RO) (program1.o内的Code与RO data 放在第一执行区域)DRAM 0x18000(第二执行区域开始地址) 0x8000(第二执行区域最大字节数)program1.o ( RW, ZI) (program1.o内的RW data与 ZI data 放在第二执行区域)LOAD_ROM_2 0x4000(下载区域二起始地址)EXEC_ROM_2 0x4000program2.o( RO) (program2.o内的Code与R

22、O data 放在第一执行区域)SRAM 0x8000 0x8000program2.o ( RW, ZI) (program2.o内的RW data与 ZI data 放在第二执行区域)Part2 基本语法2.1 BNF 符号与语法" :由引号赖标示的符号保持其字面原意,如A” ”B标示A B。A := B :定义A为B。A :标示可选部分,如ABC用来标示ABC或AC。A :用来标示A可以重复任意次,如A 可标示A,AA,AAA, A* :同A 。A | B :用来标示选择其一,不能全选。如A|B用来标示A或者B。(A B) :标示一个整体,当和|符号或复杂符号的多次重复一起使用

23、时尤其强大,如(AB) (C|D)标示ABC,ABD,ABABC,ABABD, 2.2 分散加载文件各部分描述(2.1)如图2.1所示为一个完整的分散加载脚本描述结构图。下面我们对图示中各个部分进行讲述。每个加载区有:ó名称:供连接器确定不同下载区域ó基地址:相对或绝对地址ó属性:可选ó最大字节数:可选ó执行区域列:确定执行时各执行区域的类型与位置load_region_name (base_address | (" " offset) attribute_list max_size ""executio

24、n_region_description""load_region_name:下载区域名称,最大有效字符数31。(并不像执行区域段名用于Load$region_name,而是仅仅用于标示下载区域)。base_address:本区域内部目标被连接到的地址(按字对齐)。offset:相对前一个下载区域的偏移量(4的整数倍,如果为第一个区域)。每个执行区有:ó名称:供连接器确定不同下载区域ó基地址:相对或绝对地址ó属性:确定执行区域的属性ó最大字节数:可选ó输入段:确定放在该执行区域的模块exec_region_name (bas

25、e_address | " " offset) attribute_list max_size""input_section_description""exec_region_name:执行区域名称,最大有效字符数31。base_address:本执行区域目标要被联接到的位置,按字对齐。offset:相对于前一个执行区域结束地址的偏移量,4的整数倍;如果没有前继之能够行区域(本执行区域为该下载区域的第一个执行区域),则该偏移量是相对于该下载区域的基址偏移量。attribute_list:PI,OVERLAY,ABSOLUTE,FIXE

26、D,UNINIT。PI: 位置独立。OVERLAY: 覆盖。ABSOLUTE: 绝对地址。FIXED: 固定地址,下载地址与执行地址具有该地址指示确定。UNINIT: 未初始化数据。RELOC:无法明确指定执行区域具有该属性,而只能通过继承前一个执行区或父区域获得。对于PI,OVERLAY,ABSOLUTE,FIXED,我们只能选择一个,缺省属性为ABSOLUTE。一个执行区域要么直接继承其前面的执行区域的属性或者具有属性为ABSOLUTE。具有PI,OVERLAY,RELOC属性的执行区域允许其地址空间重叠,对于BSOLUTE,FIXED 属性执行区域地址空间重叠Armlink会报错。max

27、_size:可选,他用于指使Armlink在实际分配空间大于指定值时报错。input_section_description:指示输入段的内容。输入段:ó模块名:目标文件名,库成员名,库文件名。名称可以使用通配符。ó输入段名,或输入段属性(READ-ONLY,CODE)。module_select_pattern"("(" " input_section_attr | input_section_pattern)("," " " input_section_attr | ","

28、; input_section_pattern)*")"module_select_pattern:选择的模块名称(目标文件,库文件成员,库文件),模块名可以使用通配符(*匹配任意多个字符,?匹配任意一个字符),名称不区分字母大小写,它是供选择的样本。例1:*libtx.a ( RO)libtx.a为threadX库文件。例2:tx_ill.o (INIT)tx_ill.o为threadX中断向量目标文件。input_section_attr:输入段属性选择子,每个选择子以” ”开头,选择子不区分大小写字符。选择子可选RO-CODE,RO-DATA,RO( selects

29、both RO-CODE and RO-DATA),RW-DATA,RW-CODE,RW( selects both RW-CODE and RW-DATA),ZI,ENTRY( that is a section containing an ENTRY point)。以下同义词可以选择:CODE (for RO-CODE),CONST( for RO-DATA),TEXT (for RO),DATA (for RW),BSS (for ZI)。还有两个伪属性:FIRST,LAST。如果各段的先后顺序比较重要时,可以使用FIRST,LAST标示一个执行区域的第一个和最后一个段。例1:os_ma

30、in_init.o (INIT , FIRST)FIRST表示放于本执行区域的开始处。例2:*libtx.a ( RO)RO 表示*libtx.a的只读部分。input_section_pattern:输入段名。例1:os_main_init.o (INIT , FIRST)INIT 为os_main_init.o的一个段。例2:os_stackheap.o (heap)heap 为os_stackheap.o的一个段。例3:os_stackheap.o (stack)stack为os_stackheap.o的一个段。/-分散加载文件事例ADS下的分散加载文件应用实例load_region_n

31、ame start_address | " "offset attributes max_sizeexecution_region_name start_address | " "offset attributesmax_sizemodule_select_pattern "("(" " input_section_attr | input_section_pattern)(","input_section_pattern) *")"load_region: 加载区,用来保存

32、永久性数据(程序和只读变量)的区域;execution_region: 执行区,程序执行时,从加载区域将数据复制到相应执行区后才能被正确执行;load_region_name: 加载区域名,用于“Linker”区别不同的加载区域,最多31个字符;start_address: 起始地址,指示区域的首地址;offset: 前一个加载区域尾地址offset 做为当前的起始地址,且“offset”应为“0”或“4”的倍数;attributes: 区域属性,可设置如下属性:PI 与地址无关方式存放;RELOC 重新部署,保留定位信息,以便重新定位该段到新的执行区;OVERLAY 覆盖,允许多个可执行区域

33、在同一个地址,ADS不支持;ABSOLUTE 绝对地址(默认);max_size: 该区域的大小; " " input_section_attr | ","execution_region_name:执行区域名;start_address: 该执行区的首地址,必须字对齐;offset: 同上;attributes: 同上;PI 与地址无关,该区域的代码可任意移动后执行;OVERLAY 覆盖;ABSOLUTE 绝对地址(默认);FIXED 固定地址;UNINIT 不用初始化该区域的ZI段;module_select_pattern: 目标文件滤波器,支持通

34、配符“*”和“?”;*.o匹配所有目标,* (或“.ANY”)匹配所有目标文件和库。input_section_attr: 每个input_section_attr必须跟随在“”后;且大小写不敏感;RO-CODE 或 CODERO-DATA 或 CONSTRO或TEXT, selects both RO-CODE and RO-DATARW-DATARW-CODERW 或 DATA, selects both RW-CODE and RW-DATAZI 或 BSSENTRY, that is a section containing an ENTRY point.FIRST,用于指定存放在一个

35、执行区域的第一个或最后一个区域;LAST,同上;input_section_pattern: 段名;汇编中指定段:AREA vectors, CODE, READONLYC中指定段:#pragma arm section sort_type="name" ,sort_type="name"*sort_type: code、rwdata、rodata、zidata如果“sort_type”指定了但没有指定“name”,那么之前的修改的段名将被恢复成默认值。#pragma arm section / 恢复所有段名为默认设置。应用:#pragma arm se

36、ction rwdata = "SRAM",zidata = "SRAM"static OS_STK SecondTaskStk256; / “rwdata”“zidata”将定位在“sram”段中。#pragma arm section / 恢复默认设置分散加载文件中定义如下:Exec_Sram 0x80000000 0x40000* (sram)“PI” 属性使用示例:LR_1 0x010000 PI ; The first load region is at 0x010000.ER_RO 0 ; The PI attribute is inheri

37、ted from parent.code can be moved.*( RO)ER_RW 0 ABSOLUTE*( RW)moved.ER_ZI 0*( ZI)LR_1 0x010000ER_RO 0 ; The default execution address is 0x010000, but the ; All the RO sections go here. ; PI attribute is overridden by ABSOLUTE. ; The RW sections are placed next. They cannot be ; ER_ZI region placed

38、after ER_RW region. ; All the ZI sections are placed consecutively here. ; The first load region is at 0x010000. ; Default ABSOLUTE attribute is inherited fromparent. The execution address; is 0x010000. The code and ro data cannot be moved.*( RO) ; All the RO sections go here.ER_RW 0x018000 PI ; PI

39、attribute overrides ABSOLUTE*( RW) ; The RW sections are placed at 0x018000 and they can be moved.ER_ZI 0 ; ER_ZI region placed after ER_RW region.*( ZI) ; All the ZI sections are placed consecutively here.程序中对某区域地址等的引用方法:Load$region_name$Base Load address of the region.Image$region_name$Base Execut

40、ion address of the region.Image$region_name$Length Execution region length in bytes (multiple of 4).Image$region_name$Limit Address of the byte beyond the end of the execution region.Image$region_name$ZI$Base Execution address of the ZI output section in this region.Image$region_name$ZI$Length Lengt

41、h of the ZI output section in bytes (multiple of 4).Image$region_name$ZI$Limit Address of the byte beyond the end of the ZI output sectionin the execution region.SectionName$Base Input Address of the start of the consolidated section called SectionName.SectionName$Limit Input Address of the byte bey

42、ond the end of the consolidated section called SectionName.Load: 加载区,即存放地址;Image: 执行区,即运行地址;Base: 区首地址;Limit: 区尾地址;Length: 区长度;region_name: RO、RW、ZI、load_region_name、execution_region_name;例如:“RAM1”区域的首地址: Image$RAM1$Base上例中“sram”段首地址: sram$Base汇编引用示例:IMPORT |Load$Exec_RAM1$Base| / Exec_RAM1 为“RW”段IM

43、PORT |Image$Exec_RAM1$Base|IMPORT |Image$Exec_RAM1$Length|IMPORT |Image$Exec_RAM1$Limit|LDR R0, =|Load$Exec_RAM1$Base|LDR R1, =|Image$Exec_RAM1$Base|LDR R2, =|Image$Exec_RAM1$Limit|CMP R1, R2LDRCC R3, R0, #4STRCC R3, R1, #4BCC %b0C 引用:extern unsigned char Load$Exec_RAM1$Base;extern unsigned char Ima

44、ge$Exec_RAM1$Base;extern unsigned char Image$Exec_RAM1$Length;void MoveRO(void)unsigned char * psrc, *pdst;unsigned int count;count = (unsigned int) &Image$Exec_RAM1$Length;psrc = (unsigned char *)&Load$Exec_RAM1$Base;pdst = (unsigned char *)&Image$Exec_RAM1$Base;while (count-) *pdst = *

45、psrc ;加载文件示例一:起始地址 大小ROM: 0x00000000 256KRAM 0x40000000 16KSRAM 0x80000000 512KLOAD_ROM1 0x00000000 0x1f8EXEC_ROM1 0 0x1f8 首地址为加载去首地址Startup.o (vectors, FIRST)第一段irq.o ( RO)LOAD_ROM2 0x000002000x1fc 保留为加密字,程序在ROM中运行; ;用于全局变量及任务堆栈; ;SRAM速度慢,主要用于存放大的数据表; ; 指定该加载区域首地址、大小 ; 没有前一加载区域,所以该执行区域 ; 并指定该区域长度 ;

46、 目标文件的“vectors”段放在该执行区域的 ; 目标文件的所有“RO”段放在该执行区域 ; 第二个加载区域 ;EXEC_ROM2 0 0x3e600* ( RO) ; 所有目标文件和库文件中的“RO”段存放在该区域RAM1 0x40000000 0x4000* ( RW, ZI) ; 所有目标文件和库文件的“RW”和“ZI”段存放在该区域SRAM2 0x80000000 0x80000* (sram) ; 所有目标文件中的“sram”段存放在该区域示例二:“iap.o”定义在“Exec_RAM1”中运行,所以设置“PI”属性;在调用“iap.c”中函数之前应该将其从“Load$Exec_

47、IAP$Base”复制到指定的“Exec_RAM1”区域;Load_region1 0x00000000 0x1fcEXEC_ROM1 0Startup.o (vectors, FIRST)irq.o ( RO)Load_region2 0x00000200 0x3e600EXEC_ROM2 0* ( RO)Exec_IAP 0 PI / 可能引起链接器未使用该属性警告,忽略iap.o ( RO)Exec_RAM1 0x40000000 0x4000* ( RW, ZI)Exec_Sram 0x80000000 0x40000* (SRAM)/ 移动“IAP.o”中的所有函数到“ImageEx

48、ecIAPBase”加载区,并调用其中的函数extern unsigned char Load$Exec_IAP$Base;extern unsigned char Image$Exec_IAP$Length;#define ImageExecIAPBase (0x40000000 0x1000) / 加载区首址void MoveIAPRO(void)unsigned char * psrc, *pdst;unsigned int count;count = (unsigned int) &Image$Exec_IAP$Length;psrc = (unsigned char *)&a

49、mp;Load$Exec_IAP$Base;pdst = (unsigned char *)ImageExecIAPBase;while (count-) *pdst = *psrc ;/ 调用“IAP.O”中的某函数void (* pfnIAPWrite)(unsigned long, int);pfnIAPWrite = (void (*)(unsigned long, int)(ImageExecIAPBase(unsigned int)IAPWrite - / 被调用函数名(unsigned int)&Load$Exec_IAP$Base);pfnIAPWrite(int)(C

50、UPDATA *)CODESTARTADDR)->data,(CUPDATA *)CODESTARTADDR)->length);/ARM编译程序参考介绍ARM编译程序的ARM特有方面,包括:Pragmas 编译指示Function keywords 函数关键字Variable declaration keywords 变量声明关键字PragmasARM编译程序可识别一下格式的编译指示:#pragma no_ feature-name编译指示优于相关的命令行选项。能识别的编译选项如下:Pragma nameDefaultReferencearm sectionOffPragmas

51、controlling code generationcheck_printf_formatsOffPragmas controlling printf and scanf argument checking check_scanf_formatsOffPragmas controlling printf and scanf argument checking check_stackOnPragmas controlling code generationdebugOnPragmas controlling debuggingimportcode generationOspaceoptimizationOtimeoptimizationOnumoptimizationsoftfp_linkageOffcode generatio

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论