Problem with __far function pointer in S12XEP100

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem with __far function pointer in S12XEP100

Jump to solution
2,381 Views
cs_Lukasz
Contributor III

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

Labels (1)
0 Kudos
1 Solution
612 Views
cs_Lukasz
Contributor III

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);

 

View solution in original post

0 Kudos
4 Replies
612 Views
cs_Lukasz
Contributor III

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.

Message Edited by cs_Lukasz on 2009-07-06 02:25 PM
0 Kudos
612 Views
CompilerGuru
NXP Employee
NXP Employee

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). 

0 Kudos
612 Views
cs_Lukasz
Contributor III

Thanks for reply!

 

Sometimes it is useful to read a documentation :smileyhappy:. 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

Message Edited by cs_Lukasz on 2009-07-07 10:50 AM
0 Kudos
613 Views
cs_Lukasz
Contributor III

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);

 

0 Kudos