0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

文件系统-一切皆文件的设计理念

冬至子 来源:编程外星人 作者:怪蛙 2023-10-11 10:10 次阅读

在这一节中,我们来一起学习和完成文件树中最后一个关键性内容——一切皆文件的设计理念。

所谓一切皆文件就是指计算机操作系统将一切计算机的可用资源都映射成文件形式向使用者提供统一的操作方式。我们在第一节时已经有了明确的讲述,在这一节中我们来看一下具体的设计理念和实现方法。我们在操作系统中为用户构建的虚拟系统中,树的每一个节点都是一个文件,而这些文件虽然有着不同的类型和功能,如普通文件、键盘、鼠标、打印机、显示器、内存页、操作系统调度状态等等,但却有着相同的文件操作接口。对于用户而言普通文件的操作通常只有“打开”、“关闭”、“读取”、“写入”这几个操作,而对于较为特殊的文件,通常还需要加入“输入输出控制”、“尝试获取数据”这两个操作,因此对于虚拟文件系统中的文件我们可以为其定义这样6个通用的操作:

  • open()
  • close()
  • read()
  • write()
  • ioctl()
  • poll()
    `
    这6个函数是目前操作系统中对文件操作的函数,当然有的操作系统还实现了一些其它的操作函数,我们不一一列举,只是针对这6个最具有代表性的函数进行说明。用户对文件树中的文件进程上面6个操作,也就是说每一个文件节点中应该有这6个函数的实现方法。具体来说,我们在虚拟文件树中注册一个设备节点时,这个设备节点就是虚拟文件树中的一个文件,我们可以为此设备节点的结构体加入上述6个函数指针:
typedef struct file_operations_s
{
  int (*open)(void);
  int (*close)(void);
  size_t (*read)(void *, size_t);
  size_t (*write)(const void *, size_t);
  int (*ioctl)(unsigned int, unsigned long);
  int (*poll)(unsigned int);
} file_operations_s;


typedef struct vfs_node_s
{
  struct vfs_node_s *sibling;
  struct vfs_node_s *child;
  char name[NODE_NAME_SIZE];
  struct file_operations_s ops;
} vfs_node_s;

在这里我们定义了一个结构体struct file_operations_s,这个结构体中定义了6个函数指针,用于表示这个文件的通用的6个操作。而具体的实现由注册这个设备节点的具体驱动程序来实现。接下来我们来实现当用户对某一个文件进行这6个操作时,虚拟文件系统的具体实现方法:

//打开文件
int open(char *path, int oflag, int mode)
{
  vfs_node_s *node = fs_get_node(path);
  pcb_s *pcb = sche_curr_pcb();
  node- >ops.open();
  uint32_t ind = fcntl_first_empty(pcb);
  //申请节点
  fcntl_alloc(pcb, ind);
  pcb- >fnodes[ind] = node;
  return ind;
}


//关闭文件
int close(int fd)
{
  pcb_s *pcb = sche_curr_pcb();
  vfs_node_s *node = pcb- >fnodes[fd];
  int ret = node- >ops.close();
  pcb- >fnodes[fd] = NULL;
  fcntl_free(pcb, fd);
  return ret;
}


//读取文件内容
size_t read(int fd, void *buf, size_t count)
{
  pcb_s *pcb = sche_curr_pcb();
  vfs_node_s *node = pcb- >fnodes[fd];
  return node- >ops.read(NULL, buf, count);
}


//写入文件内容
size_t write(int fd, void *buf, size_t count)
{
  pcb_s *pcb = sche_curr_pcb();
  vfs_node_s *node = pcb- >fnodes[fd];
  return node- >ops.write(NULL, buf, count);
}


//输入输出控制
int ioctl(int fd, unsigned int cmd, unsigned long arg)
{
  pcb_s *pcb = sche_curr_pcb();
  vfs_node_s *node = pcb- >fnodes[fd];
  return node- >ops.ioctl(NULL, cmd, arg);
}


//尝试获取资源
int poll(int fd, unsigned int ms)
{
  pcb_s *pcb = sche_curr_pcb();
  vfs_node_s *node = pcb- >fnodes[fd];
  return node- >ops.poll(ms);
}

最后,我们来具体看一下如何编写一个驱动程序,并将这个驱动程序注册为虚拟文件系统中的一个设备节点,即文件。用户又如何通过通用的操作来实现对此设备的控制。

最简单的,我们可以通过对一个GPIO引脚的拉高拉低来实现一个LED灯的亮和灭,使用Cortex-M3处理下的实现方式有两步,第一步:初始化GPIO引脚;第二步:对GPIO进行拉高或拉低,从而达到LED亮和灭的操作。具体实现程序如下:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);

接下来,当我们需要点亮LED灯时,对PC4引脚拉低;当需要熄灭时,对PC4引脚拉高,于是程序如下:

//点亮,拉低
GPIO_WriteBit(GPIOC, GPIO_Pin_4, 0);


//熄灭,拉高
GPIO_WriteBit(GPIOC, GPIO_Pin_4, 1);

对于驱动程序而言,我们不希望用户在使用LED时编写较为复杂的、直接操作硬件的代码,而是希望操作系统为用户提供一个通用的操作接口函数,于是我们就可以编写一个驱动程序,并向操作系统注册一个"/dev/led"设备节点,而"/dev/led"这个文件就是一个设备文件,它的内部由驱动开发人员完成与硬件交互的功能,对使用人员则只提供open()、close()、read()、write()、ioctl()、poll()等操作函数。对于LED灯来说,驱动程序比较简单我们只实现其open()、close()、ioctl()这3个函数。有兴趣的读者可以自行实现read()、write()、poll()等函数:

#define LED_IOCTL_ON (0)
#define LED_IOCTL_OFF (0)


void led_drv_init(void)
{
  file_operations_s ops = {0};
  ops.open = led_open;
  ops.close = led_close;
  ops.read = NULL;
  ops.write = NULL;
  ops.ioctl = led_ioctl;
  ops.poll = NULL;
  fs_register_dev("/dev/led", ops);
}


int led_open(void)
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);


  return 0;
}


int led_close(void)
{
  return 0;
}


int led_ioctl(void, unsigned int cmd, unsigned long arg)
{
  switch (cmd)
  {
  case LED_IOCTL_ON:
    GPIO_WriteBit(GPIOC, GPIO_Pin_4, 0);
    break;


  case LED_IOCTL_OFF:
    GPIO_WriteBit(GPIOC, GPIO_Pin_4, 1);
    break;

  default:
    break;
  }
  return 0;
}

这样我们就编写了一个LED灯的驱动程序,并在操作系统中注册为"/dev/led"设备节点,即文件。用户可以通过以下方式来操作这个LED设备:

int fd = open("/dev/led");


//点亮
ioctl(fd, LED_IOCTL_ON);
//熄灭
ioctl(fd, LED_IOCTL_OFF);


close(fd);

对于用户而言,操作这个硬件LED灯就与操作普通文件一样,通过open()函数打开这个文件,通过ioctl这个函数对这个文件进行相关的控制,使用完毕之后再通过close()函数关闭此文件,于是,硬件与用户之间就减少了很多特定的功能操作,用户也不必关心硬件设备的具体实现细节,只需要对这个设备文件进行通用操作即可。而对于编写驱动程序的人员来说,只需要将硬件相关的程序和操作封装到驱动程序内部即可,无需暴露给用户。这样就实现了“一切皆文件”的设计理念。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • led灯
    +关注

    关注

    22

    文章

    1554

    浏览量

    107030
  • 计算机
    +关注

    关注

    19

    文章

    6649

    浏览量

    84523
  • Cortex-M3
    +关注

    关注

    9

    文章

    268

    浏览量

    59162
  • GPIO
    +关注

    关注

    16

    文章

    1133

    浏览量

    50570
  • PCB
    PCB
    +关注

    关注

    1

    文章

    1576

    浏览量

    13204
收藏 人收藏

    评论

    相关推荐

    嵌入式Linux根文件系统概述

    Linux中一切文件! 是指:在Linux系统中,各个部分都可把它看成是文件,包括了所有的
    发表于 12-16 06:37

    Linux文件系统课程

    本章学习目标理解什么是文件系统了解文件系统工作原理理解Fedora Core Linux文件系统的结构掌握Fedora Core Linux文件系统的类型、权限和修改方法掌握如何安装、
    发表于 04-10 17:07 0次下载

    NTFS文件系统,NTFS文件系统是什么意思

    NTFS文件系统,NTFS文件系统是什么意思 NTFS是Windows NT以及之后的Windows 2000、Windows XP、Windows Server 2003、Windows Server 2008
    发表于 03-29 10:38 5678次阅读

    XfS文件系统,XfS文件系统是什么意思

    XfS文件系统,XfS文件系统是什么意思 XfS文件系统是SGI开发的高级日志文件系统,XFS极具伸缩性,非常健壮。所幸的是SGI将其移植到了Lin
    发表于 03-29 10:39 4076次阅读

    Linux根文件系统简介

    Linux根文件系统简介 什么是根文件   根文件系统首先是一种文件系统,但是相对于普通的文件系统,它的特殊之处在于,它是内核启动时所m
    发表于 04-21 17:01 5027次阅读

    FatFs文件系统使用

    STM系列FatFs文件系统使用文件,希望对大家有帮助。
    发表于 11-06 18:10 8次下载

    文件系统是什么?浅谈EXT文件系统历史

    在先前关于Linux文件系统的文章中,我很想去深入地讨论更多EXT文件系统的特性的信息。所以,首先让我们来回答这个问题:什么是文件系统?一个文件系统应该遵循以下特点。
    发表于 06-28 09:03 5432次阅读
    <b class='flag-5'>文件系统</b>是什么?浅谈EXT<b class='flag-5'>文件系统</b>历史

    linux文件系统中的虚拟文件系统设计详解

    Linux 中允许众多不同的文件系统共存,如 ext2, ext3, vfat 等。通过使用同一套文件 I/O 系统 调用即可对 Linux 中的任意文件进行操作而无需考虑其所在的具体
    发表于 04-02 14:37 1583次阅读
    linux<b class='flag-5'>文件系统</b>中的虚拟<b class='flag-5'>文件系统</b>设计详解

    如何区别Linux文件系统呢?

    虚拟文件系统是一种神奇的抽象,它使得 “一切文件” 哲学在 Linux 中成为了可能。
    的头像 发表于 08-09 18:00 3408次阅读

    Linux文件系统与持久性内存

    1、Linux 虚拟文件系统介绍 在 Linux 系统一切文件,除了通常所说的狭义的文件以外,目录、设备、套接字和管道等都是
    的头像 发表于 11-26 14:34 2283次阅读
    Linux<b class='flag-5'>文件系统</b>与持久性内存

    如何去自制文件系统?开发文件系统为什么难?

    我们先从什么是文件系统讲起,简单介绍一些探索文件系统的基础知识。
    的头像 发表于 06-11 16:27 3152次阅读
    如何去自制<b class='flag-5'>文件系统</b>?开发<b class='flag-5'>文件系统</b>为什么难?

    FATFS文件系统详解

    一、文件系统负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。即在磁盘上组织文件
    发表于 11-29 09:51 29次下载
    FATFS<b class='flag-5'>文件系统</b>详解

    FATFS文件系统原版文件下载

    FATFS文件系统原版文件下载
    发表于 06-25 09:02 0次下载

    什么是分布式文件系统

    我们无时无刻不在使用文件系统,进行开发时在使用文件系统,浏览网页时在使用文件系统,玩手机时也在使用文件系统
    的头像 发表于 03-10 16:21 3659次阅读

    Linux的文件系统特点

    Linux的文件系统特点 文件系统要有严格的组织形式,使得文件能够以块为单位进行存储。 文件系统中也要有索引区,用来方便查找一个文件分成的多
    的头像 发表于 11-09 14:48 482次阅读
    Linux的<b class='flag-5'>文件系统</b>特点