Electronic – Microchip’s XC8 Linker doesn’t recognize some custom section names

linkermicrochippicxc8

Slightly related to this one: https://softwareengineering.stackexchange.com/questions/254734/microchip-xc8-how-to-pack-code-against-an-upper-limit

I can relocate code just fine, but I'm having some trouble with constants:

Example code:

#include <xc.h>

unsigned char buffer[16];

__section("SecConst1") const unsigned char constants1[] = "const1";
__section("SecConst2") const unsigned char constants2[] = "const2";
//__section("SecText1") const unsigned char constants1[] = "const1";
//__section("SecText2") const unsigned char constants2[] = "const2";

__section("SecText1") void fill_buffer1(void)
{
    unsigned char i = sizeof(constants1);
    do
    {
        i--;
        buffer[i] = constants1[i];
    }
    while(i);
}

__section("SecText2") void fill_buffer2(void)
{
    unsigned char i = sizeof(constants2);
    do
    {
        i--;
        buffer[i] = constants2[i];
    }
    while(i);
}

__section("SecText") void main(void)
{
    while(1)
    {
        fill_buffer1();
        fill_buffer2();
    }
}

Linker Options:

-L-aClass1=1200h-17FFh,1800h-1FFDh -L-dClass1=2 -L-pSecText1=Class1 -L-pSecText2=Class1 -L-pSecText=Class1

If I build it with no linker options, or if I only specify the functions (as above), it builds with no errors and I see all of the section names in the map file, so I know they're all there. But if I specify where to place a constant, the build fails because that section name was not defined. If I switch to the other set of constant declarations (swap the comments), then those names are suddenly not defined.

I feel that this is a bug in the toolchain, and I've told Microchip about it via their support site, but does anyone know of a good workaround?

I'd rather not specify the address of every constant directly in the source code because the complete project has a lot of them and they can all change size and contents from one version to the next.

I'm using a PIC16F1454, but I'm pretty sure that doesn't matter for this problem.

Best Answer

I submitted a ticket to Microchip's tech support, and after a few days, they found that

 #pragma psect <default_section>=<new_section>

would work for constants just like it's supposed to. They've made a note of the problem and said they'd fix it in the next release so either that or __section("new_section") will also work for constants.

I don't like the #pragma because you have to know the default_section (can be found by compiling successfully without the directive and searching the map file) and because it affects the entire source file, while __section() only affects the one item that it's used with. But for my application, it works.