sharing function pointers (s12x and xgate)

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

sharing function pointers (s12x and xgate)

4,052 Views
benni
Contributor I
hi
i'm having some trouble sharing a function pointer from s12x to the xgate.
so far i have the following:
  • a s12x funktion wich fills a buffer with a pointer to the function the xgate is supposed to call
  • an xgate isr to trigger the xgate and perform the actual function call
  • the xgate function which is to be called

i have a simple scheduler on the xgate, and an a simple 'instruction queue' which is filled via the isr. whenever a new 'command' from the s12x is issued, an xgate isr is called which copies the buffer into an queue. in addition, every 10ms an xgate isr is called (the simple scheduler) which looksup the queue and performs the commands. everything works as intended except the adress translation. '&function' gives the right logical adress of my xgate function, but i'd need the xgate adress. is there an easy way to share function pointers? i could construct the right xgate adress from the logical adress, but that would be somewhat messy in the code. i hope you understand what i mean :smileywink:

here the (non-functional) code:

Code:

typedef void (* fkt_ptr_char)(char);struct xgate_shared_data { fkt_ptr_char fkt; unsigned char data;};//XGATE function prototypesinterrupt void Copy_Command(int value); //copies command into an queueinterrupt void PIT1(int value); //runs queued commands, every 10msvoid CallMe(char value); //the function to be called//S12X function prototypesbool issue_XGATE_command(fkt_ptr_char fkt, char data); //calls Copy_Command, fkt_ptr is correct logical adress, but not xgate adress//call somewhere in the s12x codeissue_XGATE_command( &__X_CallMe, 0x1);


 

Message Edited by benni on 2007-02-1212:56 PM

Message Edited by benni on 2007-02-1212:56 PM

Labels (1)
0 Kudos
Reply
7 Replies

979 Views
kef
Specialist I
Benni,
 
I think you are doing it the odd way. There are serious differences between XGATE and S12X address maps and addressing modes. When accessing some data defined in *.cxgate file, CW can make all necessary address translations and both S12X and XGATE can access these datas. But still be careful since native 16bits S12X data pointer is not compatible with 16bits-only XGATE pointers. Pointer initialized in S12X will point to different stuff when used in XGATE!
When dealing with code, S12X can't dereference pointer to XGATE function properly, because S12X can't execute XGATE function. And XGATE can't execute S12X functions. Pointer to XGATE function and pointer to S12X function are not compatible and are very different types. Taking in S12X address of XGATE function (&CallMe) is not the same as taking in XGATE address of XGATE function.
 
In you first message you wrote that you have CallMe XGATE funcion
Code:
void CallMe(char value); //the function to be called

 
but
Code:
//call somewhere in the s12x codeissue_XGATE_command( &__X_CallMe, 0x1);

 
Why are you referencing different function? Please don't cheat Smiley Happy
 
 
BTW, you wrote:
 
...the function 'CallMe' is at XGATE adress E000, Global FE000 and Logical FE1000
and later:

...didnt help either, it always used adress FE1000. maybe im not getting how to use far at all...

Note that CallMe is in RAM and "logical" FE1000 is RPAGE based address! You could translate it to XGATE address but better try to avoid passing pointers between cores.

 

0 Kudos
Reply

979 Views
benni
Contributor I

Hi kef, thanks for your reply!


kef wrote:
 
In you first message you wrote that you have CallMe XGATE funcion
Code:
void CallMe(char value); //the function to be called

 
but
Code:
//call somewhere in the s12x codeissue_XGATE_command( &__X_CallMe, 0x1);

 
Why are you referencing different function? Please don't cheat Smiley Happy

Well, thats because i have to cheat a little so the linker stops complaining :smileywink:
The project i'm working on, has various libraries and a somewhat messy makefile-system. So if i'd type
 
Code:
//call somewhere in the s12x codeissue_XGATE_command( &CallMe, 0x1);

the linker would complain about a missing Symbol 'CallMe'. Don't ask me why, but i blame the various makefiles, which noone really understands anymore (and i'm new here) :smileywink:. The XGATE compiler exports every function Symbol as __X_<functionname>, so if i use __X_CallMe, the linker stops whining about missing Symbols. It sure has something to do with the order the libs are linked together, but as i said, the makefiles aren't what you'd call understandable neither editable.
 


kef wrote:
BTW, you wrote:
 
...the function 'CallMe' is at XGATE adress E000, Global FE000 and Logical FE1000
and later:

...didnt help either, it always used adress FE1000. maybe im not getting how to use far at all...

Note that CallMe is in RAM and "logical" FE1000 is RPAGE based address! You could translate it to XGATE address but better try to avoid passing pointers between cores.


Yes i know. I could do it 'by hand' as the Logical Mapping for the XGATE is fixed, but as Steve explained, converting a gloabal adress to XGATE adress is much simpler. So i'd prefer that, as it would assure more readable code. But i can't get the global adress of the function, only the logical one :smileysad:.

I sure could do all the funktion calling stuff on the xgate via table lookup, but that would mean i'd have to assure consistency in various places, the table, the command (which would be the table index) and still would need a data pointer for the argument list. So giving a function pointer makes all this much simpler, you'd never have to worry about too big tables or an too small index-datatype.

