MS-RTOS 文件系统

更新时间:
2023-11-30
下载文档

MS-RTOS 文件系统

本章将介绍 MS-RTOS 文件系统开发。

文件系统实现

文件系统实现是 MS-RTOS IO 子系统对不同实现方法面向不同储存介质的文件系统技术的抽象。

不同的文件系统实现提供了不同的 API,MS-RTOS 为了保证上层应用能使用统一的一套 API 操作、读写文件达到跨平台的目的,MS-RTOS IO 子系统对文件系统进行了抽象。

多套文件系统实现能够在 MS-RTOS 中共存,MS-RTOS 针对各种储存介质和需求提供了丰富的文件系统支持:

文件系统面向的储存介质特性
devfs设备文件系统
MS-FLASHFSMCU 内部 FLASH掉电安全,主要用于存放 APP 镜像和启动参数文件,支持 APP XIP(片内执行)
fatfsSD 卡、U 盘FAT 文件系统,PC 交换数据便利,开源免费
littlefsNOR FLASH掉电安全、磨损平衡,开源免费
yaffsNAND FLASH掉电安全、磨损平衡、坏块管理,十分成熟,商用收费
uffsNAND FLASH掉电安全、磨损平衡、坏块管理,内存占用较 yaffs 少,开源免费
edgefsSD 卡、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 子系统内核对象的统计信息
文档内容是否对您有所帮助?
有帮助
没帮助