Arduboy custom bootloader

Yes it would after the standard timeout (I’m using 7.5 seconds instead of 8 for the RGB sequence) times out. When DOWN is pressed the timeout counter is simply not updated. When DOWN is released it continues counting towards it’s timeout value. It’s convenient this way and when you accidentally release the button it won’t leave bootloader mode right away.

However when your testing sketches a lot, after each upload it takes another 7.5 seconds to exit bootloader mode and start the sketch (timeout value gets reset during uploading). By pressing the B button after a successful upload, you can start the sketch immediately

Wouldn’t the sketch start immediately after a successful upload anyway? That is, as long as no button was being held. I assume if you were holding the UP button, you would release it as soon as you saw the TX and RX lights flashing, indicating that an upload had started.

If you’ve moved the magic key to RAMEND-1, then I’d think times that powering up into the bootloader and/or extending it’s timeout would be required would be extremely rare. I don’t even see the necessity of needing to extend the current timeout value.

No, because there is no execute command (see CDCtask caterina.c). the bootloader relies on timing out to start the sketch. Both the programming and read commands reset the timeout counter. so when the upload and verify are complete the sketch won’t start until the timeout period has passed.

Oops! I forgot the E command is issued and sets timeout to half a second .:blush:

I agree. But I think it’s a a nice little 4 byte feature for Arduboys with broken reset buttons or for anyone not having a toothpick at hand when an application bricked Arduboy.:

		sbis	PINF,4		;test DOWN button
		rjmp	run_bootloader	;button pressed, enter bootloader
1 Like

So it sounds like you just need:

  • If DOWN is pressed when powering up then start the bootloader instead of the sketch.
  • If DOWN is detected as pressed when you would increment the timeout counter then don’t increment it.
  • (Detecting B or any other button to exit the bootloader isn’t required.)

Yes I see the B button feature is not really worth it. Better save those 10 bytes of code for something more useful. Just made a new test version with the updated features and added it to the zip file


The features:

  • 7.5 second timeout where the RGB LED breathes Red, Green , Blue and off 3 times.
    *double MAGIC KEY check + boot signature to enter bootloader mode from opening and closing USB port at 1200baud.
  • Pressing DOWN button in bootloader mode will hold the bootloader timeout period for as long as the button is held down.
  • Pressing DOWN while turing on Arduboy put’s it in bootloader mode instead of running the sketch.

Behind the curtain changes:

  • Identifies it self as ‘ARDUBOY’ programmer instead of ‘CATERIN’ to distinguish itself from the standard bootloader.
  • minor optimized code (3886 bytes atm)

Okay I thought it was time to test it on the real thing. so I quickly made an ICSP clip for Arduboy and burned the bootloader…

After I turned it on it always ended up in bootloader mode. Having a quick look at the main code I realized that SetupHardware was called after I tried reading the DOWN button :stuck_out_tongue: Putting the port initializing code in the right order made ik work as it should :smiley:

I removed all the previous test versions and just kept the best version



Managed to kick out just over half a K (526 bytes to be exact) so there are now 562 bytes for new code :sunny:
The RGB LED breathing is a bit faster now due to the code optimalisation. There are now 5 RGB cycles with the original 8 seconds timeout.

added arduboy-bootloader-leonardo-8-sec-timeout-dual-bootkey-down-button-v3.hex to the zip file


Sounds great! Is there a repo where your changes to the bootloader can be followed/reviewed? It’s mostly curiosity on my part at this stage but I think it would be useful to have traceability back to the “original” Caterina source for a potential substitute bootloader. Thanks!

Not yet but I’ll put it up on my github later when it’s cleaned and more documented (It’s pure assembly) also still need to find out how to make a proper makefile for it (just using a batch file atm and adding the boot signature at the end manually)

If your code is derived from the Caterina bootloader, I suggest you honour its license agreement, which I believe is included in comments at the start of the source code files.

