ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_fs_fat_exfat_label.c
Go to the documentation of this file.
1
27
28#include <stddef.h>
29#include <stdint.h>
30
31#include "ra8_attributes.h"
32#include "ra8_fs.h"
33#include "ra8_fs_fat_internal.h"
34#include "ra8_fs_meta.h"
35
68 exfat_setpos_t* out_pos,
69 uint8_t* out_entry,
70 bool* out_present)
71{
72 const uint8_t label_type =
73 (uint8_t)((uint32_t)k_exfat_entry_label & (uint32_t)~(uint32_t)k_exfat_inuse_bit);
74 exfat_dir_t root = {};
75 priv_exfat_dir_root(m, &root);
76 exfat_cursor_t cur = {};
77 priv_exfat_cursor_init(&root, &cur);
78 while (cur.scanned < (uint32_t)k_exfat_scan_limit) {
79 const exfat_setpos_t at = {.cluster = cur.cluster, .index = cur.entry_in_cluster};
80 uint8_t e[k_exfat_entry_bytes] = {};
81 const ra8_err_t err = priv_exfat_next_entry(m, &cur, e);
82 if (err != k_ra8_ok) {
83 return err;
84 }
85 if (e[0] == (uint8_t)k_exfat_entry_eod) {
86 *out_pos = at;
87 *out_present = false;
88 return k_ra8_ok;
89 }
90 if ((uint8_t)(e[0] & (uint8_t)~(uint8_t)k_exfat_inuse_bit) == label_type) {
91 *out_pos = at;
92 priv_byte_copy(out_entry, e, (uint32_t)k_exfat_entry_bytes);
93 *out_present = true;
94 return k_ra8_ok;
95 }
96 }
98}
99
123static void internal_exfat_label_decode(const uint8_t* entry, char* out, uint32_t out_len)
124{
125 uint32_t n = (uint32_t)entry[k_exfat_de_lbl_cnt];
126 if (n > (uint32_t)k_exfat_fmt_label_max) {
127 n = (uint32_t)k_exfat_fmt_label_max;
128 }
129 uint32_t w = 0U;
130 for (uint32_t i = 0U; i < n; i++) {
131 if ((w + 1U) >= out_len) {
132 break;
133 }
134 out[w] = (char)entry[(uint32_t)k_exfat_de_lbl_name + (i * 2U)];
135 w++;
136 }
137 out[w] = '\0';
138}
139
140/* `priv_exfat_get_label()`: see header for the documented contract. */
141ra8_err_t priv_exfat_get_label(const ra8_fs_mount_t* m, char* out, uint32_t out_len)
142{
143 exfat_setpos_t pos = {};
144 uint8_t entry[k_exfat_entry_bytes] = {};
145 bool present = false;
146 const ra8_err_t err = internal_exfat_locate_label(m, &pos, entry, &present);
147 if (err != k_ra8_ok) {
148 return err;
149 }
150 if (!present || (entry[0] != (uint8_t)k_exfat_entry_label)) {
151 out[0] = '\0'; /* no entry, or a cleared (0x03) one: unlabelled */
152 return k_ra8_ok;
153 }
154 internal_exfat_label_decode(entry, out, out_len);
155 return k_ra8_ok;
156}
157
158/* `priv_exfat_set_label()`: see header for the documented contract. */
160{
161 exfat_setpos_t pos = {};
162 uint8_t found[k_exfat_entry_bytes] = {};
163 bool present = false;
164 const ra8_err_t err = internal_exfat_locate_label(m, &pos, found, &present);
165 if (err != k_ra8_ok) {
166 return err;
167 }
168 uint8_t entry[k_exfat_entry_bytes] = {};
169 entry[0] = (uint8_t)k_exfat_entry_label;
170 uint32_t n = 0U;
171 if (label != nullptr) {
172 while (n < (uint32_t)k_exfat_fmt_label_max) {
173 if (label[n] == '\0') {
174 break;
175 }
176 entry[(uint32_t)k_exfat_de_lbl_name + (n * 2U)] = (uint8_t)label[n];
177 n++;
178 }
179 }
180 entry[k_exfat_de_lbl_cnt] = (uint8_t)n;
181 return priv_exfat_write_dir_set(m, pos.cluster, pos.index, entry, (uint32_t)k_exfat_entry_bytes);
182}
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ 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).
void priv_byte_copy(uint8_t *dst, const uint8_t *src, uint32_t n)
Length-checked byte copy used in place of memcpy().
Definition ra8_fs_fat.c:110
void priv_exfat_dir_root(const ra8_fs_mount_t *m, exfat_dir_t *out)
Fill out with the volume root's directory location.
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_exfat_get_label(const ra8_fs_mount_t *m, char *out, uint32_t out_len)
Read an exFAT volume's label into an ASCII buffer.
ra8_err_t priv_exfat_set_label(const ra8_fs_mount_t *m, const char *label)
Set (or clear) an exFAT volume's label in place.
static void internal_exfat_label_decode(const uint8_t *entry, char *out, uint32_t out_len)
Decode an exFAT Volume Label entry's UTF-16LE label into ASCII.
static ra8_err_t internal_exfat_locate_label(const ra8_fs_mount_t *m, exfat_setpos_t *out_pos, uint8_t *out_entry, bool *out_present)
Locate the exFAT Volume Label entry (or the slot to create one at).
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.
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.
Cross-TU shared declarations for the FAT/exFAT ra8_fs adapter.
@ k_exfat_entry_label
Volume Label directory entry.
@ k_exfat_fmt_label_max
Volume-label cap (UTF-16 units).
@ k_exfat_entry_bytes
Directory entry size.
@ k_exfat_entry_eod
End-of-directory marker.
@ k_exfat_scan_limit
Max dir entries scanned (P10 bound).
@ k_exfat_inuse_bit
Directory entry type bit 7 = in use.
@ k_exfat_de_lbl_name
Volume-label entry: UTF-16 label.
@ k_exfat_de_lbl_cnt
Volume-label entry: CharacterCount.
Volume-level metadata: free space, volume label, and per-entry utime.
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 entry_in_cluster
Next entry index within the cluster.
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.