Hello,
In my project I use function pointers. Memory is banked. I dont use X-Gate
typedef struct {
...
volatile Byte (*__far proc_pointer) (void); // pointer do wykonania procedury
...
} pseq_pdat;
Byte pseq_addproc (Byte *name, void *__far pointer) // dodanie procedury do kolejki
{
volatile pseq_dat *pseq_datx;
volatile pseq_pdat *pseq_pdatx;
...
pseq_pdatx[i].proc_pointer = (Byte (* __far) (void))pointer;
...
}
In code I use a function for ex:
pseq_addproc((Byte*)"SysLed Timer", &Tmr_SysLed);
In map file function Tmr_SysLed has address 0xFEA3E6. But when I run debug mode I see the pointer has address: 0xFE2B07. There are no functions at this address, but there is struct pseq_datx. I dont now why pointer points to bad address ;/
Best regard
Lukasz
Solved! Go to Solution.
I find the solution:
- bad syntax:
pseq_addproc((Byte*)"SysLed Timer", &Tmr_SysLed);
- good syntax:
void (*__far FunPtr)(void)= Tmr_SysLed;
pseq_addproc((Byte*)"SysLed Timer", FunPtr);
EDIT:
My code is small and is located only in PPAGE 0xFE so i'm not sure but propably i dont have to use far pointers. But when I executed function pointer pseq_pdatx[i].proc_pointer(); a PC jump to illegal address ;/
I forget earlier my code works well but on memory model large. When i'm usink memory model banked it dont work.
Not sure if this is you issue, but in the code I see a conversion from a __far data to a __far function pointer.
Note that those types of pointers are not compatible, you can start with a __far function pointer, cast it to a __far void pointer and cast it back, that ok.
But you cannot direcly use a data pointer to access the code the function pointer points to.
(or use a function pointer to execute the code a data pointer points to).
The reason is that __far data and __far function pointers are using a different byte ordering, see the compiler manual for details. Basically __far data pointers are big endian encoded, __far function pointer use a format so they are in memory usable by the HC12 CALL instruction.
I doubt a bit because the address you mention does not look like this is the issue you have. Just something which comes to mind when looking at __far function pointers.
Check if the function pseq_addproc is called with the right address or if the problem occurs in there.
Daniel
(and, BTW, for the S12X, __far data pointer are using global addresses too).
Thanks for reply!
Sometimes it is useful to read a documentation . Thath right my function pointer points to data not function. So I modify my code like that:
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Byte pseq_addproc (Byte *name, void * pointer) // dodanie procedury do kolejki
{
void (*__far FunPtr)(void)= Tmr_SysLed;
...
pseq_pdatx[i].proc_pointer = FunPtr;
...
}
That works fine but I dont use input *pointer from function pseq_addproc but I openly write pointer to function Tmr_SysLed fo FunPtr and later to structure pseq_pdatx. I have no idea how write input pointer to structure instead od FunPtr like now.
In line
pseq_addproc((Byte*)"SysLed Timer", &Tmr_SysLed);
I have warning Pointer conversion: possible loss of data, so pointer is ony 16 bit wide ;/
Earlier I have no problem here because of using large memory model and pointer was always 23 bit wide. When I modify function like that:
pseq_addproc (Byte *name, void *__far pointer),
pointer is 23 bit wide but points to bad address (page is wrong), for example:
Tmr_SysLed has address: a3d5FE
pointer points to: a3d57F
I find the solution:
- bad syntax:
pseq_addproc((Byte*)"SysLed Timer", &Tmr_SysLed);
- good syntax:
void (*__far FunPtr)(void)= Tmr_SysLed;
pseq_addproc((Byte*)"SysLed Timer", FunPtr);