|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Path metadata lookup – what is at this path, without opening it. More...
#include <stddef.h>#include <stdint.h>#include "ra8_attributes.h"#include "ra8_fs.h"#include "ra8_fs_fat_internal.h"Go to the source code of this file.
Enumerations | |
| enum | fs_stat_field_t : uint16_t { k_stat_fat_year_shift = 9U , k_stat_fat_month_shift = 5U , k_stat_fat_month_mask = 0x0FU , k_stat_fat_day_mask = 0x1FU , k_stat_fat_hour_shift = 11U , k_stat_fat_hour_mask = 0x1FU , k_stat_fat_minute_shift = 5U , k_stat_fat_minute_mask = 0x3FU , k_stat_fat_second_mask = 0x1FU , k_stat_tenths_per_second = 100U , k_stat_month_max = 12U , k_stat_hour_max = 23U , k_stat_minute_max = 59U , k_stat_second_max = 59U , k_stat_creation_tenth_max = 199U , k_stat_packed_time_mask = 0xFFFFU , k_stat_utc_sign_bit = 0x40U , k_stat_utc_field_modulus = 128U } |
| FAT/exFAT packed timestamp field geometry and validation bounds. More... | |
Functions | |
| static bool | internal_path_is_root (const char *path) |
Does path name the volume root rather than an entry inside it? | |
| static bool | internal_stat_fat_time_valid (const ra8_fs_datetime_t *v, uint8_t tenth, bool have_tenth) |
| Is a decoded FAT civil date/time within every legal calendar bound? | |
| static void | internal_stat_decode_fat (uint16_t date, uint16_t time, uint8_t tenth, bool have_tenth, ra8_fs_timestamp_t *out) |
| Decode one FAT-format packed date/time pair into a public timestamp. | |
| static void | internal_stat_decode_exfat (uint32_t packed, uint8_t tenth, bool have_tenth, uint8_t utc, ra8_fs_timestamp_t *out) |
| Decode one exFAT packed stamp, 10-ms increment, and UTC-offset byte. | |
| static void | internal_stat_fat_times (const uint8_t *entry, ra8_fs_stat_t *out) |
| Decode all three timestamp fields from one FAT directory entry. | |
| static void | internal_stat_exfat_times (const uint8_t *entry, ra8_fs_stat_t *out) |
| Decode all three timestamp fields from one exFAT File entry. | |
| static void | internal_stat_root (const ra8_fs_mount_t *m, ra8_fs_stat_t *out) |
Fill in out for the volume root itself. | |
| static void | internal_entry_to_stat (const uint8_t *entry, ra8_fs_stat_t *out) |
| Translate a 32-byte FAT directory entry into a ra8_fs_stat_t. | |
| static ra8_err_t | internal_stat_exfat (const ra8_fs_mount_t *m, const char *path, ra8_fs_stat_t *out) |
| stat a name on an exFAT volume, at any depth. | |
| static ra8_err_t | internal_stat_fat (const ra8_fs_mount_t *handle, const char *path, ra8_fs_stat_t *out) |
| Resolve one name in a FAT12/16/32 directory and decode its entry. | |
| static ra8_err_t | internal_stat_locked (const ra8_fs_mount_t *handle, const char *path, ra8_fs_stat_t *out) |
| Look a path up – the guarded body of ra8_fs_stat(). | |
| ra8_err_t | ra8_fs_stat (const ra8_fs_mount_t *handle, const char *path, ra8_fs_stat_t *out) |
| Report what a path names – file or directory – without opening it. | |
Path metadata lookup – what is at this path, without opening it.
stat resolves a path exactly as open does and then stops at the directory entry, reading the attribute byte, the size and the first cluster straight out of it. Not opening anything is the whole point: a directory opens perfectly well and reports DIR_FileSize 0, so an open-based stat cannot tell a folder from an empty file – and it spends one of the four file-table slots to fail at it.
Split out of ra8_fs_fat_dir.c for the 1000-line file-size cap.
Definition in file ra8_fs_fat_stat.c.
| enum fs_stat_field_t : uint16_t |
FAT/exFAT packed timestamp field geometry and validation bounds.
Definition at line 28 of file ra8_fs_fat_stat.c.
|
static |
Translate a 32-byte FAT directory entry into a ra8_fs_stat_t.
Copies the attribute byte through verbatim – read-only, hidden and system survive, where the old VFS stat invented archive for every entry – and derives is_directory from the ATTR_DIRECTORY bit rather than asserting it is clear. A directory's DIR_FileSize is 0 by specification; it is forced to 0 here anyway so a volume written by some other implementation cannot report a directory with a non-zero length.
| [in] | entry | 32 bytes of on-disk directory entry. |
| [out] | out | Receives the decoded metadata. |
entry addresses 32 readable bytes. out is non-NULL. Definition at line 368 of file ra8_fs_fat_stat.c.
References ra8_fs_stat_t::attr, ra8_fs_stat_t::first_cluster, internal_stat_fat_times(), ra8_fs_stat_t::is_directory, k_dir_off_attr, k_dir_off_file_size, k_ra8_fs_attr_directory, priv_entry_first_cluster(), priv_rd32(), and ra8_fs_stat_t::size_bytes.
Referenced by internal_stat_fat().
|
static |
Does path name the volume root rather than an entry inside it?
The root has no directory entry of its own, so it cannot be looked up; it is answered from the mount geometry instead. Any run of leading slashes with nothing after it is the root, which covers both "" and "/".
| [in] | path | NUL-terminated path. |
path names the root directory. | true | Only slashes (or nothing at all). |
| false | At least one name character follows. |
path is non-NULL. path is NUL-terminated. path.Definition at line 73 of file ra8_fs_fat_stat.c.
Referenced by internal_stat_locked().
|
static |
Decode one exFAT packed stamp, 10-ms increment, and UTC-offset byte.
Uses the FAT-compatible packed civil fields, then decodes exFAT's signed 15-minute UTC offset only when its validity bit is set.
| [in] | packed | exFAT 32-bit date/time value. |
| [in] | tenth | Optional 10-ms increment. |
| [in] | have_tenth | true for create/modify, false for access. |
| [in] | utc | exFAT UtcOffset byte. |
| [out] | out | Decoded timestamp. |
out is non-NULL. packed, tenth, and utc are raw fields from one File entry. Definition at line 207 of file ra8_fs_fat_stat.c.
References internal_stat_decode_fat(), k_fs_utc_field_mask, k_fs_utc_span_max, k_fs_utc_span_min, k_fs_utc_step_min, k_fs_utc_valid_bit, k_stat_packed_time_mask, k_stat_utc_field_modulus, k_stat_utc_sign_bit, ra8_fs_datetime_t::utc_offset_min, ra8_fs_timestamp_t::utc_offset_valid, ra8_fs_timestamp_t::valid, and ra8_fs_timestamp_t::value.
Referenced by internal_stat_exfat_times().
|
static |
Decode one FAT-format packed date/time pair into a public timestamp.
Reconstructs FAT's even-second field and optional creation centiseconds, then rejects every out-of-range calendar component through internal_stat_fat_time_valid.
| [in] | date | Packed FAT date word. |
| [in] | time | Packed FAT time word (zero for date-only access time). |
| [in] | tenth | FAT 10-ms byte (creation only), or zero. |
| [in] | have_tenth | true when tenth belongs to the stamp. |
| [out] | out | Decoded timestamp; invalid when the fields are illegal. |
out is non-NULL. date and time are raw little-endian values already read as host integers. Definition at line 160 of file ra8_fs_fat_stat.c.
References ra8_fs_datetime_t::centisecond, ra8_fs_datetime_t::day, ra8_fs_datetime_t::hour, internal_stat_fat_time_valid(), k_fs_time_epoch_year, k_stat_fat_day_mask, k_stat_fat_hour_mask, k_stat_fat_hour_shift, k_stat_fat_minute_mask, k_stat_fat_minute_shift, k_stat_fat_month_mask, k_stat_fat_month_shift, k_stat_fat_second_mask, k_stat_fat_year_shift, k_stat_tenths_per_second, ra8_fs_datetime_t::minute, ra8_fs_datetime_t::month, ra8_fs_datetime_t::second, ra8_fs_timestamp_t::utc_offset_valid, ra8_fs_timestamp_t::valid, ra8_fs_timestamp_t::value, and ra8_fs_datetime_t::year.
Referenced by internal_stat_decode_exfat(), and internal_stat_fat_times().
|
static |
stat a name on an exFAT volume, at any depth.
Reuses priv_exfat_lookup, which resolves the path's intermediate components and hands back the whole Stream entry plus the File entry's attribute byte, so a directory is told from a file by the bit that says so and the lengths come out of the same 32 bytes.
| [in] | m | Mounted exFAT volume. |
| [in] | path | Path, UTF-8, nested or root-level. |
| [out] | out | Receives the metadata of the entry. |
| k_ra8_ok | Entry found; out populated. |
| k_ra8_err_not_found | No such name, or a component is missing. |
| k_ra8_err_invalid_arg | An intermediate component names a file. |
| k_ra8_err_* | Backend read failure. |
m, path and out are non-NULL; m->type is exFAT. Definition at line 409 of file ra8_fs_fat_stat.c.
References ra8_fs_stat_t::attr, ra8_fs_stat_t::first_cluster, internal_stat_exfat_times(), ra8_fs_stat_t::is_directory, k_exfat_entry_bytes, k_exfat_off_file_attr, k_exfat_set_max_entries, k_exfat_strm_off_clus, k_exfat_strm_off_dlen, k_ra8_fs_attr_directory, k_ra8_ok, priv_exfat_find_set(), priv_exfat_resolve_parent(), priv_rd32(), priv_rd64(), and ra8_fs_stat_t::size_bytes.
|
static |
Decode all three timestamp fields from one exFAT File entry.
Maps creation, modification, and access stamps plus their UTC markers into the corresponding public stat timestamps.
| [in] | entry | exFAT File entry of at least 32 bytes. |
| [out] | out | Stat result receiving the three timestamps. |
entry is non-NULL and readable for one File entry. out is non-NULL and writable. Definition at line 292 of file ra8_fs_fat_stat.c.
References ra8_fs_stat_t::accessed, ra8_fs_stat_t::created, internal_stat_decode_exfat(), k_exfat_off_file_atime, k_exfat_off_file_autc, k_exfat_off_file_c10ms, k_exfat_off_file_ctime, k_exfat_off_file_cutc, k_exfat_off_file_m10ms, k_exfat_off_file_mtime, k_exfat_off_file_mutc, ra8_fs_stat_t::modified, and priv_rd32().
Referenced by internal_stat_exfat().
|
static |
Resolve one name in a FAT12/16/32 directory and decode its entry.
The leaf is matched by packed 8.3 name and, failing that, by VFAT long name – the same two-step priv_open_locked() uses, so stat and open agree about what exists. Split out of ::priv_stat_locked() so each stays inside the function-size gate.
| [in] | handle | Mounted FAT volume. |
| [in] | path | NUL-terminated path; never the volume root. |
| [out] | out | Receives the metadata of the entry. |
| k_ra8_ok | Entry found; out populated. |
| k_ra8_err_not_found | Nothing at path. |
| k_ra8_err_invalid_arg | A component is not a valid 8.3 name. |
| k_ra8_err_* | Backend read failure. |
handle, path and out are non-NULL; the mount is in use. out describes the entry at path. Definition at line 473 of file ra8_fs_fat_stat.c.
References internal_entry_to_stat(), internal_stat_fat(), k_max_8_3_name, k_ra8_err_not_found, k_ra8_fs_dir_entry_bytes, k_ra8_ok, priv_dir_find(), priv_dir_find_long(), priv_path_to_83(), and priv_resolve_parent().
Referenced by internal_stat_fat(), and internal_stat_locked().
|
static |
Is a decoded FAT civil date/time within every legal calendar bound?
Checks month, day, hour, minute, second, and the optional creation-centisecond byte. There is deliberately no upper-bound check on the day: FAT stores it in five bits, so date & k_stat_fat_day_mask cannot exceed 31, which is already the largest civil day. Only day == 0 is representable and illegal, and that is the guard below. Every check here is a single-condition if.
| [in] | v | Decoded (not yet validated) civil fields. |
| [in] | tenth | FAT 10-ms byte (creation only), or zero. |
| [in] | have_tenth | true when tenth belongs to the stamp. |
| true | Every field is legal. |
| false | At least one field is out of range. |
v is non-NULL. v was decoded from a raw packed FAT date/time pair. v, tenth, and have_tenth.Definition at line 110 of file ra8_fs_fat_stat.c.
References ra8_fs_datetime_t::day, ra8_fs_datetime_t::hour, k_stat_creation_tenth_max, k_stat_hour_max, k_stat_minute_max, k_stat_month_max, k_stat_second_max, ra8_fs_datetime_t::minute, ra8_fs_datetime_t::month, and ra8_fs_datetime_t::second.
Referenced by internal_stat_decode_fat().
|
static |
Decode all three timestamp fields from one FAT directory entry.
Maps creation, modification, and date-only access fields into the corresponding public stat timestamps without mutating the entry.
| [in] | entry | FAT directory entry of at least 32 bytes. |
| [out] | out | Stat result receiving the three timestamps. |
entry is non-NULL and readable for one directory entry. out is non-NULL and writable. Definition at line 255 of file ra8_fs_fat_stat.c.
References ra8_fs_stat_t::accessed, ra8_fs_stat_t::created, internal_stat_decode_fat(), k_dir_off_crt_date, k_dir_off_crt_time, k_dir_off_crt_time_tenth, k_dir_off_lst_acc_date, k_dir_off_wrt_date, k_dir_off_wrt_time, ra8_fs_stat_t::modified, and priv_rd16().
Referenced by internal_entry_to_stat().
|
static |
Look a path up – the guarded body of ra8_fs_stat().
Validates the arguments, answers the volume root out of the mount geometry (the root has no directory entry to read), and otherwise hands off to the exFAT or the FAT lookup. Nothing is opened on any path, so no file-table slot is consumed and a directory never has to be mistaken for a zero-byte file to be reported at all.
| [in] | handle | Mount handle. |
| [in] | path | NUL-terminated path. |
| [out] | out | Receives the metadata of the entry. |
| k_ra8_ok | Entry found; out populated. |
| k_ra8_err_null_ptr | Any pointer argument was NULL. |
| k_ra8_err_invalid_state | Mount is not in use. |
| k_ra8_err_not_found | Nothing at path. |
| k_ra8_err_* | As documented for ra8_fs_stat(). |
path. Definition at line 534 of file ra8_fs_fat_stat.c.
References internal_path_is_root(), internal_stat_fat(), internal_stat_locked(), internal_stat_root(), k_ra8_err_null_ptr, k_ra8_fs_type_exfat, and k_ra8_ok.
Referenced by internal_stat_locked(), and ra8_fs_stat().
|
static |
Fill in out for the volume root itself.
The root always exists and is always a directory. Its first_cluster is the FAT32 / exFAT root cluster, and 0 on FAT12/16 where the root is a fixed sector region with no chain – which is the same "no chain" value an empty file carries.
| [in] | m | Mounted volume supplying the root cluster. |
| [out] | out | Receives the metadata of the root. |
m and out are non-NULL. m is in use. Definition at line 334 of file ra8_fs_fat_stat.c.
References ra8_fs_stat_t::attr, ra8_fs_stat_t::first_cluster, ra8_fs_stat_t::is_directory, k_ra8_fs_attr_directory, ra8_fs_mount_t::root_cluster, and ra8_fs_stat_t::size_bytes.
Referenced by internal_stat_locked().
|
nodiscard |
Report what a path names – file or directory – without opening it.
Resolves path the same way ra8_fs_open() does (parent walk, 8.3 lookup, VFAT long-name fallback on FAT; root-directory entry-set scan on exFAT) but stops at the directory entry and reads the answer straight out of it. Nothing is opened, so no file-table slot is consumed and a directory is reported as a directory rather than as a zero-byte file – which is what opening one would have made it look like, DIR_FileSize being 0 by definition.
Creation, modification, and access timestamps are decoded from the same entry. FAT access time is date-only and FAT carries no UTC offset; exFAT reports its 10-ms increments and offset-valid bits. A malformed third-party stamp is returned with timestamp.valid == false rather than guessed.
A path naming the volume root ("", "/") is answered from the mount geometry: it always exists and is always a directory. Because the root has no directory entry of its own, its three timestamp results are invalid.
| [in] | handle | Mount handle. |
| [in] | path | NUL-terminated path. Nested paths resolve on every supported filesystem, FAT12/16/32 and exFAT alike. |
| [out] | out | Receives the entry's metadata on success. |
| k_ra8_ok | Entry found; out populated. |
| k_ra8_err_null_ptr | Any pointer argument was NULL. |
| k_ra8_err_invalid_state | Mount is not in use. |
| k_ra8_err_not_found | Nothing at path (or an intermediate component is missing). |
| k_ra8_err_invalid_arg | A path component is longer than 247 characters. |
| k_ra8_err_* | Backend read failure. |
Definition at line 565 of file ra8_fs_fat_stat.c.
References internal_stat_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_stat().
Referenced by demo_file_ops(), internal_native_stat(), and ra8_fs_stat().