Memory placements of C-function

2019-06-10 14:57发布

问题:

I would like a create a software where some functions (or block) can be programmed later on my micro controller without having to re-flash the entire software again (flash will be done by a communication interface e.g. SPI). The new blocks will all have the same API (e.g. 5 bytes as arguments, 1 byte returned).

Memory architecture will be organized as shown on this picture: memory architecture

To summarize, the FBL and APPL blocks will be programmed only 1 time on the MCU. Later in the process, I want to have the possibility to program or change some functions in the created blocks (BLOCK 1, BLOCK 2 ...)

For each block, I have:

  • 2 sections of flash (one for the init function and one for the "task" function).
  • 1 section of RAM where I can put my static variables.

Currently, my issue is that I cannot create a single memory block with all the content of my function in it. For example if I want to use a function from math.h in my new block, the linker will place the math.h functions in my APPL sector and not in the allocated memory sector dedicated for this block. But as I said, my APPL sector should not change because it will be programmed only 1 time. So I would like to know how I can write some "independents" blocks...

Thanks a lot !

回答1:

You must make sure all functions of the standard library you ever need are called at least once and so will be included in your binary base code.

For your "variable" code, you must have a kind of jump table at the beginning of the block. Your base code calls the function in the variable code and the jump table jumps to the actual function enrty point (or you can have wrapper functions), for example:

char f1(int a, int b) { return _f1(a,b)}
char f2(int a, int b) { return _f2(a,b)}

char _f1(int a, int b) { return 0;} /* function not yet developed */
char _f2(int a, int b) { return 0;} /* function not yet developed */

and in the code once developed:

char f1(int a, int b) { return _f1(a,b)}
char f2(int a, int b) { return _f2(a,b)}

char _f1(int a, int b) {
   /* lots of complex stuff */
   return result;
}
char _f2(int a, int b) {
   /* lots of complex stuff */
   return result;
}

Here, the functions f1, f2 etc will all be in a fixed place of the variable code and so can be called from the base code. Once the final version of the code block is flashed, they call their final version.


Note: I am not sure how to handle the variable code calling functions from the standard library that are placed in your base code area. The linker for the variable block must either duplicate loading the function in the variable code or must know its absolute location in the base code area. You should check the linker/loader documentation for that.