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

Run log names on the card, and which entries a bounded list keeps. More...

#include <stdbool.h>
#include <stddef.h>

Go to the source code of this file.

Macros

#define LOG_RUN_FIRST   1
 The first and the last run number the panel writes.
#define LOG_RUN_LAST   999
#define LOG_RUN_NAME_MAX   13
 Room for the longest name, "SUPPL999.CSV" or "ATEST999.CSV", and its terminator.
#define LOG_PREFIX_WRITTEN   ((int)LOG_PREFIX_BENCH)
 How many prefixes this firmware writes: ATEST to SUPPL.
#define LOG_NAME_FORMS   (LOG_PREFIX_WRITTEN * 2)
 Every name a number written now can be carried by: each written prefix with ".CSV" and with ".TXT", 10 names.

Enumerations

enum  log_prefix_t {
  LOG_PREFIX_ATEST = 0 , LOG_PREFIX_LIMIT , LOG_PREFIX_SERVO , LOG_PREFIX_MOTOR ,
  LOG_PREFIX_SUPPL , LOG_PREFIX_BENCH , LOG_PREFIX_ESC , LOG_PREFIX_COUNT
}
 Which writer a run's name says made it. More...

Functions

void log_name_build (char *out, size_t out_size, log_prefix_t prefix, int number, bool report)
 Write the name of run number by writer prefix: "ATEST001.CSV", or with report its report "ATEST001.TXT".
log_prefix_t log_name_armed_prefix (bool asked, bool asked_throttle, bool throttle_armed)
 The writer of an ARMED run's log, by the screen that armed the bench.
void log_run_name (char *out, size_t out_size, int number)
 log_name_build() for LOG_PREFIX_BENCH: "BENCH001.CSV" to "BENCH999.CSV", the name firmware 0.21.0 and older gave a run in the root.
int log_run_number (const char *name)
 The run number in name, or -1 when the name is not a run log under any of the 7 prefixes.
void log_report_name (char *out, size_t out_size, int number)
 A run's report beside its log: "ATEST001.TXT", and "SERVO001.TXT" or "BENCH001.TXT" in the root of a card written by firmware 0.21.0 or older. log_report_number() reads any prefix, with the same rules for the number and the case as log_run_number(); log_report_name() is log_name_build() for LOG_PREFIX_BENCH with the report suffix.
int log_report_number (const char *name)
 Run number of a report name.
int log_name_number (const char *name)
 The number name takes from its folder's series: a run log's or a report's, under any of the 7 prefixes, or -1 for a name that takes none.
int log_name_parse (const char *name, log_prefix_t *prefix, bool *report)
 The writer, the kind and the number of a run log's or a report's name: "LIMIT004.TXT" is LOG_PREFIX_LIMIT, a report, 4.
void log_name_form (char *out, size_t out_size, int number, int form)
 Write the form'th of the LOG_NAME_FORMS names number number can be carried by, 0 to LOG_NAME_FORMS - 1: form / 2 is the written prefix and form % 2 the report.
int log_name_next (int highest)
 The first number a run may take on a card whose highest number, by log_name_number(), is highest (below LOG_RUN_FIRST for a card that holds none): one above it.
void log_name_report_of (char *out, size_t out_size, const char *run_name)
 Write the report that goes with run log run_name: the same prefix and number, ".TXT", in upper case.
