35typedef enum : uint8_t {
45typedef enum : uint16_t {
52typedef enum : uint32_t {
103 portable.
valid =
true;
112 uint16_t length = 0U;
113 while (length < cap) {
114 if (text[length] ==
'\0') {
134 uint16_t cursor = 0U;
135 for (uint16_t i = 0U; i < mount_len; ++i) {
141 for (uint16_t i = 0U; i <= path_len; ++i) {
142 out[cursor] = path[i];
203 uint8_t native_align)
205 const uintptr_t base = (uintptr_t)directory_state;
207 const uintptr_t cursor = (base + cursor_align - 1U) & ~(cursor_align - 1U);
209 const uintptr_t align = (uintptr_t)native_align;
210 const uintptr_t native = (cursor_end + align - 1U) & ~(align - 1U);
212 .workspace = (
void*)native,
213 .cursor_end = (size_t)(cursor_end - base),
214 .consumed = (size_t)(native - base)};
244 if ((uint64_t)state_bytes < (uint64_t)layout.
cursor_end) {
253 if (layout.
consumed > (
size_t)state_bytes) {
262 state_bytes - (uint32_t)layout.
consumed);
334 .name_bytes = length,
338 bool keep_going =
true;
350 uint32_t max_entries,
362 .callback_ctx = callback_ctx,
363 .max_entries = max_entries,
366 *out_count = bridge.
count;
367 *out_complete = !bridge.
stopped;
380 return operation(state->
path_a);
458 uint32_t state_bytes)
474 file->native =
nullptr;
480internal_read(
void* ctx,
void* file_state, uint8_t* dst, uint32_t cap, uint32_t* out_read)
484 return ra8_fs_read(file->native, dst, cap, out_read);
489internal_write(
void* ctx,
void* file_state,
const uint8_t* src, uint32_t len, uint32_t* out_written)
530 file->native =
nullptr;
539 if (path[i] ==
'\0') {
561 static const char digits[] =
"0123456789ABCDEF";
563 const uint8_t shift =
572 uint16_t last_slash = 0U;
573 uint16_t length = 0U;
575 const char value = destination[length];
591 for (uint16_t i = 0U; i <= last_slash; ++i) {
592 out[i] = destination[i];
594 uint16_t cursor = (uint16_t)(last_slash + 1U);
661 void* transaction_state,
662 uint32_t state_bytes,
663 const char* destination,
678 if (destination_stat.
exists) {
682 (void)
memset(txn, 0,
sizeof(*txn));
693 void* transaction_state,
696 uint32_t* out_written)
725 void* transaction_state,
750 const ra8_err_t checked = validator(validator_ctx, &staged);
769 *out_published =
true;
834 uint16_t length = 0U;
836 const char value = name[length];
854 for (uint16_t i = 0U; i <= length; ++i) {
881 uint16_t* out_max_open)
887 uint32_t native_bytes = 0U;
888 uint8_t native_align = 0U;
896 const uint64_t total =
898 if (total > (uint64_t)UINT32_MAX) {
904 *out_bytes = (uint32_t)total;
905 *out_align = outer_align;
927 uint32_t directory_bytes,
928 uint8_t directory_alignment,
929 uint16_t max_directories)
940 .directory_workspace_bytes = directory_bytes,
946 .max_open_directories = max_directories,
948 .directory_workspace_align = directory_alignment,
962 if (out ==
nullptr) {
965 if (state ==
nullptr) {
968 if (cfg ==
nullptr) {
974 if (cfg->
mount ==
nullptr) {
980 (void)
memset(state, 0,
sizeof(*state));
987 uint32_t directory_bytes = 0U;
988 uint16_t max_directories = 0U;
989 uint8_t directory_alignment = 0U;
992 if (directory_requirements !=
k_ra8_ok) {
993 return directory_requirements;
static uint32_t internal_read(void)
Read current GPT counter ticks, or return UINT32_MAX on err.
Architecture-neutral filesystem namespace, stream, and transaction ports.
ra8_err_t fw_fs_close(fw_fs_file_t *file)
Close and consume an open handle.
Backend-author interface for binding concrete filesystem ports.
ra8_err_t fw_fs_bind(fw_fs_t *out, const fw_fs_namespace_iface_t *namespace_iface, const fw_fs_stream_iface_t *stream_iface, const fw_fs_transaction_iface_t *transaction_iface, void *ctx, const fw_fs_caps_t *caps)
Bind segregated vtables and one context into a complete facade.
static ra8_err_t internal_stage_path(const char *destination, uint32_t id, char *out)
static void internal_hex6(char out[k_vfs_stage_hex_digits], uint32_t value)
Render a fixed-width six-digit hexadecimal transaction id.
vfs_numeric_limits_t
Timestamp and transaction arithmetic constants.
@ k_vfs_transaction_id_mask
Six hexadecimal digits.
@ k_vfs_nanoseconds_per_centisecond
Nanoseconds in 0.01 s.
ra8_err_t fw_fs_ra8_vfs_init(fw_fs_t *out, fw_fs_ra8_vfs_state_t *state, const fw_fs_ra8_vfs_cfg_t *cfg)
Bind a live named VFS mount into the portable filesystem facade.
static ra8_err_t internal_txn_commit(void *ctx, void *transaction_state, bool *out_published)
static void internal_list_entry(const char *name, uint8_t attr, uint64_t size, void *ctx)
Translate one format-list callback into the legacy bounded facade.
static ra8_err_t internal_seek(void *ctx, void *file_state, uint64_t offset)
vfs_path_limits_t
Portable-path limits exposed by the FAT/exFAT adapter.
@ k_vfs_fat_name_max_bytes
FAT LFN component byte cap.
@ k_vfs_stage_leaf_bytes
TX + six hex digits + .TMP.
@ k_vfs_exfat_name_max_bytes
exFAT component byte cap.
static ra8_err_t internal_txn_begin(void *ctx, void *transaction_state, uint32_t state_bytes, const char *destination, fw_fs_transaction_policy_t policy)
static const fw_fs_namespace_iface_t s_namespace_iface
Immutable firmware namespace vtable.
static ra8_err_t internal_rename(void *ctx, const char *old_path, const char *new_path, bool replace)
static vfs_directory_state_t * internal_dir_cursor(void *directory_state)
Round a caller directory-state span up to the cursor's alignment.
vfs_stage_limits_t
Bounded attempts to find an unused short staging name.
@ k_vfs_stage_hex_digits
Hex digits in a stage identifier.
@ k_vfs_hex_last_digit
Highest valid index in a stage identifier.
@ k_vfs_hex_nibble_bits
Bits represented by one hex digit.
@ k_vfs_stage_attempts
Collision-search cap.
@ k_vfs_hex_nibble_mask
Low-nibble mask.
static ra8_err_t internal_full_path(fw_fs_ra8_vfs_state_t *state, const char *path, char *out)
static ra8_err_t internal_stage_open(fw_fs_ra8_vfs_state_t *state, vfs_transaction_state_t *txn)
Open an unused VFS staging file after a bounded collision search.
static ra8_err_t internal_space(void *ctx, fw_fs_space_t *out)
static ra8_err_t internal_txn_validate(void *ctx, void *transaction_state, fw_fs_validate_fn_t validator, void *validator_ctx)
static ra8_err_t internal_write(void *ctx, void *file_state, const uint8_t *src, uint32_t len, uint32_t *out_written)
static ra8_err_t internal_dir_close(void *ctx, void *directory_state)
static ra8_err_t internal_read(void *ctx, void *file_state, uint8_t *dst, uint32_t cap, uint32_t *out_read)
static uint16_t internal_len(const char *text, uint16_t cap)
static ra8_err_t internal_close(void *ctx, void *file_state)
static ra8_err_t internal_path_op(void *ctx, const char *path, ra8_err_t(*operation)(const char *))
One-path VFS dispatch helper.
static vfs_dir_layout_t internal_dir_layout(void *directory_state, uint8_t native_align)
Derive both aligned bases inside a caller directory-state span.
static ra8_err_t internal_mkdir(void *ctx, const char *path)
static ra8_err_t internal_listdir(void *ctx, const char *path, uint32_t max_entries, fw_fs_list_fn_t callback, void *callback_ctx, uint32_t *out_count, bool *out_complete)
static const fw_fs_transaction_iface_t s_transaction_iface
Immutable firmware transaction vtable.
static ra8_err_t internal_txn_abort(void *ctx, void *transaction_state)
static const fw_fs_stream_iface_t s_stream_iface
Immutable firmware stream vtable.
static ra8_err_t internal_txn_seek(void *ctx, void *transaction_state, uint64_t offset)
static ra8_err_t internal_copy_path(char *out, const char *path)
static fw_fs_caps_t internal_capabilities(const fw_fs_ra8_vfs_cfg_t *cfg, uint32_t directory_bytes, uint8_t directory_alignment, uint16_t max_directories)
Compose the portable capability record for one mounted VFS format.
static ra8_err_t internal_rmdir(void *ctx, const char *path)
static ra8_err_t internal_mount_name(fw_fs_ra8_vfs_state_t *state, const char *name)
static ra8_err_t internal_size(void *ctx, void *file_state, uint64_t *out_size)
static ra8_err_t internal_txn_write(void *ctx, void *transaction_state, const uint8_t *src, uint32_t len, uint32_t *out_written)
static ra8_err_t internal_mode(fw_fs_open_mode_t mode, ra8_fs_mode_t *out)
static ra8_err_t internal_tell(void *ctx, void *file_state, uint64_t *out_offset)
static fw_fs_timestamp_t internal_timestamp(const ra8_fs_timestamp_t *native)
static ra8_err_t internal_unlink(void *ctx, const char *path)
static ra8_err_t internal_dir_next(void *ctx, void *directory_state, fw_fs_dirent_value_t *out, bool *out_entry)
static ra8_err_t internal_dir_requirements(fw_fs_ra8_vfs_state_t *state, uint32_t *out_bytes, uint8_t *out_align, uint16_t *out_max_open)
Query the named format and compose aligned adapter cursor requirements.
static ra8_err_t internal_dir_open(void *ctx, const char *path, void *directory_state, uint32_t state_bytes)
static ra8_err_t internal_stat(void *ctx, const char *path, fw_fs_stat_t *out)
static ra8_err_t internal_open(void *ctx, const char *path, fw_fs_open_mode_t mode, void *file_state, uint32_t state_bytes)
Firmware filesystem-port adapter over ra8_io_vfs and ra8_fs.
File-local contracts for the firmware VFS filesystem adapter.
@ k_fw_fs_node_none
No node exists at the path.
@ k_fw_fs_node_directory
Directory.
@ k_fw_fs_node_file
Regular byte stream.
struct fw_fs_stream_iface fw_fs_stream_iface_t
struct fw_fs_transaction_iface fw_fs_transaction_iface_t
ra8_err_t(* fw_fs_validate_fn_t)(void *ctx, fw_fs_file_t *staged)
Validate staged bytes through a read-only generic file handle.
@ k_fw_fs_path_cap
Largest portable path including its NUL.
struct fw_fs_namespace_iface fw_fs_namespace_iface_t
fw_fs_open_mode_t
Open intent for fw_fs_open.
@ k_fw_fs_open_append
Create/append, write-only.
@ k_fw_fs_open_read
Existing file, read-only.
@ k_fw_fs_open_write_truncate
Create/truncate, write-only.
ra8_err_t(* fw_fs_list_fn_t)(void *ctx, const fw_fs_dirent_t *entry, bool *out_continue)
Bounded list callback.
fw_fs_transaction_policy_t
Destination policy for a staged transaction.
@ k_fw_fs_txn_create_new
Commit only when destination is absent.
@ k_fw_fs_cap_stream
Regular-file stream operations are available.
@ k_fw_fs_cap_namespace
Metadata and namespace operations are available.
@ k_fw_fs_cap_space_query
Volume capacity and available bytes can be queried.
@ k_fw_fs_cap_rejects_symlink_walk
Path traversal refuses symbolic-link components.
@ k_fw_fs_cap_removable_media
The backing volume may disappear at runtime.
@ k_fw_fs_cap_same_volume_rename
Rename is supported within one backend volume.
@ k_fw_fs_cap_modified_time
Modification timestamps may be reported as valid.
@ k_fw_fs_cap_accessed_time
Access timestamps may be reported as valid.
@ k_fw_fs_cap_atomic_noreplace
Rename can atomically reject an existing destination.
@ k_fw_fs_cap_created_time
Creation timestamps may be reported as valid.
@ k_fw_fs_cap_transactions
Staged publication operations are available.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Error Code Definitions for ra8-firmware.
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_exists
Item already exists – cannot create again.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_err_not_initialized
Module not initialized – _init() not yet called successfully.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
Minimal FAT12/FAT16/FAT32 filesystem adapter (read + write).
ra8_err_t ra8_fs_write(ra8_fs_file_t *file, const uint8_t *buf, uint32_t len)
Write len bytes; allocate new clusters from FAT free-space scan as needed.
ra8_err_t ra8_fs_size(const ra8_fs_file_t *file, uint64_t *out_bytes)
Report the file's size in bytes (64-bit on exFAT, #676).
ra8_err_t ra8_fs_read(ra8_fs_file_t *file, uint8_t *buf, uint32_t max_len, uint32_t *got_len)
Read up to max_len bytes; advance the cluster chain on cluster crossings.
ra8_err_t ra8_fs_close(ra8_fs_file_t *file)
Close an open file, stamping its final modification time.
ra8_err_t ra8_fs_seek(ra8_fs_file_t *file, uint64_t offset_bytes)
Move the file offset to offset_bytes (clamped to size).
ra8_err_t ra8_fs_tell(const ra8_fs_file_t *file, uint64_t *out_offset)
Report the current offset (64-bit; see ra8_fs_seek).
@ k_ra8_fs_fat_max_file_bytes
4 GiB - 1: max DIR_FileSize.
@ k_ra8_fs_type_exfat
exFAT (read + streaming write + format).
@ k_ra8_fs_attr_directory
MS FAT spec sec 6 "ATTR_DIRECTORY".
@ k_ra8_fs_max_files
Max concurrent open file handles.
ra8_fs_mode_t
File-open modes accepted by ra8_fs_open().
@ k_ra8_fs_mode_append
Open at EOF for writing.
@ k_ra8_fs_mode_read
Read-only, must exist.
@ k_ra8_fs_mode_write
Truncate (or create) for writing.
ra8_io virtual filesystem – mount many volumes, address them by name.
ra8_err_t ra8_io_vfs_dir_requirements(const char *path, uint32_t *out_bytes, uint8_t *out_align, uint16_t *out_max_open)
Query cursor workspace requirements for a qualified directory path.
ra8_err_t ra8_io_vfs_listdir(const char *path, ra8_fs_listdir_cb_t cb, void *ctx)
Enumerate a directory named "name:/path".
ra8_err_t ra8_io_vfs_free_space(const char *name, ra8_fs_space_t *out)
Query free and total bytes through a mounted format's ops.
ra8_err_t ra8_io_vfs_open(const char *path, ra8_fs_mode_t mode, ra8_fs_file_t **out_file)
Open a file by "name:/path".
@ k_ra8_io_vfs_name_max
Mount name length incl NUL.
ra8_err_t ra8_io_vfs_dir_next(ra8_io_vfs_dir_t *directory, ra8_fs_dirent_t *out, bool *out_entry)
Copy one stable entry or report clean end-of-directory.
ra8_err_t ra8_io_vfs_mkdir(const char *path)
Create a directory named "name:/path".
ra8_err_t ra8_io_vfs_unlink(const char *path)
Delete a file by "name:/path".
ra8_err_t ra8_io_vfs_dir_close(ra8_io_vfs_dir_t *directory)
Close and consume one caller-owned VFS directory cursor.
ra8_err_t ra8_io_vfs_stat(const char *path, ra8_io_vfs_stat_t *out)
Query metadata for "name:/path".
ra8_err_t ra8_io_vfs_rmdir(const char *path)
Remove the empty directory named "name:/path".
ra8_err_t ra8_io_vfs_dir_open(const char *path, ra8_io_vfs_dir_t *directory, void *workspace, uint32_t workspace_bytes)
Open a format-neutral incremental directory cursor.
ra8_err_t ra8_io_vfs_rename(const char *old_path, const char *new_path)
Rename a file within one mount.
Static properties and workspace requirements of one bound port.
uint32_t flags
OR of fw_fs_capability_t.
uint16_t year
Full civil year.
int16_t utc_offset_min
Offset from UTC when the validity flag is set.
uint8_t month
Month, 1..12.
uint32_t nanosecond
Fraction within second, 0..999,999,999.
uint8_t second
Second, 0..59.
uint8_t minute
Minute, 0..59.
One directory entry, valid only for the callback invocation.
Stable caller-owned value returned by fw_fs_dir_next.
uint64_t size_bytes
File length; zero for dirs.
uint16_t name_bytes
Bytes excluding the NUL.
fw_fs_node_type_t type
Entry kind.
char name[k_fw_fs_path_cap]
Copied NUL-terminated leaf.
Caller-owned open file; fields are private to the facade.
Composition-root configuration for one firmware filesystem binding.
const char * mount_name
Registered VFS name without :.
bool removable_media
True for hot-removable media such as SD.
ra8_fs_mount_t * mount
Matching live mount for space/caps.
Caller-owned adapter context.
uint32_t directory_workspace_bytes
Native cursor workspace bytes.
char mount_name[k_ra8_io_vfs_name_max]
Bounded mount name.
ra8_fs_mount_t * mount
Live mount.
char path_a[k_fw_fs_ra8_vfs_full_path_cap]
First path scratch.
uint16_t max_open_directories
Native concurrent cursor limit.
bool removable_media
Capability input.
uint8_t directory_workspace_align
Native cursor alignment.
uint32_t transaction_id
Stage-name counter.
char path_b[k_fw_fs_ra8_vfs_full_path_cap]
Rename path scratch.
Portable volume usage snapshot.
uint64_t free_bytes
Bytes available to new data.
uint64_t total_bytes
Addressable data bytes.
uint64_t used_bytes
Allocated bytes.
Result of a portable metadata query.
fw_fs_timestamp_t created
Creation/birth time, when supported.
uint64_t size_bytes
File length; zero for a directory.
fw_fs_timestamp_t accessed
Last access time, when supported.
bool exists
False means a clean lookup miss.
fw_fs_node_type_t type
Kind of node at the path.
fw_fs_timestamp_t modified
Content modification time, when supported.
One complete composition-root filesystem binding.
One portable timestamp and independent availability facts.
fw_fs_datetime_t value
Decoded civil date and time.
bool utc_offset_valid
True when utc_offset_min is known.
bool valid
True when the field is meaningful.
uint8_t hour
Hour of day, 0..23.
uint8_t minute
Minute of hour, 0..59.
int16_t utc_offset_min
Offset of the civil fields from UTC, in minutes.
uint8_t second
Second of minute, 0..59.
uint8_t month
Month of year, 1..12.
uint8_t centisecond
Hundredths within second, 0..99.
uint16_t year
Full civil year, e.g.
uint8_t day
Day of month, 1..31.
Stable directory-entry value copied by ra8_fs_dir_next.
char name[k_ra8_fs_dir_name_cap]
NUL-terminated visible leaf.
uint8_t attr
On-disk FAT attributes.
uint64_t size_bytes
File bytes; zero for dirs.
ra8_fs_type_t type
FAT12 / FAT16 / FAT32.
uint8_t in_use
0 = slot free, 1 = mounted.
A mounted volume's capacity, free space, and cluster geometry.
uint64_t used_bytes
Allocated data region, in bytes.
uint64_t free_bytes
Unallocated data region, in bytes.
uint64_t total_bytes
Whole data region, in bytes.
One decoded on-disk timestamp plus availability facts.
ra8_fs_datetime_t value
Decoded civil date/time.
bool valid
true => the on-disk date is legal.
bool utc_offset_valid
true => utc_offset_min is known.
Caller-owned format-neutral directory cursor.
Metadata returned by ra8_io_vfs_stat.
uint64_t size_bytes
File size in bytes (0 for directories).
ra8_fs_timestamp_t modified
Last-modified time, when present.
bool is_directory
true => path names a directory.
ra8_fs_timestamp_t accessed
Last-accessed time/date, when present.
ra8_fs_timestamp_t created
Creation time, when present.
bool exists
true => the path resolves to an entry.
Where the cursor and the native workspace sit inside a caller span.
size_t cursor_end
Span bytes up to one past the cursor.
void * workspace
First native-aligned base past the cursor.
size_t consumed
Span bytes ahead of workspace.
void * cursor
First alignof(vfs_directory_state_t) base in the span.
Backend state stored in a caller's directory workspace.
ra8_io_vfs_dir_t native
Independent format-neutral VFS cursor.
Backend state stored in a caller's file workspace.
ra8_fs_file_t * native
Open repository VFS handle, or NULL when consumed.
Callback-list compatibility bridge over a format-owned enumeration.
uint32_t count
Deliveries attempted.
fw_fs_list_fn_t callback
Portable callback.
ra8_err_t callback_error
First callback/entry error.
void * callback_ctx
Portable callback context.
bool stopped
Budget or callback stop seen.
uint32_t max_entries
Delivery ceiling.
Backend state stored in a caller's transaction workspace.
bool writer_open
Writer is owned.
bool stage_exists
Stage is owned.
vfs_file_state_t file_state
Stage handle state.
char destination[k_fw_fs_path_cap]
Final portable path.
char stage[k_fw_fs_path_cap]
Private stage path.
fw_fs_transaction_policy_t policy
Fixed publish policy.