Bootloader
- Pick an address (for now)
- In the future, I should probably store this somewhere that can be re-flashed
Memory map
Address | Page IDX | Notes |
---|---|---|
Application range | ||
0x0800_0000 | 0 | NOTE: Reset vector MUST point to 0x0800_C000, MSP must be... ? No Flip Link? |
0x0800_0800 | 1 | |
0x0800_1000 | 2 | |
0x0800_1800 | 3 | |
0x0800_2000 | 4 | |
0x0800_2800 | 5 | |
0x0800_3000 | 6 | |
0x0800_3800 | 7 | |
0x0800_4000 | 8 | |
0x0800_4800 | 9 | |
0x0800_5000 | 10 | |
0x0800_5800 | 11 | |
0x0800_6000 | 12 | |
0x0800_6800 | 13 | |
0x0800_7000 | 14 | |
0x0800_7800 | 15 | |
0x0800_8000 | 16 | |
0x0800_8800 | 17 | |
0x0800_9000 | 18 | |
0x0800_9800 | 19 | |
0x0800_A000 | 20 | |
0x0800_A800 | 21 | |
0x0800_B000 | 22 | |
0x0800_B800 | 23 | Last App Page |
Bootloader range | ||
0x0800_C000 | 24 | |
0x0800_C800 | 25 | |
0x0800_D000 | 26 | |
0x0800_D800 | 27 | |
0x0800_E000 | 28 | TODO: Move Bootloader Here? |
0x0800_E800 | 29 | |
0x0800_F000 | 30 | |
0x0800_F800 | 31 | Settings Page |
Settings Page
- I2C address?
- App
- Bootloader
- Listen to pin(s) for bootload?
- Listen to pin(s) for I2C addr?
- Checksum
Do I want a separate command for changing settings? Or just allow it like any other subpage write?
Do sanity checks on settings?
Procedure
- Bootloader boots
- Disable all interrupts
- Is button held?
- Y: GOTO 5
- N: Continue
- Is bootload RAM flag set + magic word valid?
- Y: GOTO 5
- N: Continue
- Boot app at 0x0000_0000
- Bootload.
- LED blink?
- Listen to I2C
- Write transactions:
- 0x40 - Start bootload
- 4 bytes - total checksum (later crc32)
- 1 byte - total subpages to write
- NOTE: must be less than 23 * 8 for now
- 0x41 - write page command
- Must have set 0x40 already
- Always 1 + 1 + 256 + 4 bytes
- 1: 0x41
- 1: Page/Subpage
- 0bPPPPP_SSS (32 pages, 8 sub-pages)
- 0bPPPPP must be <= 23
- 256: subpage contents
- 4 byte: For now: 32-bit checksum. Later, CRC32 or Poly1305?
- On writes to subpage zero: erase page
- Stretch write ack until checksum + erase + write?
- I can't use the flash while erasing (or writing?) anyway
- On writes to 0:0: make sure the reset vector is 0x0800_C000
- Make sure MSP is maxval?
- 0:0 must be the last thing written
- 0x42 - reboot to new image
- 0x43 - abort bootload
- No data
- 0x44 - Offer image downstream
- Only after finishing 0x40 transaction
- 0x40 - Start bootload
- Read transactions
- wr-then-rd 0x10 + 16 bytes => b'sprocket boot!!!'
- wr-then-rd 0x11 + 4 bytes => maj.min.triv.reserved
- wr-then-rd [0x21, P:S] + 260 bytes => Read subpage
- wr-then-rd 0x22 + 1 byte => status
- wr-then-rd 0x23 + 4 bytes => children flashed
- Write transactions:
Status
Represent:
- Is bootload (of me): idle, active, complete, error (2-bit)
- Does my app look reasonable? yes/no (1-bit)
- Is bootload (of chain): invalid, idle, active (next), active (downstream), complete
TODO: On (critical?) error?
- Finish current transaction
- Disable I2C (auto-naks)
- reboot
- Probably not for checksum errors, unless a lot
Compile time to-do for bootloader
- Change memory range
- Disable interrupts
- Ensure Reset is at base of flash (add linker assert?)