Hi
I have a project made with a custom board with STM32F3, and I use ARM Keil and ARM Tools for development of the project. The current memory's layout is a partition for bootloader and other for firmware. Now, the project's specifications is changed and the memory layout is divided by 3 partition: a bootloader, kernel, firmware. The kernel has a relevant and critical functions which the final user cannot update, only can update the firmware partition.
I was thinking do a library which contains the kernel but this library must be in a static partition of the memory and some functions must be allocated in a specific address because the firmware has to access it. Do I need make a keil project to build and generate a lib? In the firmware keil project, how can a made an interface to access in the function's library?
Best regards
The kernel must be 100% self-sufficient unless you want a lot of problems later on.
With the kernel as a library, the linker may link the symbols to different addresses at different times.
And with the kernel as a library, the kernel and the firmware will share the same set of runtime library functions which includes all internal, hidden, symbols within the runtime library. And besides the obvious RTL functions, the compiler regularly introduces hidden helper functions, such as for 64-bit arithmetic or similar that might be too large to inline at every needed location.
So build the boot loader as one project. And the kernel as a second object. And then the updateable part as a third project - and this project might then make use of a pointer table or similar to locate the entry points in the kernel. This makes the kernel behave similar to a BIOS in a computer - an update of a program doesn't require the BIOS to be updated, and an update of the BIOS doesn't require the application to be updated.
I was thinking do a library which contains the kernel but this library must be in a static partition of the memory and some functions must be allocated in a specific address because the firmware has to access it.
A library is the wrong tool for that task. What you need is a pre-linked and located image, with special options passed to the linker so it doesn't throw away all code that the kernel itself does not use.
Thank you for answer Westermark.
How can I make this pointer table? Do I need a specific linker commands to do that? I was thinking how to do, but it doesn't seems a optimal procedure. Every time I build the second project (kernel), I need to know where are located the relevant functions and generate a callers for the thrid project. This can do it throught a script after build.
//******************* // 2on project //******************* // Relevant funciton. Find the location of this function // after build the project. void foo (void); void foo (void){ // do something }
//****************** // 3rd project //****************** // Caller generated by script after build the 2on project extern void foo (void) __at__ (0x8013000);
You could use absolute jump addresses in your app. But if you find an error in the middle tier so you need to fix it, then all function addresses might change and the released applications must be recompiled.
With a pointer table - just a struct or array with pointers stored at a fixed address - the app doesn't need to care about changed addresses in the middle tier. All it cares about is the pointer table and that the function pointers continues to have the same calling conventions and input/output signatures.
Hi Westermark,
I understand this struct/arry is located to an absolut address in the middle region but how is it initialized? Is correct this initialization from the middle region and how the firmware is getting the pointer table?
//****************** // Middle region //****************** struct PointerTable{ int (*foo)(void); void (*bar)(void); }; int foo(void); void bar(void); int foo (void){ // ... } int foo (void){ // ... } // Inizialize pointer table struct at 0x80100005 const struct PointerTable pt = {foo, bar} __at__ 0x8010005;
//****************** // App region //****************** struct PointerTable{ int (*foo)(void); void (*bar)(void); }; struct PointerTable pt __at__ 0x8010005; // Middle region address pt.foo(); pt .bar();
Thank you very much for your help
Hi Hans-Bernhard Broeker,
Which special options you mean?
Thank you for your attention