flashwrite.h File Reference

riotboot flash writing module More...

Detailed Description

riotboot flash writing module

This module provides an API to reliably write a firmware image to flash.

The API is similar to stream hashing functions:

  1. initialize state structure using riotboot_flashwrite_init()
  2. put some data using riotboot_flashwrite_putbytes()
  3. repeat 2. until all data has been received
  4. finish update using riotboot_flashwrite_finish()

The module will not automatically reboot after an image has been successfully written.

Under the hood, the module tries to abstract page sizes for writing the image to flash. Verification of the image is left to the caller. If the data is not correctly written, riotboot_put_bytes() will return -1.

The module makes sure that at no point in time an invalid image is bootable. The algorithm for that makes use of the bootloader verifying checksum and works as follows:

  1. erase first block (making its checksum invalid)
  2. write image starting at second block
  3. write first block

When using raw mode is used with this module, the need to buffer a full flashpage page is removed, instead it must buffer two times the FLASHPAGE_WRITE_BLOCK_SIZE. One is used to buffer the current write block, the other buffers the first chunk (offset zero, page zero). This first chunk is written when finalizing the flash operation. The minimal size for RIOTBOOT_FLASHPAGE_BUFFER_SIZE is 4, at least the riotboot magic number must fit into this and FLASHPAGE_SIZE must be a multiple of RIOTBOOT_FLASHPAGE_BUFFER_SIZE

Author
Kaspar Schleiser kaspa.nosp@m.r@sc.nosp@m.hleis.nosp@m.er.d.nosp@m.e
Koen Zandberg koen@.nosp@m.berg.nosp@m.zand..nosp@m.net

Definition in file flashwrite.h.

#include "riotboot/slot.h"
#include "periph/flashpage.h"
+ Include dependency graph for flashwrite.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  riotboot_flashwrite_t
 firmware update state structure More...
 

Macros

#define CONFIG_RIOTBOOT_FLASHWRITE_RAW   1
 Enable/disable raw writes to flash.
 
#define RIOTBOOT_FLASHPAGE_BUFFER_SIZE   4
 Intermediate buffer size for firmware image data.
 
#define RIOTBOOT_FLASHPAGE_BUFFER_ATTRS   __attribute__((aligned(FLASHPAGE_WRITE_BLOCK_ALIGNMENT)))
 Extra attributes required for the firmware intermediate buffer.
 
#define RIOTBOOT_FLASHWRITE_SKIPLEN   sizeof(RIOTBOOT_MAGIC)
 Amount of bytes to skip at initial write of first page.
 

Functions

int riotboot_flashwrite_init_raw (riotboot_flashwrite_t *state, int target_slot, size_t offset)
 Initialize firmware update (raw version) More...
 
static int riotboot_flashwrite_init (riotboot_flashwrite_t *state, int target_slot)
 Initialize firmware update (riotboot version) More...
 
int riotboot_flashwrite_putbytes (riotboot_flashwrite_t *state, const uint8_t *bytes, size_t len, bool more)
 Feed bytes into the firmware writer. More...
 
int riotboot_flashwrite_flush (riotboot_flashwrite_t *state)
 Force flush the buffer onto the flash. More...
 
int riotboot_flashwrite_finish_raw (riotboot_flashwrite_t *state, const uint8_t *bytes, size_t len)
 Finish a firmware update (raw version) More...
 
static int riotboot_flashwrite_finish (riotboot_flashwrite_t *state)
 Finish a firmware update (riotboot version) More...
 
size_t riotboot_flashwrite_slotsize (const riotboot_flashwrite_t *state)
 Get a slot's size. More...
 
int riotboot_flashwrite_verify_sha256 (const uint8_t *sha256_digest, size_t img_size, int target_slot)
 Verify the digest of an image. More...
 

Function Documentation

◆ riotboot_flashwrite_finish()

static int riotboot_flashwrite_finish ( riotboot_flashwrite_t state)
inlinestatic

Finish a firmware update (riotboot version)

This function finishes a firmware update by re-writing the first header so it includes riotboot's magic number ("RIOT").

Parameters
[in]stateptr to previously used state structure
Returns
0 on success, <0 otherwise

Definition at line 221 of file flashwrite.h.

◆ riotboot_flashwrite_finish_raw()

int riotboot_flashwrite_finish_raw ( riotboot_flashwrite_t state,
const uint8_t *  bytes,
size_t  len 
)

Finish a firmware update (raw version)

This function finishes a firmware update by re-writing the first header

Parameters
[in]stateptr to previously used state structure
[in]bytesdata to re-write in the first page
[in]lensize of data in bytes (must be <=FLASHPAGE_SIZE)
Returns
0 on success, <0 otherwise

◆ riotboot_flashwrite_flush()

int riotboot_flashwrite_flush ( riotboot_flashwrite_t state)

Force flush the buffer onto the flash.

Parameters
[in,out]stateptr to previously used update state
Returns
0 on success, <0 otherwise

◆ riotboot_flashwrite_init()

static int riotboot_flashwrite_init ( riotboot_flashwrite_t state,
int  target_slot 
)
inlinestatic

Initialize firmware update (riotboot version)

This function initializes a firmware update, skipping riotboot's magic number ("RIOT") by calling riotboot_flashwrite_init_raw() with an offset of RIOTBOOT_FLASHWRITE_SKIPLEN (4). This ensures that riotboot will ignore the slot until the magic number has been restored, e.g., through riotboot_flashwrite_finish().

Parameters
[in,out]stateptr to preallocated state structure
[in]target_slotslot to write update into
Returns
0 on success, <0 otherwise

Definition at line 164 of file flashwrite.h.

◆ riotboot_flashwrite_init_raw()

int riotboot_flashwrite_init_raw ( riotboot_flashwrite_t state,
int  target_slot,
size_t  offset 
)

Initialize firmware update (raw version)

Allows setting the initial offset to offset, which would mean that the first bytes passed in via riotboot_flashwrite_putbytes() will be written to (slot_start + offset).

Note
offset should be <= FLASHPAGE_SIZE, otherwise the results are undefined.
Parameters
[in,out]stateptr to preallocated state structure
[in]target_slotslot to write update into
[in]offsetBytes offset to start write at
Returns
0 on success, <0 otherwise

◆ riotboot_flashwrite_putbytes()

int riotboot_flashwrite_putbytes ( riotboot_flashwrite_t state,
const uint8_t *  bytes,
size_t  len,
bool  more 
)

Feed bytes into the firmware writer.

Note
If the update has been initialized via riotboot_flashwrite_init(), make sure to skip the first RIOTBOOT_FLASHWRITE_SKIPLEN bytes.
Parameters
[in,out]stateptr to previously used update state
[in]bytesptr to data
[in]lenlen of data
[in]morewhether more data is coming
Returns
0 on success, <0 otherwise

◆ riotboot_flashwrite_slotsize()

size_t riotboot_flashwrite_slotsize ( const riotboot_flashwrite_t state)

Get a slot's size.

Parameters
[in]stateptr to state struct
Returns
the size of the slot that state is configured to update to

◆ riotboot_flashwrite_verify_sha256()

int riotboot_flashwrite_verify_sha256 ( const uint8_t *  sha256_digest,
size_t  img_size,
int  target_slot 
)

Verify the digest of an image.

Parameters
[in]sha256_digestcontent of the image digest
[in]img_sizethe size of the image
[in]target_slotthe image slot number
Returns
-1 when image is too small
0 if the digest is valid
1 if the digest is invalid