30 while (s[n] !=
'\0') {
45 return (
char)(c - (
'a' -
'A'));
210 if (contig_end != 0U) {
211 const uint32_t adjacent = cluster + 1U;
212 if (adjacent >= contig_end) {
215 *out_next = adjacent;
261 if ((pos + i) >= nlen) {
265 const uint16_t unit =
priv_rd16(&entry[b]);
338 const uint16_t* name,
379 while (*path ==
'/') {
451 file->mount = handle;
452 file->first_cluster = first;
453 file->cur_cluster = first;
454 file->walk_cache_idx = 0U;
455 file->walk_cache_cluster = first;
458 file->dir_entry_lba = 0U;
459 file->dir_entry_idx = 0U;
461 file->entry_set_cluster = 0U;
462 file->entry_set_index = 0U;
463 file->entry_set_count = 0U;
464 file->alloc_clusters = 0U;
465 file->tail_cluster = 0U;
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ 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_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).
uint32_t priv_rd32(const uint8_t *p)
Decode a little-endian uint32_t from a byte buffer.
ra8_err_t priv_fat_get(const ra8_fs_mount_t *m, uint32_t cluster, uint32_t *out_value)
Fetch the FAT entry for cluster, returning the next-cluster value.
uint16_t priv_rd16(const uint8_t *p)
Decode a little-endian uint16_t from a byte buffer.
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.
uint8_t priv_is_eoc(const ra8_fs_mount_t *m, uint32_t value)
Test whether value is an end-of-chain marker for this FAT type.
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.
uint32_t priv_bps(const ra8_fs_mount_t *m)
One mounted volume's sector size in bytes.
void priv_byte_copy(uint8_t *dst, const uint8_t *src, uint32_t n)
Length-checked byte copy used in place of memcpy().
uint64_t priv_rd64(const uint8_t *p)
Decode a little-endian uint64_t from a byte buffer.
uint32_t priv_cluster_bytes(const ra8_fs_mount_t *m)
One mounted volume's cluster size in bytes.
uint8_t * priv_sec_io(void)
The IO-role sector buffer (leaf data / bitmap sector transfers).
ra8_err_t priv_exfat_lookup(const ra8_fs_mount_t *m, const char *path, uint8_t *out_strm, uint8_t *out_attr)
Resolve a path and return the leaf entry set's location fields.
ra8_err_t priv_exfat_open_write(ra8_fs_mount_t *handle, const char *path, ra8_fs_mode_t mode, ra8_fs_file_t **out_file)
Open an exFAT file for writing: create, truncate, or position to append.
ra8_err_t priv_exfat_name_to_units(const ra8_fs_mount_t *m, const char *path, uint16_t *out, uint32_t *out_units)
Convert a caller's exFAT name to code units, refusing what will not fold.
ra8_err_t priv_exfat_open(ra8_fs_mount_t *handle, const char *path, ra8_fs_mode_t mode, ra8_fs_file_t **out_file)
Open a file (read-only) on a mounted exFAT volume.
ra8_err_t priv_exfat_next_entry(const ra8_fs_mount_t *m, exfat_cursor_t *cur, uint8_t *out)
Fetch the next 32-byte directory entry, following the cluster chain.
uint32_t priv_strlen(const char *s)
Length of a NUL-terminated string.
static void internal_exfat_seed_read(ra8_fs_file_t *file, ra8_fs_mount_t *handle, const uint8_t *strm)
Populate a read handle from the file's Stream-extension entry.
static ra8_err_t internal_exfat_parse(ra8_fs_mount_t *m, const uint8_t *buf)
Parse an exFAT VBR into the mount's geometry fields.
static uint8_t internal_exfat_is_volume(const uint8_t *buf)
Detect an exFAT volume from its boot sector.
uint8_t priv_exfat_name_chunk_eq(const uint8_t *entry, const uint16_t *name, uint32_t pos, uint32_t nlen)
Compare one file-name entry's 15 UTF-16 units against a needle.
void priv_exfat_upcase_verify(ra8_fs_mount_t *m)
Decide whether this build's fold matches the mounted volume's table.
static ra8_err_t internal_exfat_match_set(const ra8_fs_mount_t *m, exfat_cursor_t *cur, const uint16_t *name, uint32_t nlen, uint8_t *out_strm)
Read a stream-ext + name set and test it against path.
ra8_err_t priv_exfat_needle_units(const ra8_fs_mount_t *m, const char *name, uint16_t *out, uint32_t *out_units, ra8_err_t too_long)
Convert a leaf name to code units, mapping over-long to too_long.
void priv_exfat_dir_root(const ra8_fs_mount_t *m, exfat_dir_t *out)
Fill out with the volume root's directory location.
ra8_err_t priv_exfat_step_cluster(const ra8_fs_mount_t *m, uint32_t cluster, uint32_t contig_end, uint32_t *out_next)
Compute the cluster that follows cluster in a directory.
char priv_ascii_upper(char c)
Uppercase an ASCII character (others returned unchanged).
void priv_exfat_cursor_init(const exfat_dir_t *dir, exfat_cursor_t *out)
Aim a fresh cursor at the start of dir.
ra8_err_t priv_parse_volume(ra8_fs_mount_t *m)
Parse the volume at the current base: exFAT first, then FAT BPB.
ra8_err_t priv_exfat_find(const ra8_fs_mount_t *m, const exfat_dir_t *dir, const char *path, uint8_t *out_strm, uint8_t *out_attr)
Find a name in ONE exFAT directory.
void priv_exfat_dir_from_set(const ra8_fs_mount_t *m, const uint8_t *strm, exfat_dir_t *out)
Build a directory location from a Stream entry's allocation fields.
uint16_t priv_exfat_upcase_unit(uint16_t unit)
Fold a UTF-16 code unit through the canonical exFAT up-case table.
uint32_t priv_exfat_upcase_checksum(void)
Rotate-add checksum of the up-case table this build embeds.
Cross-TU shared declarations for the FAT/exFAT ra8_fs adapter.
ra8_fs_file_t * priv_alloc_file_slot(void)
Allocate a free entry from the file table; returns NULL if full.
uint8_t g_fs_scratch[k_ra8_fs_sector_max]
Single max-sector scratch buffer reused across all I/O.
ra8_err_t priv_parse_bpb_into_mount(ra8_fs_mount_t *m)
Parse the BPB layout fields out of g_fs_scratch into m.
@ k_exfat_entry_upcase
Up-case Table directory entry.
@ k_exfat_name_off
File-name entry character offset.
@ k_exfat_strm_off_dlen
Stream-ext DataLength (low 32 used).
@ k_exfat_off_root_clus
FirstClusterOfRootDirectory.
@ k_exfat_off_fat_lba
FatOffset (sectors from VBR).
@ k_exfat_strm_off_nlen
Stream-ext NameLength (UTF-16 units).
@ k_exfat_strm_off_clus
Stream-ext FirstCluster.
@ k_exfat_strm_off_flags
Stream-ext GeneralSecondaryFlags.
@ k_exfat_off_spc_shift
SectorsPerClusterShift (log2).
@ k_exfat_off_fat_len
FatLength (sectors).
@ k_exfat_off_bps_shift
BytesPerSectorShift (log2).
@ k_exfat_off_fsname
"EXFAT " filesystem-name field (8 chars).
@ k_exfat_off_num_fats
NumberOfFats.
@ k_exfat_off_clus_count
ClusterCount.
@ k_exfat_off_heap_lba
ClusterHeapOffset (sectors from VBR).
@ k_exfat_upc_off_csum
Up-case-table entry TableChecksum (32-bit).
@ k_exfat_secflag_no_fat
GeneralSecondaryFlags: NoFatChain.
@ k_exfat_name_per_entry
UTF-16 units per file-name entry.
@ k_exfat_entry_bytes
Directory entry size.
@ k_exfat_bps_shift_min
log2(512): smallest BytesPerSectorShift.
@ k_exfat_off_strm_valid
Stream entry: ValidDataLength (8 B).
@ k_exfat_entry_eod
End-of-directory marker.
@ k_exfat_entry_stream
Stream-extension entry.
@ k_exfat_off_file_attr
File entry: FileAttributes (2 bytes).
@ k_exfat_scan_limit
Max dir entries scanned (P10 bound).
@ k_exfat_attr_directory
FileAttributes: directory.
@ k_exfat_entry_name
File-name entry.
@ k_exfat_bps_shift_max
log2(4096): largest BytesPerSectorShift.
@ k_exfat_name_cap
Longest name we store, in UTF-16 units.
@ k_exfat_fsname_len
"EXFAT " field length.
@ k_exfat_entry_file
File directory entry.
@ k_exfat_foff_vol_len
VolumeLength (64-bit).
@ k_ra8_fs_type_exfat
exFAT (read + streaming write + format).
ra8_fs_mode_t
File-open modes accepted by ra8_fs_open().
@ k_ra8_fs_mode_read
Read-only, must exist.
uint8_t priv_utf16_all_ascii(const uint16_t *in, uint32_t units)
Is every unit of in inside the ASCII range?
ra8_err_t priv_utf8_to_utf16(const char *in, uint16_t *out, uint32_t cap, uint32_t *out_units)
Convert a NUL-terminated UTF-8 name into UTF-16LE code units.
Linear cursor over a directory's 32-byte entries.
uint32_t scanned
Total entries read (P10 bound).
uint32_t cluster
Current directory cluster.
uint32_t contig_end
One past the run's last cluster; 0 => FAT.
uint32_t entry_in_cluster
Next entry index within the cluster.
Identifies the exFAT directory a lookup, scan or link operates in.
uint32_t self_cluster
Parent cluster holding this dir's File entry; 0 => root.
uint32_t cluster
First cluster of the directory.
uint32_t self_index
File-entry index within self_cluster.
uint32_t contig_end
One past the run's last cluster; 0 => FAT-chained.
Cached parse of one mounted FAT volume.
uint32_t reserved_sectors
BPB BPB_RsvdSecCnt.
uint32_t root_cluster
BPB BPB_RootClus (FAT32 only).
uint8_t exfat_upcase_ok
exFAT: volume's up-case table is ours.
ra8_fs_type_t type
FAT12 / FAT16 / FAT32.
uint32_t bytes_per_sector
Sector size (BPB / VBR == backend).
uint32_t root_entries
BPB BPB_RootEntCnt (FAT12/16).
uint64_t total_sectors
BPB TotSec / exFAT VolumeLength.
uint32_t sectors_per_cluster
BPB BPB_SecPerClus.
uint32_t num_fats
BPB BPB_NumFATs.
uint32_t fat_size_sectors
BPB BPB_FATSz16 / BPB_FATSz32.
uint64_t first_root_lba
FAT12/16 fixed root-dir start.
uint32_t count_of_clusters
Per MS spec: data_sectors / SPC.
uint64_t first_data_lba
First sector of the data region.
uint64_t first_fat_lba
Computed: first FAT sector.