Using pointer functions - 2 separate applications on 1 device - c

I asked some time ago this question How can I use one function from main application and bootloader? (embedded) and started to implement proposed solution but ran into a few problems.
On my cortex M4 I, have 2 separate applications - bootloader and user application. Now I had some (many) functions which were the same for both apps. So I compiled them only for bootloader, then created an array of function pointers at specified address, which is known for user application. So in application, I didn't compile the files with those functions again, but I use those pointers whenever needed.
This is example of code I tried to make common for both applications:
static uint8_t m_var_1;
// Sends events to the application.
static void send_event(fs_op_t const * const p_op, fs_ret_t result)
{
uint8_t var_2;
[...]
}
My application ends in Hardfault, which happens e.g. when dividing by zero or using pointer to function with NULL value. I am not sure why yet, but I started wondering what happens with those variables. var_2 will most surely be located on stack so this is no problem. But what about m_var_1? In the map file, it has a specified place in RAM. But I don't have seperate RAM sections for app and bootloader. I am not sure, but I have a feeling that this variable may use the same RAM location as when created for bootloader. Is this possible? Maybe some other issues?

Yes you are right, the code will attempt to access the global variable at the same location as it is linked for loader. This is because linking involves replacing all occurrences of identifiers (including function names and variable names) by the addresses determined after compiling.
In your application, the variable, even if it does exist there too, is likely to be at a different address.
The calling of the functions happens to work, because they are located in ROM and cannot be different for application and loader. Calling them via const pointers, which are also stored in ROM, bypasses the problem.
The solution is using a file system simulator, if you can find one for your hardware.
Otherwise you will hate having to do the following.
Part 1, setup:
introduce a special linker section with all the variables accessed by both system paprts (application and loader)
let one linker fill it
set it up for the other linker as don't-tocuh
be careful with the initialisation
preferrably do not assume any intialisation value
if you need initialisation, e.g. "bss" (init to 0) or "data" (init to specified value),
do so explicitly at the start of the system part which is not associated to the linker you let setup the variables
for safety, it is recommended to do the init the same way in both system parts
"data" init uses a special non-volatile linker section with a copy of the to-be-initialised variables, accessing that is possible
Part 2, access:
option 1)
store const pointers to those variables, like you did for the functions
option 2)
get the second linker (the other one, which did not do the actual setup of the common variable section) to create an identically structured and identically located section as the one from first linker; more studying of your linker needed here
Part 3, resuing values stored by other system part
(e.g. you want to leave some kind of message from loader, to be read my application)
design which system part initisalises which variable, the other one only reads them
separate the common variables in four sections,
written and read by both system parts, initialised by both
written and read by x, only read by y, initialised by x
written and read by y, only read by x, initialised by y
written by both system parts, not initialised, uses checksums and plausibility cehcks,
if a variable has not been initialised, init to default
init each section only in the corresponding writer system part
setup as "no init" in the other linker
setup as "no init" in both linkers for the fourth case
use getters and setters with checksum update and plausibility for the fourth case
To do all that, intense study of your linker features and syntax is needed.
So I recommend not to try, if you can get around it. Consider using an existing file system simulator; because that is basically what above means.

Related

Function block architecture in a C program

I would like a create a software where some functions (or block) can be programmed later on my micro controller without having to 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: Block architecuture.
Currently, I see no issues if I only use local variables in my new functions, because the variables will be pushed in the stack and will not be initialized in the .bss segment. But if I want to add a static variable in my function, I will have some troubles because the startup code will not initialize this variable in the .bss (or .data) segment.
My question is, is that event possible to implement an architecture like this one in a C code ? If yes, how can I adapt my startup code to initialize my new variables ? Do you think C++ is more appropriate to do such kind of things ?
Thanks a lot !
Include one function in the API which initializes the block. Host must call this function before any other functions of the block.
Also, keep in mind that if you do this, you must also reserve part of the RAM (in addition to flash) for the block, which the host shall not touch. These variables are normally marked as __no_init or something similar to prevent linker even trying to generate initialization data for .data placement.
Language you use (C or C++) most likely won't matter. Memory placement is not feature of either language, but instead is done with compiler extensions and linker features, which are toolchain specific.