The concept of function pointer passing is working pretty well, the code is slim and the space you need is constant instead of linear increasing, like in the table based approach. integration of a new XGATE function is only the function itself and the call of issue_XGATE_command();, no new command (index) is needed and no table entry. i like that :smileyhappy:

And it does work as intended, only the way i'm translating the function pointers is somwhat ugly.

 


0 Kudos
Reply

979 Views
CompilerGuru
NXP Employee
NXP Employee
Just a few notes, I'm don't have a CW for HCS12X here, so I just tiping, nothing tested.
First the __X_ prefix is added by the XGATE compiler to all function names to differentiate
HC12 code from XGATE code. Otherwise a XGATE function call could resolve to call a HC12 function, well would not work too good. So that's not some makefile magic. That's compiler magic.
Second the reason that the HCS12X compiler is using logical addresses for far HCS12X function pointers is that HC12 function pointers, (as opposed to far object pointers) are always logical. The value of functions pointers is loaded into PC/PPAGE and those registers are using only logical addresses. So if you want to get a global address instead, use an object pointer on the HCS12X side. I'm not sure if you have to declare the XGATE function also as HCS12X external variable or if declaring it as HCS12X external function works too, but declaring it as external object (with the __X_ prefix) does work. As external function maybe, not sure.
What else? Well make sure the XGATE and the HCS12X see the same struct layout, of course.
Hmm. You could also define some constants with the XGATE compiler and then refer to them as externl constants from the HCS12X. This might make the code clearer as the XGATE would be used to initialize XGATE pointers. Using the HCS12X to do this is possible, but a bit less straight forward.
What I mean, is something like this (not tested)
header.h
#include
#ifdef __XGATE__
typedef void (*XGATEFunPtr)(void);
#elif defined(__HC12__)
typedef int XGATEFunPtr; // just using any 16 bit type for the HCS12X side
#else
#error....
#endif
extern const XGATEFunPtr g_HaveFun;


hc12.c:
#include "header.h"
....= g_HaveFun;

xgate.cxgate:
#include "header.h"
void funny_xgate(void) {
}
const XGATEFunPtr g_HaveFun= funny_xgate;


This setup wastes some flash bytes for the constants, but it avoids any cross initialization of pointers.

Daniel
0 Kudos
Reply

979 Views
benni
Contributor I
Hi CompilerGuru,
thanks for your reply. Your idea is nice, but a small problem is, that function pointers have an opposite direction of bytes, so the function pointer initialised with E000 in my .cxgate file becomes 00E0 in my S12X file. that means the actual functioncall in .cxgate file has to change the byteorder (you could do it in the s12x file too).
But on the otherhand, if i use a const for every functioncall, the pointer based approch loses nearly all advantages it has from the function-table based one.
But with your info that functionpointers are always logical, i finally found an answer i can work with, maybe i'll drop the whole pointer idea and make an simple easy and just working function table :smileyhappy:
 
Thanks benni
0 Kudos
Reply

979 Views
CompilerGuru
NXP Employee
NXP Employee
I'm not sure I can follow you with the byte order.
My code was accessing the same object as function pointer from the XGATE and as int from the HCS12X. I did not use a function pointer from the HCS12X side because I did not want to interpret the thing as HCS12X function. Did you use the #ifdef?
What I did not mention in the previous mail was that HCS12X far function pointers are not just logical, they also use a special byte ordering as expected by the HC12 call instruction. So basically don't use far function pointer from the HCS12X side if the thing it refers to is a XGATE function. I used a int.

Daniel
0 Kudos
Reply

979 Views
Steve
NXP Employee
NXP Employee
Hi Benni,
I think I understand what you want to do.
I can think of two simpler ways to do it rather than converting logical addresses:
1/ Get the global address of the function. The XGATE address is the least significant 16-bits of that (e.g. global 0x0F89AB = XGATE 0x89AB). A far pointer would give you the global address.
2/ Pass an index to the function and have a look up table of all the functions - you would need to know the functions at compile time or dynamically update the table.
 
I have a feeling that there is a CW function to convert between the address spaces but I can't find a reference right now.
0 Kudos
Reply

979 Views
benni
Contributor I

Hey Steve,
thanks for your reply.
I thought of an table approach too, but that would mean to keep the table up to date, and maintain some sort of enumerated index for the command for the right call, so i think the function call would be a much cleaner design.
For the global adress...well i must admit that i just cant get it. the far seems just to be ignored.
the function 'CallMe' is at XGATE adress E000, Global FE000 and Logical FE1000 (because its the only funktion in this section so far).
i declared the function as:

Code:
extern void __X_CallMe(char);
 
in my s12x c-file.
the i pass is via

Code:
__X_CallMe to bool issue_XGATE_command(fkt_ptr_char fkt, char data);

at that time fkt holds the adress FE1000.
i tried to alter

Code:
typedef void (* fkt_ptr_char)(char); intotypedef void (* far fkt_ptr_char)(char); but no luck

declaring

Code:
extern void far __X_CallMe(char);

 
didnt help either, it always used adress FE1000. maybe im not getting how to use far at all...

p.s. can't i insert code in a reply, like i did in my first post? this post just looks ugly

Message Edited by benni on 2007-02-1205:13 PM

Alban changed for code not to look ugly :smileyhappy:, press "SRC" button in editor

Message Edited by Alban on 2007-02-12 05:20 PM

0 Kudos
Reply