Function pointer

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

Function pointer

4,041 Views
BAN
Contributor II
Hello!
 
I have some problem when trying to copy a small piece of code (a function) from ROM to RAM.
 
To do this I'm passing the source and destination address to a copy function. Previously the source address has been hordcoded into SW but I'm trying to make this more flexible by passing the address to this function instead.
 

bool (* funcP)();

funcP =&ProgFlash;
CopyString((byte
*
)funcP, (byte *)RAM_FUNCS_START, RAM_FUNCS_SIZE);

The address to progFlash() was in this case 0x40A9. The resulting part in the .lst file looks like:

 

226: funcP = &ProgFlash;
002a cc0000 [2] LDD #LOW_PAGE(ProgFlash)
002d 6c8c [2] STD 12,SP
002f c600 [1] LDAB #HIGH(ProgFlash)
0031 6b8b [2] STAB 11,SP
227:
228: CopyString((byte*)funcP, (byte *)RAM_FUNCS_START, RAM_FUNCS_SIZE);
0033 ec8c [3] LDD 12,SP
0035 160000 [4] JSR WriteEeprom:0x01a2

.

01a2 3b [2] PSHD
01a3 cc3fd0 [2] LDD #16336
01a6 3b [2] PSHD
01a7 c62b [1] LDAB #43
01a9 4a000000 [7] CALL CopyString,PAGE(CopyString)

The address to the function is stored relative to SP and then loaded back to D. But since two bytes are copied from SP + 12 the address A900 will finally be stored in D and pushed as argument to the CopyString function. LDD 11,SP would have been a better choice from my point of view.

Something is wrong in the C-code when trying to convert the functionpointer to a byte pointer but i can't figure out what. Can anyone help me??

 

//Bengt

Labels (1)
0 Kudos
4 Replies

740 Views
Technoman64
Contributor III
I use a typedef for function pointers. The compiler takes care of addressing methods in the backgorund.
 
typedef void (*Fp)(void);

int fPtrSize;

Fp FunctPtr;

FunctPtr = &Foo;

fPtrSize = sizeof(FuncPtr);

You can define alternate pointers to instruct the compiler that the function pointed to returns data and/or passes data.

At least this has worked for me using Codewarrior for HCS(X)12 and Codewarrior for Coldfire.

Dennis

 

0 Kudos

740 Views
CompilerGuru
NXP Employee
NXP Employee
Using typedef's changes nothing for the compiler, it just helps with the readability of the code for humans. So that's nice I'm pretty much always use typedefs when working with function pointers.

There is no issue using function pointers to call functions or to use data/object pointers accessing data,
the problematic case is when a __far function or a __far data pointer is assigned to a pointer of the other kind, and then this pointer is directly used.
Or as sample when initializing a const char*__far with a (far) function and then trying to read the code of the function with it.

Daniel





0 Kudos

740 Views
CompilerGuru
NXP Employee
NXP Employee
Check the compiler manual about how far function pointers and far data/object pointers are represented.
They are basically differently encoded, data pointers are using a big endian byte ordering, far function pointers are using the ordering as expected by the CALL instruction.

I thought this topic was mentioned in the forum before, but with a quick search, I did not find anything.

You could:
- Place the function into a near section, and changing the calling convention to __near too.
__near function and (__near or __far) data pointers are "compatible".
- or converting the pointer manually. See the manual of which bytes to swap.
- or place the function into a dedicated section and use the linker defined object to get the address of the section. This would also offer to get the size of the function. Also as the code to be copied should conceptually be position independent, the PIC (position independent code) section qualifier could be added (did not use PIC recently, my memory is a bit rusty here, is the qualifier __PIC_SEG? Note that the code probably works without PIC too, but certain C patterns do generate non PIC code without telling the compiler to generate PIC code).

Daniel

0 Kudos

740 Views
BAN
Contributor II
I tried the first suggestion (__NEAR_SEG) and it turned out to work fine!
 
Thank You!!
0 Kudos