36940db938a8f4a1e919496793ed439850a221c2다. 해당 파일 시스템 백엔드와 실제 저장 장치 또는 파티션이 빌드·보드에 준비되어 있다는 전제에서 공개 API와 고정 구현을 설명한다. 예시 경로는 구조를 설명하는 가상 구성으로, 어떤 보드에나 그대로 쓸 수 있는 설정값이 아니다. 그림과 표는 이 글을 위해 새로 그렸다.1. VFS는 경로를 백엔드로 보내지만 매체를 만들지 않는다
Zephyr 파일 시스템 스위치는 여러 fs_mount_t를 등록된 백엔드와 연결한다. 파일 호출은 절대 경로에서 해당 마운트 지점을 찾아 fs_file_system_t의 작업으로 위임한다. 고정 fs.c는 경로 구분자 경계를 확인하고 가장 긴 일치 마운트 지점을 선택한다. 따라서 /data/log는 /data에 속하지만 /database/log를 같은 접두사로 취급하지 않는다. 실제 저장소의 준비와 오류는 선택된 백엔드 아래에서 결정된다.
fs_open, 다른 마운트·매체 경로↔ 좁은 화면에서는 왼쪽의 호출에서 각 오른쪽 경로까지 이동하세요.
fs_open(&file, path, flags)초기화한 파일 객체·절대 경로·모드/lfs/reportVFS의 /lfs 마운트 → LittleFS → 지정한 flash area 또는 지원·설정된 block device/SD:/reportVFS의 FAT 마운트 → FatFS → Disk Access → 해당 디스크 드라이버·매체경로 이름만 만들면 파일 시스템이 생기는 것은 아니다. 백엔드 등록, 마운트 구조체, 매체 드라이버 또는 파티션이 모두 맞아야 한다. v3.7.0 ELM FAT 경로에는 허용되는 볼륨 이름 제약도 있으므로 위의 /SD:는 사용 가능한 디스크 이름을 가정한 예시다.
근거: 3.7.0 VFS·마운트 API, 경로 경계·최장 일치 선택 및 파일 호출 위임, FAT 마운트 이름 조건.
2. 성공한 fs_mount는 설정 구조체의 수명도 잡는다
fs_mount(&mp)는 타입·마운트 지점·백엔드 데이터·저장소 참조·플래그를 담은 fs_mount_t를 사용한다. 성공하면 VFS가 그 구조체의 참조를 유지하므로 호출자는 같은 포인터의 fs_unmount()가 성공할 때까지 내용을 바꾸거나 수명을 끝내면 안 된다. 마운트 해제 전에 열린 파일을 닫고, 해제의 반환값을 확인해 매체와 상위 코드의 소유권 전환을 맞춘다.
↔ 왼쪽에서 오른쪽으로 설정, 마운트, 사용, 해제 시점을 확인하세요.
type, mnt_point, fs_data, storage_dev, flags와 매체를 맞춘다.mp를 참조한다. 파일 작업 중 구조체나 매체 조건을 임의 변경하지 않는다.fs_unmount(&mp) 결과를 확인한 뒤 구조체·매체를 재설정한다.| 플래그 | 뜻 | 주의할 경계 |
|---|---|---|
FS_MOUNT_FLAG_NO_FORMAT | 마운트에 실패했을 때 백엔드의 자동 포맷 경로를 막는다. | 포맷 기능 자체가 없는 백엔드까지 새 기능을 만드는 값이 아니다. |
FS_MOUNT_FLAG_READ_ONLY | 읽기 전용 마운트를 요청하고 VFS의 생성·쓰기 경로를 제한한다. | 포맷이 필요한 매체는 읽기 전용으로 복구할 수 없으며 오류가 날 수 있다. |
FS_MOUNT_FLAG_AUTOMOUNT | 사전 정의된 fstab 마운트의 시작 시점 자동 마운트 표시다. | 호출자가 직접 만든 구조체에서는 이 플래그만으로 자동 실행되지 않는다. |
FS_MOUNT_FLAG_USE_DISK_ACCESS | Disk Access 사용을 요청한다. | LittleFS의 block-device 설정·드라이버가 필요하며, 모든 백엔드가 flash 경로와 disk 경로를 둘 다 제공하지 않는다. |
3. LittleFS와 FatFS는 같은 VFS 아래의 다른 저장 경로다
고정 LittleFS 구현은 기본 flash-area 경로와, CONFIG_FS_LITTLEFS_BLK_DEV를 갖춘 block-device 경로를 구분한다. 마운트의 storage_dev가 가리키는 대상과 USE_DISK_ACCESS 플래그가 일치해야 한다. FatFS는 Disk Access가 제공하는 볼륨에 접근한다. SD 카드뿐 아니라 flash-disk처럼 flash 파티션을 block device로 바꿔 제공할 수도 있지만, 그것이 LittleFS의 flash-area 경로와 동일하다는 뜻은 아니다.
↔ 오른쪽으로 이동하며 각 백엔드의 전제와 끝점을 비교하세요.
flash_area_*| 선택 | 매체 준비 | 마운트에 실패할 때 확인할 점 |
|---|---|---|
| LittleFS · flash | Flash map 영역과 맞는 fs_littlefs 설정 | NO_FORMAT·READ_ONLY가 없으면 고정 백엔드는 실패 후 포맷을 시도할 수 있다. |
| LittleFS · block | CONFIG_FS_LITTLEFS_BLK_DEV, Disk Access 볼륨, USE_DISK_ACCESS | 장치·block 크기·기존 on-disk 형식이 맞는지 확인한다. |
| FatFS | 허용되는 볼륨 이름과 Disk Access 장치; 매체별 구성 | CONFIG_FS_FATFS_MOUNT_MKFS가 켜진 경우에만, 해당 조건에서 자동 포맷 경로가 생긴다. NO_FORMAT은 이를 막는다. |
데이터가 남아 있는 매체에서는 포맷 설정부터 검토한다. LittleFS 예시 문서는 호환되지 않는 파티션 내용이 빈 파일 시스템으로 바뀔 수 있다고 설명한다. FAT 예시도 마운트에 실패하면 설정에 따라 재포맷될 수 있다고 경고한다. 이것은 모든 마운트 실패가 데이터 손상이라는 뜻도, 모든 실패가 자동 복구된다는 뜻도 아니다.
근거: LittleFS flash/block 분기·포맷 분기, FatFS Disk Access·조건부 포맷, 3.7.0 LittleFS 매체 예시, 3.7.0 FAT 예시 경고, Disk Access와 flash-disk.
4. 파일 객체의 수명은 open과 close 사이에 있다
fs_file_t_init()로 파일 객체를 초기화한 뒤 절대 경로와 모드 플래그를 fs_open()에 준다. 성공한 객체는 사용 후 fs_close()로 닫는다. FS_O_CREATE는 없는 파일 생성, FS_O_APPEND는 쓰기 전 끝으로 이동, FS_O_TRUNC는 열 때 길이를 0으로 만드는 요청이며, truncate에는 쓰기 모드와 백엔드 지원이 필요하다. 모드 0은 파일이 있어도 읽기·쓰기 권한을 주지 않는다.
| 단계 | API와 반환 | 호출자의 책임 |
|---|---|---|
| 객체 준비 | fs_file_t_init(&file) | 처음 사용 전에 초기화한다. 같은 열린 객체에 다시 open하면 -EBUSY다. |
| 열기 | fs_open(&file, path, flags); 0 또는 음수 오류 | 절대 경로·마운트·모드·백엔드 지원을 구분한다. |
| 읽기 | fs_read; 실제 읽은 바이트 수 또는 음수 오류 | 요청한 길이보다 짧은 성공을 처리한다. |
| 쓰기 | fs_write; 실제 쓴 바이트 수 또는 음수 오류 | 짧은 쓰기와 남은 데이터 처리·오류를 확인한다. |
| 정리 | fs_close(&file); 0 또는 음수 오류 | 성공한 뒤 파일 객체를 재사용한다. v3.7.0은 백엔드 close가 실패하면 file.mp를 비우지 않으므로, 실패를 닫기 완료로 취급하지 않는다. |
5. 오류 번호는 어느 경계에서 막혔는지 말해 준다
열기 실패를 모두 “매체가 없다”로 해석하면 진단이 틀어진다. 경로 문법, 마운트 검색, 읽기 전용 제한, 백엔드 미구현, 파일 부재는 각각 다른 단계다. fs_read()와 fs_write()의 0 이상 값은 요청 전체가 처리됐다는 뜻이 아니라 실제 처리한 바이트 수다. v3.7.0 문서는 짧은 쓰기에서 전역 errno도 확인하도록 안내한다. 장치에 영속 반영되는 시점은 백엔드마다 달라질 수 있으므로 성공한 write만으로 전원 장애 내구성을 선언하지 않는다.
| 관찰 | 우선 확인할 경계 | 다음 행동 |
|---|---|---|
fs_open → -EINVAL | 절대 경로와 유효한 파일 이름 | 호출 인자와 경로 문법을 확인한다. |
fs_open → -ENOENT | 마운트 지점 또는 요청 파일 부재 | 마운트 성공·생성 플래그·파일 존재를 구분한다. |
fs_open → -EROFS | 읽기 전용 마운트의 생성·쓰기 요청 | 마운트 플래그와 열기 모드를 확인한다. |
fs_open → -ENOTSUP | 백엔드의 해당 작업 미구현 | 파일 시스템 드라이버와 옵션을 확인한다. |
fs_read/write → n < 요청 길이 | 정상적인 짧은 읽기 또는 쓰기 실패·용량 문제 | 읽기 종료와 쓰기 잔량을 별도로 처리한다. |
6. 보드에 넣기 전에는 구성과 수명을 함께 점검한다
| 질문 | 확인할 대상 | 놓치면 생기는 일 |
|---|---|---|
| 어느 마운트에 들어가는가? | 절대 경로·마운트 이름·해당 백엔드 등록 | 잘못된 매체로 이동하거나 -ENOENT |
| 매체 경로가 맞는가? | LittleFS flash area/block, FatFS Disk Access 및 드라이버 | 마운트 실패 또는 설정과 다른 장치 접근 |
| 포맷이 허용되는가? | NO_FORMAT 및 FatFS 포맷 Kconfig | 기존 내용이 빈 파일 시스템으로 바뀔 수 있음 |
| 파일과 마운트는 누가 닫는가? | fs_close 뒤 fs_unmount의 반환 | 매체를 분리할 때 미반영 데이터·수명 경합 |
| 성공한 I/O 길이가 충분한가? | fs_read/write의 바이트 수와 오류 | 부분 데이터가 전체 처리로 오인됨 |
테스트는 새 매체와 기존 데이터가 있는 매체를 따로 준비하고, 예상한 백엔드의 마운트 성공·실패, 읽기 전용, 용량 부족, 짧은 I/O, 안전한 분리 순서를 확인한다. 이 글의 그림은 고정 버전의 계약을 설명하는 자료이며 특정 보드의 신뢰성·전원 장애 복구를 실험한 결과는 아니다.
7. 고정 버전 근거와 이어 읽기
공개 계약은 Zephyr 3.7.0 File Systems와 v3.7.0 fs.h, 경로·핸들 동작은 fs.c, 저장 경로는 LittleFS와 FatFS에 고정했다. 매체 조건과 포맷 경고는 해당 버전의 LittleFS 예시·FAT 예시·Disk Access 문서와 대조했다.