bool log_name_busy (const char *name, unsigned open_run, unsigned open_test, unsigned open_txt)
 Whether name is a file the logger is still writing, or one whose deletion would remove such a file: a run log whose number is open_run (the armed or supply run), open_test (an AUTOMATIC TEST's CSV) or open_txt (a test's or a limit run's report, which a deleted run takes with it), or a report whose number is open_txt. 0 is no file open.
int log_name_case_cmp (const char *a, const char *b)
 Compare two names with case folded: negative when a sorts first, as the browse list orders what it draws.
int log_name_rank (const char *a, const char *b)
 Order two listed names by which one a full list keeps.

Detailed Description

Run log names on the card, and which entries a bounded list keeps.

A run is written under the name of what started it and a number from 001 to 999, in one of two folders (card_tree.h):

BENCH/LOGS, the automatic logs (AUTO LOGS on SETUP > SD CARD): SERVOnnn.CSV an ARMED run armed on the SERVO screen; MOTORnnn.CSV an ARMED run armed on MOTOR & ESC, ESC STICK included; SUPPLnnn.CSV a switch-on of the SUPPLY output while SAFE. USER/LOGS, the tests a user starts (USER LOGS on SETUP > SD CARD): ATESTnnn.CSV the AUTOMATIC TEST, with its report ATESTnnn.TXT; LIMITnnn.TXT a LIMIT RUN's report, alone.

Which screen armed the bench is read off the roles the arm asked for (log_name_armed_prefix()): MOTOR & ESC and ESC STICK ask for the throttle, SERVO for the surfaces. An arm with no roles recorded is a MOTOR run while the throttle outputs are armed and a SERVO run otherwise.

Firmware 0.21.0 and older wrote every run to the card's root as BENCHnnn, ESCnnn and SERVOnnn (a servo test, with SERVOnnn.TXT, or a limit run's SERVOnnn.TXT alone). Those names stay readable: their numbers rank, a deleted BENCHnnn.CSV or SERVOnnn.CSV takes its report, and a folder that holds them numbers above them. SERVOnnn.CSV therefore means a servo test in the root and an ARMED run armed on SERVO in BENCH/LOGS.

Every name is a FAT (File Allocation Table) 8.3 name: at most 8 characters, a dot and 3. The numbers are one series per folder, across every prefix, so a number names one run in a folder whichever writer made it. The panel takes one above the highest number the folder already holds under any prefix, so a higher number is a later run without exception – a gap left by a deleted file is not filled, because a run written into one would be the newest run wearing the oldest number and would rank last in a full list. A folder holding a number 999 under any prefix takes no further run.

Nothing else about an entry's age is reliable on this bench. The board carries no clock that survives a power cycle: until NTP sets it on the home network (wall_clock.h), a file the panel writes is dated 1980 in the FAT directory – the year the filesystem clamps an unset clock to – and directory order is creation order only until a file is deleted and its slot filled again. The number in the name is the only age every file has.

Both ends of that rule are here: the logger builds a name with log_name_build(), the viewer reads the number back with log_run_number(), and log_name_rank() orders a listing when a folder holds more entries than the screen has room for.

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

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ LOG_NAME_FORMS

#define LOG_NAME_FORMS   (LOG_PREFIX_WRITTEN * 2)

Every name a number written now can be carried by: each written prefix with ".CSV" and with ".TXT", 10 names.

A number is taken while any of them is in the folder; the numbering walk reads all 7 prefixes.

Enumeration Type Documentation

◆ log_prefix_t

Which writer a run's name says made it.

The first LOG_PREFIX_WRITTEN are the names this firmware writes; BENCH and ESC are read and never written.

Enumerator
LOG_PREFIX_ATEST 

"ATEST": the AUTOMATIC TEST

LOG_PREFIX_LIMIT 

"LIMIT": a LIMIT RUN's report

LOG_PREFIX_SERVO 

"SERVO": ARMED on SERVO; in the root, a servo test of firmware 0.21.0 and older

LOG_PREFIX_MOTOR 

"MOTOR": ARMED on MOTOR & ESC or ESC STICK

LOG_PREFIX_SUPPL 

"SUPPL": the SUPPLY output on while SAFE

LOG_PREFIX_BENCH 

"BENCH": firmware 0.21.0 and older

LOG_PREFIX_ESC 

"ESC": firmware 0.21.0 and older

Function Documentation

◆ log_name_armed_prefix()

