|
|||||||||||
Technical Support Support Resources
Product Information |
CX51: 'far' Function Pointers for Philips MXInformation in this article applies to:
QUESTIONHow do I create a function table with 24-bit function pointers on the Philips MX architecture? The following code generates only 16-bit function pointers: #define abs_fct1 0x901000 #define abs_fct2 0x902000 code void (code *fp_tab[]) (void) = { abs_fct1, abs_fct2 }; When I compile this code I get: *** WARNING C196: mspace probably invalid Is there a way to avoid this warning message? I also need to generate ECALL instructions to reach this memory location. However, my application is using the ROM(LARGE) model, and I want to avoid using the ROM(HUGE) model. Is there a way to get ECALL instructions when using ROM(LARGE)? ANSWERTo get 3-byte function pointers, you need to use far pointers in your function pointer definition as shown in the following example. It is also possible to omit the 'far' memory type since the compiler then defaults to 3-byte generic pointers which are identical to the 'far' pointers. #define abs_fct1 ((void far *) 0x901000) #define abs_fct2 ((void far *) 0x902000) code void (far *fp_tab[]) (void) = { abs_fct1, abs_fct2 }; void main (void) { fp_tab[0] (); } The program code above compiles without warnings and generates correct calls when using the ROM(HUGE) model. To stay in the ROM(LARGE) model, call the following assembler interface function that generates the ECALL instruction: PUBLIC _farcall ?PR?_farcall?farcall SEGMENT CODE RSEG ?PR?_farcall?farcall ACC DATA 0E0H _farcall: MOV A,R1 PUSH ACC MOV A,R2 PUSH ACC MOV A,R3 PUSH ACC ERET ; indirect ECALL RET END Call the function farcall from your C code as follows: extern void _farcall (void far *); void main (void) { farcall (fp_tab[0]); } If you need to call functions that get function parameters, you need to use the following method. The difference is in using a global variable to store the function pointer. This allows parameter passing via different function prototypes that are all using the same entry address in the assembly interface. PUBLIC _fcall1, _fcall2, farfunc ?DT?_farcall SEGMENT DATA RSEG ?DT?_farcall farfunc: DS 3 ?PR?_fcall1?farcall SEGMENT CODE RSEG ?PR?_fcall1?farcall _fcall1: _fcall2: PUSH farfunc+2 PUSH farfunc+1 PUSH farfunc ERET ; indirect ECALL RET END Call the function farcall from your C code as follows: extern void _fcall (int void far *); extern char *fcall1 (long l1); extern char *fcall1 (char *p, int i1); char *p; void main (void) { farfunc = fp_tab[0]; p = fcall1 (0x12345678); fcall2 (p, 0x8000); } MORE INFORMATION
Last Reviewed: Thursday, January 14, 2021 | ||||||||||
|
Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.