Home > OS >  Sharing a variable between bootloader and application in C
Sharing a variable between bootloader and application in C

Time:08-24

I want to share a variable (a boolean is enough) between bootloader and application. Bootloader should write a boolean instead the application should read it.

I thought I can write 1 or a 0 to a certain address (0x40000100), like this:

uint8_t *microType = (uint8_t *)0x40000100;

microType = 1;

Is it right?

As microprocessor I'm using NXP MPC5645C Thank you in advance.

CodePudding user response:

  1. You need to create the section in the bootloader and application linker script. It is required compiler and linker do not place any other variables in this chunk of memory. The best place is the beginning or end of RAM as other sections cannot have "gaps". Section should have fixed address and to be the fist (or last if it is placed at the end of RAM) defined in the linker script.

Then you simply create the variable(s) and place them in those section.

CodePudding user response:

To do this, you will need to set up and reserve a dedicated RAM segment at an absolute address. You obviously cannot use 0x40000100 because that points into the middle of the stack and the stack can't be used for this. You also can't just use any variable identifier to something located in .bss/.data, because that one may translate to a different physical address at any point, whenever the program is changed.

Also, you shouldn't rely on values in RAM getting preserved after reset, so if you execute the bootloader, then MCU reset and execute the application, that's not a good idea for the average kind of mission-/safety-critical applications MPC56 are usually used for. NXP microcontrollers have a tradition of well-defined value preservation of variables in RAM upon "soft reset" such as watchdog timeout, but I don't remember if this applies to MPC56.

Furthermore, if the value is to be preserved between resets, you have to consider how to initialize this custom RAM segment manually. Doing so means you'll have to tweak the CRT code, which isn't trivial. You'll want to zero-out the segment upon power-on reset and similar, but to leave it untouched upon watchdog reset etc.

As for how to make a custom memory segment, that depends on the tool chain. In Codewarrior you'd have to tweak the linker script (.lcf file), creating one memory range below MEMORY and add a GROUP below SECTIONS. Be careful with alignment; it will expect at least 32 bit alignment but there might be other considerations too (check the friendly manual). Then add some icky pragma to the actual variable declaration, along the lines of this:

#pragma section RW ".my_section"
__declspec(section ".my_section") 
volatile uint32_t the_variable;

Once you've gotten that far, this variable should be accessible from both the bootloader and the application. It has to be volatile so that the compiler compiling the application doesn't make strange assumptions about the variable never getting written to.

CodePudding user response:

  1. Assign value to the address should be

    *microType = 1;

  2. Make sure the address is legal for your kernel.

  3. In x86, if a loader passes some parameters it will use registers to store them. For your platform you may study for the call-convention to see which register is available then use inline assembly to store the parameter.

  • Related