Yes it’s based on the reversed Caterina bootloader (which I’ll include) and I’ll include the original licence too.


Too bad the weekends over again :frowning: So I had to stop optimizing. Bootloader size is currently at 3196 bytes (900 free bytes) no time for a making a new test. But he next one will be down 1K for sure :slight_smile:


OK I I’ve optimized and crunched enough for my liking. Bootloader size is down to 2752 bytes without removing features, actually added features :smiley:

I’ve also added software bootloader protection so any block write to flash or page commit in the bootloader area will not be executed.

Changed the timeout back to 7.5 secs for 4 flashy RGB LED cycles Updated the zip file with:


Just discovered @eried’s Dock the other day. Which I like so much I want to add write to display and read button support to the bootloader now. So when Arduboy is in bootloader, Arduboy could be used as a mini terminal.

The idea I have atm is to extend the AVR910 command ‘B’ (WriteMemoryBlock) by adding memory type ‘D’ that writes to a 1K display buffer and outputs ito oled when 1K address is reached.


Preventing writes to the bootloader area using software is totally unnecessary as long as the lock bits have been set properly.

If you have the capability to burn the bootloader, you also have the capability to properly set the lock bits. If you use the Arduino IDE to burn the bootloader, this will be done automatically.

The last part is usually the problem. You can easely forget to set them (even my recently purchased Arduboy didn’t have then configured)

What about If you don’t have the capability and the bootloader was burned by someone else who didn’t set the lock bits properly? You’d have to go through some trouble to get it fixed.

Hmmm… this taking about bootloader protection and lock bits. just gives me an Idea: I’ve freed over 1K of space in the bootloader. With just software bootloader protection I could make that area unprotected. That would be great for a selfprogramming bootloader extension or extra space

1 Like

I must admit, there have been many cases of the lock bits not being set, even on newer Arduboys.

Happened to me with my first one.
RIP my 1st arduboy, have no programmer to bring you back to life. qq

1 Like

I you have the capability to burn the bootloader, then forgetting to lock it isn’t a problem. You can always just burn it again if it gets corrupted.

If someone else burns the bootloader for you, then it should be their responsibility to make sure it’s protected. If not, it’s on them to correct the problem (which the Arduboy organisation has be very good about dealing with).

The proper way of handling the problem is not to add code that would be useless if the hardware is set properly. It should be handled by making sure the problem doesn’t occur, such as by using a script that both does the burning and sets the locks in one operation. Or, by using the Arduino IDE to burn the bootloader.

1 Like

Well I’m also keeping in mind that the bootloader can be used for the regular Arduino’s Leonaro, Micro ProMico,etc.

It’s a 30 byte protection now that only protects the 1st 3K of the bootloader allowing the last 1K to be self programmed if the bootloader bit’s are not set. I’ve also dubbed the bootloader ‘Cathy3K’ now because of it taking up 3K

But back to the Arduboy features. it’s in!
I’ve successfully added the streaming to display code, button reading and a little USB connector sprite to display in bootloader mode just for fun :sunny: Bootloader size is at 2988 bytes now.

bootloader hex file and python demo at:

Streaming is quite simple:

Set current address to 0 using command ‘A’,0x00,0x00 wait for response byte
8 times: write 128 bytes of display data using command ‘B’,0x00,0x80, ‘D’ followed by the 128 bytes of display data and wait for response byte

Reading the buttons is done using the hardware version command ‘v’ (lover case)
write command ‘v’, read response byte. if not equal ‘?’ (normal bootloader response) read another response byte.
button_AB_state = ResponseByte1 -‘1’, D-Pad_state = ResponseByte2 - ‘A’

Still need to work on command 'x to control the LEDs. So no control of the LEDs yet.


If you expect this to be usable with an Arduino Micro, make sure you have defines and/or code to take into account the fact that the polarity of the TX and RX LEDs is reversed. You set their pin high to turn them on rather than low.