从串口驱动到Linux驱动模型

由于文章太长建议点链接进去看,里面梳理了一些基本概念,我对这些的理解也差不多。

 

摘自: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内核完成了驱动模型和特定硬件的分离:

图片

串口驱动数据结构总图:

图片

免责声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值