log_prefix_t log_name_armed_prefix ( bool asked,
bool asked_throttle,
bool throttle_armed )

The writer of an ARMED run's log, by the screen that armed the bench.

asked: the arm recorded the roles it asked for (arming_roles() is not 0). asked_throttle: those roles hold the throttle, as MOTOR & ESC and ESC STICK ask for; SERVO asks for the surfaces alone. An arm that asked is LOG_PREFIX_MOTOR or LOG_PREFIX_SERVO by asked_throttle, whatever an IOmcu older than protocol 4.18 armed beside them. An arm with nothing recorded is LOG_PREFIX_MOTOR while throttle_armed and LOG_PREFIX_SERVO otherwise. A supply run is LOG_PREFIX_SUPPL.

Parameters
askedThe arm recorded the roles it asked for.
asked_throttleThose roles hold the throttle.
throttle_armedThe throttle outputs are armed.
Returns
The writer prefix.

◆ log_name_build()

void log_name_build ( char * out,
size_t out_size,
log_prefix_t prefix,
int number,
bool report )

Write the name of run number by writer prefix: "ATEST001.CSV", or with report its report "ATEST001.TXT".

A number outside LOG_RUN_FIRST to LOG_RUN_LAST, a prefix outside the table, or an out_size under LOG_RUN_NAME_MAX, writes an empty string rather than a name that would name a different file.

Parameters
outReceives the name.
out_sizeSize of out, bytes.
prefixThe writer.
numberThe run number.
reporttrue for the ".TXT" report, false for the ".CSV" log.

◆ log_name_busy()

bool log_name_busy ( const char * name,
unsigned open_run,
unsigned open_test,
unsigned open_txt )

