Skip to content

EmbedLink Secure Bootloader Application for Wireless Firmware Update

License

Notifications You must be signed in to change notification settings

berknylm/EmbedBoot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EmbedBoot

EmbedLink Secure Bootloader Application for Wireless Firmware Update

Overview

The ELP Bootloader enables firmware updates over the ELP communication protocol. It operates as an ELPX application (PID=0xFA) that manages flash memory operations on embedded nodes.

Constants

Name Value Description
ELPX_BOOTLOADER_PID 0xFA Protocol ID
ELPX_BOOTLOADER_VERSION 0xFF01 Bootloader version
ELPX_BOOTLOADER_KEY 0xFF0011FF Security key for BOOT command
ELPX_BIN_PART_SIZE 1024 Part size (bytes)
ELPX_BIN_SUBPART_SIZE 16 Subpart size (bytes)
ELPX_BIN_MAX_SUBPART_IDX 64 Max subparts per part (1024/16)

Part/Subpart Structure

Firmware is transferred in a hierarchical structure:

Firmware Binary
├── Part 0 (1024 bytes)
│   ├── Subpart 0  (16 bytes)
│   ├── Subpart 1  (16 bytes)
│   ├── ...
│   └── Subpart 63 (16 bytes)
├── Part 1 (1024 bytes)
│   ├── Subpart 0  (16 bytes)
│   └── ...
└── Part N (≤1024 bytes)
    └── ...
  • Part: 1024-byte block written to flash at once
  • Subpart: 16-byte chunk transferred in single ELP packet (payload limit is 26 bytes)
  • Transfer: 64 PARTLOAD commands fill one part buffer, then PROGRAM writes to flash

Protocol Phases

┌─────────┐    ┌─────────┐    ┌─────────────┐    ┌─────────┐    ┌──────────┐
│  BOOT   │───►│  ERASE  │───►│   PROGRAM   │───►│  VERIFY │───►│ FIRMWARE │
│ (lock)  │    │ (flash) │    │ (load+write)│    │  (CRC)  │    │  (jump)  │
└─────────┘    └─────────┘    └─────────────┘    └─────────┘    └──────────┘
Phase State Flow Description
BOOT READY → COMPLETED Lock bootloader with firmware parameters
ERASE READY → BUSY → COMPLETED Erase flash sectors
PROGRAM READY → BUSY → READY (repeat) Load subparts and program parts
VERIFY READY → COMPLETED Verify CRC32 of written firmware
FIRMWARE - Jump to application (no return)

Commands

STATUS (0x00)

Get current bootloader state.

Request: [PID][CMD] Response: ELPX_BOOTLOADER_STATUS_O

INFO (0x01)

Get bootloader information.

Request: [PID][CMD] Response: ELPX_BOOTLOADER_INFO_O

typedef struct {
    uint16_t b_version;     // Bootloader version
    uint32_t b_sector_size; // Flash sector size
    uint32_t b_part_size;   // Part size (1024)
    uint32_t b_fws;         // Firmware area start address
    uint32_t b_fwl;         // Firmware area max length
} ELPX_BOOTLOADER_INFO_O;  // 18 bytes

BOOT (0x02)

Lock bootloader and set firmware parameters.

Request: [PID][CMD][ELPX_BOOTLOADER_BOOT_I] Response: ELPX_BOOTLOADER_STATUS_O

typedef struct {
    uint32_t key;   // Must be ELPX_BOOTLOADER_KEY
    uint32_t fwid;  // Firmware ID
    uint32_t fws;   // Firmware start address
    uint32_t fwl;   // Firmware length (bytes)
    uint32_t fwcrc; // Firmware CRC32
} ELPX_BOOTLOADER_BOOT_I;  // 20 bytes

ERASE (0x03)

Erase flash firmware area. Returns progress callbacks during operation.

Request: [PID][CMD] Response: Multiple ELPX_BOOTLOADER_STATUS_O (progress + completion)

PARTLOAD (0x04)

Load 16-byte subpart into part buffer.

Request: [PID][CMD][ELPX_BOOTLOADER_PARTLOAD_I] Response: ELPX_BOOTLOADER_PARTLOAD_O

