I came across this problem twice in my project and the last time I used a kind of dirty solution.
Platform: PIC18F87J60, XC8 v1.12
I'm trying to use function pointers to point to functions that possibly reside in the upper halve of my ROM (>= 0x10000). This means that the pointer itself needs to be 17-bits or bigger (up to 20) to be able to address such a function.
This is the relevant code snippet (simplyfied):
void test(void) @ 0x1C000
{
printf("function pointer called!\r\n");
}
void main(void) {
void (*testPointer) (void) = &test;
//Now testPointer contains 0x0C000
(*testPointer)(); //Doesn't call test. Instead it jumps to 0x0C000
}
What happens is that test never actually gets called. When I use the debugger (PICKIT 3) I can see that the value in testPointer is 0x0C000. It just seems that the address in the pointer is rounded down to just 16-bits max and this always happens. But when I place test() somewhere below 0x10000 everything works fine because then the pointer just needs to be max 16 bits.
When I read back the program from the device test() really is placed at 0x1C000 so that is not the problem, the code is there.
The last time I solved the situation by casting a literal long to a pointer and that worked but its dirty and now I want to avoid it.
Does anyone recognize the problem? Is this a compiler bug? If so, does Microchip already know about this? Any clean work-arounds? Does the XC8 compiler support 20-bit const pointers at all?
Edit: fixed typo in code above &testPointer(); --> (*testPointer()); (no, this was not causing my problem)
The MPLAB C18 Compiler User's Guide lists a few extra storage qualifiers that appear to be relevant to your use-case:
Later on, the manual shows an example of creating "a function pointer that can access up to a beyond 64K of program memory space":
The XC8 manual is less clear about the function of the
far
qualifier, but still lists it, which strongly suggests that it still is recognized by the newer compilers.