5.15.3 Changing and Linking the Allocated Section

The __section() specifier allows you to have a object or function redirected into a user-define psect, or section.

5.15.1 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 4.6.1.18 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, numeric characters, or the underscore character, _. It cannot have a name which 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 4.3.2 Startup and Initialization). For 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), which 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.

The following are examples of a object and function allocated to a non-default section.

int __section("myData") foobar;
int __section("myCode") helper(int mode) { /* ... */ }

Typically you locate new sections you create with an explicit linker option. So, for example, if you wanted to place the sections created in the above example, you could use the following driver options:

-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 7.1 Operation for linker options that can be passed using the -Wl driver option (4.6.11.8 Wl: Pass Option To The Linker, Option).

If you are creating a new class for a memory range in program memory and your target is a Baseline or Mid-range PIC device, then you will need to inform the linker that this class defines memory that is word addressable. Do this by using the linker’s -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.

If you would like to set special flags with the new section, you can do this by providing a definition of the new section in your source code. For example, if you wanted the 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 6.1.9.39.16 Reloc Flag) can all be redefined in this way. Redefinitions might trigger assembler warning messages; however, these can be ignored in this circumstance.