字符设备是一种通过一组字符进行IO操作的设备,与块设备(如硬盘)不同。PC上典型的字符设备有:
serial ports:串口
parallel ports:并口
text-mode consoles:字符模式的控制台
pseudo terminals(ptys):虚拟终端
程序通常使用标准的open()、close()、read()、write() API来操作字符设备。一些附加的函数用于操作字符设备的特有实行,如传送速度(baud rate),奇偶性、流控制等。字符设备的共享库为io-char.
1、Driver / io-char communication
io-char 库管理程序与设备之间的数据流,它是通过分配给每个字符设备的内存对列进行数据传输,每个字符会被分配三个先进先出队列。
接受数据会被驱动放到输入队列中,当程序需要数据时由io-char消费。驱动中的终端处理会调用io-char中提供的技能将数据添加到输入队列中。这能够保证输入处理的统一性,并减少驱动的职责。
io-char 将输出数据放到输出队列中,由驱动程序将其传输给设备。只有当输出队列满的时候,io-char才会阻塞用户进程。
标准队列(canonical queue)由io-char管理,由于处理在编辑模式中的输入数据,这个队列的大小决定了特定设备能够编辑的输入行大小。
所以这些对列的大小都通过命令来修改,它们默认值通常都比硬件的配置来打一点,但你也可以减少它们一降低整个系统的内存需求。设备驱动只是将输入数据添加到输入队列,并将输出队列中的数据传输给设备。io-char决定何时、如何阻塞输出处理、如何响应接受的数据等。
2、Device control
底层设备的控制通过devctl()来实现。POSIX的终端控制功能基于devctl()提供了一下功能:
tcgetattr():取得终端属性
tcsetattr():设定终端属性
tcgetpgrp():取得终端控制程序组的ID
tcsetpgrp():设定终端控制程序组的ID
tcsendbreak():发送一个阻塞condition
tcflow():中断或者重新开始数据的传输和接受
QNX扩展了两个:
tcdropline():开始中断连接。对串口来说就是加DTR
tcinject():向标准对列中插入字符
3、input mode
1)、Raw input mode 直接输入模式
在直接输入模式中中断程序会将接受到的每个字符直接放入输入队列,这个能够减少每个字符的处理,并提供最好的读取性能。当一个程序需要数据时,可以指定一个特殊的条件。只要条件满足时,中断处理程序才会让设备运行,才开始接受数据,一下支持的条件:
MIN:只有接受到指定数目字符时才开始相应
TIME:当字符流发生时,延迟指定的时间响应
TIMEOUT:指定时间后响应
FORWARD:接受到一组数据时在响应
2)、Edit input mode
在编辑输入模式中io-char提供了基于行的编辑操作。只有一行已经输入完成(通常是回车),这行数据才能够被程序处理。在编辑输入模式中每个字符都会被中断处理程序直接放到输入队列中,而不像直接输入模式中等待特定条件满足时才可以。这是因为:编辑输入模式很少用于高性能的通信协议;编辑模式不适合在中断中处理
当驱动运行后,io-char会检查这些字符并将其复制到标准队列中。当一行数据完成后,如果程序需要数据就会从标准队列中传输给程序。
4、Device subsystem performance 设备子系统的性能
为了最小化直接输入模式下的设备子系统的开销,通常有一下规则:
中断处理直接将接受的数据放入队列中
当读取操作满足时直接将数据从输入队列中传输给对应程序