SMP Two-Page Switch Record#

Application-side flash helpers for the SMP switch pages.

Bootloader support for selecting application 1 or 2 from a two-page switch record (no NVM3).

Requires BTL_SMP_SUPPORT and the address symbols in btl_smp_cfg.h: switch page bases, app 2 base, optional default app id. App 1 base defaults to BTL_APPLICATION_BASE.

Modules#

btl_smp_switch_record_t

Functions#

bool
btl_smp_switch_erase_page(bool use_page_1)

Erase one switch page.

bool
btl_smp_switch_write_record(bool use_page_1, uint16_t seq, uint8_t app_id)

Write a full switch record to one page.

bool
get_smp_page_bases_from_storage(uint32_t *page1Base, uint32_t *page2Base)

Get SMP switch metadata page base addresses from the bootloader storage vtable.

bool

Request that the next boot runs the given application.

Macros#

#define
BTL_SMP_RECORD_MAGIC 0x534D5050UL

Magic value identifying a valid switch record ("SMPP" in ASCII).

#define
BTL_SMP_RECORD_VERSION 1U

Record format version.

#define
BTL_SMP_APP_ID_1 1U

Application ID: app 1 (first application region).

#define
BTL_SMP_APP_ID_2 2U

Application ID: app 2 (second application region).

#define
BTL_SMP_APP_ID_MIN BTL_SMP_APP_ID_1

Minimum valid app_id (inclusive).

#define
BTL_SMP_APP_ID_MAX BTL_SMP_APP_ID_2

Maximum valid app_id (inclusive). Extend if more apps are added.

#define
BTL_SMP_RECORD_HEADER_CRC_LEN (sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint8_t) + sizeof(uint8_t))

Byte length of (magic, seq, app_id, version) used as input to btl_crc32Stream.

Function Documentation#

btl_smp_switch_erase_page#

bool btl_smp_switch_erase_page (bool use_page_1)

Erase one switch page.

Parameters
TypeDirectionArgument NameDescription
bool[in]use_page_1

true = Page 1, false = Page 2.

The application must not erase the page that holds the current valid record until after the new record is written to the other page.

Returns

  • Returns true on MSC success, false on MSC error.


btl_smp_switch_write_record#

bool btl_smp_switch_write_record (bool use_page_1, uint16_t seq, uint8_t app_id)

Write a full switch record to one page.

Parameters
TypeDirectionArgument NameDescription
bool[in]use_page_1

true = write to Page 1, false = Page 2.

uint16_t[in]seq

Sequence value for the record.

uint8_t[in]app_id

Target app (BTL_SMP_APP_ID_1 or BTL_SMP_APP_ID_2).

Note

  • Non-validating fields are written first, then CRC, then magic last. The implementation sets magic, version (BTL_SMP_RECORD_VERSION), and crc32; the caller supplies seq and app_id.

Returns

  • Returns true on MSC success, false on MSC error.


get_smp_page_bases_from_storage#

bool get_smp_page_bases_from_storage (uint32_t * page1Base, uint32_t * page2Base)

Get SMP switch metadata page base addresses from the bootloader storage vtable.

Parameters
TypeDirectionArgument NameDescription
uint32_t *[out]page1Base

Page 1 base if non-NULL.

uint32_t *[out]page2Base

Page 2 base if non-NULL.

Requires BOOTLOADER_CAPABILITY_SMP_SWITCH (via bootloader_getInfo()) and a non-NULL getSmpSwitchPageBases pointer in BootloaderStorageFunctions_t. The bootloader supplies bases from its layout; the app does not use btl_smp_cfg.h.

Returns

  • False if SMP is not supported, or the storage vtable does not expose page bases.


btl_smp_switch_request_next_boot_app#

bool btl_smp_switch_request_next_boot_app (uint8_t next_app_id)

Request that the next boot runs the given application.

Parameters
TypeDirectionArgument NameDescription
uint8_t[in]next_app_id

Desired app for next boot (BTL_SMP_APP_ID_1 or BTL_SMP_APP_ID_2).

Reads both pages, selects the other page, erases it, and writes a new record (sequence incremented, app_id set). The application should trigger a software reset after success.

Returns

  • Returns true if the switch record was updated successfully. Returns false if BOOTLOADER_CAPABILITY_SMP_SWITCH is not set, or if read/validate or erase/write failed.

Note

  • When the next sequence wraps in uint16_t (65535 + 1), next_seq is 0; both switch pages are erased and seq restarts at 1 (epoch reset). The target metadata page for the new record stays the same as the non-epoch algorithm would have chosen. Which application boots is always next_app_id, not the page index.