-
Notifications
You must be signed in to change notification settings - Fork 399
HowOptibootWorks
Optiboot implements a small subset of the "STK500 communications protocol" (version 1) defined by Atmel in their Application Note AVR061 In order to conserve code space, many of the protocol commands are ignored and receive "lies" rather than correct response codes, leading to the possibility that the bootloader may not operate correctly with all host-side software. It is known to work with versions of "avrdude" supporting the "-c arduino" programmer type.
Optiboot is designed to reside in the bootloader section, and chip fuses should be set appropriately for the size of optiboot (normally 256 words) (BOOTSZx) and to reset to the bootloader start address (BOOTRST) Note that BOOTSZx values are chip-dependent, and some of the chips suppored by Optiboot have a 512word minimum bootloader size.)
- On reset, Optiboot starts and reads the reset reason from MCUSR. For any cause other than "external reset", the application is started immediately. Otherwise, optiboot attempts to download new application software:
- The "start LED" is flashed to indicate that optiboot is running. (which pin is used, and how many times it flashes, is configurable.)
- The (configurable) UART is configured and the WDT is enabled with a 1s timeout.
- Optiboot attempts to read commands from the (configurable) serial port. Valid characters will cause the WDT to be reset, and the application flash area to be programmed (hopefully.)
- With no valid UART traffic, or after programming, the WDT is allowed to expire, causing the chip to reset.
- Since the WDT reset is NOT an 'external reset', the application is started as in (1) - the AVR at the time the application is run has all IO registers except MCUSR and SP in their pristine, reset, state.
The following core commands are "supported"; they actually do something useful WRT loading code via the bootloader:
Cmd Name | Value | Description |
---|---|---|
STK_LOAD_ADDRESS | 0x55,'U' | Note: 16bit word address, 128kb flash max. |
STK_PROG_PAGE | 0x64,'d' | Flash only |
STK_READ_PAGE | 0x74,'t' | Flash only |
STK_READ_SIGN | 0x75,'u' | Reads compiled-in signature. |
STK_LEAVE_PROGMODE | 0x51,'Q' | Starts application code via WDT reset. |
STK_GET_PARAMETER | 0x41,'A' | Supports "minor SW version" and "major SW version" Returns 3 for all other parameters. |
The following commands will have their arguments correctly read, and produce in a "success" response, but they don't actually do anything:
Cmd Name | Value |
---|---|
STK_UNIVERSAL | 0x56, 'V' |
STK_SET_DEVICE | 0x42, 'B' |
STK_SET_DEVICE_EXT | 0x45, 'E' |
All other commands will result in a success response if they are immediate followed by CRC_EOP (0x20, ' ') (ie they are ignored), or a WDT reset (start applicatin) otherwise.
In order to save space, Optiboot utilizes a couple of techniques that may be of general interest:
- The Vector table and normal startup code are omitted by using linker options "-nostdlib -nostartfiles"
- This requires that main() be declared with attribute OS_main and manually placed in the .init9 section.
- and thus main() has to initialize the known-zero register (r1) and SP on chips that don't automatically set SP to end-of-ram.
- inlining of functions is carefully controlled.