ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_fs_seams.h File Reference

The two dependency-injection seams ra8_fs offers its callers. More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_fs_types.h"
Include dependency graph for ra8_fs_seams.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_fs_lock_t
 Dependency-injection seam for mutual exclusion around the public API. More...
struct  ra8_fs_clock_t
 Caller-supplied calendar source used to stamp files. More...

Functions

ra8_err_t ra8_fs_set_lock (const ra8_fs_lock_t *lock)
 Install (or remove) the lock taken around every public ra8_fs call.
ra8_err_t ra8_fs_set_clock (const ra8_fs_clock_t *clock)
 Install (or remove) the calendar source used to stamp files.

Detailed Description

The two dependency-injection seams ra8_fs offers its callers.

ra8_fs is written for a world with no scheduler and no calendar, and that stays its default. What this header adds is somewhere for a caller that HAS one to put it:

  • ra8_fs_set_lock installs the mutual exclusion taken around every public call, so an RTOS-world consumer does not have to wrap each call site by hand or ship a second filesystem to get a lock;
  • ra8_fs_set_clock installs the calendar the on-disk timestamps are stamped from, so a data logger's files carry a real date instead of the 1980 epoch this library falls back to.

Both are the same shape as ra8_fs_backend_t: a small struct of function pointers plus a caller-owned cookie, copied on install, with no primitive, no RTOS header and no clock driver named anywhere in this library. The adapters that bind tx_mutex_get or ra8_rtc_get() live with the caller that owns them.

They live in their own header because they are the parts of the API a caller wires ONCE at init and never touches again, and because ra8_fs.h – which describes the filesystem itself – had grown past the repository's 1000-line source cap carrying them. ra8_fs.h includes this file, so nothing a consumer includes changes.

Since
0.1.0

Definition in file ra8_fs_seams.h.

Function Documentation

◆ ra8_fs_set_clock()

ra8_err_t ra8_fs_set_clock ( const ra8_fs_clock_t * clock)
nodiscard

Install (or remove) the calendar source used to stamp files.

With no binding installed – the default – every timestamp ra8_fs writes is 1980-01-01 00:00:00, the first instant both FAT and exFAT can express. That is deliberate and is NOT the same as leaving the fields zero: a FAT date of 0 encodes month 0 and day 0, and both fields are 1-based, so it is not a calendar date at all. macOS (msdosfs) reads a zero date as uninitialised and shows 31 Dec 1969, Linux clamps the fields to 1 and shows 1980-01-01, and Windows shows a blank. No host agrees, and none of them is showing a time. Writing the epoch makes every host agree.

Installing a binding replaces the default for every subsequent stamp. A now that returns anything but k_ra8_ok falls back to the epoch for that stamp only – a clock that has not been set yet must not stop a data logger from writing.

The binding is COPIED, so one built as a compound literal or on the installing function's stack stays valid; the ctx cookie remains the caller's to keep alive.

Parameters
[in]clockBinding to install, or NULL to go back to the epoch default.
Returns
ra8_err_t Error code.
Return values
k_ra8_okBinding installed, or removed when clock was NULL.
k_ra8_err_invalid_argclock is non-NULL but its now is NULL.
Precondition
No filesystem operation is in flight (this is an init-time call).
clock, when non-NULL, has a now that does not itself call into ra8_fs.
Postcondition
On k_ra8_ok every later create/write/rename stamps from clock.
On k_ra8_err_invalid_arg the previously installed binding is unchanged.
Note
Not thread-safe; install before any concurrent filesystem use.
Warning
Timestamps already on disk are not revisited. Installing a clock affects later writes only.
See also
ra8_fs_clock_t
Since
0.1.0

Definition at line 611 of file ra8_fs_fat_time.c.

References k_ra8_err_invalid_arg, k_ra8_ok, ra8_fs_clock_t::now, s_clock, and s_clock_bound.

◆ ra8_fs_set_lock()

ra8_err_t ra8_fs_set_lock ( const ra8_fs_lock_t * lock)
nodiscard

Install (or remove) the lock taken around every public ra8_fs call.

There is one lock for the whole library, not one per mount: the state that needs serialising – the file-handle table, the mount table and the static scratch sector – is shared by every mount. Installing a lock therefore serialises every public entry point against every other one.

Passing NULL removes the binding and restores the default: no lock, no call, and the caller is once again responsible for serialising access. That is the state the library powers up in, so a bare-metal consumer never calls this function at all and pays nothing for its existence.

The binding is copied, so the caller's ra8_fs_lock_t need not outlive the call; the object ra8_fs_lock_t::ctx points at must, however, outlive every subsequent ra8_fs call.

Call this before the first ra8_fs call and before any other thread can reach the library: swapping the binding while a call is in flight would release a lock the caller never took.

Parameters
[in]lockLock binding to install, or NULL to remove the current one.
Returns
ra8_err_t Error code.
Return values
k_ra8_okBinding installed (or removed for a NULL lock).
k_ra8_err_invalid_arglock is non-NULL but acquire or release is NULL – a half-filled binding would leave the library holding a lock it cannot drop.
Precondition
No ra8_fs call is in flight on any thread.
When lock is non-NULL, both of its callbacks are non-NULL.
Postcondition
On k_ra8_ok with a non-NULL lock, every subsequent public call brackets itself with acquire / release.
On k_ra8_ok with a NULL lock, no callback is invoked again.
On k_ra8_err_invalid_arg the previous binding is unchanged.
Note
Not thread-safe with respect to itself; this is an init-time call.
Warning
Installing a lock does not make one open ra8_fs_file_t shareable between threads. It serialises the library, not a handle: two threads reading the same handle still race on its offset.
MC/DC:
Decision: if (lock->acquire == nullptr || lock->release == nullptr) – vectors live in tests/storage/src/test_ra8_fs_lock.c.
See also
ra8_fs_lock_t The binding this installs.
Since
0.1.0

Definition at line 92 of file ra8_fs_fat_lock.c.

References ra8_fs_lock_t::acquire, k_ra8_err_invalid_arg, k_ra8_ok, ra8_fs_lock_t::release, s_lock, and s_lock_installed.

Referenced by tx_application_define().