比如某例程中有UART_VINIT、IO_VINIT、MAIN_VINIT、MAIN、TIMER2等函数。其中TIMER2是我们需要固定其入口地址的函数。编译链接之后在工程目录下会生成M51文件(后缀为M51)。可以用记事御前塌本将其打开。打开悔晌后我们找到LINK MAP OF MODULE 项,在默认编译链接情况下其内容为:
LINK MAP OF MODULE: T2test2 (TIMER)
TYPEBASE LENGTHRELOCATION SEGMENT NAME
-----------------------------------------------------
* * * * * * * D A T A M E M O R Y * * * * * * *
REG 0000H 0008H ABSOLUTE "REG BANK 0"
DATA0008H 0001H UNIT ?DT?MAIN?TIMER
DATA0009H 0001H UNIT ?DT?GETCHAR
000AH 0016H *** GAP ***
BIT 0020H.0 0000H.1 UNIT ?BI?GETCHAR
0020H.1 0000H.7*** GAP ***
IDATA 0021H 0001H UNIT ?STACK
* * * * * * * C O D E M E M O R Y * * * * * * *
CODE0000H 0003H ABSOLUTE
0003H 0028H *** GAP ***
CODE002BH 0003H ABSOLUTE
002EH 07D2H *** GAP ***
CODE0800H 0062H UNIT ?PR?MAIN?TIMER
CODE0862H 0027H UNIT ?PR?PUTCHAR?PUTCHAR
CODE0889H 0026H UNIT ?C?LIB_CODE
CODE08AFH 001FH UNIT ?PR?UART_VINIT?STARTUP
CODE08CEH 001EH UNIT ?PR?MAIN_VINIT?STARTUP
CODE08ECH 0011H UNIT ?PR?GETCHAR?GETCHAR
CODE08FDH 000CH UNIT ?C_C51STARTUP
CODE0909H 000BH UNIT ?PR?TIMER2?TIMER
CODE0914H 000AH UNIT ?PR?_GETKEY?_GETKEY
CODE091EH 0004H UNIT ?PR?IO_VINIT?STARTUP
以上就是链接后各函数的入口地址信息。找到我们需要指定入口地址的项。这里假设我们需要指定TIMER2这个子函数。找到其对应项“?PR?TIMER2?TIMER”,其中间部分即为函数名,后部分为所在文件名。我们发现其入口地址为0909H,长度为000BH。找到这一项之后,复制其值。然后打开菜单Project,选择Options,再选择BL51 Locate项。在Code栏后面的输入框里粘下所复制的值,然后在后面加上小括号,括号内给出其入口地址的值。如 ?PR?TIMER2?TIMER(0x1000)。如图一所示:
图一
点击确定后,重新编译链接,再打开M51文件,发现LINK MAP OF MODULE项内容变为:
LINK MAP OF MODULE: T2test2 (TIMER)
TYPEBASE LENGTHRELOCATION SEGMENT NAME
-----------------------------------------------------
* * * * * * * D A T A M E M O R Y * * * * * * *
REG 0000H 0008H ABSOLUTE "REG BANK 0"
DATA0008H 0001H UNIT ?DT?MAIN?TIMER
DATA0009H 0001H UNIT ?DT?GETCHAR
000AH 0016H *** GAP ***
BIT 0020H.0 0000H.1 UNIT ?BI?GETCHAR
0020H.1 0000H.7*** GAP ***
IDATA 0021H 0001H UNIT ?STACK
* * * * * * * C O D E M E M O R Y * * * * * * *
CODE0000H 0003H ABSOLUTE
0003H 0028H *** GAP ***
CODE002BH 0003H ABSOLUTE
002EH 07D2H *** GAP ***
CODE0800H 0062H UNIT ?PR?MAIN?TIMER
CODE0862H 0027H UNIT ?PR?PUTCHAR?PUTCHAR
CODE0889H 0026H UNIT ?C?LIB_CODE
CODE08AFH 001FH UNIT ?PR?UART_VINIT?STARTUP
CODE08CEH 001EH UNIT ?PR?MAIN_VINIT?STARTUP
CODE08ECH 0011H UNIT ?PR?GETCHAR?GETCHAR
CODE08FDH 000CH UNIT ?C_C51STARTUP
CODE0909H 000AH UNIT ?PR?_GETKEY?_GETKEY
CODE0913H 0004H UNIT ?PR?IO_VINIT?STARTUP
0917H 06E9H *** GAP ***
CODE1000H 000BH UNIT ?PR?TIMER2?TIMER
在链接信息中发现TIMER2函数已经定位到地址1000H。当然在下载到目标板或者在模拟器中调试时,可以发现在地址1000H处是函数TIMER2的入口地址。至此,子函数定位完成。
在要指定代码的存储空间不是一件特别简单的事情,尤其是你想为某个或某几个函数指定具体的地址。1,编译器只有在最终的Link阶段才会为代码和数据分配内存地址,因此指定代码段的地址一般是通过写一个link脚本来进行的。Link阶段时,编译器的Linker会读取你写的Link脚本,并且按照脚本的规定隐凯伍给代码分配地址。
2,根据ARM开发工具的不同,link脚本的语法和形式也有所不孙悉同。ARM MDK,ARM ADS,Eclips+GCC,Linux GCC, ARM Realview等开发工具都支持Link脚本。
如果你英文还可以,建议你直接找到开发工具的Help手册去研究。如果你英语实在不行,灶或也可以把开发工具名称和你代码的具体情况告诉我,我帮你看看。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)