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

The file manager's jobs on the card: copy, move, rename, delete, make a folder, make an empty file, save a text and load a file, one step at a time. More...

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "fm_io.h"
#include "fm_rules.h"

Go to the source code of this file.

Data Structures

struct  fm_job_t
 One job. The fields are the job's; the screen reads them through fm_job_state(). More...

Macros

#define FM_CHUNK   16384u
 The chunk the panel copies, saves and loads in: 16KiB.

Typedefs

typedef size_t(*) fm_fill_fn(void *ctx, uint64_t at, uint8_t *dst, size_t cap)
 The bytes a save writes, asked for one chunk at a time.

Enumerations

enum  fm_job_kind_t {
  FM_JOB_NONE = 0 , FM_JOB_COPY , FM_JOB_MOVE , FM_JOB_RENAME ,
  FM_JOB_DELETE , FM_JOB_MKDIR , FM_JOB_CREATE , FM_JOB_SAVE ,
  FM_JOB_LOAD
}
 What a job does.
enum  fm_job_state_t {
  FM_JOB_IDLE = 0 , FM_JOB_RUNNING , FM_JOB_DONE , FM_JOB_STOPPED ,
  FM_JOB_FAILED
}
 Where a job stands. More...

Functions

fm_err_t fm_job_copy (fm_job_t *job, const fm_bench_t *bench, unsigned mount, const char *src_dir, const char *name, const char *dst_dir)
 Copy file name of folder src_dir into folder dst_dir under the same name.
fm_err_t fm_job_move (fm_job_t *job, const fm_bench_t *bench, unsigned mount, const char *src_dir, const char *name, bool is_dir, const char *dst_dir)
 Move file or empty folder name of src_dir into dst_dir.
fm_err_t fm_job_rename (fm_job_t *job, const fm_bench_t *bench, unsigned mount, const char *dir, const char *name, bool is_dir, const char *new_name)
 Give entry name of folder dir the name new_name.
fm_err_t fm_job_delete (fm_job_t *job, const fm_bench_t *bench, unsigned mount, const char *dir, const char *name, bool is_dir)
 Delete file or empty folder name of folder dir.
fm_err_t fm_job_mkdir (fm_job_t *job, const fm_bench_t *bench, unsigned mount, const char *dir, const char *name)
 Make folder name in folder dir.
fm_err_t fm_job_create (fm_job_t *job, const fm_bench_t *bench, unsigned mount, const char *dir, const char *name)
 Make the empty file name in folder dir.
