I have a 8051 project which includes ROM and XRAM, both are used as code memory The memory address and range is as follows
CODE Space Main CODE at RAM C:0x0000 ~ C:0x2FFF Lib CODE at ROM C:0x3000 ~ C:0x3FFF XDATA Space XDATA RAM at X:0x0000 ~ X:0x0FFF
I want to build a library code by Keil C51, and put the library code in fixed ROM memory, so the code in RAM is able to call the library routine in the existing ROM. For example:
main.c in CODE RAM (C:0x0000 ~ C:0x2FFF)
main() { int x, y, z; x = 1; y = 2; z = Add(x, y); }
lib.c in CODE ROM (C:0x3000 ~ C:0x3FFF)
int Add(int x, int y) { int z; z = x + y; return z; } int Sub(int x, int y) { int z; z = x - y; return z; }
My question is: 1. Is there easy way to tell Keil C51 where to call library code at (C:0x3000 ~ C:0x3FFF) ? If a lot of routines in library.
2. Is it possible to call library function with arguments ?
3. Can library routine use local variables ?
Thanks for your response
Implement a call table - let the library code contain a table at a fixed addres where each entry in the table is the address of the different exported functions.
But it is unable to passing arguments when calling library. In addition, using local variables may cause some over-write problems between the caller and callee. As the sample code above, I really don't know how to solve the issue.
Well, notice that you have select a 8051 processor and Keil C51 as compiler.
But the 8051 is not designed for use with the C programming language, and the Keil C51 have to break the back backwards to try to implement C for the processor.
If you did spend looking at the documentation, you would know that the compiler+linker together tries to convert all parameters and local variables into shared global variables. Not so fun if you already have some magic code already stored in a flash area.
Fill a struct with the values you want to send. Have a fixed RAM address where you store the pointer to this struct.
Or switch to a processor architecture that is better suited for traditional stack/register passing of parameters.
What you are trying to do is have two completely separate programs interact. So document the exact interface that the library part should export to the other program. And then implement that exact interface.
A call table (or function table, vtable, dispatch table, et al.) is a struct of function pointers:
struct call_table { int (*add) (int x, int y); int (*sub) (int x, int y); //... }; struct call_table MY_CALL_TABLE __at(0x3000) = { Add, Sub, };
Then just call the function via the table:
sum = MY_CALL_TABLE.add(2, 3);
Note that "just call the function via the table" isn't so easy with C51 and interfacing two separate programs.
C51 will place the parameters in global memory cells. But the calling program will not know what global cells the receiving side have allocated for the parameters. Not only that, but the two programs will have to have two completely separated RAM regions, with the exception of some shared RAM for data passing.
8051 is not a good processor for trying some more advanced programming concepts.