当前位置:文档之家› Linux串口(serial、uart)驱动程序设计

Linux串口(serial、uart)驱动程序设计

Linux串口(serial、uart)驱动程序设计/space.php?uid=23089249&do=blog&id=34481一、核心数据结构串口驱动有3个核心数据结构,它们都定义在<#include linux/serial_core.h> 1、uart_driveruart_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_portuart_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_CONSOLEunsigned long sysrq;/* sysrq timeout */#endifupf_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;wait_queue_head_t delta_msr_wait;};3、uart_opsuart_ops涵盖了串口驱动可对串口设备进行的所有操作。

相关主题