rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
art_store.h File Reference

Keeping a board's drawing, so it is fetched once and not every time the link comes up. More...

#include <stdbool.h>
#include <stdint.h>

Go to the source code of this file.

Data Structures

struct  art_flash_t
 The flash a store lives in. More...
struct  art_entry_t
 What a slot says it holds: the board and the ARTWORK page it came from. More...
struct  art_keep_t
 The write art_store_put() does, cut into steps of at most one sector each, so a caller can stop between any two and carry on later. More...

Macros

#define ART_SLOT_BYTES   (16u * 1024u)
 One slot: a sector of header and the payload after it.
#define ART_KEEP_READ_BYTES   256u
 Bytes read back per read while a keep checks what it wrote.

Enumerations

enum  art_keep_status_t {
  ART_KEEP_IDLE = 0 , ART_KEEP_WAITING , ART_KEEP_RUNNING , ART_KEEP_DONE ,
  ART_KEEP_FAILED
}
 What a step of a keep did; see art_keep_step(). More...

Functions

bool art_entry_same (const art_entry_t *a, const art_entry_t *b)
 Whether two entries describe the same payload: every field equal.
uint32_t art_store_slots (const art_flash_t *f)
 How many drawings this partition has room for.
uint32_t art_store_capacity (const art_flash_t *f)
 The most bytes a drawing may be for this partition to hold it.
bool art_store_find (const art_flash_t *f, uint16_t board, art_entry_t *out)
 What is kept for board, without reading the drawing itself.
bool art_store_read (const art_flash_t *f, uint16_t board, uint8_t *dst, uint32_t cap)
 Read the drawing for board into dst.
bool art_store_read_same (const art_flash_t *f, const art_entry_t *key, uint8_t *dst, uint32_t cap)
 Read the drawing key describes into dst: only when the entry kept for key->board equals key in every field (art_entry_same()) and the payload checks out.
bool art_store_put (const art_flash_t *f, uint16_t board, const art_entry_t *entry, const uint8_t *payload)
 Keep payload for board, replacing anything kept for it already.
bool art_store_forget (const art_flash_t *f, uint16_t board)
 Forget what is kept for board.
bool art_keep_begin (art_keep_t *k, const art_flash_t *f, uint16_t board, const art_entry_t *entry, const uint8_t *payload)
 Set k up to keep payload for board.
art_keep_status_t art_keep_step (art_keep_t *k, bool may_write)
 One step, when may_write is true: at most one sector erased, written or read back, or the header written.
bool art_keep_busy (const art_keep_t *k)
 Whether k has a keep under way, waiting or not.

Detailed Description

Keeping a board's drawing, so it is fetched once and not every time the link comes up.

The drawing is written to a partition of the panel's own flash with the identity the IOmcu reports and everything its ARTWORK page says about the payload: format, outline, length, CRC (cyclic redundancy check) and hash. The kept drawing is the board's only while all of those still match the page, so an IOmcu flashed with another drawing under the same board ID is fetched again instead of shown from the cache.

Fixed slots rather than a packed heap. A slot is erased, filled, and only then given a header; nothing has to be moved when one is replaced, and the store cannot be left half compacted by a power cut. The cost is the tail of a slot a smaller drawing does not use, which buys simplicity in code that runs while a bench is live.

The order of a write is the whole point: payload, read it back, and write the header last. A header is what makes a slot findable, so a drawing interrupted by an unplugged board or a power cut is never found – rather than found and wrong, which is the failure that would survive in flash until somebody wired a lead by it.

Nothing here knows about esp_partition. The flash is passed in, so the whole store runs on the host against memory.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ ART_KEEP_READ_BYTES

#define ART_KEEP_READ_BYTES   256u

Bytes read back per read while a keep checks what it wrote.

The buffer is in the keeper, so a step costs its caller's stack no more than its frame.

Enumeration Type Documentation

◆ art_keep_status_t

What a step of a keep did; see art_keep_step().

Enumerator
ART_KEEP_IDLE 

nothing is being kept

ART_KEEP_WAITING 

not allowed to write: nothing was touched

ART_KEEP_RUNNING 

one operation done, more to come

ART_KEEP_DONE 

the header is written: the drawing is findable

ART_KEEP_FAILED 

an operation failed: nothing findable for it

Function Documentation

◆ art_entry_same()

bool art_entry_same ( const art_entry_t * a,
const art_entry_t * b )

