63typedef enum : uint32_t {
105 const uint16_t* leaf,
306 for (uint32_t attempt = 0U; attempt <= (uint32_t)
k_lfnw_grow_max; attempt++) {
382 const uint32_t total = (uint32_t)plan->
lfn_entries + 1U;
390 for (uint32_t i = 0U; i < total; i++) {
397 (uint8_t)((i == 0U) ? 1U : 0U),
406 if ((i + 1U) < total) {
448 uint32_t len = *len_io;
451 run[i - 1U] = run[i];
512 if ((w.
cur_lba == tlba) && (off == toff)) {
516 const uint8_t* ent = &buf[off];
563 uint64_t cur = pos[0].
lba;
568 for (uint32_t i = 0U; i < count; i++) {
569 if (pos[i].lba != cur) {
590 const uint8_t* name83)
615 err =
priv_dir_find(m, loc, name83, out_lba, out_off, out_entry);
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Minimal FAT12/FAT16/FAT32 filesystem adapter (read + write).
ra8_err_t priv_fat_set(const ra8_fs_mount_t *m, uint32_t cluster, uint32_t value)
Write value into the FAT entry for cluster across every FAT copy.
uint64_t priv_cluster_to_lba(const ra8_fs_mount_t *m, uint32_t cluster)
Convert a cluster number into its first data-region LBA.
uint32_t priv_dir_eps(const ra8_fs_mount_t *m)
Directory entries per sector on one mounted volume.
ra8_err_t priv_read_sector(const ra8_fs_mount_t *m, uint64_t lba, uint8_t *buf)
Read a single sector into the module scratch buffer.
void priv_byte_copy(uint8_t *dst, const uint8_t *src, uint32_t n)
Length-checked byte copy used in place of memcpy().
ra8_err_t priv_write_sector(const ra8_fs_mount_t *m, uint64_t lba, const uint8_t *buf)
Write a single sector from a caller-provided buffer.
uint8_t * priv_sec_walk(void)
The WALK-role sector buffer (directory scans and entry RMW).
const uint8_t k_zero_sector[k_ra8_fs_sector_max]
One whole sector of zero bytes, in read-only storage.
ra8_err_t priv_alloc_eoc_cluster(const ra8_fs_mount_t *m, uint32_t *out_c)
Allocate a fresh cluster, mark it EOC, and return its number.
Cross-TU shared declarations for the FAT/exFAT ra8_fs adapter.
uint8_t priv_sfn_checksum(const uint8_t *name83)
Compute the 8.3 short-name checksum carried in each LFN directory entry.
void priv_lfn_fill_slot(uint8_t *ent, const uint16_t *name, uint32_t nlen, uint32_t order, uint8_t is_last, uint8_t csum)
Fill one 32-byte slot with the order -th group of a long name.
ra8_err_t priv_free_chain(const ra8_fs_mount_t *m, uint32_t start)
Free an entire cluster chain starting at start.
ra8_err_t priv_dir_find_long(const ra8_fs_mount_t *m, const dir_loc_t *loc, const char *want, uint64_t *out_lba, uint32_t *out_entry_off, uint8_t out_entry[k_ra8_fs_dir_entry_bytes])
Find a directory entry by its VFAT long name (case-insensitive).
ra8_err_t priv_dir_reserve(const ra8_fs_mount_t *m, const dir_loc_t *loc, const char *leaf, dir_insert_t *out)
Decide how a name will be stored and set aside the slots for it.
static ra8_err_t internal_dir_erase_positions(const ra8_fs_mount_t *m, const dir_pos_t *pos, uint32_t count)
Mark every listed slot deleted, one sector read-modify-write at a time.
ra8_err_t priv_dir_erase_chain(const ra8_fs_mount_t *m, const dir_loc_t *loc, uint64_t lba, uint32_t off, const uint8_t *name83)
Delete a directory entry together with its long-name chain.
static ra8_err_t internal_alias_unique(const ra8_fs_mount_t *m, const dir_loc_t *loc, const uint16_t *leaf, uint32_t n, uint8_t *out11)
Pick the lowest ~N alias the directory does not already hold.
ra8_err_t priv_dir_find_free_run(const ra8_fs_mount_t *m, const dir_loc_t *loc, uint32_t need, dir_slot_t *out)
Locate need consecutive free entry slots in a given directory.
ra8_err_t priv_dir_lookup_any(const ra8_fs_mount_t *m, const dir_loc_t *loc, const char *leaf, uint64_t *out_lba, uint32_t *out_off, uint8_t out_entry[k_ra8_fs_dir_entry_bytes])
Resolve one leaf name by 8.3 first and by long name second.
ra8_fs_lfnw_local_t
Bounds used only by this translation unit's directory manipulation.
@ k_lfnw_grow_max
Cluster-growth retries before reporting no_mem.
static uint8_t internal_slot_is_free(const uint8_t *ent)
Is this 32-byte slot available for a new entry?
static ra8_err_t internal_slot_advance(const ra8_fs_mount_t *m, dir_slot_t *cur, uint8_t *buf, uint64_t *lba_io)
Step a slot cursor forward one entry, flushing across sector edges.
static ra8_err_t internal_dir_grow(const ra8_fs_mount_t *m, const dir_loc_t *loc)
Append one zeroed cluster to a directory's chain.
ra8_err_t priv_dir_commit(const ra8_fs_mount_t *m, const dir_insert_t *plan, const uint8_t *tmpl, uint64_t *out_lba, uint32_t *out_off)
Write a reserved run: the long-name chain, then the 8.3 entry.
static ra8_err_t internal_dir_collect_chain(const ra8_fs_mount_t *m, const dir_loc_t *loc, uint64_t tlba, uint32_t toff, uint8_t csum, dir_pos_t *run, uint32_t *out_len)
Collect the long-name slots that belong to one 8.3 entry.
static void internal_run_push(dir_pos_t *run, uint32_t *len_io, uint64_t lba, uint32_t off)
Record one long-name slot address, keeping the newest on overflow.
void priv_lfn_alias_basis(const uint16_t *leaf, uint32_t n, uint32_t tail, uint8_t *out11)
Derive the LONGNA~N.TXT 8.3 alias a long name is filed under.
ra8_fs_name_kind_t priv_name_classify(const char *leaf, uint16_t *out_units, uint32_t *out_nunits, uint8_t *out83, uint8_t *out_ntres)
Decide whether a leaf needs one entry, one entry plus case flags, or a chain.
void priv_dir_walk_init_loc(const ra8_fs_mount_t *m, const dir_loc_t *loc, dir_walk_t *w)
Initialise a directory walker for an arbitrary directory location.
uint8_t priv_path_to_83(const char *path, uint8_t *out11)
Convert a "/FILE.TXT"-style path to packed 11-byte 8.3 form.
ra8_err_t priv_dir_find(const ra8_fs_mount_t *m, const dir_loc_t *loc, const uint8_t *name83, uint64_t *out_lba, uint32_t *out_entry_off, uint8_t out_entry[k_ra8_fs_dir_entry_bytes])
Find a directory entry by 8.3 name within a given directory.
ra8_err_t priv_dir_walk_next_sector(const ra8_fs_mount_t *m, dir_walk_t *w, uint8_t *out_eod)
Advance the walker to the next sector.
ra8_fs_name_kind_t
How a leaf component has to be stored in a FAT directory.
@ k_name_kind_invalid
Empty, over-long, or holds an illegal character.
@ k_name_kind_long
Needs a VFAT chain and a generated ~N alias.
@ k_dir_off_attr
MS FAT spec sec 6 "DIR_Attr".
@ k_dir_off_ntres
MS FAT spec sec 6 "DIR_NTRes".
@ k_dir_name_field_len
8 + 3 raw chars (no dot).
@ k_dir_off_name
MS FAT spec sec 6 "DIR_Name" (11 bytes).
@ k_dir_marker_free_used
Slot was used, deleted.
@ k_dir_marker_free_perm
End-of-directory.
@ k_max_8_3_name
8.3 packed length without dot.
@ k_lfn_alias_tail_max
Highest ~N probed by the alias generator.
@ k_lfn_off_checksum
Checksum of the matching 8.3 name.
@ k_lfn_erase_max
Longest chain we ERASE (spec LDIR_Ord max).
@ k_lfn_chars_per_ent
UTF-16 chars carried per LFN entry.
@ k_ra8_fs_type_fat32
count_of_clusters >= 65525.
@ k_ra8_fs_attr_lfn
Long-file-name marker (we skip).
@ k_ra8_fs_dir_entry_bytes
MS FAT spec sec 6 "Directory Entry".
Everything decided about a new directory entry before anything is written.
uint32_t nunits
How many of units the name occupies.
uint8_t name83[k_max_8_3_name]
Packed 8.3 name, or the generated alias.
uint8_t lfn_entries
Chain slots ahead of the 8.3 entry.
uint8_t ntres
DIR_NTRes case flags for the entry.
dir_slot_t start
First slot of the reserved run.
uint16_t units[k_lfn_write_max]
The name, as UTF-16LE code units.
Identifies the directory a lookup/scan should operate in.
uint8_t is_root
1 => the volume root; 0 => the subdirectory at cluster.
The on-disk address of one 32-byte directory slot.
uint32_t off
Byte offset of the slot in that sector.
uint64_t lba
Sector holding the slot.
A directory cursor that addresses one entry, not just one sector.
dir_walk_t w
Sector-level cursor for the containing directory.
uint32_t ent
Entry index within w.cur_lba.
Internal cursor used by the directory iterator.
uint32_t cluster
Current cluster (FAT32 root case).
uint64_t cur_lba
Currently loaded LBA.
Cached parse of one mounted FAT volume.
ra8_fs_type_t type
FAT12 / FAT16 / FAT32.
uint32_t sectors_per_cluster
BPB BPB_SecPerClus.