Remote update-able function or code in a statically linked firmware of embedded device (microcontroller) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Is it possible to remote update or patch only certain piece of code to an embedded device (microcontroller)?
I am writing a bare metal C program on a microcontroller. Lets say I have main program which comprises of function A(), B(), C() and D() each in their own .c file.
I would like to do a remote update (patching) of only B() which has its own custom section in the main program so that the address is fixed and known.
The thing that puzzles me is how do I produce an updated executable of B()? Given that it relies on standard C library or other global variables from the main program. I need to resolve all the symbols from the main program.
Would appreciate any suggestions or reference to other thread if this question has been asked before (I tried to search but couldn't find any)
Solutions:
from Russ Schultz: Compile the new B(), and link it with the symbol file previously generated from the main program using gcc --just-symbols option. The resultant elf will contain just B() that assumes all these other symbols are there. (I haven't tried it but this is the concept that I was looking for)
Compile the whole program with the new B(), and manually take only the B() part binary from the main program (because its section address and size are known). Send B() binary to the device for remote update (not efficient as it involves many manual works).
Dynamic loading and linking requires run-time support - normally provided by an OS. VxWorks for example includes support for that (although the code is normally loaded into RAM over a network or mass-storage file-system rather then Flash or other re-writable ROM).
You could in theory write your own run-time linker/loader. However for it to work, the embedded firmware must contain a symbol table in order to complete the link. The way it works in VxWorks, is the object code to be loaded is partially linked and contains unresolved symbols that are completed by the run-time linker/loader by reference to the embedded symbol table.
Other embedded operating systems that support dynamic loading are:
Precise/MQX
Nucleus
Another approach that does not require a symbol table is to provide services via a software interrupt API (as used in PC-BIOS and MS-DOS). The loaded module will necessarily have a restricted access to services provided by the API, but because they are interrupts, the actual location of such services does not need to be known to the loadable module, not explicitly linked at run-time.
There is an article on dynamically loading modules in small RTOS systems on Embedded.com:
Bring big system features to small RTOS devices with downloadable app modules.
The author John Carbone works for Express Logic who produce ThreadX RTOS, which gives you an idea of the kind of system it is expected to work on, although the article and method described is not specific to ThreadX.
Some approach like this requires that the programmer manually manages all code allocation with their own custom segments. You'd have to know the fixed address of the function and it can't be allowed to grow beyond a certain size.
The flash memory used will dictate the restrictions, namely how large an area do you need to erase before programming. If you can execute code from eeprom/data flash then that's the obvious choice.
Library calls etc are irrelevant as the library functions are most likely stored elsewhere. Or in the rare case where they are inlined, they'll be small. But you might have to write the function in assembler, since C compiler-generated machine code may screw up the calling convention or unexpectedly overwrite registers if taken out of the expected context.
Because all of the above is fairly complex, the normal approach is to only modify const variables, rather than code, and keep those in eeprom/data flash, then have your program act based on those values.
I'm assuming you're talking about bare metal with my answer.
First off, linking a new function B() with the original program is relatively simple, particularly with GCC. LD can take a 'symbol file' as input using the --just-symbols option. So, scrape your map file, create the symbol file and use it as an input to your new link. Your resultant elf will contain just your code that assumes all these other symbols are there.
At that point, compile your new function B(), which should be a different name than B() (so we'll choose B_()). It should have the exact same signature as B() or things won't work right. You have to compile with the same headers, etc. that your original code was compiled with or it likely won't work.
Now, depending on how you've architected your original program, life can be easy or a real mess.
If you make your original program with the idea of patching in mind, then the prep is relatively trivial. Identify which functions you might want to patch and then call them through function pointers, e.g.:
void OriginalB(void)
{
//Original implementation of B goes here
}
void (B*)(void) = OriginalB;
void main(void)
{
B(); //this calls OriginalB() through the function pointer B. Once you
//patch the global function pointer B to point to B_(), then this
//code will call your new function.
}
Now your patch program is the original program linked with your B_(), but you somehow have to update the global function pointer B to point to B_() (rather than OriginalB())
Assuming you can use your new elf (or hex file) to update your device, it's pretty easy to just go modify those to change the value of B or assign the new function pointer directly in your code.
If not, then whatever method of injection you need to do also needs to inject a change to the global pointer.
If you didn't prep your original program, then it can be a real bear (but doable) to go modify references to B() to instead jump to your new B_(). It might get super tricky if your new function is too far away for a relative jump, but still doable in theory. I've never actually done it. ;)
If you're trying to patch a ROM, you almost have to have prepped the original ROMmed program to use function points for potential patch points. Or have some support in the ROM hardware to allow limited patching (usually it's just a few locations it will let you patch).
Some of the details may be incorrect for GCC (I use the Keil tools in my professional flow), but the concept is the same. It's doable. It's fragile. There's no standard way of doing this and it's highly tool and application dependent.

GCC on ARM Cortex M3: Calling functions from specific addresses

I need to call function from a specific addresses (e.g. Double function indirection in C) but not exactly the same. I could pull the pointers from the mapping table and manipulate dynamically generated function pointers, which I prefer to avoid. E.g., I want to avoid this type of call:
((int)(*)(void*)) compute_volume = ((int)(*)(void*)) 0x20001000;
int vol = (*compute_volume)();
Instead, I would prefer to use some sort of linker provided symbols or other methods to achieve the following, except that the compute_volume() function is provided by a different image, perhaps something like this:
extern int compute_volume(void);
vol = compute_volume();
In other words, I intend to split my code into multiple images, thus reducing the need for modifying or overwriting the flash everytime a symbol or computation changes.
Any suggestions/ideas?
You can define jump table which would reside always in te same flash region (you can define that region in linker and pragmas in the code I think) and when called it jumps to desired function.
In firmware part I you only define symbols which refer to "passing" functions addresses (if you will always keep it in the same region it will make future updates MUCH easier). In firmware part II you create jump table which resides in the address space you were referring to in firmware part I and calls the actual functions.
I am not 100% sure I have described it correctly but this should give you some notion how to solve your problem. The link Ring Ø provided should help you with placing jump table code in one place.

Win32, WinMain vs custom Entry Point (huge size difference), why?

As topic says.
I noticed that if i use WinMain or any other default Entry Point, a C application can be like 70kb.
But if i just specify a custom Entry Point, say "RawMain", int RawMain().
Then the file will be like 6kb.
So i am wondering, why is this, what does it add/reference to the file?
I could understand there being some small difference in size, but the difference is huge for an empty application.
Thanks!
When building for windows in most environments, the actual program entry point will be provided by a function in a small runtime library. That will do some environment preparation and then call a function you provide, such as main, wmain, WinMain, etc.
The code that runs before your user-provided main function includes running global C++ constructors, enabling TLS variables, initializing global mutexes so that standard-library calls work properly in a multithreaded environment, setting up the standard locale, and other stuff.
One thing that setting the entry point does is starts the linker with an undefined symbol with the name you give the entry point, so for example, if you're using mingw32, the linker will start assuming that it needs to link libmingw32.a and with the undefined symbol __tmainCRTStartup.
The linker will find (hopefully) __tmainCRTStartup in libmingw32.a, and include the object file crtexe.o which contains it, along with anything else needed to satisfy undefined symbols emanating from crtexe.o, which is where the extra size comes from.
When you set your own entry point, you override this, and just set the linker to look for whatever function you specify. You get a smaller executable, but you have to be careful that features you're using don't rely on any of the global initialization that would be done by the runtime's startup function.

Two different programs in Flash

Is it possible to RUN 2 different C programs(ie 2 main()), stored in Flash(micro controller), one at a time?
I have a bootloader code which is a separate program and resides in separate protected section of ROM. Then I have my application program which resides in separate ROM section. Although, residing in memory is not an issue, but how will linker interpret this? How can I switch between 2 programs. Is this possible?
For example:
Once I am done with bootloader, I can make it jump to Application function, but how will linker know this function?
Just to add, I am using Freescale HCS08 series and IDE is Codewarrior.
Further, here are the sequence of steps:
I load a Bootloader code in ROM. Then this bootloader code is required to load my application code. And then my application code should take over.
Bootloader Code:
Program Application Area ROM
Start Application Program
Application Code:
Check if to run Bootloader code or application itself.
Main is just a function. You may rename it and write another main which call either of them.
If you do not want rename main in the source you may mangle its name by define or compiler key:
cc -Dmain=main1 ...
(for first program), and
cc -Dmain=main2 ...
(for the second). Selector main:
int main(void) {
if(x) return main1();
else return main2();
}
Then link all together and download to your controller.
But there's problem with ISR's: you cannot assign two routines to single irq vector. If vectors are hardcoded to some flash location (like in most 8-bit controllers) you cannot switch ISR's. You will have to write ISR wrapper, recognizing which program is run and calling appropriate ISR.
UPD
Second issue is that statically linked variables from first and second program will be in RAM simultaneously while only one set of them is used. This may exhaust RAM (small amount of which often exists in microcontroller) too early.
UPD2
Oh, now I really understand. If you want to link and download them separately, you should deal with linker maps. In this case same symbol names (such as many main's) s not an issue. In linker map you should define known entry point [set it to absolute address], from which either application code starts. Startup code (commonly it is assemble code) should be linked from this address. From selector you should decide and jump to defined location directly. (Do this only for bootloader if your app is also a selector).
Entry point provided by linker may be accessible by program as extern function:
int app2_start(void);
{
.... /* condition check */
app2_start(); /* this symbol defined in linker map, not in any source */
}
But this is not the address of it's main(), because C RTL have do make many initialisations (stack, initialised variables, heap, IO, etc.) before main() can start.
There's more common way that the bootloader decides, should it run itself or application, because if application code fails, boodloader may became inaccessible.
The way I've seen this done is to stick the entry point into a header for the application. Then have the boot loader pull that entry point out and jump to it with an appropriate inline assembly instruction. You may need a linker script to get the entry point itself from the application. Gnu ld uses ENTRY.

Resources