由于文章太长建议点链接进去看,里面梳理了一些基本概念,我对这些的理解也差不多。
摘自:https://mp.weixin.qq.com/s/O5R1bxbxFYFWGveXFEazIg
因为我们和开发板的人机交互的接口是Windows下的串口控制台。这就是上面所说的控制台终端。但是我们用了console = ttySAC0.即把串口终端当做控制台终端。所以我们要研究具体的代码需要cd到serial子目录下。即串口终端目录。ls显示serial下的文件结点。如图所示:
我们主要关心的是两类文件。一类是与体系结构和板载资源无关的通用串口操作文件。(samsung.c)一类是与体系结构相关的硬件操作文件。(s3c2440.c s3c2410.c s5pv210.c等),我们为了得到具体的调用链。在具体的发送函数中加入回溯。如图所示。
我们得到的函数调用链是这样的(以发送函数。即文件的写操作为例.
write->
sys_write->
vfs_write->
redirected_tty_write->
tty_write->
n_tty_write->
uart_write->
uart_start->
s3c24xx_serial_start_tx
从具体代码上来看。这些函数基本上都是通过结构体中的函数指针调用。我们可以把这个调用链分为三个部分。即tty子系统核心。tty链路规程。tty驱动
tty核心。是对整个tty设备的抽象。对用户提供统一的接口。包括sys_write->vfs_write
tty线路规程。是对传输数据的格式化。在tty_ldisc_N_TTY变量中描述。包括redirected_tty_write->tty_write->n_tty_write->
tty驱动。是面向tty设备的硬件驱动。这里面真正的对硬件进行操作。包括uart_write->uart_start->s3c24xx_serial_start_tx
这是从具体函数的角度来看的调用链。下面为了从数据结构的角度来分析调用链。介绍linux内核中针对于这一个串口硬件的主要数据结构。对于具体的字段我们用到的时候再解释。
uart_driver。
就是uart驱动程序结构。封装了tty_driver,使得底层的UART驱动无需关心tty_driver具体定义如下。
uart_port
uart_port用于描述一个UART端口(直接对应于一个串口)的I/O端口或者IO内存地址等信息。
uart_ops定义了针对UART的一系列操作。注意这里不要把uart_ops结构和uart_ops变量混淆。uart_ops结构是我们这里的数据结构。而uart_ops变量则是一个tty_operations的变量。
在serial_core.c中定义了tty_operations的实例。即uart_ops变量,包含uart_open();uart_close();uart_send_xchar()等成员函数,这些函数借助uart_ops结构体中的成员函数来完成具体的操作:
uart_ops变量是tty_operations型的一个变量。如下图所示:
uart_state是uart的状态结构。
uart_info是uart的信息结构。在这个体系结构下定义为s3c24xx_uart_info:
所以很显然。用数据结构来描述函数调用链就是
uart_driver ->
uart_state->
uart_port->
uart_ops->
特定的函数指针。
初始化过程比较复杂。不赘述。从函数指针的调用流程为主线。忽略一些入参检查和内核中的信号量代码。大致的初始化流程如下图所示:
打开设备和初始化流程类似。如图所示:
同理数据的发送和接收如图所示:
这里我们需要注意的是。使能发送并没有真正的发送过程。而只是使能发送中断
这一句:enable_irq(ourport->tx_irq);
这是因为ARM9处理器上有一个循环缓冲。用户从write系统调用传下来的数据就会写入这个UTXH0寄存器。发送完事之后处理器会产生一个内部中断。我们通过这个内部中断就可以实现流控过程、我们打开芯片手册可以看到如下字样(拿ARM11举例也一样,。这是ARM11的):
如下才是发送中断的ISR(Interrupt Service Routine)中断服务例程。一个irqreturn_t类型的handler。
这个wr_regb(port, S3C2410_UTXH, port->x_char);就是往特定寄存器写的过程。
至此我们的分析已经结束。相信读者对于Linux下的tty子系统已经有一个概观了。下面是这个uart驱动的总图。结合数据结构的调用链。Linux内核完成了驱动模型和特定硬件的分离:
串口驱动数据结构总图:
免责声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。