typedef struct {
    uint16_t part_idx;                      // Part index (0, 1, 2, ...)
    uint16_t subpart_idx;                   // Subpart index (0-63)
    uint8_t  subpart[ELPX_BIN_SUBPART_SIZE]; // 16 bytes data
} ELPX_BOOTLOADER_PARTLOAD_I;  // 20 bytes

typedef struct {
    uint16_t phase;
    uint16_t state;
    uint32_t completed;     // Bytes transferred so far
    uint32_t total;         // Total firmware length
    uint16_t part_idx;      // Expected next part
    uint16_t subpart_idx;   // Expected next subpart
} ELPX_BOOTLOADER_PARTLOAD_O;  // 16 bytes

PROGRAM (0x05)

Write loaded part to flash.

Request: [PID][CMD] Response: ELPX_BOOTLOADER_STATUS_O

VERIFY (0x06)

Verify firmware CRC32.

Request: [PID][CMD] Response: ELPX_BOOTLOADER_VERIFY_O

typedef struct {
    uint32_t fwid;  // Firmware ID from flash
    uint32_t fws;   // Firmware start from flash
    uint32_t fwl;   // Firmware length from flash
    uint32_t fwcrc; // Firmware CRC from flash
    uint8_t  fwv;   // Firmware valid (1=yes, 0=no)
} ELPX_BOOTLOADER_VERIFY_O;  // 17 bytes

FIRMWARE (0x07)

Jump to application. No response (node reboots).

Request: [PID][CMD] Response: None

RESET (0x08)

Reset bootloader state.

Request: [PID][CMD] Response: None

Programming Sequence

MASTER                          NODE
  │                               │
  │─── INFO ─────────────────────►│
  │◄── INFO_O (b_fws, b_fwl) ─────│
  │                               │
  │─── BOOT (key,fwid,fws,fwl,crc)│
  │◄── STATUS_O (COMPLETED) ──────│
  │                               │
  │─── ERASE ────────────────────►│
  │◄── STATUS_O (progress) ───────│ (multiple)
  │◄── STATUS_O (COMPLETED) ──────│
  │                               │
  │   ┌─── For each part ───────┐ │
  │   │                         │ │
  │   │ ┌─ For each subpart ──┐ │ │
  │   │ │                     │ │ │
  │   │ │─ PARTLOAD (idx,data)│►│ │
  │   │ │◄ PARTLOAD_O (sync) ─│ │ │
  │   │ │                     │ │ │
  │   │ └─────────────────────┘ │ │
  │   │                         │ │
  │   │─── PROGRAM ────────────►│ │
  │   │◄── STATUS_O (ok) ───────│ │
  │   │                         │ │
  │   └─────────────────────────┘ │
  │                               │
  │─── VERIFY ───────────────────►│
  │◄── VERIFY_O (fwv=1) ──────────│
  │                               │
  │─── FIRMWARE ─────────────────►│
  │         (node jumps to app)   │

Synchronization

The PARTLOAD response includes expected indices for next transfer:

  • part_idx: Expected part index
  • subpart_idx: Expected subpart index

Master must verify these match before continuing. If sync fails, master should retry or abort.

CRC32 Algorithm

uint32_t crc32(const uint8_t *data, uint32_t len) {
    uint32_t crc = 0xFFFFFFFF;
    for (uint32_t i = 0; i < len; i++) {
        crc ^= data[i];
        for (uint8_t j = 0; j < 8; j++) {
            if (crc & 1)
                crc = (crc >> 1) ^ 0xEDB88320;
            else
                crc >>= 1;
        }
    }
    return ~crc;
}

Usage Example

# Flash firmware to all discovered nodes
python elpx_bootloader.py firmware.bin

# Flash to specific node
python elpx_bootloader.py firmware.bin --node 0x10

# Interactive mode
python elpx_bootloader.py

Error Handling

  • NACK: Transport layer retransmits automatically (up to 3 retries)
  • Sync Fail: PARTLOAD response indices don't match - retry or abort
  • CRC Mismatch: VERIFY returns fwv=0 - reflash required
  • Phase Error: Commands received in wrong phase return no response

About

EmbedLink Secure Bootloader Application for Wireless Firmware Update

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published