Question

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)

Was it helpful?

Solution

The MPLAB C18 Compiler User's Guide lists a few extra storage qualifiers that appear to be relevant to your use-case:

near/far Program Memory Objects
The far qualifier is used to denote that a variable that is located in program memory can be found anywhere in program memory, or, if a pointer, that it can access up to and beyond 64K of program memory space.

ram/rom Qualifiers
The rom qualifier denotes that the object is located in program memory, whereas the ram qualifier denotes that the object is located in data memory.

Later on, the manual shows an example of creating "a function pointer that can access up to a beyond 64K of program memory space":

far rom void (*fp) (void);

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top