Absolute Variable Location.
Variables may be located at absolute memory locations in your C program
source modules using the _at_ keyword. The usage for this feature is:
type memory_space variable_name _at_ constant;
where:
memory_space is the memory space for the variable. If missing from the
declaration, the default memory space is used. Refer to
“Memory Models” on page 94 for more information about
the default memory space.
type is the variable type.
variable_name is the variable name.
constant is the address at which to locate the variable.
The absolute address following _at_ must conform to the physical boundaries of
the memory space for the variable. The Cx51 compiler checks for invalid
address specifications.
//例子:
struct link
{
struct link idata *next;
char code *test;
};
struct link list idata _at_ 0x40; /* list at idata 0x40 */
char xdata text[256] _at_ 0xE000; /* array at xdata 0xE000 */
int xdata i1 _at_ 0x8000; /* int at xdata 0x8000 */
void main ( void ) {
link.next = (void *) 0;
i1 = 0x1234;
text [0] = 'a';
}
//但:
2. Functions and variables of type bit cannot be located at an absolute address
你看看我说的这种方式能不能解决你的问题:
1,你可以看一下bootload的初始化代码,中断函数入口地址都是定义在0地址开始的地方,你可以把你的模块函数入口地址放在接下去的地方就可以通过把绝对地址赋值给指向函数的指针来调用你的函数了。建议可以看下stm32 usb IAP的示例,里面是通过绝对地址跳转到真正的main()函数,你就能明白了。
2,keil中有个定义变量后面加上__at(地址)的方式把你的变量定义到指定的位置,你可以试一下定义在最前面。
1、函数定位:
假如要把C源文件 tools.c 中的函数
int BIN2HEX(int xx)
{
...
}
放在CODE MEMORY的0x1000处,先编译该工程,然后打开该工程的M51文件,在
* * * C O D E M E M O R Y * * *
行下找出要定位的函数的名称,应该形如:
CODE xxxxH xxxxH UNIT ?PR?_BCD2HEX?TOOLS
然后在:
Project->Options for Target ...->BL51 Locate:Code
中填写如下内容:
?PR?_BCD2HEX?TOOLS(0x1000)
再次Build,在M51中会发现该函数已放在CODE MEMORY的0x1000处了
2、赋初值的变量定位:
要将某变量定位在一绝对位置且要赋初值,此时用 _at_ 不能完成,则如下操作:
在工程中建立一个新的文件,如InitVars.c,在其中对要处理的变量赋初值(假设是code变
量):
char code myVer = {"COPYRIGHT 2001-11"};
然后将该文件加入工程,编译,打开M51文件,若定义的是code型,则在
* * * C O D E M E M O R Y * * *
下可找到:
CODE xxxxH xxxxH UNIT ?CO?INITVARS
然后在:
Project->Options for Target ...->BL51 Locate:Code
中填入:
?CO?INITVARS(0x200)
再次编译即可。
相应地,如为xdata变量,则InitVars.c中写:
char xdata myVer = {"COPYRIGHT 2001-11"};
然后将该文件加入工程,编译,打开M51文件,在
* * * X D A T A M E M O R Y * * *
下可找到:
XDATA xxxxH xxxxH UNIT ?XD?INITVARS
然后在:
Project->Options for Target ...->BL51 Locate:Xdata
中填入:
?XD?INITVARS(0x200)
再次编译即可。相应地,若定义的是data/idata等变量,则相应处理即可。
to iwillalwaysloveyou,
我也有过这样的疑问,基本上在KEIL工具上,要想函数的临时变量不要采用固定的地址,只有可重入(reentrant),不过可重入后代码就变大许多,可以说keil没有考虑好把部分模块打包lib后时,采用堆栈这种模式来调用,或者是没有优化好吧。
IAR Embedded Workbench for MCS-51就基本可以解决这个问题,IAR编译出来的程序,局部变量采用的堆栈的模式,是完全可以满足你的要求。
只有写过一些MASKROM程序的人才有这样的体会,我们现在就在用IAR的模式,IAR就是入门难一点,IAR有点GCC的风格,程序的连接过程完全能有开发者自主控制住你的程序。