integration of bootloader with the main code

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've successfully written a custom bootloader. Now I would like to integrate everything in one single project, so that I can write all with a single operation.

I am not sure this is possible but maybe someone with more experience may give me a suggestion.

The bootloader uses some standard libraries that are allocated in the .text segment

If .text is relocated in the bootloader area, the main program will not fit.

If, bootloader code is moved to a different segment - say .boot - and that segment is relocated, standard libraries will still be in .text and thus destroyed while the bootloader writes the new flash code.

To make everything work I would need to link some libraries twice - one copy that uses .text, the other relocated in the boot section.

Any ideas?? :shock: :?:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kalbun wrote:
The bootloader uses some standard libraries that are allocated in the .text segment
That's a bad starting point.

What do you mean by "standard libraries"?

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi JW, thanks for the quick reply.

With "standard libraries" I mean those found in the headers of standard C or AVR extensions.
In my case, I use only two of these functions: memset() and _delay_ms(). I also use some functions found in , but they only contain asm code and no reference to external functions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Those functions should not occupy more than one or two hundred bytes of FLASH.

Could you please try to build the bootloader in whatever way you do and show us the mapfile?

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kalbun wrote:
Now I would like to integrate everything in one single project, so that I can write all with a single operation.
You can use external utility like one from SRecord project to concatenate two .hex-files after build before programming. It allows you to keep bootloader and application independent from each other.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

innocent_bystander wrote:
You can use external utility like one from SRecord

Thank you bystander, this could be a very good solution. I'll give SRecord a try very soon.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If I understand correctly, the problem is a bootloader that
is too big for the bootloader region of the processor.
My first thought is to use -Os instead of -O0.

If -O0 is not the problem and you really do have a useful bootloader that will not fit in the bootloader region,
it can be got into the processor without too much arcana.
Compiler and link the bootloader in two chunks:
bootloader-out.elf will contain the part of
the bootloader outside the bootloader region.
bootloader-in.elf will contain the
part inside the bootloader region.
The former must contain no direct or indirect references to the latter.
For example, it must not contain a main( ).
link bootloader-out.elf without startup code or vector table.
Link bootloader-in.elf with -Wl,--just-symbols,bootloader-out.elf
Use srecord or whatever to combine hex files.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
The former [the part which does not fit to the bootloader area thus remained out of it] must contain no direct or indirect references to the latter [the part in the bootloader area].
Can you please elaborate?

Thanks,

Jan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wek wrote:
skeeve wrote:
The former [the part which does not fit to the bootloader area thus remained out of it] must contain no direct or indirect references to the latter [the part in the bootloader area].
Can you please elaborate?
It might be possible to use separate linking even with chunks of code that refer to each other,
but it would be trickier.
'Twould require at least three link steps:
one for the first linked chunk, one to link the second chunk and
one to resolve the symbols left unresolved by the first link.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kalbun wrote:
...
The bootloader uses some standard libraries that are allocated in the .text segment

If .text is relocated in the bootloader area, the main program will not fit.


Uh oh. This seems like a case of:
Quote:
Patient: Doctor, it hurts when I do *this*.
Doctor: Well, don't do that!

Bootloaders are often written in ASM to be teeny. And always written to be self-contained so they can't be broken later. On the AVR, the boot sections size increases in some cases by twofold each size step. So if the code is one byte too big, well, you get the idea.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everybody, maybe my first post wasn't so clear.
The bootloader fits in the boot area with no problems. What I want to do - and I wasn't able to do so far - is to add the source code of the bootloader to the rest of the project, to compile, and to have one single HEX (or ELF) with both on board.
ATMega2560 does not allow to selectively delete application area while leaving bootload untouched.

The problem is that my bootloader uses some calls inside standard libraries, such as memset() or _delay_ms(). They reside in the .text segment, so in the bootloader I simply moved .text in the boot area and that's all.
But this strategy does not work if the bootloader code is merged with that of the main project.

By examining your answers and suggestions, it seems the best strategy is to remove every reference to standard libraries from the bootloader.

An alternate strategy is doing what bystander suggests: merge the HEX instead than the sources, maybe with a post-compilation event.

Sorry if my message was not clear in the start, anyway the resulting discussion is by all means interesting.

