Electronic – XC8 – constant ROM allocation for PIC12F1501

microchipmplabxc8

I have troubles with const memory allocation with XC8. I try to do this:

const unsigned char patterns[12] = {
    0, 0, 0, 0,
    0, 0, 0, 0,
    0, 0, 0, 0,
};

but I get this error: "can't find 0xC words (0xc withtotal) for psect "stringtext" in class "STRCODE" (largest unused contiguous range 0x57)". That's strange because space needed is less than space available (contiguous). In the user guide:

http://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB_XC8_C_Compiler_User_Guide.pdf

I read that

stringtext psect must be linked within the first half of each program memory page

I'm not quite sure why. I guess the compiler fills all the first halves before trying to find space for constants. Can anyway advice me how to give a hint to the compiler where to locate the constants section? Or Is there any other way to workaround this problem.

I'm using MPLAB because I find it difficult to use MPLAB X.

P.S. Keep in mind that the ROM is almost full – only 0x57 bytes left. It's well fragmented in small sections in order to fit better.

Best Answer

stringtext psect must be linked within the first half of each program memory page

This restriction only applies to 'baseline' PICs such as the 12C509, which can only call subroutines in the first half of each 256 byte page. Why does this matter? In older PICs there are no instructions for reading data from ROM, so a method was developed called Table Read, in which data arrays are stored as a sequence of RETLW instructions (return from subroutine with literal in working register).

The 12F1501 is one of the new generation of enhanced mid range PICs which can use their index register to read the ROM directly, so it has no restrictions on placement of data in the ROM. However the XC8 compiler still insists on trying to align stringtext on page boundaries, and refuses to put it in page zero even when only a few bytes of initialization code are 'in the way'! This may result in running out of space even though you have a significant amount of 'free' ROM.

The easiest way around this problem is to simply force your arrays into a code section - then the compiler should align them on word boundaries with no gaps (like normal code). Just add a section specifier to each array definition, like this:-

const __section("mystringtext") unsigned char patterns[12] = {
    0, 0, 0, 0,
    0, 0, 0, 0,
    0, 0, 0, 0,
};