Atmega328p bootloader shared function

My goal to place the "shared function" in boot sector which will be accessible for run from boot application and also from main application. Microcontroller atmega328p.

code of boot app: boot.c boot.c · GitHub

logic of boot application:

  1. If button is pressed then blink of the LED.
  2. goto main app

The shared function has name "blink_twice"

compiling:

avr-gcc -g -DF_CPU=16000000UL -Os -Wall -std=gnu99 -mmcu=atmega328p -v -c boot.c -o boot.o
avr-gcc -g -DF_CPU=16000000UL -Os -Wall -std=gnu99 -mmcu=atmega328p -v -Wl,-Ttext=0x7800 -o boot.elf boot.o

convert to asm

avr-objdump -D boot.elf > boot.asm

get for function address

grep '<blink_twice>:' boot.asm

In my case it is:
00007880 <blink_twice>:

From boot app and main app the "shared function" I can use that way:

#define shared_function_addr 0x7880 // blink_twice address
#define shared_function (*((void(*)(void))(shared_function_addr/2)))
shared_function();

The issue with this approach:

  • It is hard to guarantee that the address 0x7880 will not change on another compiler version.
  • The address 0x7880 can be changed if the boot app will have a changes.
    As consequences of that it will be required to change the address in the main app. And that I want to avoid.

One of the idea was to store "shared function" address in the constant address (0x7FFE) in flash memory.

  1. convert address to word 7880/2 -> 3c40
  2. change to big-endian 3c40 -> 403c
  3. build a "hex" line and calculate a control summ :02 7FFE 00 403c 05
  4. add the "hex" line into the hex file
    The result is here: boot.hex · GitHub

Now in the main app runtime use the pgmspace it is possible read address of "shared function" from address 0x7FFE.

But I feel the solution is a monkeypatch.
And now I do not see another way how to solve it.

I feel the solution belong to linker area but I do not have enough experience for that.
I will be really grateful for any help.

** PS
Also I tried to store "shared function" address with line:

void* const shared_function_address __attribute__((__progmem__)) = blink_twice;

It is added the address in the "hex" file but I didn't found the way how to put it on specific address in flash memory.

** PPS
Also I tried to store "shared function" address with below line:

void* const shared_function_address __attribute__((section("fnaddr"))) = blink_twice;

for compiling I used commands:

avr-gcc -g -DF_CPU=16000000UL -Os -Wall -std=gnu99 -mmcu=atmega328p -v -c boot.c -o boot.o
avr-gcc -g -DF_CPU=16000000UL -Os -Wall -std=gnu99 -mmcu=atmega328p -v -Wl,-Ttext=0x7800 -Wl,--section-start=fnaddr=0x7FFE -o boot.elf boot.o

After make asm
avr-objdump -D boot.elf > boot.asm

In boot.asm file I can see lines:

Disassembly of section fnaddr:
00007ffe <shared_function_address>:
    7ffe:	40 3c       	cpi	r20, 0xC0	; 192

But after build in "hex" file I can't find data "403c" in address "0x7ffe"

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.