日期:2014-05-16  浏览次数:20591 次

Linux中tty框架与uart框架之间的调用关系剖析

之前本人在"从串口驱动的移植看linux2.6内核中的驱动模型 platform device & platform driver"一文中已经写到了移植的设备是如何通过platform总线来与对应的驱动挂载。

在这期间有一个问题困扰着我,那就是来自用户空间的针对uart设备的操作意图是如何通过tty框架逐层调用到uart层的core驱动,进而又是如何调用到真实对应于设备的设备驱动的,本文中的对应设备驱动就是8250驱动,最近我想将这方面的内容搞清楚。

在说明这一方面问题之前我们先要大致了解两个基本的框架结构,tty框架和uart框架。

首先看看tty框架:

在linux系统中,tty表示各种终端。终端通常都跟硬件相对应。比如对应于输入设备键盘鼠标,输出设备显示器的控制终端和串口终端。

下面这张图是一张很经典的图了,很清楚的展现了tty框架的层次结构,大家先看图,下面给大家解释。


最上面的用户空间会有很多对底层硬件(在本文中就是8250uart设备)的操作,像read,write等。用户空间主要是通过设备文件同tty_core交互,tty_core根据用空间操作的类型再选择跟line discipline和tty_driver也就是serial_core交互,例如设置硬件的ioctl指令就直接交给serial_core处理。Read和write操作就会交给line discipline处理。Line discipline是线路规程的意思。正如它的名字一样,它表示的是这条终端线程的输入与输出规范设置,主要用来进行输入/输出数据的预处理。处理之后,就会将数据交给serial_core,最后serial_core会调用8250.c的操作

下图是同一样一副经典的uart框架图,将uart重要的结构封装的很清楚,大家且看。


一个uart_driver通常会注册一段设备号.即在用户空间会看到uart_driver对应有多个设备节点。例如:
/dev/ttyS0  /dev/ttyS1 每个设备节点是对应一个具体硬件的,这样就可做到对多个硬件设备的统一管理,而每个设备文件应该对应一个uart_port,也就是说:uart_device要和多个uart_port关系起来。并且每个uart_port对应一个circ_buf(用来接收数据),所以uart_port必须要和这个缓存区关系起来。

1 自底向上
接下来我们就来看看对设备的操作是怎样进行起来的,不过在此之前我们有必要从底层的uart驱动注册时开始说起,这样到后面才能更清晰。