Should I code my own bootloader

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

Hey everyone,

 

I'm building a project where I will need to implement a bootloader on the ATmega328PB that will allow me to download/flash new firmware from a host UART programmer (the host is a Particle Electron --> STM32)  I will use this bootloader to allow the UART programmer host MCU to tell my ATmega to prepare for a firmware update, at which point the ATmega will "reset" itself, enter bootloader, and wait for the Electron to begin flashing new firmware to it (i.e. no external reset signal will be provided... only signals between the ATmega and the programmer are GND, UART-TX, and UART_RX)

 

I am at the start of this journey and am quite confused about how to proceed.

 

I feel like I should be trying to use Optiboot as-is.  This would allow me to easily adapt the ArduinoAsISP sketch to the Electron without having to re-invent the wheel.  The problem with this approach (as far as I can tell) is that I would need to re-work how the ATmega resets, since Optiboot requires a hardware reset in order to accept new firmware.   I started a separate thread on this subject  and it would seem from the answers therein that I should be able to use something like the following to "meta-reset" the ATmega without use of the software watchdog or external reset pin:

 

typedef void(* fptr_t) (void);
fptr_t resetFunc = (fptr_t)0x7E00; //declare reset function @ address 0x7E00 --> bootloader start address
resetFunc();  //pseudo-reset (enter bootloader)

 

My understanding is that if I do things this way, then the MCUCSR register will be 0 when Optiboot spools up, which in turn will allow it to run.  Approaching things this way would mean that all registers and RAM would be in the state they were in when I called resetFunc().   Would this break Optiboot (i.e. does optiboot need to be run on a "fresh" ATmega runtime instance... with registers in their POR values?) or will things hum along nicely?

 

Is my reasoning for using Optiboot sound, or should I roll up my sleeves and take a deep-dive into the world of coding my own bootloader from scratch?

 

FYI I have no prior experience writing bootloaders or using Make.

I love the smell of burning silicon in the morning

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

+1 for Optiboot

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

Seems like it would take a couple of minutes of your time to test it and see if it works un-modified!

 

Jim

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

Why not simply adopt the Arduino approach that uses the (normally ignored) DTR line to trigger a quick pulse on the AVR reset line when you wish to use the bootloader?  The programmer-device software that uses a USB COM port asserts the DTR line.   A capacitor in-line between DTR (on the USB-serial IC) and the AVR reset makes the logic-level change on DTR into a quick pulse.  It's a hardware kluuge that actually works elegantly.

 

Does the Electron not use a USB COM port connection?  Do the TX and RX lines from the Electron connect directly to the AVR's TX and RX lines?

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

I'm using a 2-wire bare-bones UART system (needed to keep conductor count low) so there's no DTR line I can utilize to initiate a reset pulse.  The Electron TX is connected directly (though multiplexed) to the RX on the ATmega (and vice versa with RX/TX).

 

I suppose that I could simply do the same thing by connecting a capacitor with pullup and drain transistor controlled by a pin on the ATmega and have it commit supoku on its own by pulling it's reset line low once the Electron instructed the ATmega that it wanted to program it.

 

I love the smell of burning silicon in the morning

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

jaza_tom wrote:
I'm using a 2-wire bare-bones UART system (needed to keep conductor count low) so there's no DTR line I can utilize to initiate a reset pulse.
A GreenPAKTM can be a BREAK detector on the UART and buffer the UART signals.

UART inactive is high, BREAK is low for a certain duration then the GreenPAK resets the AVR.

The GreenPAK is a board controller; conversely, that could be done by a tinyAVR.

Sometimes one needs more analog comparators; these are in a GreenPAK (though about two orders of magnitude slower than an AVR's AC)

 

https://www.dialog-semiconductor.com/configurable-mixed-signal

https://www.dialog-semiconductor.com/reset-ic

 

"Dare to be naïve." - Buckminster Fuller

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

I suppose that I could simply do the same thing by connecting a capacitor with pullup and drain transistor controlled by a pin on the ATmega and have it commit supoku on its own by pulling it's reset line low once the Electron instructed the ATmega that it wanted to program it.

Never rely on the app to trigger the bootloader.  What happens if there's a bug in your app?  Or an oversight?  Or a power-failure during bootloading?

"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."

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

 

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

Approaching things this way would mean that all registers and RAM would be in the state they were in when I called resetFunc().   Would this break Optiboot (i.e. does optiboot need to be run on a "fresh" ATmega runtime instance... with registers in their POR values?) or will things hum along nicely?

 Mostly, you need to make sure that any peripheral configured to generate an interrupt is turned off, and interrupts themselves are turned off.  An example was recently modified in the Optiboot repository to show how the bootloader can be started from an application: https://github.com/Optiboot/opti...

 

Optiboot doesn't use very much, but it is also not careful to set ALL the registers to a known state (you can probably break it by setting UBRR0H to a non-zero value, for example.

 

(these are problems that you'll have with any bootloader, though...)

 

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

Good points to consider for sure.  The chance of a power failure during bootloading is basically 0 for my application, so we can take that off the list.

 

The remaining points do give me pause however.  Thanks for the words of caution, I will have to wrestle with these before I'll be able to fall asleep tonight.  cheeky

 

 

This project is extremely cost-sensitive so it would be nice if I could avoid having to drop an additional $0.50 on a ATtiny to act as a UART break detector/resetter.

 

It looks like I could probably accomplish the same thing with a CD4541 programmable timer/counter configure (via 5 external resistors, an NPN transistor, and a cap) to do the same thing, as in the below schematic capture.  This would cost ~$0.23 in qty 2500

 

I love the smell of burning silicon in the morning

Last Edited: Mon. Sep 10, 2018 - 01:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jaza_tom wrote:
The chance of a power failure during bootloading is basically 0 for my application, so we can take that off the list.
It's not just power failure - could simply be a comms failure (or some other unexpected failure). Bottom line is that when designing bootloaders you should always consider the occasion on which the app is part erased/part reprogrammed at next power on. As such an app can make use and rely on the bootloader (as it's always there) but a bootloading mechanism should never rely on anything in the app or any function it may perform. (apart from anything else there's potentially the chicken/egg situation where the only thing loaded into the chip is the bootloader and no app code has been delivered at all!)