Reference:IAR Technial Note 27787
How to place a constant at specific address in code memory
EW targets: | PIC |
EW component: | C/C++ compiler |
Keywords: | "@" / #pragma locate, constant |
Last update: | April 20, 2000 |
1) Why can I not use #pragma locate and/or the"@" syntax for constant variables?
Regarding the "@" and the #pragma locate syntax for located variables - located variables can not be initialized when defining them, thus it is not very useful for const variables. This is true up to and including v2.00A of ICCPIC (Spring 2000), the special case of constant and located variables may be handled better in future versions.
2) How can I put a constant, i.e., a RETLW #, at a specific location in code memory?
To place a RETLW constant in code memory at a specified address, you could use #pragma constseg and define a segment of your own as the example below. Note that there is a problem with pragma constseg in ICCPIC version 1.23, this is fixed in version 2.00A. As a workaround for version 1.23A, you can use the assembler example below.
3) How can I put a constant, i.e., a plain number, at a specific location in code memory?
This is useful only for chips with table read. Suggested way is to use assembly, as the example below.
Examples of how to define constants in code memory:
-- Assembler file
PUBLIC myasmconst1 PUBLIC myasmconst2 RSEG myacseg1:CODE(1) myasmconst1 DB 0x34,0x56 RSEG myacseg2:CODE(1) myasmconst2 RETLW 0x78 END
-- C-file
extern unsigned int __rtable myasmconst1; extern const unsigned char myasmconst2; #pragma constseg=myccseg const unsigned char mycconst=0x12; #pragma constseg=default void main(void) { int i; i=myasmconst1+myasmconst2+mycconst; }
-- Corresponding lines to add to copy of linker xcl-file (example for 17c756)
-Z(CODE)myccseg=1FFFA-1FFFB -Z(CODE)myacseg1=1FFFC-1FFFD -Z(CODE)myacseg2=1FFFE-1FFFF
---------------------------------------------------------------------------------
要想在指定的Code区域定义常量,需要在汇编、c、xcl文件三方面修改。
---------------------------------------------------------------------------------
CONTROLLING DATA AND FUNCTION PLACEMENT
The @operator, alternatively the #pragma locationdirective, can be used for placing
global and static variables at absolute addresses. The syntax can also be used for placing
variables or functions in named segments. The variables must be declared either
__no_initor const. If declared const, it is legal for them to have initializers. The
named segment can either be a predefinedsegment, or a user-defined segment.
Note:Take care when explicitly placing a variable or function in a predefined segment
other than the one used by default. This is possible and useful in some situations, but
incorrect placement can result in anythingfrom error messages during compilation and
linking to a malfunctioning(错误的) application. Carefully consider the circumstances(情况); there
might be strict requirements on the declaration and use of the function or variable.
C++ static member variables can be placed atan absolute address or in named segments,
just like any other static variable.
Data placement at an absolute location
To place a variable at an absolute address, the argument to the operator @and the
#pragma locationdirective should be a literal number(字面常量数), representing(符号地址? ) the actual
address.
Example
__no_init char alpha @ 0x80; /* OK */ __no_init __bit bool beta @ 0x60; /* OK */ #pragma location=0x90 __code const int gamma; /* OK */ __xdata_rom const int delta @ 0xA0 = 3; /* OK */ int epsilon @ 0xB0; /* Error, neither */ /* "__no_init" */ /* nor"const".*/
Note:A variable placed at an absolute location should be defined in an include file, to
be included in every module that uses the variable. An unused definition in a module
will be ignored.
Example
__no_init int alpha @ "MYSEGMENT"; /* OK */ #pragma location="MYSEGMENT" __xdata_rom const int beta; /* OK */ __code const int gamma @ "MYSEGMENT" = 3;/* OK */ int delta @ "MYSEGMENT"; /* Error, neither */ /* "__no_init" nor "const" */
Function placement into named segments
It is possible to place functions into named segments using either the @operator or the
#pragma locationdirective. When placing functionsinto segments, the segment is
specified as a string literal.
Example
void f() @ "MYSEGMENT"; void g() @ "MYSEGMENT" { } #pragma location="MYSEGMENT" void h();