往期内容
本专栏往期内容:Uart子系统
- UART串口硬件介绍
- 深入理解TTY体系:设备节点与驱动程序框架详解
- Linux串口应用编程:从UART到GPS模块及字符设备驱动
interrupt子系统专栏:
- 专栏地址:interrupt子系统
- Linux 链式与层级中断控制器讲解:原理与驱动开发 – 末片,有专栏内容观看顺序
pinctrl和gpio子系统专栏:
- 专栏地址:pinctrl和gpio子系统
- 编写虚拟的GPIO控制器的驱动程序:和pinctrl的交互使用– 末片,有专栏内容观看顺序
input子系统专栏:
- 专栏地址:input子系统
- input角度:I2C触摸屏驱动分析和编写一个简单的I2C驱动程序 – 末片,有专栏内容观看顺序
I2C子系统专栏:
- 专栏地址:IIC子系统
- 具体芯片的IIC控制器驱动程序分析:i2c-imx.c-CSDN博客 – 末篇,有专栏内容观看顺序
总线和设备树专栏:
- 专栏地址:总线和设备树
- 设备树与 Linux 内核设备驱动模型的整合-CSDN博客 – 末篇,有专栏内容观看顺序
目录
1.框图
2.uart_port
uart_port
结构体包含 UART 端口的具体信息,包括寄存器地址、锁、端口设置等,UART 核心和底层驱动共同使用此结构体来实现端口的配置、控制和数据传输。下面的成员是有所省略的。
\Linux-4.9.88\include\linux\serial_core.h
/**
* struct uart_port - 描述 UART 端口的硬件配置及控制方法
* @lock: 自旋锁,用于保护端口数据访问的同步
* @iobase: 端口的 IO 基地址,用于 IO 映射
* @membase: 端口的内存映射基地址,用于内存映射方式
* @serial_in: 函数指针,用于读取寄存器中的数据
* @serial_out: 函数指针,用于写入数据到寄存器
* @set_termios: 配置串口的波特率、数据位等参数
* @get_mctrl: 获取控制信号状态(如 CTS、DCD 等)
* @set_mctrl: 设置控制信号(如 RTS、DTR 等)
* @startup: 启动 UART 端口
* @shutdown: 关闭 UART 端口
* @throttle: 降速处理,当缓冲区快满时限制数据传输
* @unthrottle: 恢复数据传输
* @handle_irq: 中断处理函数,处理端口的中断请求
* @pm: 电源管理回调,用于切换电源状态
* @handle_break: 处理中断信号
* @irq: 端口的 IRQ 编号
* @irqflags: IRQ 标志,用于设置中断类型
* @uartclk: UART 基准时钟频率,用于计算波特率
* @fifosize: 发送 FIFO 的大小
* @flags: 端口的控制标志,包含流控制、低延迟等设置
* @status: UART 端口的状态标志
* @ops: 指向 UART 操作的结构体指针,包含各种操作函数
* @dev: 指向此 UART 端口的设备结构体指针
* @private_data: 通用平台数据指针,用于存储私有数据
*/structuart_port{spinlock_t lock;// 端口锁,用于保护并发访问unsignedlong iobase;// IO 基地址unsignedchar __iomem *membase;// 内存映射的基地址unsignedint(*serial_in)(structuart_port*,int);// 读取寄存器void(*serial_out)(structuart_port*,int,int);// 写入寄存器void(*set_termios)(structuart_port*,structktermios*new,structktermios*old);// 配置串口unsignedint(*get_mctrl)(structuart_port*);// 获取控制信号void(*set_mctrl)(structuart_port*,unsignedint);// 设置控制信号int(*startup)(structuart_port*port);// 启动 UART 端口void(*shutdown)(structuart_port*port);// 关闭 UART 端口void(*throttle)(structuart_port*port);// 数据传输限制void(*unthrottle)(structuart_port*port);// 恢复数据传输int(*handle_irq)(structuart_port*);// 中断处理函数void(*pm)(structuart_port*,unsignedint state,unsignedint old);// 电源管理void(*handle_break)(structuart_port*);// 处理中断信号int(*rs485_config)(structuart_port*,structserial_rs485*rs485);// RS485 配置unsignedint irq;// 中断请求编号unsignedlong irqflags;// 中断标志unsignedint uartclk;// 基准时钟频率unsignedint fifosize;// FIFO 缓冲区大小unsignedchar x_char;// XON/XOFF 字符unsignedchar regshift;// 寄存器偏移量unsignedchar iotype;// IO 访问类型unsignedint read_status_mask;// 读取状态掩码unsignedint ignore_status_mask;// 忽略状态掩码structuart_state*state;// 指向 UART 状态structuart_icount icount;// UART 统计数据structconsole*cons;// 控制台指针upf_t flags;// UART 端口的标志upstat_t status;// 端口状态标志int hw_stopped;// 硬件停止状态unsignedint mctrl;// 调制解调控制状态unsignedint timeout;// 超时设置unsignedint type;// UART 端口类型conststructuart_ops*ops;// UART 操作接口unsignedint custom_divisor;// 自定义波特率分频器unsignedint line;// UART 端口编号unsignedint minor;// 次设备号resource_size_t mapbase;// IO 内存基地址resource_size_t mapsize;// IO 内存大小structdevice*dev;// 设备指针unsignedchar hub6;// Hub6 ISA 卡的配置unsignedchar suspended;// 挂起状态unsignedchar irq_wake;// IRQ 唤醒状态structattribute_group*attr_group;// 端口的特定属性conststructattribute_group**tty_groups;// 全部 tty 属性structserial_rs485 rs485;// RS485 协议配置void*private_data;// 平台特定的私有数据指针};
3.uart_driver
uart_driver
结构体包含了 UART 驱动程序的相关信息,例如驱动名称、主次设备号等,用于注册和管理 UART 驱动。
\Linux-4.9.88\include\linux\serial_core.h
/**
* struct uart_driver - 描述 UART 驱动信息
* @owner: 指向驱动程序模块的指针,通常设置为 THIS_MODULE
* @driver_name: 驱动程序的名称,通常用于 sysfs 中
* @dev_name: 设备名称前缀,用于生成设备节点名称(如 ttyS)
* @major: 主设备号,用于指定 UART 驱动的主设备号
* @minor: 次设备号,通常用于为多个 UART 设备提供编号
* @nr: 最大支持的 UART 端口数量
* @cons: 与驱动相关联的控制台设备
* @state: 指向每个 UART 端口的状态信息,通常由 UART 核心初始化
* @tty_driver: 指向 tty_driver 结构体的指针,表示与此 UART 驱动关联的 TTY 驱动
*/structuart_driver{structmodule*owner;// 驱动程序模块的指针constchar*driver_name;// UART 驱动的名称constchar*dev_name;// 设备名称前缀int major;// 主设备号int minor;// 次设备号int nr;// 支持的最大 UART 端口数structconsole*cons;// 控制台设备结构体指针// 以下字段应由 UART 核心初始化,底层驱动不应直接操作structuart_state*state;// UART 状态信息structtty_driver*tty_driver;// TTY 驱动的指针};
4.tty_port
tty_port
结构体管理 TTY 端口的资源和状态,包括等待队列、互斥锁、缓冲区等,用于简化驱动层对 TTY 端口的管理。
\Linux-4.9.88\include\linux\tty.h
/**
* struct tty_port - 描述 TTY 端口的信息和状态
* @buf: 缓冲区头,用于管理端口的数据缓冲区,内部锁定保护
* @tty: 指向 tty_struct 的指针,用于指向已分配的 TTY 结构体(回指)
* @itty: 内部指向 tty_struct 的指针,用于指向内部TTY 结构体(内部回指)
* @ops: 指向 tty_port_operations 结构体的指针,定义了端口的操作函数
* @lock: 自旋锁,用于保护 tty 字段的访问
* @blocked_open: 阻塞打开标志,用于表示端口是否正在等待打开
* @count: 使用计数,表示端口被打开的次数
* @open_wait: 等待队列,用于阻塞打开的进程
* @delta_msr_wait: 调制解调器状态变化等待队列,用于等待调制解调器状态改变
* @flags: 用户 TTY 标志,表示端口的属性,例如异步标志
* @iflags: 内部标志,用于表示端口的内部状态(TTY_PORT_ 开头)
* @console: 标志位,表示该端口是否是控制台
* @low_latency: 可选标志位,表示是否调优以降低延迟
* @mutex: 互斥锁,用于端口锁定
* @buf_mutex: 缓冲区分配锁,用于管理缓冲区的分配
* @xmit_buf: 可选发送缓冲区,用于保存传输的数据
* @close_delay: 关闭端口时的延迟,单位为毫秒
* @closing_wait: 输出完成的延迟时间
* @drain_delay: 排空延迟,当无需基于时间的纯排空时设置为零,否则设置为 FIFO 大小
* @kref: 引用计数器,用于控制 tty_port 结构体的引用计数
*/structtty_port{structtty_bufhead buf;// 数据缓冲区头,管理端口的缓冲区structtty_struct*tty;// 指向 tty_struct 的指针(回指)structtty_struct*itty;// 内部指向 tty_struct 的指针(内部回指)conststructtty_port_operations*ops;// 端口的操作函数指针spinlock_t lock;// 自旋锁,保护 tty 字段int blocked_open;// 阻塞打开标志int count;// 使用计数wait_queue_head_t open_wait;// 打开等待队列wait_queue_head_t delta_msr_wait;// 调制解调器状态变化等待队列unsignedlong flags;// 用户 TTY 标志(如 ASYNC_)unsignedlong iflags;// 内部标志(如 TTY_PORT_)unsignedchar console:1;// 是否是控制台unsignedchar low_latency:1;// 是否调优为低延迟structmutex mutex;// 端口互斥锁structmutex buf_mutex;// 缓冲区分配锁unsignedchar*xmit_buf;// 可选的发送缓冲区unsignedint close_delay;// 关闭端口时的延迟(毫秒)unsignedint closing_wait;// 输出完成延迟时间int drain_delay;// 排空延迟structkref kref;// 引用计数器};
5.tty_driver
tty_driver
结构体负责管理 TTY 驱动的基本信息,包括驱动名称、设备编号、TTY 数量等。同时,定义了特定的驱动操作函数接口,以便 TTY 子系统调用这些函数来操作设备。
/**
* struct tty_driver - 描述 TTY 驱动的信息及操作函数
* @magic: 魔数,用于识别 TTY 驱动结构体的合法性
* @kref: 引用计数管理,用于控制结构体的生命周期
* @cdevs: 指向字符设备的指针数组
* @owner: 指向驱动模块的指针,通常为 THIS_MODULE
* @driver_name: 驱动程序的名称,用于标识驱动
* @name: TTY 设备名称,用于生成设备节点名称(例如 ttyS)
* @name_base: 名称基址,用于计算 TTY 设备的完整名称
* @major: 主设备号,用于标识驱动
* @minor_start: 起始次设备号,通常用于为多个 TTY 设备提供编号
* @num: 分配的设备数量
* @type: 驱动类型,用于区分不同类型的 TTY 驱动
* @subtype: 驱动子类型,进一步区分 TTY 驱动的类型
* @init_termios: 初始终端设置,用于初始化 TTY 的终端属性
* @flags: 驱动标志,用于标识驱动的特殊属性
* @proc_entry: 指向 proc 文件系统的条目指针
* @other: 仅用于 PTY 驱动,指向配对的 TTY 驱动
* @ttys: 指向 tty_struct 指针数组,用于管理所有 TTY 设备
* @ports: 指向 tty_port 指针数组,指向所有端口信息
* @termios: 指向 ktermios 指针数组,保存每个 TTY 的终端属性
* @driver_state: 驱动状态指针,用于存储特定的驱动状态信息
* @ops: 指向 tty_operations 的指针,包含驱动操作函数
* @tty_drivers: TTY 驱动列表,用于连接多个 TTY 驱动
*/structtty_driver{int magic;// 魔数,确保结构体合法性structkref kref;// 引用计数管理structcdev**cdevs;// 字符设备指针数组structmodule*owner;// 指向驱动模块(通常为 THIS_MODULE)constchar*driver_name;// 驱动程序的名称constchar*name;// TTY 设备名称int name_base;// 名称基址int major;// 主设备号int minor_start;// 起始次设备号unsignedint num;// 分配的设备数量short type;// 驱动类型short subtype;// 驱动子类型structktermios init_termios;// 初始终端设置unsignedlong flags;// 驱动标志structproc_dir_entry*proc_entry;// /proc 文件系统条目structtty_driver*other;// 配对的 TTY 驱动(仅用于 PTY 驱动)// 指向 TTY 数据结构的指针structtty_struct**ttys;// TTY 结构体指针数组structtty_port**ports;// TTY 端口指针数组structktermios**termios;// TTY 的终端设置void*driver_state;// 驱动状态信息// 驱动方法conststructtty_operations*ops;// 驱动操作函数structlist_head tty_drivers;// TTY 驱动列表};
6.uart_state
uart_driver结构体的成员
\Linux-4.9.88\include\linux\serial_core.h
/*
* This is the state information which is persistent across opens.
*/structuart_state{structtty_port port;// 表示与TTY设备相关的端口信息,包含串口的输入输出控制功能。enumuart_pm_state pm_state;// UART的电源管理状态,指示串口的当前电源状态(如:活动、休眠等)。structcirc_buf xmit;// 用于存储要发送的字符的循环缓冲区,支持异步传输。atomic_t refcount;// 引用计数,用于跟踪当前有多少个打开的句柄指向此状态结构体。wait_queue_head_t remove_wait;// 用于进程等待的队列头,如果设备正在被移除,则相应的进程可以等待。structuart_port*uart_port;// 指向具体的UART端口结构体,包含硬件相关信息,如基地址、IRQ等。};
truct circ_buf xmit;// 用于存储要发送的字符的循环缓冲区,支持异步传输。atomic_t refcount;// 引用计数,用于跟踪当前有多少个打开的句柄指向此状态结构体。wait_queue_head_t remove_wait;// 用于进程等待的队列头,如果设备正在被移除,则相应的进程可以等待。structuart_port*uart_port;// 指向具体的UART端口结构体,包含硬件相关信息,如基地址、IRQ等。};
uart_state
结构体用于表示UART(通用异步收发传输)设备的状态信息,保存了关于设备操作的多个重要参数,如当前的电源管理状态、待发送的数据缓冲区、引用计数等。这些信息在设备打开和关闭时保持不变。
7.tty_operations
tty_driver
结构体的成员
structtty_operations{structtty_struct*(*lookup)(structtty_driver*driver,// 查找TTY结构体的操作函数structfile*filp,int idx);// 根据驱动、文件和索引返回相应的tty_struct。int(*install)(structtty_driver*driver,// 安装TTY设备的操作函数structtty_struct*tty);// 初始化tty_struct。void(*remove)(structtty_driver*driver,// 移除TTY设备的操作函数structtty_struct*tty);// 清理tty_struct资源。int(*open)(structtty_struct* tty,// 打开TTY设备的操作函数structfile* filp);// 对应于打开文件的系统调用。void(*close)(structtty_struct* tty,// 关闭TTY设备的操作函数structfile* filp);// 对应于关闭文件的系统调用。void(*shutdown)(structtty_struct*tty);// 关闭TTY设备并清理资源的操作函数。void(*cleanup)(structtty_struct*tty);// 清理TTY设备资源的操作函数。int(*write)(structtty_struct* tty,// 写入数据到TTY设备的操作函数constunsignedchar*buf,int count);// 将缓冲区中的数据写入tty。int(*put_char)(structtty_struct*tty,// 向TTY设备发送单个字符的操作函数unsignedchar ch);// 字符。void(*flush_chars)(structtty_struct*tty);// 刷新TTY设备中的字符(清空缓冲区)。int(*write_room)(structtty_struct*tty);// 获取TTY设备的写入空间大小。int(*chars_in_buffer)(structtty_struct*tty);// 获取TTY设备缓冲区中字符的数量。int(*ioctl)(structtty_struct*tty,// 处理TTY设备的控制命令的操作函数unsignedint cmd,unsignedlong arg);// 控制命令和参数。long(*compat_ioctl)(structtty_struct*tty,// 处理兼容性的ioctl命令的操作函数unsignedint cmd,unsignedlong arg);void(*set_termios)(structtty_struct*tty,// 设置TTY设备的终端属性structktermios* old);// 旧的终端属性。void(*throttle)(structtty_struct* tty);// 暂停TTY设备的输出。void(*unthrottle)(structtty_struct* tty);// 恢复TTY设备的输出。void(*stop)(structtty_struct*tty);// 停止TTY设备的操作。void(*start)(structtty_struct*tty);// 启动TTY设备的操作。void(*hangup)(structtty_struct*tty);// 挂断TTY设备的操作。int(*break_ctl)(structtty_struct*tty,int state);// 控制TTY设备的断开状态。void(*flush_buffer)(structtty_struct*tty);// 刷新TTY设备的缓冲区。void(*set_ldisc)(structtty_struct*tty);// 设置TTY设备的线路设备。void(*wait_until_sent)(structtty_struct*tty,int timeout);// 等待TTY设备发送完毕。void(*send_xchar)(structtty_struct*tty,char ch);// 向TTY设备发送控制字符。int(*tiocmget)(structtty_struct*tty);// 获取TTY设备的状态位。int(*tiocmset)(structtty_struct*tty,// 设置TTY设备的状态位。unsignedint set,unsignedint clear);// 要设置和清除的位。int(*resize)(structtty_struct*tty,// 调整TTY设备窗口大小的操作函数。structwinsize*ws);// 新的窗口大小。int(*set_termiox)(structtty_struct*tty,// 设置扩展终端参数的操作函数。structtermiox*tnew);// 新的终端参数。int(*get_icount)(structtty_struct*tty,// 获取TTY设备中输入计数的操作函数。structserial_icounter_struct*icount);// 输入计数结构体。#ifdefCONFIG_CONSOLE_POLLint(*poll_init)(structtty_driver*driver,int line,char*options);// 初始化轮询的操作函数。int(*poll_get_char)(structtty_driver*driver,int line);// 获取字符的轮询操作函数。void(*poll_put_char)(structtty_driver*driver,int line,char ch);// 发送字符的轮询操作函数。#endifconststructfile_operations*proc_fops;// 指向文件操作的结构体,用于处理proc文件系统。};
tty_operations
结构体定义了与TTY(终端)设备相关的操作函数的指针。这些函数用于管理TTY设备的生命周期、数据读写、状态控制等。每个函数的实现可以根据不同的TTY驱动进行定制,提供与硬件相关的操作接口。
8.uart_ops
uart_port
结构体的成员
\Linux-4.9.88\include\linux\serial_core.h
/*
* This structure describes all the operations that can be done on the
* physical hardware. See Documentation/serial/driver for details.
*/structuart_ops{unsignedint(*tx_empty)(structuart_port*);// 检查传输寄存器是否为空的操作函数。void(*set_mctrl)(structuart_port*,unsignedint mctrl);// 设置控制线的操作函数。unsignedint(*get_mctrl)(structuart_port*);// 获取控制线状态的操作函数。void(*stop_tx)(structuart_port*);// 停止数据发送的操作函数。void(*start_tx)(structuart_port*);// 开始数据发送的操作函数。void(*throttle)(structuart_port*);// 暂停数据发送的操作函数。void(*unthrottle)(structuart_port*);// 恢复数据发送的操作函数。void(*send_xchar)(structuart_port*,char ch);// 发送一个特定字符的操作函数。void(*stop_rx)(structuart_port*);// 停止数据接收的操作函数。void(*enable_ms)(structuart_port*);// 启用调制解调器信号的操作函数。void(*break_ctl)(structuart_port*,int ctl);// 控制断开信号的操作函数。int(*startup)(structuart_port*);// 启动UART设备的操作函数。void(*shutdown)(structuart_port*);// 关闭UART设备的操作函数。void(*flush_buffer)(structuart_port*);// 刷新缓冲区的操作函数。void(*set_termios)(structuart_port*,structktermios*new,structktermios*old);// 设置终端属性的操作函数。void(*set_ldisc)(structuart_port*,structktermios*);// 设置线路设备的操作函数。void(*pm)(structuart_port*,unsignedint state,unsignedint oldstate);// 进行电源管理的操作函数。/*
* Return a string describing the type of the port
*/constchar*(*type)(structuart_port*);// 返回描述端口类型的字符串的操作函数。/*
* Release IO and memory resources used by the port.
* This includes iounmap if necessary.
*/void(*release_port)(structuart_port*);// 释放端口使用的IO和内存资源的操作函数。/*
* Request IO and memory resources used by the port.
* This includes iomapping the port if necessary.
*/int(*request_port)(structuart_port*);// 请求端口使用的IO和内存资源的操作函数。void(*config_port)(structuart_port*,int);// 配置端口的操作函数。int(*verify_port)(structuart_port*,structserial_struct*);// 验证端口配置的操作函数。int(*ioctl)(structuart_port*,unsignedint,unsignedlong);// 处理IO控制命令的操作函数。#ifdefCONFIG_CONSOLE_POLLint(*poll_init)(structuart_port*);// 初始化轮询的操作函数。void(*poll_put_char)(structuart_port*,unsignedchar);// 轮询发送字符的操作函数。int(*poll_get_char)(structuart_port*);// 轮询接收字符的操作函数。#endif};
uart_ops
结构体用于定义与物理UART硬件相关的所有操作。这些操作涵盖了UART设备的基本功能,如数据传输、控制线管理、端口配置、资源请求等。- 每个函数指针代表一种操作,具体的实现由对应的UART驱动提供。这样,
uart_ops
结构体使得不同的UART硬件能够通过统一的接口进行操作,从而简化了驱动程序的开发。 - 例如,
start_tx
和stop_tx
用于控制数据发送,而set_termios
则用于配置UART的终端参数。这些函数的实现可以根据具体的硬件特性进行调整,确保在不同平台上能有效地控制UART设备。
需要额外注意的是不要和tty_operations混淆,因为驱动程序中经常这样去定义:
struct tty_operations uar_ops
和
struct uart_ops imx_xxxxx
,是不是很容易混淆,这点一定要注意。
9.联系
10.tty_truct
/*
* 该结构体存储与TTY相关的所有状态信息,当TTY处于打开状态时。
* 由于termios状态在TTY关闭后仍应保留(例如波特率等),
* 因此不会在此存储,而是存储指向真实状态的指针。
* winsize结构可能应采取相同的处理,但(1)默认的80x24通常是正确的,
* 并且(2)它最常由窗口系统使用,每次创建或调整窗口大小时都会设置正确的大小。
* - TYT, 9/14/92
*/structtty_operations;// 前向声明TTY操作结构structtty_struct{int magic;// 结构的魔术值,用于识别TTY结构的有效性structkref kref;// 引用计数,用于管理TTY结构的生命周期structdevice*dev;// 关联的设备结构指针structtty_driver*driver;// 指向驱动程序的指针conststructtty_operations*ops;// TTY操作的指针int index;// TTY设备的索引/* 保护线路纪律变化:锁定TTY而不是PTY */structld_semaphore ldisc_sem;// 用于保护线路纪律的信号量structtty_ldisc*ldisc;// 指向线路纪律的指针structmutex atomic_write_lock;// 保护原子写入的互斥锁structmutex legacy_mutex;// 旧代码的互斥锁structmutex throttle_mutex;// 用于控制流的互斥锁structrw_semaphore termios_rwsem;// 保护termios的读写信号量structmutex winsize_mutex;// 保护窗口大小的互斥锁spinlock_t ctrl_lock;// 控制状态的自旋锁spinlock_t flow_lock;// 控制流的自旋锁/* termios值由termios_rwsem保护 */structktermios termios, termios_locked;// termios结构,保存串口设置structtermiox*termiox;// 可能为NULL,表示不支持的扩展设置char name[64];// TTY的名称structpid*pgrp;// 进程组ID,由ctrl_lock保护structpid*session;// 会话IDunsignedlong flags;// 状态标志位int count;// 当前打开的引用计数structwinsize winsize;// 窗口大小,受winsize_mutex保护unsignedlong stopped:1,// 表示流是否停止
flow_stopped:1,// 表示流是否已停止
unused:BITS_PER_LONG -2;// 未使用的位int hw_stopped;// 硬件停止标志unsignedlong ctrl_status:8,// 控制状态
packet:1,// 表示是否为数据包
unused_ctrl:BITS_PER_LONG -9;// 未使用的位unsignedint receive_room;// 接收队列的可用字节数int flow_change;// 流控制变化标志structtty_struct*link;// 指向其他TTY结构的链接structfasync_struct*fasync;// 异步通知结构int alt_speed;// 用于38400 bps的魔法替代wait_queue_head_t write_wait;// 写等待队列头wait_queue_head_t read_wait;// 读等待队列头structwork_struct hangup_work;// 处理挂断的工作结构void*disc_data;// 线路纪律的私有数据void*driver_data;// 驱动程序的私有数据spinlock_t files_lock;// 保护tty_files列表的自旋锁structlist_head tty_files;// 关联的打开文件列表#defineN_TTY_BUF_SIZE4096// 定义TTY缓冲区大小int closing;// 指示TTY是否正在关闭unsignedchar*write_buf;// 写入缓冲区指针int write_cnt;// 写入计数/* 如果TTY有待处理的do_SAK,将其排队在此 - akpm */structwork_struct SAK_work;// 处理SAK的工作结构structtty_port*port;// 指向TTY端口的指针};
- 此结构体用于保存与TTY设备的状态信息和相关数据。它在TTY设备打开时保持活动状态。
- 包含对TTY设备的各种信息,如引用计数、设备驱动、操作函数、窗口大小、流控制状态等。
- 通过不同的锁和信号量保护其各个部分的并发访问,确保在多线程环境中操作的安全性。
11.tty_port_operaion
tty_port的成员
structtty_port_operations{/*
* 返回 1 如果载波(carrier)信号被抬起。
* 这个函数用于检查串行端口的载波状态。
*/int(*carrier_raised)(structtty_port*port);/*
* 控制 DTR(数据终端就绪)和 RTS(请求发送)线路。
* 通过设置参数来抬起或放下这两条控制线路。
*/void(*dtr_rts)(structtty_port*port,int raise);/*
* 当最后一个关闭操作完成或挂起操作结束时调用,
* 仅在端口已初始化的情况下调用。
* 注意:不要在此处释放资源,因为它是在端口互斥锁下调用的,
* 用于序列化激活和关闭操作。
*/void(*shutdown)(structtty_port*port);/*
* 在 tty_port_open 函数中在端口互斥锁下调用,
* 用于初始化设备。长远来看,希望将 tty 参数移出此函数,
* 以提高通用性(特别是对于控制台)。
*/int(*activate)(structtty_port*port,structtty_struct*tty);/*
* 在端口的最后一次释放(put)时调用。
* 这个函数用于清理与端口相关的资源。
*/void(*destruct)(structtty_port*port);};
tty_port_operations
是一个函数指针结构体,定义了一组与TTY端口操作相关的回调函数。这些函数由具体的端口实现提供,以支持不同的串行设备。
版权归原作者 憧憬一下 所有, 如有侵权,请联系我们删除。