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

Keeping a board's drawing. More...

#include "art_store.h"
#include <stddef.h>
#include <string.h>
#include "link_crc.h"

Data Structures

struct  art_head_t

Macros

#define ART_MAGIC   0x61626372uL
#define ART_VERSION   2u

Enumerations

enum  {
  KEEP_IDLE = 0 , KEEP_ERASE , KEEP_WRITE , KEEP_VERIFY ,
  KEEP_HEAD
}

Functions

static uint16_t head_crc (const art_head_t *h)
 The checksum of a slot header, over the fields before it.
static bool usable (const art_flash_t *f)
 Whether the flash has the geometry the store needs.
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.
static bool slot_head (const art_flash_t *f, uint32_t i, art_head_t *out)
 The header of slot i, if it has one that checks out.
static uint32_t find_slot (const art_flash_t *f, uint16_t board)
 Which slot holds board, or the count when none does.
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_entry_same (const art_entry_t *a, const art_entry_t *b)
 Whether two entries describe the same payload: every field equal.
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.
static uint32_t slot_for (const art_flash_t *f, uint16_t board)
 A slot to put a drawing in: the board's own, else an empty one, else the first – something has to give, and a store this small is not worth an eviction policy nobody can predict.
static bool entry_fits (const art_flash_t *f, const art_entry_t *e)
 What art_store_put() and art_keep_begin() both refuse before anything is written: an entry this flash cannot hold, an empty payload, one with no format, or one with no outline.
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_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.
bool art_keep_busy (const art_keep_t *k)
 Whether k has a keep under way, waiting or not.
static bool keep_erase (art_keep_t *k)
 The first step chooses the slot, and erases its header with the same call's first sector.
static bool keep_write (art_keep_t *k)
 Write one sector of the payload.
static bool keep_verify (art_keep_t *k)
 Read back before the header is written.
static bool keep_head (art_keep_t *k)
 Write the slot header, the last step of a keep.
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_store_forget (const art_flash_t *f, uint16_t board)
 Forget what is kept for board.

Detailed Description

Keeping a board's drawing.

See art_store.h.

SPDX-License-Identifier: MIT

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.

◆ entry_fits()

bool entry_fits ( const art_flash_t * f,
const art_entry_t * e )
static

What art_store_put() and art_keep_begin() both refuse before anything is written: an entry this flash cannot hold, an empty payload, one with no format, or one with no outline.

What the payload says inside is the reader's to check (link_drawing_parse()); the store keeps bytes.

◆ keep_head()

bool keep_head ( art_keep_t * k)
static

Write the slot header, the last step of a keep.

Parameters
kKeep state.
Returns
true when the write succeeded.

◆ keep_verify()

bool keep_verify ( art_keep_t * k)
static

Read back before the header is written.

A write that reported success and did not take would otherwise be sealed with a header saying it did, and the store would hand out a corrupt drawing for as long as the board is known.

◆ keep_write()

bool keep_write ( art_keep_t * k)
static

Write one sector of the payload.

Parameters
kKeep state.
Returns
true when the write succeeded.

◆ usable()

bool usable ( const art_flash_t * f)
static

Whether the flash has the geometry the store needs.

Parameters
fFlash to check.
Returns
true when the store can use it.