本篇开始介绍“信号系统”、“IO系统”以及“标准设备”。详细信息请访问SylixOS官网:http://www.sylixos.com。
信号是一种异步通信方式,也是POSIX兼容操作系统唯一的异步通信方式(之后章节只要提到异步通信,例如异步I/O都是信号驱动的)。SylixOS支持POSIX标准所定义的信号系统。
信号实际上是一种在软件层次上模拟的中断,其处理流程如下图所示。
所谓异步通信是指:应用程序不用等待事件的发生,当信号发生时应用程序自动陷入到对应的信号处理句柄中,就相当于应用程序被中断了一样。很多重要的系统级应用程序都要处理信号。信号提供了一种处理异步事件的方法。SylixOS共提供64个不同类型的信号,分别对应系统产生的不同类型的异常,例如:定时器到时,异步I/O操作完成,管道断裂,内存非法访问,除0操作,子进程结束等等。
这里需要说明的是SylixOS支持POSIX规定的信号排队功能。
SylixOS兼容标准的POSIX输入输出系统,使用户非常容易上手。SylixOS的I/O概念与UNIX兼容系统相同,认为一切都是文件。这些文件有不同的类型,它们包括:
1. 普通数据文件:最常用的文件类型,内部存放数据集合。
2. 目录文件:这个文件包含了其他文件的名字以及这些文件的指针。
3. 块设备文件:这种文件提供的I/O接口标准符合SylixOS对块设备的定义。
4. 字符设备文件:这是标准的不带缓冲的设备文件,系统中的设备不是块设备就是字符设备。
5. FIFO文件:管道通信文件。它对应了一个命名管道。
6. 套接字(socket)文件:进程间或者主机间的网络通信。
7. 符号链接:该文件指向另一个文件。
SylixOS I/O系统结构如下图所示。
不同的文件描述符可以对应同一个文件节点,当对应同一个文件节点的所有文件描述符被关闭则操作系统会释放对应的文件节点,同时调用相应的驱动程序。不同的文件节点可以指向同一个逻辑设备,例如一个FAT文件系统设备就可以被打开很多个文件节点。不同的逻辑设备也可以对应一个驱动程序,例如串口0、串口1可以对应一组为其服务的驱动程序。当然哪一组驱动程序为哪一个硬件服务则由用户底层BSP代码决定。
SylixOS的文件描述符与POSIX定义兼容,它是从0开始一直到一个最大值的整型数字,每一个打开的文件都有一个或者多个(dup)文件描述符与之对应。SylixOS和绝大多数操作系统相同,打开文件时总是使用一个最小的未使用的文件描述符作为新分配的文件描述符。
根据习惯0号文件描述符代表标准输入,即scanf对应的输入文件,一般为一个终端,1号文件为标准输出,即printf对应的输出文件,2号文件为标准错误,即strerror对应的输出文件。这里需要说明的是SylixOS每个进程拥有自己的文件描述符表。各个进程间互不冲突,子进程继承父进程除FD_CLOEXEC外的所有文件描述符。一个进程内的所有线程共享进程文件描述符。而内核中也有一个全局的文件描述符表,这张表不包含0,1,2号标准文件,这三个文件描述符在内核中为重映射标志,即SylixOS允许内核中每个内核任务拥有自己的标准文件。
针对于文件操作,SylixOS提供一组统一的API函数。这组API分为三类,他们是标准I/O操作、异步I/O操作和高级I/O操作。
标准I/O 又称作同步I/O操作,SylixOS支持POSIX规定的绝大多数同步输入输出操作,他们分别是:creat、open、close、unlink、read、write、readv、writev、pread、pwrite、pread64、pwrite64、ioctl、stat、stat64、lstat、lstat64、lseek、lseek64、fsstat、vfsstat、dup、dup2、ttyname、sync、fsync、fdatasync、fchmod、chmod等等。这些API的行为与POSIX规定的一致,所以其他POSIX兼容操作系统的应用程序只需重新编译就可以在SylixOS系统上运行。
以上这些API都属于同步I/O范畴,即发起传输和对I/O的控制都是用户主动行为。设备必须在用户的干预下运转,目前绝大多数应用软件都使用这一类型的I/O操作。
SylixOS支持POSIX1003.1b实时扩展协议规定的标准异步I/O接口,即:aio_cancel、aio_error、aio_fsync、aio_read、aio_write、aio_return、aio_suspend、lio_listio。这组API用来操作异步I/O。异步I/O是针对同步I/O提出的概念,它不需要线程等待I/O处理结果,而只需要请求进行传输,然后系统会自动完成I/O传输,结束或者出现错误时会产生相应的I/O信号,用户程序只需要设置好对应的信号陷入函数,即可处理一个异步I/O事件。
POSIX系统高级I/O是针对于标准I/O的不足进行设计的。这些功能包括:非阻塞I/O、记录锁、I/O多路复用、存储器I/O映射。
非阻塞I/O用于可能产生阻塞的I/O操作,例如:read、wirte等等。用户可以通过相关API设置指定的文件描述符O_NONBLOCK标志,将对应的文件设置为非阻塞I/O模式,这时如果设备没有准备好,则系统调用会立即退出不会发生阻塞,同时errno将设置为EWOULDBLOCK,表示对应的操作没有完成,需要稍后再重新执行。用户设置O_NONBLOCK标志的API包括ioctl的FIONBIO命令或者fcntl的F_SETFL选项。
记录锁的功能是:当一个进程正在读取或者修改文件的某个部分,他可以阻止其它进程修改同一文件的相同区域,它可以用来锁定文件的某个区域或者这个文件,SylixOS支持文件记录锁的API是POSIX标准的fcntl和BSD系统的flock函数,SylixOS同时兼容BSD系统在文件打开阶段自动加锁,只需要在open调用时加入O_SHLOCK与O_EXLOCK参数即可。SylixOS中分为多种设备驱动模型但是只有NEW1型设备驱动支持记录锁功能,例如FAT、NFS、YAFFS、ROMFS等常用文件系统都是用这种驱动模型,它类似于UNIX系统的vnode类型,使用NEW1设备驱动的I/O系统结构如下图所示。
I/O多路复用可以使线程阻塞在多个I/O请求上并且设置超时时间,当等待多个I/O请求时,如果有某一个文件描述符对应的事件允许时,阻塞的线程立即被激活,然后通过相关API判断有哪几个文件产生了相关的事件。它允许用户同时处理多个I/O的传输请求。I/O多路复用的API包括:select和poll。SylixOS同时支持这两个API。
存储器I/O映射可以使对一个文件的操作变成对内存的操作,它使一个文件和内存中的一个缓冲区进行映射,对缓冲区内存的操作相当于对文件的操作。这个操作需要SylixOS的虚拟内存管理支持,操作系统将通过缺页中断系统为这个映射的文件服务。完成存储器I/O映射的API是mmap。它不仅能够映射普通文件到内存,还可以映射设备文件(当然需要设备驱动程序支持),例如:我们在嵌入式系统中常用的显示设备是framebuffer,这时可以将这个设备(通常文件名为/dev/fb0)通过mmap映射到虚拟空间,这时对映射空间的操作实际就是操作显存本身。
上一节介绍的是SylixOS输入输出系统对用户提供的API基本内容,本节介绍SylixOS在I/O层之下提供的基本设备模型,这些设备包括普通设备类和总线型设备类:
普通设备类是SylixOS对一些标准设备行为的统一抽象,这些设备包括:
1. 终端
2. 虚拟终端
3. CAN节点
4. 管道
5. 共享内存
6. DMA
7. 键盘鼠标
8. 实时时钟
9. 简单图形设备
10. 声卡
11. 块设备
12. 随机数发生器设备
13. ATA(SATA)设备
14. 空设备
……
用户驱动可以使用这些标准化的设备模型来编写,这样可以对上层提供统一的,标准的设备API,方便应用程序移植。
同时SylixOS还提供了标准的总线型设备传输支持,他们包括:
1. SD总线
2. SPI总线
3. IIC总线
4. USB总线
……
其中PCI和USB总线的支持作为SylixOS的内核模块在运行时动态装入。这些总线设备使用SylixOS统一的总线管理器确保总线上的设备传输互不受影响。
(本篇结束)