GS

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
By examining your answers and suggestions, it seems the best strategy is to remove every reference to standard libraries from the bootloader.
DON'T try to merge the sources and to compile that in one step. That creates more serious problems than your "references to standard libraries". Keep and compile both separate and merge the results.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Stefan, could you please explain a bit more?

Provided I can remove those references, I simply plan to define a segment in the bootloading area, relocate all the boot-related code in that area, and it should work.

GS

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kalbun wrote:
Provided I can remove those references, I simply plan to define a segment in the bootloading area, relocate all the boot-related code in that area, and it should work.
For save operation it is necessary to set the BOOTRST fuse so the bootloader gets run first after a reset. But with your solution the bootloader contains no C startup code.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kalbun wrote:
Hi everybody, maybe my first post wasn't so clear.
Correct.
Quote:
The bootloader fits in the boot area with no problems. What I want to do - and I wasn't able to do so far - is to add the source code of the bootloader to the rest of the project, to compile, and to have one single HEX (or ELF) with both on board.
ATMega2560 does not allow to selectively delete application area while leaving bootload untouched.
ISP Erase chip
ISP Copy bootloader to chip
ISP Copy application to chip

The only problem I see with that sequence
is that the bootloader goes unused.
What is the point in having a bootloader?

Combining a bootloader and an application
is a question that comes up rather often,
but I don't understand why.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Michael,
indeed we perform the operation you describe each time we program the chip via JTAG or ISP.

When the machine is on the field, it is updated via GPRS, with the new code written into an SD card. The purpose of the bootloader is to read from SD and to write the file to flash. All of this is already working.

My fear is that in some cases my customer will directly prepare the machines without my intervention.
If he forgets to burn inside the bootloader, and there is a problem, either we need the machine sent back, or someone must go there and fix the problem.
"There" could be as far as 4000 km...
Oh, and obviously I am far from perfect, and could forget bootloader as well :-D

So I was looking for a foolproof (almost) method to ensure that the machine ALWAYS leaves with bootloader. After all merging the HEX files with a post-compile event seems the best way.

GS

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kalbun wrote:
When the machine is on the field, it is updated via GPRS, with the new code written into an SD card. The purpose of the bootloader is to read from SD and to write the file to flash. All of this is already working.

My fear is that in some cases my customer will directly prepare the machines without my intervention.
If he forgets to burn inside the bootloader, and there is a problem, either we need the machine sent back, or someone must go there and fix the problem.

Surely a customer that could program a processor with application+bootloader could also program said processor with just the bootloader.
Also, are you sure your bootloader can safely overwrite itself?

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Hi Stefan, could you please explain a bit more?

Provided I can remove those references, I simply plan to define a segment in the bootloading area, relocate all the boot-related code in that area, and it should work.


Terrible idea - clearly you have not read the bootloader FAQ in the Tutorial Forum yet.

A complete program has a reset jump, a vector table, a C run time to initialise registers and setup the .data and .bss bfore entering main(). If you just make the "bootloader" an add-on to the end of the app (but located into the BLS so it can SPM) you are now reliant on the CRT provided by the app code.

Now consider the occasion where a bootloading replacement operation has started. Some(/all?) of the app space has been erased and awaits the new code. Now one of the following occurs: (1) the battery dies, (2) someone pulls the power cord as the thing "looks dead", (3) someone pulls the USB/UART cable connected to the PC, (4) (if Windows) the PC software crashes

You now have an AVR with half a program in it and a bootloader that cannot be started because parts of the app it relies on are not there.

The one reason people cite for wanting to do it this way is so that they have a single hex/binary to program in the factory. Well how about

(a) just ISP/JTAG the bootloader then use it to actually load the app code over the comms channel.

(b) use srec_cat to join app.hex and boot.hex into factory.hex and program that

(c) use avr-objcopy to join the ELF files to make one composite ELF file for ISP-ELF programming

But do NOT join the things at source!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
(a) just ISP/JTAG the bootloader then use it to actually load the app code over the comms channel.
One more operation, one more connection, more time spent by operator - all that means increased cost in production.

clawson wrote:
(c) use avr-objcopy to join the ELF files to make one composite ELF file for ISP-ELF programming
Can you show a little example of this? Interesting, how avr-objcopy deals with duplicate symbols from both source ELFs.