Linux驱动之串口(UART)
Posted 『流浪的Coder』
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux驱动之串口(UART)相关的知识,希望对你有一定的参考价值。
struct uart_driver { struct module *owner; //拥有该uart_driver的模块,一般为THIS_MODULE constchar *driver_name; // 串口驱动名,串口设备文件名以驱动名为基础 constchar *dev_name; // 串口设备名 int major; //主设备号 int minor; //次设备号 int nr; // 该uart_driver支持的串口个数(最大) struct console *cons;// 其对应的console.若该uart_driver支持serial console,否则为NULL ............................. struct uart_state *state; struct tty_driver *tty_driver; //uart_driver封装了tty_driver,使底层uart驱动不用关心ttr_driver。 };
int uart_register_driver(struct uart_driver *drv); void uart_unregister_driver(struct uart_driver *drv); int tty_register_driver(struct tty_driver *drv); void tty_unregister_driver(struct tty_driver *drv);
struct uart_port { spinlock_t lock;/* 串口端口锁 */ unsignedint iobase;/* IO端口基地址 */ unsignedchar __iomem *membase;/* IO内存基地址,经映射(如ioremap)后的IO内存虚拟基地址 */ unsignedint irq;/* 中断号 */ unsignedint uartclk;/* 串口时钟 */ unsignedint fifosize;/* 串口FIFO缓冲大小 */ unsignedchar x_char;/* xon/xoff字符 */ unsignedchar regshift;/* 寄存器位移 */ unsignedchar iotype;/* IO访问方式 */ unsignedchar 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 */ unsignedint read_status_mask;/* 关心的Rx error status */ unsignedint ignore_status_mask;/* 忽略的Rx error status */ struct uart_info *info; //重要,见下面 struct uart_icount icount; /* 计数器 uart_icount为串口信息计数器,包含了发送字符计数、接收字符计数等。在串口的发送中断处理函数和接收中断处理函数中,我们需要管理这些计数。*/ struct console *cons;/* console结构体 */ #ifdefCONFIG_SERIAL_CORE_CONSOLE unsignedlong sysrq;/* sysrq timeout */ #endif upf_t flags; #define UPF_FOURPORT ((__forceupf_t)(1 << 1)) #define UPF_SAK ((__forceupf_t)(1 << 2)) #define UPF_SPD_MASK ((__forceupf_t)(0x1030)) #define UPF_SPD_HI ((__forceupf_t)(0x0010)) #define UPF_SPD_VHI ((__forceupf_t)(0x0020)) #define UPF_SPD_CUST ((__forceupf_t)(0x0030)) #define UPF_SPD_SHI ((__forceupf_t)(0x1000)) #define UPF_SPD_WARP ((__forceupf_t)(0x1010)) #define UPF_SKIP_TEST ((__forceupf_t)(1 << 6)) #define UPF_AUTO_IRQ ((__forceupf_t)(1 << 7)) #define UPF_HARDPPS_CD ((__forceupf_t)(1 << 11)) #define UPF_LOW_LATENCY ((__forceupf_t)(1 << 13)) #define UPF_BUGGY_UART ((__forceupf_t)(1 << 14)) #define UPF_MAGIC_MULTIPLIER((__force upf_t)(1 << 16)) #define UPF_CONS_FLOW ((__forceupf_t)(1 << 23)) #define UPF_SHARE_IRQ ((__forceupf_t)(1 << 24)) #define UPF_BOOT_AUTOCONF ((__forceupf_t)(1 << 28)) #define UPF_FIXED_PORT ((__forceupf_t)(1 << 29)) #define UPF_DEAD ((__forceupf_t)(1 << 30)) #define UPF_IOREMAP ((__forceupf_t)(1 << 31)) #define UPF_CHANGE_MASK ((__forceupf_t)(0x17fff)) #define UPF_USR_MASK ((__forceupf_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数据指针 */ };
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 leveldrivers.
*/
#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;
};
Uart_port中有一个重要的uart_ops,底层硬件需要实现:
struct uart_ops {
unsignedint(*tx_empty)(struct uart_port *); /* 串口的Tx FIFO缓存是否为空 */
void(*set_mctrl)(struct uart_port *,unsignedint mctrl);/* 设置串口modem控制 */
unsignedint(*get_mctrl)(struct uart_port *);/* 获取串口modem控制 */
void(*stop_tx)(struct uart_port *);/* 禁止串口发送数据 */
void(*start_tx)(struct uart_port *);/* 使能串口发送数据 */
void(*send_xchar)(struct uart_port *,char ch);/* 发送xChar */
void(*stop_rx)(struct uart_port *);/* 禁止串口接收数据 */
void(*enable_ms)(struct uart_port *);/* 使能modemLinux——Linux驱动之iMX6ULL平台下串口UART驱动实现RS232数据通信开发实战(UART驱动框架源码分析串口应用程序编写)
Linux——Linux驱动之iMX6ULL平台下串口UART驱动实现RS232数据通信开发实战(UART驱动框架源码分析串口应用程序编写)