linux串口驱动学习

整体框架

串口驱动隶属于linux tty驱动框架的一部分, 其整体框架可参考下图,方便有个直观印象。

前言

1、SPI,I2C驱动框架分为控制器驱动和设备驱动,然后芯片原厂负责编写控制器驱动和设备树,然后普通的驱动工程师编写/适配设备驱动和相应的设备树文件。

2、对于UART来说他没有所谓的设备驱动,只有控制器驱动,控制器驱动是由芯片原厂提供,如果不是在芯片原厂工作,一般需要编写uart驱动。如果是在芯片原厂需要编写uart驱动层,只需要编写uart硬件驱动层,Linux内核已经提供了串口核心层、tty层。

根据整体框架图。针对uart链路进行分析,以串口read和write为例,梳理整体流程如下

write流程

流程问题1:

为什么用户对文件操作后就是直接进入tty层,而不是直接进入到硬件驱动层呢?

tty文件存在其自身的字符接口:

复制代码
drivers/tty/tty_io.c文件
static const struct file_operations tty_fops 
static const struct file_operations console_fops
static const struct file_operations hung_up_tty_fops 

注册tty文件操作的接口函数为

复制代码
drivers/tty/tty_io.c文件
static int tty_cdev_add(struct tty_driver *driver, dev_t dev,
		unsigned int index, unsigned int count)

上一层调用该函数的接口只有两个

复制代码
drivers/tty/tty_io.c文件

struct device *tty_register_device_attr(struct tty_driver *driver,
				   unsigned index, struct device *device,
				   void *drvdata,
				   const struct attribute_group **attr_grp)

int tty_register_device(struct tty_driver *driver)

情况1 - tty_cdev_add直接调用

tty_cdev_add在tty_register_driver存在直接调用情况

tty_register_driver内部tty_cdev_add函数调用存在条件判断如下:

而flags值在uart_register_driver函数中的赋值情况如下,并不满足条件

因此,硬件驱动层tegra_uart_init函数调用的uart_register_driver并未完成对tty文件操作的注册。

总体调用关系如下

情况2 - tty_register_device_attr和tty_register_device间接调用

tty_register_device_attr函数在两处被调用:

tty_io.c----tty_register_device

tty_port.c---tty_port_register_device_attr

tty_io.c----tty_register_device也是因flags不满足条件在tty层tty_register_driver函数中未进行调用

流程可归纳为

tty_port.c---tty_port_register_device_attr则是在串口核心层uart_add_one_port中调用,层层追溯至硬件驱动层的tegra_uart_probe()函数中,该函数是在platform驱动框架下匹配设备树后执行。

调用流程归纳如下:

小结

1、用户对串口文件操作后直接进入tty层的原因在于驱动初始化时,将串口文件操作接口赋值为了tty文件操作函数,而不是不同的字符设备文件操作函数,使得打开串口文件时相当于打开了tty设备,所以直接进入到tty层。

2、在串口初始化时,文件操作接口赋值实际上有三次机会,但由于flags初值的原因,导致前两次在tty层并未直接完成赋值,这是因为串口属于硬件设备,需要等待硬件驱动完成后才能获得其文件节点,然后再进行文件操作接口赋值。

相关推荐
HLC++11 小时前
Linux的进程间通信
android·linux·服务器
华清远见IT开放实验室13 小时前
实验室建设案例 | 石家庄科技信息职业学院嵌入式实验室——从底层硬件到系统应用,一所应用型高校的嵌入式人才培养这样落地
linux·arm开发·stm32·嵌入式硬件·高校·实验室建设
groundhappy15 小时前
idalib安装和codex ida-mcp配置
linux·开发语言·python
通信小小昕16 小时前
Ubuntu 26.04 中文输入法安装
linux·运维·ubuntu
张小姐的猫17 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
栩栩云生17 小时前
AI 写代码犯的错,早被写进了错题集
linux·安全·ai编程
imc.1118 小时前
linux基础IO
linux·运维·服务器
BelongPanda20 小时前
Linux Nginx 纯手动 Let‘s Encrypt 泛域名证书配置教程
linux·nginx
酷可达拉斯21 小时前
Linux操作系统-shell编程(0)
linux·运维·服务器·python·云计算
2301_7779983421 小时前
Linux中断机制:操作系统如何高效运行
linux·运维·服务器