MS-RTOS 文件系统
本章将介绍 MS-RTOS 文件系统开发。
文件系统实现
文件系统实现是 MS-RTOS IO 子系统对不同实现方法面向不同储存介质的文件系统技术的抽象。
不同的文件系统实现提供了不同的 API,MS-RTOS 为了保证上层应用能使用统一的一套 API 操作、读写文件达到跨平台的目的,MS-RTOS IO 子系统对文件系统进行了抽象。
多套文件系统实现能够在 MS-RTOS 中共存,MS-RTOS 针对各种储存介质和需求提供了丰富的文件系统支持:
文件系统 | 面向的储存介质 | 特性 |
---|---|---|
devfs | 无 | 设备文件系统 |
MS-FLASHFS | MCU 内部 FLASH | 掉电安全,主要用于存放 APP 镜像和启动参数文件,支持 APP XIP(片内执行) |
fatfs | SD 卡、U 盘 | FAT 文件系统,PC 交换数据便利,开源免费 |
littlefs | NOR FLASH | 掉电安全、磨损平衡,开源免费 |
yaffs | NAND FLASH | 掉电安全、磨损平衡、坏块管理,十分成熟,商用收费 |
uffs | NAND FLASH | 掉电安全、磨损平衡、坏块管理,内存占用较 yaffs 少,开源免费 |
edgefs | SD 卡、U 盘 | 掉电安全,商用收费 |
文件系统实现示例
以 littlefs 为例,需要定义一个 ms_io_fs_t
对象及实现相关的文件系统操作 ms_io_fs_ops_t
:
// 文件系统操作
static ms_io_fs_ops_t ms_io_littlefs_ops = {
.type = MS_IO_FS_TYPE_DISKFS,
.mount = __ms_littlefs_mount,
.unmount = __ms_littlefs_unmount,
.mkfs = __ms_littlefs_mkfs,
.link = MS_NULL,
.unlink = __ms_littlefs_unlink,
.mkdir = __ms_littlefs_mkdir,
.rmdir = __ms_littlefs_unlink,
.rename = __ms_littlefs_rename,
.sync = __ms_littlefs_sync,
.truncate = __ms_littlefs_truncate,
.stat = __ms_littlefs_stat,
.lstat = __ms_littlefs_stat,
.statvfs = __ms_littlefs_statvfs,
.open = __ms_littlefs_open,
.close = __ms_littlefs_close,
.read = __ms_littlefs_read,
.write = __ms_littlefs_write,
.ioctl = MS_NULL,
.fcntl = __ms_littlefs_fcntl,
.fstat = __ms_littlefs_fstat,
.isatty = __ms_littlefs_isatty,
.fsync = __ms_littlefs_fsync,
.fdatasync = __ms_littlefs_fsync,
.ftruncate = __ms_littlefs_ftruncate,
.lseek = __ms_littlefs_lseek,
.poll = MS_NULL,
.opendir = __ms_littlefs_opendir,
.closedir = __ms_littlefs_closedir,
.readdir_r = __ms_littlefs_readdir_r,
.rewinddir = __ms_littlefs_rewinddir,
.seekdir = __ms_littlefs_seekdir,
.telldir = __ms_littlefs_telldir,
};
// 文件系统对象
static ms_io_fs_t ms_io_littlefs = {
.nnode = {
.name = MS_LITTLEFS_NAME,
},
.ops = &ms_io_littlefs_ops,
};
// 注册文件系统
ms_err_t ms_littlefs_register(void)
{
return ms_io_fs_register(&ms_io_littlefs);
}
相关 API
// 注册驱动(如块设备驱动)
ms_err_t ms_io_driver_register(ms_io_driver_t *drv);
// 注册设备(如块设备)
ms_err_t ms_io_device_register(ms_io_device_t *dev, const char *dev_path, const char *drv_name, ms_ptr_t ctx);
// 移除设备(如块设备)
ms_err_t ms_io_device_unregister(ms_io_device_t *dev);
// 注册文件系统
ms_err_t ms_io_fs_register(ms_io_fs_t *fs);
// 格式化磁盘
ms_err_t ms_io_mkfs(const char *path, ms_const_ptr_t param);
// 挂载磁盘
ms_err_t ms_io_mount(const char *mnt_path, const char *dev_path, const char *fs_name, ms_const_ptr_t param);
// 挂载磁盘
ms_err_t ms_io_mount_ex(const char *mnt_path, const char *dev_path, const char *fs_name, ms_const_ptr_t param,
ms_callback_t on_umount, ms_ptr_t on_umount_arg);
// 卸载挂载点
ms_err_t ms_io_unmount(const char *mnt_path, ms_const_ptr_t param);
磁盘热插拨与自动挂载
实现磁盘热插拨与自动挂载有以下几种方法:
- GPIO 管脚中断方式检测,通过中断底半部或 IO JOB 自动挂载
- 周期性任务检测,实现自动挂载
- 软件定时器周期性检测,实现自动挂载
- IO JOB 周期性检测,实现自动挂载
- 响应 USB 协议栈的 U 盘插拨事件,实现自动挂载
使用 IO JOB 周期性检测,实现自动挂载的示例:
// SD 卡检测
static void __stm32_sd_detect(ms_ptr_t arg)
{
static ms_io_device_t sd_blk_dev[1];
static ms_bool_t registed = MS_FALSE;
ms_bool_t detected;
ms_err_t err;
detected = BSP_SD_IsDetected();
if (detected && !registed) { // SD 已插入但之前并没有注册块设备
BSP_SD_Init();
// 注册块设备
err = ms_io_device_register(&sd_blk_dev[0], "/dev/sd_blk0", "stm32_sd", MS_NULL);
if (err == MS_ERR_NONE) {
// 标记已经注册块设备
registed = MS_TRUE;
}
// 挂载文件系统
ms_io_mount("/sd0", "/dev/sd_blk0", MS_FATFS_NAME, (ms_ptr_t)0);
} else if (!detected && registed) { // SD 已移除并且之前注册了块设备
// 卸载挂载点
ms_io_unmount("/sd0", MS_NULL);
// 卸载块设备
err = ms_io_device_unregister(&sd_blk_dev[0]);
if (err == MS_ERR_NONE) {
// 标记为未注册块设备
registed = MS_FALSE;
}
BSP_SD_DeInit();
}
}
// 注册 SD 卡驱动
ms_err_t stm32_sd_drv_register(void)
{
static ms_io_job_t sd_detect_job;
BSP_SD_Init();
ms_semc_create("sd_semc", 0, UINT32_MAX, MS_WAIT_TYPE_PRIO, &stm32_sd_sync_semid);
ms_io_driver_register(&stm32_sd_drv);
// 初始化并启动周期性检测 SD 卡热插拨的 IO JOB
ms_io_job_init(&sd_detect_job, "sd_detect", __stm32_sd_detect, MS_NULL);
ms_io_job_start(&sd_detect_job, 0, MS_TICK_PER_SEC, MS_IO_JOB_OPT_PERIODIC);
return MS_ERR_NONE;
}
相关命令
命令 | 介绍 | 参数 |
---|---|---|
ls | 查看当前工作目录或指定目录的文件和目录 | ls [path] |
cd | 切换当前工作目录 | cd path |
pwd | 查看当前工作目录路径 | 无 |
sync | 回写磁盘缓冲到磁盘 | 无 |
mkdir | 创建一个目录 | mkdir path |
touch | 创建一个文件 | touch path |
cat | 显示文件内容 | cat path |
cp | 复制文件 | cp source dest |
mv | 移动文件/文件重命名 | mv source dst |
rm | 删除一个文件或空目录 | rm path |
mkfs | 格式化磁盘 | mkfs path |
df | 查看磁盘的状态及信息 | df path |
drvs | 查看注册的驱动 | 无 |
devs | 查看注册的设备 | 无 |
fss | 查看注册的文件系统 | 无 |
mnts | 查看挂载的挂载点 | 无 |
buss | 查看注册的总线和总线上的设备 | 无 |
iostat | 查看 IO 子系统内核对象的统计信息 | 无 |