Optiboot Modification: Auto-detect UART

Hi All,

My project requires that I be able to program my boards from both UART0 and UART1. I know that Optiboot allows me to specify which of these to use, but I do not think it will monitor multiple and auto-select whichever one it first receives serial data from. Is there an easy way to implement this?

I did attempt to implement it with the following changes:

  1. Add new definitions for ‘SECONDARY_UART’ in pins_def.h
  2. Add code to monitor both secondary and primary uart
  3. Store which UART received the first STK_GET_PARAMETER in a global variable
  4. Use the global variable to only send/receive from the selected UART for future communication

However, when programming on UART0 avrdude freezes just after it starts writing flash with the error:

avrdude.exe: stk500_paged_write(): (a) protocol error, expect=0x14, resp=0x64

I’ve attached the code. Any advice would be greatly appreciated!



optiboot.c (31.9 KB)

pin_defs.h (17.1 KB)

Does your board work reliably with a UART0-only bootloader? There have been some "issues" with that.

Hi westfw,

Thanks for the reply. I have had no issues with the UART0-only bootloader on my Atmega1280. I did go back and incrementally make changes to the UART0-only bootloader, testing after each change. It looks like the first error I encounter is when I add the global:

uint8_t selectedUart;

Once this is added, I find that new sketches appear to be fully written without an error, but during the verification, avrdude throws an error stating that the sketch on the board does not match the sketch on the computer starting at byte 0x200. Does any other setting need to be changed when I add a global to the bootloader? Any other ideas/suggestions for how to have it monitor UART0 and UART1?

Thanks again,


when I add the global:
uint8_t selectedUart;

Ah hah. You probably can’t add globals, because optiboot does it’s own memory allocation (so that it can leave out all of the variable initialization stuff.) See the code here:

/* C zero initialises all global variables. However, that requires */
/* These definitions are NOT zero initialised, but that doesn't matter */
/* This allows us to drop the zero init code, saving us memory */
#define buff    ((uint8_t*)(RAMSTART))
#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))

And add something like:

#define selectedUart (*(uint8_t*)(RAMSTART+SPM+PAGESIZE*2+8))

That did the trick and I can now upload via UART0. I will start testing secondary UART later today. Thanks for your help and all of your work on optiboot.