Whether two entries describe the same payload: every field equal.

The content key of the cache – a kept drawing is shown only for an ARTWORK page that says exactly what the entry says.

Parameters
aFirst entry.
bSecond entry.
Returns
true when every field is equal.

◆ art_keep_begin()

bool art_keep_begin ( art_keep_t * k,
const art_flash_t * f,
uint16_t board,
const art_entry_t * entry,
const uint8_t * payload )

Set k up to keep payload for board.

Touches no flash.

False, with k idle, for what art_store_put() refuses before it writes, except the payload's checksums: computing them here is a pass over the whole payload in one call, and the read-back checks the same thing before the header is written. A caller that has not already checked the payload (art_fetch_step() does) uses art_store_put().

Parameters
kKeep state to set up.
fFlash the store lives in.
boardBoard ID.
entryEntry describing the payload.
payloadPayload bytes; must stay valid until the keep ends.
Returns
true when the keep may start.

◆ art_keep_busy()

bool art_keep_busy ( const art_keep_t * k)

Whether k has a keep under way, waiting or not.

Parameters
kKeep state.
Returns
true while a keep is under way.

◆ art_keep_step()

art_keep_status_t art_keep_step ( art_keep_t * k,
bool may_write )

One step, when may_write is true: at most one sector erased, written or read back, or the header written.

When it is false, WAITING, and no flash is touched.

DONE and FAILED are returned once; the keep is idle after them and a further step returns IDLE.

Parameters
kKeep state.
may_writetrue when a flash write is allowed now.
Returns
The status after this step.

◆ art_store_capacity()

uint32_t art_store_capacity ( const art_flash_t * f)

The most bytes a drawing may be for this partition to hold it.

Parameters
fFlash the store lives in.
Returns
The largest drawing in bytes.

◆ art_store_find()

bool art_store_find ( const art_flash_t * f,
uint16_t board,
art_entry_t * out )

What is kept for board, without reading the drawing itself.

False when nothing is, which includes a slot whose header did not survive being written. The header carries its own checksum, so a half-written one is not mistaken for a whole one.

Parameters
fFlash the store lives in.
boardBoard ID.
outReceives the entry.
Returns
true when a drawing is kept for board.

◆ art_store_forget()

bool art_store_forget ( const art_flash_t * f,
uint16_t board )

Forget what is kept for board.

True even when nothing was.

Parameters
fFlash the store lives in.
boardBoard ID.
Returns
true when nothing is kept for board afterwards.

◆ art_store_put()

bool art_store_put ( const art_flash_t * f,
uint16_t board,
const art_entry_t * entry,
const uint8_t * payload )

Keep payload for board, replacing anything kept for it already.

The payload is read back and checked before the header is written, so a slot only becomes findable once what is in it is known to be right. Returns false and leaves nothing findable for the board if any of that fails – including when it fails part way, which is what an unplugged board mid-transfer looks like.

Parameters
fFlash the store lives in.
boardBoard ID.
entryEntry describing the payload.
payloadPayload bytes.
Returns
true when the drawing is kept.

◆ art_store_read()

bool art_store_read ( const art_flash_t * f,
uint16_t board,
uint8_t * dst,
uint32_t cap )

Read the drawing for board into dst.

Checks the payload against the CRC and the hash the header carries, so a drawing that decayed in flash is a miss rather than a wrong drawing. False when there is nothing kept, when cap cannot hold it, or when it does not check out.

Parameters
fFlash the store lives in.
boardBoard ID.
dstBuffer to read the drawing into.
capSize of dst in bytes.
Returns
true when the drawing was read and checks out.

◆ art_store_read_same()

bool art_store_read_same ( const art_flash_t * f,
const art_entry_t * key,
uint8_t * dst,
uint32_t cap )

Read the drawing key describes into dst: only when the entry kept for key->board equals key in every field (art_entry_same()) and the payload checks out.

False for nothing kept, for another drawing kept under the same board, and for one that decayed – each a fetch, never a stale or wrong drawing.

Parameters
fFlash the store lives in.
keyEntry the kept drawing must equal.
dstBuffer to read the drawing into.
capSize of dst in bytes.
Returns
true when the drawing was read and checks out.

◆ art_store_slots()

uint32_t art_store_slots ( const art_flash_t * f)

How many drawings this partition has room for.

Parameters
fFlash the store lives in.
Returns
The number of slots.