一、核心数据结构 串口驱动有3个核心数据结构,它们都定义在<#include linux/serial_core.h> 1、uart_driver uart_driver包含了串口设备名、串口驱动名、主次设备号、串口控制台(可选)等信息,还封装了tty_driver(底层串口驱动无需关心tty_driver)。
struct uart_driver {
struct module *owner; /* 拥有该uart_driver的模块,一般为THIS_MODULE */
const char *driver_name; /* 串口驱动名,串口设备文件名以驱动名为基础 */
const char *dev_name; /* 串口设备名 */
int major; /* 主设备号 */
int minor; /* 次设备号 */
int nr; /* 该uart_driver支持的串口个数(最大) */
struct console *cons; /* 其对应的console.若该uart_driver支持serial console,否则为NULL */
/* * these are private; the low level driver should not * touch these; they should be initialised to NULL */
struct uart_state *state;
struct tty_driver *tty_driver;
};
2、uart_port uart_port用于描述串口端口的I/O端口或I/O内存地址、FIFO大小、端口类型、串口时钟等信息。实际上,一个uart_port实例对应一个串口设备
struct uart_port {
spinlock_t lock; /* 串口端口锁 */
unsigned int iobase; /* IO端口基地址 */
unsigned char __iomem *membase; /* IO内存基地址,经映射(如ioremap)后的IO内存虚拟基地址 */
unsigned int irq; /* 中断号 */
unsigned int uartclk; /* 串口时钟 */
unsigned int fifosize; /* 串口FIFO缓冲大小 */
unsigned char x_char; /* xon/xoff字符 */
unsigned char regshift; /* 寄存器位移 */
unsigned char iotype; /* IO访问方式 */
unsigned char unused1;
#define UPIO_PORT (0) /* IO端口 */
#define UPIO_HUB6 (1)
#define UPIO_MEM (2) /* IO内存 */
#define UPIO_MEM32 (3)
#define UPIO_AU (4) /* Au1x00 type IO */
#define UPIO_TSI (5) /* Tsi108/109 type IO */
#define UPIO_DWAPB (6) /* DesignWare APB UART */
#define UPIO_RM9000 (7) /* RM9000 type IO */
unsigned int read_status_mask; /* 关心的Rx error status */
unsigned int ignore_status_mask;/* 忽略的Rx error status */
struct uart_info *info; /* pointer to parent info */
struct uart_icount icount; /* 计数器 */
struct console *cons; /* console结构体 */
#ifdef CONFIG_SERIAL_CORE_CONSOLE
unsigned long sysrq; /* sysrq timeout */
#endif
upf_t flags;
#define UPF_FOURPORT ((__force upf_t) (1 << 1))
#define UPF_SAK ((__force upf_t) (1 << 2))
#define UPF_SPD_MASK ((__force upf_t) (0x1030))
#define UPF_SPD_HI ((__force upf_t) (0x0010))
#define UPF_SPD_VHI ((__force upf_t) (0x0020))
#define UPF_SPD_CUST ((__force upf_t) (0x0030))
#define UPF_SPD_SHI ((__force upf_t) (0x1000))
#define UPF_SPD_WARP ((__force upf_t) (0x1010))
#define UPF_SKIP_TEST ((__force upf_t) (1 << 6))
#define UPF_AUTO_IRQ ((__force upf_t) (1 << 7))
#define UPF_HARDPPS_CD ((__force upf_t) (1 << 11))
#define UPF_LOW_LATENCY ((__force upf_t) (1 << 13))
#define UPF_BUGGY_UART ((__force upf_t) (1 << 14))
#define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16))
#define UPF_CONS_FLOW ((__force upf_t) (1 << 23))
#define UPF_SHARE_IRQ ((__force upf_t) (1 << 24))
#define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28))
#define UPF_FIXED_PORT ((__force upf_t) (1 << 29))
#define UPF_DEAD ((__force upf_t) (1 << 30))
#define UPF_IOREMAP ((__force upf_t) (1 << 31))
#define UPF_CHANGE_MASK ((__force upf_t) (0x17fff))
#define UPF_USR_MASK ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))
unsigned int mctrl; /* 当前的moden设置 */
unsigned int timeout; /* character-based timeout */
unsigned int type; /* 端口类型 */
const struct uart_ops *ops; /* 串口端口操作函数集 */
unsigned int custom_divisor;
unsigned int line; /* 端口索引 */
resource_size_t mapbase; /* IO内存物理基地址,可用于ioremap */
struct device *dev; /* 父设备 */
unsigned char hub6; /* this should be in the 8250 driver */
unsigned char suspended;
unsigned char unused[2];
void *private_data; /* 端口私有数据,一般为platform数据指针 */ };
uart_iconut为串口信息计数器,包含了发送字符计数、接收字符计数等。在串口的发送中断处理函数和接收中断处理函数中,我们需要管理这些计数。
struct uart_icount { __u32 cts; __u32 dsr; __u32 rng; __u32 dcd; __u32 rx; /* 发送字符计数 */ __u32 tx; /* 接受字符计数 */ __u32 frame; /* 帧错误计数 */ __u32 overrun; /* Rx FIFO溢出计数 */ __u32 parity; /* 帧校验错误计数 */ __u32 brk; /* break计数 */ __u32 buf_overrun; };
uart_info有两个成员在底层串口驱动会用到:xmit和tty。用户空间程序通过串口发送数据时,上层驱动将用户数据保存在xmit;而串口发送中断处理函数就是通过xmit获取到用户数据并将它们发送出去。串口接收中断处理函数需要通过tty将接收到的数据传递给行规则层。
/* uart_info实例仅在串口端口打开时有效,它可能在串口关闭时被串口核心层释放。因此,在使用uart_port的uart_info成员时必须保证串口已打开。底层驱动和核心层驱动都可以修改uart_info实例。
* This is the state information which is only valid when the port * is open; it may be freed by the core driver once the device has * been closed. Either the low level driver or the core can modify * stuff here. */
struct uart_info {
struct tty_struct *tty;
struct circ_buf xmit;
uif_t flags;
/* * Definitions for info->flags. These are _private_ to serial_core, and * are specific to this structure. They may be queried by low level drivers. */
#define UIF_CHECK_CD ((__force uif_t) (1 << 25))
#define UIF_CTS_FLOW ((__force uif_t) (1 << 26))
#define UIF_NORMAL_ACTIVE ((__force uif_t) (1 << 29))
#define UIF_INITIALIZED ((__force uif_t) (1 << 31))
#define UIF_SUSPENDED ((__force uif_t) (1 << 30))
int blocked_open;
struct tasklet_struct tlet;
wait_queue_head_t open_wait;
上一篇:linux网卡驱动移植
下一篇:Smart210学习记录-----SD/MMC/SDIO驱动
推荐阅读最新更新时间:2026-03-20 11:27
- 使用 ON Semiconductor 的 FAN2518S 的参考设计
- LTC1530S8、3.3V/3A 稳压器
- 使用 ON Semiconductor 的 ADP3167 的参考设计
- 使用 Analog Devices 的 LT3420EDD 的参考设计
- 基于Kinetis® M的低成本单相电表参考设计
- LTC3708、具有上升/下降轨跟踪功能的 2.5V/15A 和 1.2V/15A 稳压器
- NXQ1TXH5插件板
- 应变仪仪表放大器
- WRL-13287,基于 ESP8266 802.11 无线局域网的 SparkFun Wi-Fi Shield
- 4.1W、3-LED 通用 LED 照明驱动器



Linux技术手册
【2025 DigiKey创意大赛】 学伴智盒 - 代码
智能机械臂
非常经典的关于LLC的杨波博士论文
XC6406PP60DL






京公网安备 11010802033920号