ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_fs_fat_attr.c
Go to the documentation of this file.
1
39
40#include <stddef.h>
41#include <stdint.h>
42
43#include "ra8_attributes.h"
44#include "ra8_fs.h"
45#include "ra8_fs_fat_internal.h"
46#include "ra8_fs_meta.h"
47
80 const char* path,
81 uint8_t set_mask,
82 uint8_t clear_mask)
83{
84 dir_loc_t parent = {};
85 const char* leaf = nullptr;
86 const ra8_err_t rerr = priv_resolve_parent(m, path, &parent, &leaf);
87 if (rerr != k_ra8_ok) {
88 return rerr;
89 }
90 uint8_t name83[k_max_8_3_name] = {};
91 const uint8_t have83 = priv_path_to_83(leaf, name83);
92 uint64_t lba = 0U;
93 uint32_t off = 0U;
94 uint8_t entry[k_ra8_fs_dir_entry_bytes] = {};
96 if (have83 != 0U) {
97 err = priv_dir_find(m, &parent, name83, &lba, &off, entry);
98 }
99 if (err == k_ra8_err_not_found) {
100 err = priv_dir_find_long(m, &parent, leaf, &lba, &off, entry);
101 }
102 if (err != k_ra8_ok) {
103 return err;
104 }
105 uint8_t* const sec = priv_sec_walk();
106 err = priv_read_sector(m, lba, sec);
107 if (err != k_ra8_ok) {
108 return err;
109 }
110 priv_fat_entry_apply_attr(&sec[off], set_mask, clear_mask);
111 return priv_write_sector(m, lba, sec);
112}
113
147 const char* path,
148 uint8_t set_mask,
149 uint8_t clear_mask)
150{
151 exfat_dir_t root = {};
152 priv_exfat_dir_root(m, &root);
154 uint32_t count = 0U;
155 uint8_t file_e[k_exfat_entry_bytes] = {};
156 uint8_t strm_e[k_exfat_entry_bytes] = {};
158 &root,
159 path,
160 pos,
161 (uint32_t)k_exfat_set_max_entries,
162 &count,
163 file_e,
164 strm_e);
165 if (err != k_ra8_ok) {
166 return err;
167 }
168 uint8_t eset[(uint32_t)k_exfat_set_max_entries * (uint32_t)k_exfat_entry_bytes] = {};
169 for (uint32_t k = 0U; k < count; k++) {
170 exfat_cursor_t one = {.cluster = pos[k].cluster,
171 .entry_in_cluster = pos[k].index,
172 .scanned = 0U,
173 .contig_end = 0U};
174 err = priv_exfat_next_entry(m, &one, &eset[(size_t)k * (size_t)k_exfat_entry_bytes]);
175 if (err != k_ra8_ok) {
176 return err;
177 }
178 }
179 const uint8_t attr = eset[k_exfat_off_file_attr];
181 (uint8_t)((uint8_t)(attr & (uint8_t)~clear_mask) | (uint8_t)set_mask);
183 priv_exfat_set_checksum(eset, count * (uint32_t)k_exfat_entry_bytes));
185 pos[0].cluster,
186 pos[0].index,
187 &eset[0],
188 (uint32_t)k_exfat_entry_bytes);
189}
190
226RA8_EXPECTS_LOCK("ra8_fs_lock")
228 const char* path,
229 uint8_t set_mask,
230 uint8_t clear_mask)
231{
232 if (handle == nullptr || path == nullptr) {
233 return k_ra8_err_null_ptr;
234 }
235 if (handle->in_use == 0U) {
236 return k_ra8_err_invalid_state;
237 }
238 /* Confine the change to the four host-controlled bits, and reject a bit told
239 * to be both set and cleared. Any of the three catches makes the whole request
240 * invalid_arg, so the DIRECTORY / VOLUME_ID / long-name bits can never be
241 * flipped and a caller cannot give contradictory instructions. */
242 const uint8_t settable = (uint8_t)k_ra8_fs_attr_settable;
243 if (((set_mask & (uint8_t)~settable) != 0U) || ((clear_mask & (uint8_t)~settable) != 0U) ||
244 ((set_mask & clear_mask) != 0U)) {
246 }
247 const char* p = path;
248 while (*p == '/') {
249 p++;
250 }
251 if (*p == '\0') {
252 return k_ra8_err_invalid_arg; /* the volume root has no entry to patch */
253 }
254 if (handle->type == k_ra8_fs_type_exfat) {
255 return internal_setattr_exfat(handle, path, set_mask, clear_mask);
256 }
257 return internal_setattr_fat(handle, path, set_mask, clear_mask);
258}
259
260/* =============================================================================
261 * Public entry point -- the lock bracket
262 * =============================================================================
263 */
264
265RA8_OWNS_RESOURCE("ra8_fs_lock")
267 const char* path,
268 uint8_t set_mask,
269 uint8_t clear_mask)
270{
272 const ra8_err_t err = internal_setattr_locked(handle, path, set_mask, clear_mask);
274 return err;
275}
Annotation-attribute framework macros for ra8-firmware.
#define RA8_OWNS_RESOURCE(kind)
RAII-style resource ownership contract.
#define RA8_EXPECTS_LOCK(name)
The function expects the named thread/IRQ lock to be held on entry.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
Definition ra8_err.h:173
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Minimal FAT12/FAT16/FAT32 filesystem adapter (read + write).
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.
Definition ra8_fs_fat.c:134
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.
Definition ra8_fs_fat.c:140
void priv_wr16(uint8_t *p, uint16_t v)
Encode a little-endian uint16_t into a byte buffer.
Definition ra8_fs_fat.c:61
static ra8_err_t internal_setattr_locked(const ra8_fs_mount_t *handle, const char *path, uint8_t set_mask, uint8_t clear_mask)
Set attributes – the guarded body of ra8_fs_set_attr().
static ra8_err_t internal_setattr_exfat(const ra8_fs_mount_t *m, const char *path, uint8_t set_mask, uint8_t clear_mask)
Patch the FileAttributes byte of an exFAT root-level entry.
static ra8_err_t internal_setattr_fat(const ra8_fs_mount_t *m, const char *path, uint8_t set_mask, uint8_t clear_mask)
Patch the attribute byte of a FAT12/16/32 entry.
uint8_t * priv_sec_walk(void)
The WALK-role sector buffer (directory scans and entry RMW).
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_find_set(const ra8_fs_mount_t *m, const exfat_dir_t *dir, const char *path, exfat_setpos_t *pos, uint32_t max_pos, uint32_t *out_count, uint8_t *file_copy, uint8_t *strm_copy)
Implementation of priv_exfat_find_set() – one aligned walk of a directory.
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.
uint16_t priv_exfat_set_checksum(const uint8_t *set, uint32_t bytes)
Compute the SetChecksum over a built directory entry set.
ra8_err_t priv_exfat_write_dir_set(const ra8_fs_mount_t *m, uint32_t cluster, uint32_t idx, const uint8_t *set, uint32_t bytes)
Write a pre-built entry set into consecutive directory entries.
void priv_fat_entry_apply_attr(uint8_t *entry, uint8_t set_mask, uint8_t clear_mask)
Clear then set attribute bits in a 32-byte FAT directory entry.
ra8_err_t priv_resolve_parent(const ra8_fs_mount_t *m, const char *path, dir_loc_t *out_parent, const char **out_leaf)
Resolve all-but-the-last path component to a parent directory.
Cross-TU shared declarations for the FAT/exFAT ra8_fs adapter.
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).
void priv_lock_release(void)
Drop the library lock taken by priv_lock_acquire.
void priv_lock_acquire(void)
Take the library lock, if the caller installed one.
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.
@ k_exfat_off_file_csum
File entry: SetChecksum (2 bytes).
@ k_exfat_entry_bytes
Directory entry size.
@ k_exfat_off_file_attr
File entry: FileAttributes (2 bytes).
@ k_exfat_set_max_entries
1 File + 1 Stream + 17 Name entries.
@ k_max_8_3_name
8.3 packed length without dot.
Volume-level metadata: free space, volume label, and per-entry utime.
ra8_err_t ra8_fs_set_attr(const ra8_fs_mount_t *handle, const char *path, uint8_t set_mask, uint8_t clear_mask)
Set and/or clear a named entry's file attributes (chmod-style).
@ k_ra8_fs_attr_settable
Union of the four settable bits (0x27).
@ k_ra8_fs_type_exfat
exFAT (read + streaming write + format).
@ k_ra8_fs_dir_entry_bytes
MS FAT spec sec 6 "Directory Entry".
Identifies the directory a lookup/scan should operate in.
Linear cursor over a directory's 32-byte entries.
Identifies the exFAT directory a lookup, scan or link operates in.
Directory position (cluster + entry index) of one 32-byte entry.
uint32_t index
Entry index within that cluster (0-based).
uint32_t cluster
Directory cluster holding the entry.
Cached parse of one mounted FAT volume.