Detecting when code is running in the bootloader section

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

Is there a simple way to detect when code is running in the bootloader section on an arbitrary XMEGA device?

 

Say I write a bootloader. I don't want to have to hard code the bootloader address, or re-compile for each different memory size. But I also need to use pgm_ functions with addresses calculated for data in the bootloader section, and maybe measure the size of the app section too.

 

 

If the code knows it is running in the bootloader section it can figure out all this information fairly easily.

 

There doesn't seem to bit a bit in some register that tells me this. I thought of trying to see how many bits are available in the RAMPZ register for ELPM, but I'm not sure if unused bits really are always zero as the manual claims and devices with EBI will always have the full 8 anyway.

 

This topic has a solution.
Last Edited: Tue. May 1, 2018 - 08:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  uint16_t pc;

  __asm__ __volatile__ ("rcall  .+0     \n\t"
                        "pop    %B[pc]  \n\t"
                        "pop    %A[pc]  \n\t"
                      :
                        [pc] "=e" (pc)
                      :
                       );

Now you can examine pc to know what the address of the first POP instruction is.  Note that the address will be word-based.  If you want the byte address, multiply by 2.  If your device has more than 128KiB of flash, you'll need to pop three bytes into a __uint24 or uint32_t output operand.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Mon. Apr 30, 2018 - 04:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, I thought of looking at the PC, but does it really help?

 

Say I see that the PC is around 65k... Is this a 64k device with a bootloader, or just a 128k device with >64k of code?

 

Having said that I'd settle even for being able to detect the location of .text with a clever macro, so that a recompile is all that is needed.

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

I do not understand this at all. If I write a bootloader I know that every last line of it will be located and will execute in the BLS. Why would I need a run time check to determine what I already know??

 

By:

mojo-chan wrote:
Is there a simple way to detect when code is running in the bootloader section
did you actually mean "the exact address of ..."?

 

EDIT: had a thought - do you mean one of those bootloaders that won't fit completely into the BLS so some of it is in the app section and some in the boot section and you want to determine if a particular part of it has fallen above/below the line?

Last Edited: Mon. Apr 30, 2018 - 05:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I should explain, I have a USB stack and want to include it in other projects seamlessly. Some of those projects will be bootloaders. The code needs to read USB descriptors from flash memory, which means calculating their addresses and using the _far versions of the PGM functions to generate ELPM instructions.

 

At the moment I use a #define BOOTLOADER, but I was wondering if I could automate it some way. More of a curiosity than anything I desperately need. I guess one other solution is to let the compiler just load those descriptors into RAM during init. Might actually save some code space by avoiding a memcpy_PF().

 

If the code knows it is in the bootloader it can calculate the address of the bootloader section, so it knows that the address of the data it needs is &data + the bootloader section start address.

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

Can you get the makefile to embed something in the code which says "I have been compiled to run in the boot section".

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

mojo-chan wrote:
At the moment I use a #define BOOTLOADER, but I was wondering if I could automate it some way. More of a curiosity than anything I desperately need. I guess one other solution is to let the compiler just load those descriptors into RAM during init. Might actually save some code space by avoiding a memcpy_PF().
  There is no need to distinguish between bootloader and application. Simply use the _far versions in both cases.

Use pgm_get_far_address() for the address, and bootloader or not does not matter. This 

the address of the data it needs is &data + the bootloader section start address

is wrong anyway.

 

Or you can keep up with the times and use __memx. And again it does not matter whether the code is part of a bootloader or an application.

Stefan Ernst

Last Edited: Mon. Apr 30, 2018 - 08:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
There is no need to distinguish between bootloader and application. Simply use the _far versions in both cases.

Use pgm_get_far_address() for the address, and bootloader or not does not matter.

 

Thanks, that's what I need.