Whether name is a file the logger is still writing, or one whose deletion would remove such a file: a run log whose number is open_run (the armed or supply run), open_test (an AUTOMATIC TEST's CSV) or open_txt (a test's or a limit run's report, which a deleted run takes with it), or a report whose number is open_txt. 0 is no file open.

The numbers are one series in a folder, so the prefix does not enter into it; the caller passes 0 for a file open in another folder (log_marks_busy() in log_take.h).

Parameters
nameThe file name.
open_runNumber of the open armed or supply run, or 0.
open_testNumber of the open AUTOMATIC TEST CSV, or 0.
open_txtNumber of the open report, or 0.
Returns
true when the file is busy.

◆ log_name_case_cmp()

int log_name_case_cmp ( const char * a,
const char * b )

Compare two names with case folded: negative when a sorts first, as the browse list orders what it draws.

A card written on a computer holds "bench042.csv" and one written here holds "BENCH042.CSV", and the two are one file.

Parameters
aThe first name.
bThe second name.
Returns
Negative, zero or positive as a sorts before, with or after b.

◆ log_name_form()

void log_name_form ( char * out,
size_t out_size,
int number,
int form )

Write the form'th of the LOG_NAME_FORMS names number number can be carried by, 0 to LOG_NAME_FORMS - 1: form / 2 is the written prefix and form % 2 the report.

An empty string for a form or a number outside them. The logger probes each before it takes a number.

Parameters
outReceives the name.
out_sizeSize of out, bytes.
numberThe run number.
formIndex of the name, 0 to LOG_NAME_FORMS - 1.

◆ log_name_next()

int log_name_next ( int highest)

The first number a run may take on a card whose highest number, by log_name_number(), is highest (below LOG_RUN_FIRST for a card that holds none): one above it.

Above LOG_RUN_LAST when the card holds 999: the card is full, and a lower free number is not taken.

Parameters
highestThe highest number the card holds.
Returns
The first number a run may take.

◆ log_name_number()

int log_name_number ( const char * name)

The number name takes from its folder's series: a run log's or a report's, under any of the 7 prefixes, or -1 for a name that takes none.

What the numbering walk reads.

Parameters
nameThe file name.
Returns
The number, or -1.

◆ log_name_parse()

int log_name_parse ( const char * name,
log_prefix_t * prefix,
bool * report )

The writer, the kind and the number of a run log's or a report's name: "LIMIT004.TXT" is LOG_PREFIX_LIMIT, a report, 4.

The same rules for the number and the case as log_run_number().

Parameters
nameThe name to read.
prefixTakes the writer's prefix; may be NULL.
reportTakes true for a ".TXT" report, false for a ".CSV" log; may be NULL.
Returns
The number, LOG_RUN_FIRST to LOG_RUN_LAST, or -1 for a name that is neither; then prefix and report are left as they were.

◆ log_name_rank()

int log_name_rank ( const char * a,
const char * b )

Order two listed names by which one a full list keeps.

Negative when a is kept ahead of b, positive when b is. Runs come first, by number, the newest first, whichever writer made them: MOTOR043.CSV ranks ahead of SERVO042.CSV. A report ranks by its number as a run does (log_name_number()), so LIMIT044.TXT, a limit run's only file, ranks ahead of MOTOR043.CSV. An operator opening a log is almost always after a recent one, and a run is the only entry whose age is known. Everything else follows the runs by name, case folded.

The order is strict: zero only for one name, compared with case folded (log_name_case_cmp()). Two names with one number, a run and its report or, on a card edited on a computer, two runs under different prefixes, follow by name: ATEST042.CSV, then ATEST042.TXT, then MOTOR042.CSV. Paging needs that (log_select.h): a name that ranked equal to a page's edge would be on neither side of it.

A card holding as many runs as a page has room for therefore leaves no room on the first page for a file the bench did not write; the browse panel says how many entries the card holds.

Parameters
aA name; NULL ranks as "".
bA name; NULL ranks as "".
Returns
Negative when a ranks ahead, positive when b does, 0 for one name.

◆ log_name_report_of()

void log_name_report_of ( char * out,
size_t out_size,
const char * run_name )

Write the report that goes with run log run_name: the same prefix and number, ".TXT", in upper case.

An empty string when run_name is not a run log. Deleting a run deletes this file with it.

Parameters
outReceives the name.
out_sizeSize of out, bytes.
run_nameThe run log's file name.

◆ log_report_name()

void log_report_name ( char * out,
size_t out_size,
int number )

A run's report beside its log: "ATEST001.TXT", and "SERVO001.TXT" or "BENCH001.TXT" in the root of a card written by firmware 0.21.0 or older. log_report_number() reads any prefix, with the same rules for the number and the case as log_run_number(); log_report_name() is log_name_build() for LOG_PREFIX_BENCH with the report suffix.

A number belongs to a run while either file carries it: the logger takes one above both, so a report whose CSV was deleted is never overwritten by the next run's.

Parameters
outReceives the name.
out_sizeSize of out, bytes.
numberThe run number.

◆ log_report_number()

int log_report_number ( const char * name)

Run number of a report name.

Parameters
nameThe file name.
Returns
The run number, or -1 when the name is not a report.

◆ log_run_name()

void log_run_name ( char * out,
size_t out_size,
int number )

log_name_build() for LOG_PREFIX_BENCH: "BENCH001.CSV" to "BENCH999.CSV", the name firmware 0.21.0 and older gave a run in the root.

Parameters
outReceives the name.
out_sizeSize of out, bytes.
numberThe run number.

◆ log_run_number()

int log_run_number ( const char * name)

The run number in name, or -1 when the name is not a run log under any of the 7 prefixes.

Case is ignored, so a card taken to a computer and written back in lower case still lists in run order. The name has to be one of the prefixes, exactly three digits in range, and the suffix, with nothing after it: "BENCH12.CSV", "BENCH000.CSV", "SERVO001.CSV.BAK" and "ESCAPE01.CSV" are not run logs.

Parameters
nameThe file name.
Returns
The run number, or -1.