fm_err_t fm_job_save (fm_job_t *job, const fm_bench_t *bench, unsigned mount, const char *dir, const char *name, uint64_t len, fm_fill_fn fill, void *fill_ctx)
 Write len bytes from fill as file name of folder dir, through "<name>.NEW" (the file's comment).
fm_err_t fm_job_load (fm_job_t *job, const fm_bench_t *bench, unsigned mount, const char *dir, const char *name, uint8_t *buf, size_t cap)
 Read file name of folder dir into buf. A read: the gate does not stop it.
fm_job_state_t fm_job_step (fm_job_t *job, const fm_io_t *io, const fm_bench_t *bench, uint8_t *chunk, size_t size)
 Run the job's next step.
void fm_job_cancel (fm_job_t *job)
 Ask the job to stop at its next chunk. A single call that has started finishes.
fm_job_state_t fm_job_state (const fm_job_t *job, uint64_t *done, uint64_t *total)
 Where the job stands.

Detailed Description

The file manager's jobs on the card: copy, move, rename, delete, make a folder, make an empty file, save a text and load a file, one step at a time.

A job is started by one of the fm_job_*() calls, which check what can be checked without the card: the arguments, the write gate and the places (fm_rules.h), and the names a path and a ".NEW" need. Nothing is read or written until fm_job_step(), which a task of its own calls until the job is no longer FM_JOB_RUNNING: one step is one call of the card, or a few short ones, or one chunk of a copy, a save or a load. The screen reads fm_job_state() for the progress box.

Every overwrite is refused: FAT (File Allocation Table) renames over no name, and no job of the file manager replaces a file it did not write. A target name that is taken is FM_ERR_EXISTS, and so is a ".NEW" of the target that is there already: it can be the only whole copy of a save that was cut short.

COPY writes "<name>.NEW" in the target folder in chunks, puts it on the card (sync) and gives it its name. A copy stopped part way, by CANCEL, by the gate or by a failure, closes both files and removes its ".NEW"; the source is never written.

SAVE is the servo programmer's journal pattern: write "<name>.NEW", sync, close, delete "<name>", rename "<name>.NEW" to "<name>". A "<name>" that was not there when the save opened its ".NEW" is never deleted: one that is there by the rename was made by someone else, and the save fails with FM_ERR_EXISTS, the ".NEW" kept and listed. Between the delete and the rename only "<name>.NEW" holds the text: a card pulled or a power cut there leaves "<name>.NEW" whole and "<name>" gone, and the next listing shows "<name>.NEW" for a RENAME. A rename that fails there keeps "<name>.NEW" for the same reason. A failure before the delete removes "<name>.NEW" and leaves "<name>" as it was.

The rules (fm_allowed(): the write gate, the place, the IOmcu link and the logger's files) are asked again as the job runs, with the bench as fm_job_step() is handed it. A MOVE, RENAME, DELETE or NEW asks them once more right before its single call: queued while SAFE and run once the bench is ARMED or a log is open, it fails (FM_JOB_FAILED) with the refusal and changes nothing. A copy, a save or a load asks before its files are opened and before every chunk: a bench switched to ARMED, a log run opened, or the IOmcu link gone while the fault log is copied stops it there (FM_JOB_STOPPED: FM_ERR_ARMED, FM_ERR_LOGGING, FM_ERR_BUSY), as CANCEL does (FM_ERR_CANCELLED). A single call that has started, and the end of a copy or a save (sync, close, rename), finish. MOVE, RENAME and DELETE find the entry as the kind it was listed as, or refuse with FM_ERR_ARG: a file listed that is a folder now was never asked about as a folder.

A job runs on the mount its names were listed from (fm_io.h hold()): on another card it fails with FM_ERR_CARD_GONE and writes nothing. A card pulled part way fails the job with FM_ERR_CARD_GONE; a ".NEW" written so far stays on that card.

DELETE of a run's log takes its report with it, as LOGS' DELETE does: ATEST042.CSV takes ATEST042.TXT (log_name_report_of()). A report that cannot be deleted fails the job with the card's answer, the log gone and the report there; the caller reads the folder again. A folder is moved or deleted only when it is empty.

Pure C, no ESP-IDF (Espressif Internet-of-Things Development Framework).

SPDX-License-Identifier: MIT

Typedef Documentation

◆ fm_fill_fn

typedef size_t(*) fm_fill_fn(void *ctx, uint64_t at, uint8_t *dst, size_t cap)

The bytes a save writes, asked for one chunk at a time.

Parameters
ctxthe caller's context
atthe offset of the first byte wanted
dsttakes the bytes
caproom in dst
Returns
the bytes written into dst, 0 only past the text's end

Enumeration Type Documentation

◆ fm_job_state_t

Where a job stands.

Enumerator
FM_JOB_IDLE 

no job started

FM_JOB_RUNNING 

fm_job_step() has more to do

FM_JOB_DONE 

finished

FM_JOB_STOPPED 

stopped by CANCEL or the gate: err says which

FM_JOB_FAILED 

refused or failed: err says why

Function Documentation

◆ fm_job_cancel()

void fm_job_cancel ( fm_job_t * job)

Ask the job to stop at its next chunk. A single call that has started finishes.

Parameters
jobthe job

◆ fm_job_copy()

fm_err_t fm_job_copy ( fm_job_t * job,
const fm_bench_t * bench,
unsigned mount,
const char * src_dir,
const char * name,
const char * dst_dir )

Copy file name of folder src_dir into folder dst_dir under the same name.

Parameters
jobthe job
benchthe gate and the rules; may be NULL
mountthe mount the names were listed from
src_dirthe source's folder
namethe file's name
dst_dirthe target folder
Returns
FM_OK when the job runs; else the refusal, which the job holds as FM_JOB_FAILED: FM_ERR_ARG, FM_ERR_ARMED, FM_ERR_LOGGING, FM_ERR_BUSY, FM_ERR_LOCKED, FM_ERR_FIXED, FM_ERR_SAME for one folder, FM_ERR_NAME

◆ fm_job_create()

fm_err_t fm_job_create ( fm_job_t * job,
const fm_bench_t * bench,
unsigned mount,
const char * dir,
const char * name )

Make the empty file name in folder dir.

Parameters
jobthe job
benchthe gate and the rules; may be NULL
mountthe mount the folder was listed from
dirthe folder to make it in
namethe new file's name
Returns
FM_OK, or the refusal

◆ fm_job_delete()

fm_err_t fm_job_delete ( fm_job_t * job,
const fm_bench_t * bench,
unsigned mount,
const char * dir,
const char * name,
bool is_dir )

Delete file or empty folder name of folder dir.

Parameters
jobthe job
benchthe gate and the rules; may be NULL
mountthe mount the names were listed from
dirthe folder
namethe entry's name
is_dirthe entry is a folder
Returns
FM_OK, or the refusal

◆ fm_job_load()

fm_err_t fm_job_load ( fm_job_t * job,
const fm_bench_t * bench,
unsigned mount,
const char * dir,
const char * name,
uint8_t * buf,
size_t cap )

Read file name of folder dir into buf. A read: the gate does not stop it.

Parameters
jobthe job
benchthe rules; may be NULL
mountthe mount the file was listed from
dirthe file's folder
namethe file's name
buftakes the bytes
caproom in buf; a larger file is FM_ERR_TOO_BIG
Returns
FM_OK, or the refusal

◆ fm_job_mkdir()

fm_err_t fm_job_mkdir ( fm_job_t * job,
const fm_bench_t * bench,
unsigned mount,
const char * dir,
const char * name )

Make folder name in folder dir.

Parameters
jobthe job
benchthe gate and the rules; may be NULL
mountthe mount the folder was listed from
dirthe folder to make it in
namethe new folder's name
Returns
FM_OK, or the refusal

◆ fm_job_move()

fm_err_t fm_job_move ( fm_job_t * job,
const fm_bench_t * bench,
unsigned mount,
const char * src_dir,
const char * name,
bool is_dir,
const char * dst_dir )

Move file or empty folder name of src_dir into dst_dir.

Parameters
jobthe job
benchthe gate and the rules; may be NULL
mountthe mount the names were listed from
src_dirthe source's folder
namethe entry's name
is_dirthe entry is a folder
dst_dirthe target folder
Returns
FM_OK, or the refusal as fm_job_copy(); FM_ERR_SAME also for a folder moved into itself

◆ fm_job_rename()

fm_err_t fm_job_rename ( fm_job_t * job,
const fm_bench_t * bench,
unsigned mount,
const char * dir,
const char * name,
bool is_dir,
const char * new_name )

Give entry name of folder dir the name new_name.

A change of case alone is a rename of one entry, not an overwrite.

Parameters
jobthe job
benchthe gate and the rules; may be NULL
mountthe mount the names were listed from
dirthe folder
namethe entry's name now
is_dirthe entry is a folder
new_nameits new name
Returns
FM_OK, or the refusal; FM_ERR_ARG for the same name

◆ fm_job_save()

fm_err_t fm_job_save ( fm_job_t * job,
const fm_bench_t * bench,
unsigned mount,
const char * dir,
const char * name,
uint64_t len,
fm_fill_fn fill,
void * fill_ctx )

Write len bytes from fill as file name of folder dir, through "<name>.NEW" (the file's comment).

Parameters
jobthe job
benchthe gate and the rules; may be NULL
mountthe mount the file was read from
dirthe file's folder
namethe file's name; it need not be there yet
lenthe text's bytes
fillhands over the bytes
fill_ctxpassed to fill
Returns
FM_OK, or the refusal

◆ fm_job_state()

fm_job_state_t fm_job_state ( const fm_job_t * job,
uint64_t * done,
uint64_t * total )

Where the job stands.

Parameters
jobthe job; NULL is FM_JOB_IDLE
donetakes the bytes done; may be NULL
totaltakes the bytes to do; may be NULL
Returns
its state

◆ fm_job_step()

fm_job_state_t fm_job_step ( fm_job_t * job,
const fm_io_t * io,
const fm_bench_t * bench,
uint8_t * chunk,
size_t size )

Run the job's next step.

Parameters
jobthe job
iothe card
benchthe gate as it stands now; may be NULL
chunkroom for one chunk of a copy, a save or a load
sizebytes chunk takes; FM_CHUNK on the panel
Returns
the job's state after the step