5.15.3 Changing and Linking the Allocated Section
The __section()
specifier allows you to have an object or
function redirected into a user-defined psect, or section.
Compiler-Generated Psects lists the default sections the compiler uses to hold objects and code. The default section used by a function or object can be changed if the object has unique linking requirements that cannot be addressed by existing compiler features.
New sections created by the specifier for objects will have no linker
class associated with them. In addition, the compiler will not make assumptions
about the final location of the new section. You can link objects specified with
__section()
into any data bank. However, since the compiler
cannot know where the new section will be placed until the linker has executed,
the code to access the relocated object will be less efficient than the code used
to access the object without the specifier.
Since the new section is linked after other objects have been allocated
memory, you might also receive memory errors when using the
__section()
specifier. If this is the case, you will need to
reserve memory for the new section (see Reserve Option).
New sections created by the specifier for functions will inherit the same flags. However, there are fewer linking restrictions relating to functions and this has minimal impact on the generated code.
The name of the new section you specify must be a valid assembly-domain
identifier. The name must contain only alphabetic characters, numeric characters,
or the underscore character, _
. It cannot have a name that is the
same as that of an assembler directive, control, or directive flag. If the new
section contains executable code and you wish this code to be optimized by the
assembler, ensure that the section name contains the substring
text
, e.g., usb_text
. Sections named
otherwise will not be modified by the assembler optimizer.
Objects that use the __section()
specifier will be
cleared or initialized in the usual way by the runtime startup code (see Startup and Initialization). In the
case of initialized objects, the compiler will automatically allocate an
additional new section (whose name will be the same as the section specified,
prefixed with the letter i
) that will contain the initial values.
This section must be stored in program memory, and you might need to locate this
section explicitly with a linker option.
int __section("myData") foobar;
int __section("myCode") helper(int mode) { /* ... */ }
-Wl,-PmyData=0200h
-Wl,-AMYCODE=50h-3ffh
-Wl,-PmyCode=MYCODE
which will place the section myData
at address 0x200, and
the section myCode
anywhere in the range 0x50 to 0x3ff
represented by the linker class, MYCODE
. See Operation for linker
options that can be passed using the -Wl
driver option (Wl: Pass Option To The Linker,
Option).
-D
option, which indicates a delta value for a
class. For example:-Wl,-DMYCODE=2
Do not use this option for PIC18 devices, which have byte-addressable program memory.
myCode
section to be placed at an
address that is a multiple of 100h, then you can place the following in your
source file:__asm("PSECT mycode,reloc=100h");
int __section("myCode") helper(int mode) { /* ... */ }
The reloc
, size
, and
limit
psect flags (see, for example, Reloc Flag) can all be
redefined in this way. Redefinitions might trigger assembler warning messages;
however, these can be ignored in this circumstance.