44 return (uint16_t)((uint16_t)p[0] | ((uint16_t)p[1] <<
k_shift_byte));
104 for (uint32_t i = 0U; i < n; i++) {
112 for (uint32_t i = 0U; i < n; i++) {
120 for (uint32_t i = 0U; i < n; i++) {
175 return (uint64_t)cluster + ((uint64_t)cluster / 2U);
178 return (uint64_t)cluster * 2U;
183 return (uint64_t)cluster * 4U;
191 const uint32_t sec_off = (uint32_t)(fat_offset %
priv_bps(m));
202 uint8_t b0 = buf[sec_off];
205 b1 = buf[sec_off + 1U];
214 uint16_t raw = (uint16_t)((uint16_t)b0 | ((uint16_t)b1 <<
k_shift_byte));
215 if ((cluster & 1U) != 0U) {
275 if (straddle == 0U) {
319 uint8_t straddle = 0U;
324 uint8_t b0 = buf[sec_off];
327 b1 = buf[sec_off + 1U];
336 uint16_t raw = (uint16_t)((uint16_t)b0 | ((uint16_t)b1 <<
k_shift_byte));
337 if ((cluster & 1U) != 0U) {
344 if (straddle == 0U) {
489 for (uint32_t i = 0; i < m->
num_fats; i++) {
491 const uint64_t sec_num = fat_base + (fat_offset /
priv_bps(m));
492 const uint32_t sec_off = (uint32_t)(fat_offset %
priv_bps(m));
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_ok
Success – operation completed with all postconditions satisfied.
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.
void priv_wr64(uint8_t *p, uint64_t v)
Encode a uint64_t into a byte buffer, little-endian.
static ra8_err_t internal_fat16_set_one(const ra8_fs_mount_t *m, uint64_t sec_num, uint32_t sec_off, uint32_t value)
Write a FAT16 entry into one sector.
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.
void priv_byte_fill(uint8_t *dst, uint8_t value, uint32_t n)
Fill n bytes of dst with value.
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.
static ra8_err_t internal_fat32_set_one(const ra8_fs_mount_t *m, uint64_t sec_num, uint32_t sec_off, uint32_t value)
Write a FAT32 entry into one sector (preserves top 4 reserved bits).
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.
static uint64_t internal_fat_entry_byte_offset(const ra8_fs_mount_t *m, uint32_t cluster)
Compute the byte offset of cluster's FAT entry 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.
static ra8_err_t internal_fat12_set_one(const ra8_fs_mount_t *m, uint64_t sec_num, uint32_t sec_off, uint32_t cluster, uint32_t value)
Write a FAT12 entry, handling sector-straddling 12-bit packing.
uint8_t priv_byte_equal(const uint8_t *a, const uint8_t *b, uint32_t n)
Compare two byte buffers for equality (length n).
uint32_t priv_eoc_write(const ra8_fs_mount_t *m)
End-of-chain value to write for this FAT type.
void priv_wr32(uint8_t *p, uint32_t v)
Encode a little-endian uint32_t into a byte buffer.
ra8_err_t priv_alloc_cluster(const ra8_fs_mount_t *m, uint32_t *out_cluster)
Free-cluster scan from the next-free hint, wrapping exactly once.
static ra8_err_t internal_exfat_fat_set_one(const ra8_fs_mount_t *m, uint64_t sec_num, uint32_t sec_off, uint32_t value)
Write an exFAT FAT entry – all 32 bits, nothing reserved.
static uint32_t internal_alloc_start(const ra8_fs_mount_t *m, uint32_t hint)
Normalise a next-free hint into a real cluster number.
void priv_byte_copy(uint8_t *dst, const uint8_t *src, uint32_t n)
Length-checked byte copy used in place of memcpy().
static ra8_err_t internal_fat12_store(const ra8_fs_mount_t *m, const uint8_t *buf, const uint8_t *buf2, uint64_t sec_num, uint8_t straddle)
Commit one (or, when straddling, two) FAT12 sectors and refresh the cache.
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.
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.
void priv_wr16(uint8_t *p, uint16_t v)
Encode a little-endian uint16_t into a byte buffer.
void priv_free_count_took(const ra8_fs_mount_t *m, uint32_t n)
Account n clusters as taken out of the volume's free space.
void priv_fat_sector_wrote(const ra8_fs_mount_t *m, const uint8_t *buf, uint64_t lba)
Tell the cache that lba has just been written with buf.
void priv_alloc_hint_set(const ra8_fs_mount_t *m, uint32_t cluster)
Move the next-free hint forward to cluster.
ra8_err_t priv_fat_sector_read(const ra8_fs_mount_t *m, uint64_t lba, uint8_t *buf)
Read one FAT sector, through the shared one-sector cache.
uint32_t priv_alloc_hint_get(const ra8_fs_mount_t *m)
Report the cluster a free-space scan should start from.
uint8_t * priv_sec_fat2(void)
The FAT2-role sector buffer (the FAT12 straddle's second sector).
uint8_t * priv_sec_fat(void)
The FAT-role sector buffer (priv_fat_get and the FAT setters).
Cross-TU shared declarations for the FAT/exFAT ra8_fs adapter.
@ k_fat12_high_nibble_mask
Untouched nibble (odd cluster).
@ k_cluster_eoc_write_fat32
Cluster eoc write fat32.
@ k_cluster_eoc_min_fat32
MS FAT spec sec 4.2 EOC threshold.
@ k_cluster_eoc_min_fat12
MS FAT spec sec 4.1 EOC threshold.
@ k_cluster_free
Cluster free.
@ k_cluster_eoc_min_fat16
MS FAT spec sec 4.1 EOC threshold.
@ k_fat12_low_nibble_mask
Untouched nibble (even cluster).
@ k_cluster_first_data
Cluster numbers start at 2.
@ k_cluster_eoc_write_exfat
exFAT spec sec 4.1 EOC marker.
@ k_cluster_eoc_write_fat16
Cluster eoc write fat16.
@ k_cluster_mask_fat32
Top 4 bits reserved on FAT32.
@ k_fat12_value_mask
12-bit FAT12 entry mask.
@ k_cluster_eoc_min_exfat
exFAT spec sec 4.1 EOC threshold.
@ k_cluster_eoc_write_fat12
Value we write to terminate.
@ k_shift_byte
Shift byte.
@ k_shift_nibble
Shift nibble.
@ k_shift_two_bytes
Shift two bytes.
@ k_shift_word32
Shift a whole 32-bit word (u64 halves).
@ k_shift_three_bytes
Shift three bytes.
@ k_ra8_fs_type_fat12
count_of_clusters < 4085.
@ k_ra8_fs_type_exfat
exFAT (read + streaming write + format).
@ k_ra8_fs_type_fat16
4085 <= count_of_clusters < 65525.
@ k_ra8_fs_dir_entry_bytes
MS FAT spec sec 6 "Directory Entry".
ra8_err_t(* read_block)(void *ctx, uint64_t lba, uint32_t count, uint8_t *buf)
Read count consecutive blocks starting at lba.
ra8_err_t(* write_block)(void *ctx, uint64_t lba, uint32_t count, const uint8_t *buf)
Write count consecutive blocks starting at lba.
void * ctx
Caller-owned context passed back into the function pointers.
Cached parse of one mounted FAT volume.
ra8_fs_type_t type
FAT12 / FAT16 / FAT32.
uint32_t bytes_per_sector
Sector size (BPB / VBR == backend).
uint32_t sectors_per_cluster
BPB BPB_SecPerClus.
uint32_t num_fats
BPB BPB_NumFATs.
ra8_fs_backend_t backend
Block-device backend.
uint32_t fat_size_sectors
BPB BPB_FATSz16 / BPB_FATSz32.
uint64_t partition_base_lba
MBR/GPT partition start (0 = superfloppy).
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.