1、核心數據結構
串口驅動有3個核心數據結構,它們都定義在<#include linux/serial_core.h>
一、uart_driver
uart_driver包含了串口設備名、串口驅動名、主次設備號、串口控制檯(可選)等信息,還封裝了tty_driver(底層串口驅動無需關心tty_driver)。 css
1: struct uart_driver {
2: struct module *owner; /* 擁有該uart_driver的模塊,通常爲THIS_MODULE */
3: const char *driver_name; /* 串口驅動名,串口設備文件名以驅動名爲基礎 */
4: const char *dev_name; /* 串口設備名 */
5: int major; /* 主設備號 */
6: int minor; /* 次設備號 */
7: int nr; /* 該uart_driver支持的串口個數(最大) */
8: struct console *cons; /* 其對應的console.若該uart_driver支持serial console,不然爲NULL */
9:
10: /*
11: * these are private; the low level driver should not
12: * touch these; they should be initialised to NULL
13: */
14: struct uart_state *state;
15: struct tty_driver *tty_driver;
16: };
二、uart_port
uart_port用於描述串口端口的I/O端口或I/O內存地址、FIFO大小、端口類型、串口時鐘等信息。實際上,一個uart_port實例對應一個串口設備 html
1: struct uart_port {
2: spinlock_t lock; /* port lock 串口端口鎖 */
3: unsigned long iobase; /* in/out[bwl] io端口基地 */
4: unsigned char __iomem *membase;/* read/write[bwl] IO內存基地址,經映射(如ioremap)後的IO內存虛擬基地址 */
5: unsigned int (*serial_in)(struct uart_port *, int);
6: void (*serial_out)(struct uart_port *, int, int);
7: void (*set_termios)(struct uart_port *,
8: struct ktermios *new,
9: struct ktermios *old);
10: void (*pm)(struct uart_port *, unsigned int state,
11: unsigned int old);
12: unsigned int irq; /* irq number */
13: unsigned long irqflags; /* irq flags */
14: unsigned int uartclk; /* base uart clock */
15: unsigned int fifosize; /* tx fifo size */
16: unsigned char x_char; /* xon/xoff char */
17: unsigned char regshift; /* reg offset shift */
18: unsigned char iotype; /* io access style */
19: unsigned char unused1;
20:
21: #define UPIO_PORT (0)
22: #define UPIO_HUB6 (1)
23: #define UPIO_MEM (2)
24: #define UPIO_MEM32 (3)
25: #define UPIO_AU (4) /* Au1x00 type IO */
26: #define UPIO_TSI (5) /* Tsi108/109 type IO */
27: #define UPIO_DWAPB (6) /* DesignWare APB UART */
28: #define UPIO_RM9000 (7) /* RM9000 type IO */
29: #define UPIO_DWAPB32 (8) /* DesignWare APB UART (32 bit accesses) */
30:
31: unsigned int read_status_mask; /* driver specific */
32: unsigned int ignore_status_mask; /* driver specific */
33: struct uart_state *state; /* pointer to parent state */
34: struct uart_icount icount; /* statistics */
35:
36: struct console *cons; /* struct console, if any */
37: #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ)
38: unsigned long sysrq; /* sysrq timeout */
39: #endif
40:
41: upf_t flags;
42:
43: #define UPF_FOURPORT ((__force upf_t) (1 << 1))
44: #define UPF_SAK ((__force upf_t) (1 << 2))
45: #define UPF_SPD_MASK ((__force upf_t) (0x1030))
46: #define UPF_SPD_HI ((__force upf_t) (0x0010))
47: #define UPF_SPD_VHI ((__force upf_t) (0x0020))
48: #define UPF_SPD_CUST ((__force upf_t) (0x0030))
49: #define UPF_SPD_SHI ((__force upf_t) (0x1000))
50: #define UPF_SPD_WARP ((__force upf_t) (0x1010))
51: #define UPF_SKIP_TEST ((__force upf_t) (1 << 6))
52: #define UPF_AUTO_IRQ ((__force upf_t) (1 << 7))
53: #define UPF_HARDPPS_CD ((__force upf_t) (1 << 11))
54: #define UPF_LOW_LATENCY ((__force upf_t) (1 << 13))
55: #define UPF_BUGGY_UART ((__force upf_t) (1 << 14))
56: #define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15))
57: #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16))
58: #define UPF_CONS_FLOW ((__force upf_t) (1 << 23))
59: #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24))
60: /* The exact UART type is known and should not be probed. */
61: #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27))
62: #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28))
63: #define UPF_FIXED_PORT ((__force upf_t) (1 << 29))
64: #define UPF_DEAD ((__force upf_t) (1 << 30))
65: #define UPF_IOREMAP ((__force upf_t) (1 << 31))
66:
67: #define UPF_CHANGE_MASK ((__force upf_t) (0x17fff))
68: #define UPF_USR_MASK ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))
69:
70: unsigned int mctrl; /* current modem ctrl settings */
71: unsigned int timeout; /* character-based timeout */
72: unsigned int type; /* port type */
73: const struct uart_ops *ops;
74: unsigned int custom_divisor;
75: unsigned int line; /* port index */
76: resource_size_t mapbase; /* for ioremap */
77: struct device *dev; /* parent device */
78: unsigned char hub6; /* this should be in the 8250 driver */
79: unsigned char suspended;
80: unsigned char irq_wake;
81: unsigned char unused[2];
82: void *private_data; /* generic platform data pointer */
83: };
uart_iconut爲串口信息計數器,包含了發送字符計數、接收字符計數等。在串口的發送中斷處理函數和接收中斷處理函數中,咱們須要管理這些計數。linux
1: struct uart_icount {
2: __u32 cts;
3: __u32 dsr;
4: __u32 rng;
5: __u32 dcd;
6: __u32 rx; /* 發送字符計數 */
7: __u32 tx; /* 接受字符計數 */
8: __u32 frame; /* 幀錯誤計數 */
9: __u32 overrun; /* Rx FIFO溢出計數 */
10: __u32 parity; /* 幀校驗錯誤計數 */
11: __u32 brk; /* break計數 */
12: __u32 buf_overrun;
13: };
uart_stat有兩個成員在底層串口驅動會用到:xmit和port。用戶空間程序經過串口發送數據時,上層驅動將用戶數據保存在xmit;而串口發送中斷處理函數就是經過xmit獲取到用戶數據並將它們發送出去。串口接收中斷處理函數須要經過port將接收到的數據傳遞給行規則層。ios
1: /*
2: * This is the state information which is persistent across opens.
3: */
4: struct uart_state {
5: struct tty_port port;
6:
7: int pm_state;
8: struct circ_buf xmit;
9:
10: struct tasklet_struct tlet;
11: struct uart_port *uart_port;
12: };
三、uart_ops 緩存
uart_ops涵蓋了串口驅動可對串口設備進行的全部操做 數據結構
1: /*
2: * This structure describes all the operations that can be
3: * done on the physical hardware.
4: */
5: struct uart_ops {
6: unsigned int (*tx_empty)(struct uart_port *);/* 串口的Tx FIFO緩存是否爲空 */
7: void (*set_mctrl)(struct uart_port *, unsigned int mctrl);/* 設置串口modem控制 */
8: unsigned int (*get_mctrl)(struct uart_port *); /* 獲取串口modem控制 */
9: void (*stop_tx)(struct uart_port *);/* 禁止串口發送數據 */
10: void (*start_tx)(struct uart_port *);/* 使能串口發送數據 */
11: void (*send_xchar)(struct uart_port *, char ch);/* 發送xChar */
12: void (*stop_rx)(struct uart_port *);/* 禁止串口接收數據 */
13: void (*enable_ms)(struct uart_port *);/* 使能modem的狀態信號 */
14: void (*break_ctl)(struct uart_port *, int ctl); /* 設置break信號 */
15: int (*startup)(struct uart_port *);/* 啓動串口,應用程序打開串口設備文件時,該函數會被調用 */
16: void (*shutdown)(struct uart_port *);/* 關閉串口,應用程序關閉串口設備文件時,該函數會被調用 */
17: void (*flush_buffer)(struct uart_port *);
18: void (*set_termios)(struct uart_port *, struct ktermios *new,
19: struct ktermios *old);/* 設置串口參數 */
20: void (*set_ldisc)(struct uart_port *, int new);
21: void (*pm)(struct uart_port *, unsigned int state,
22: unsigned int oldstate);/* 串口電源管理 */
23: int (*set_wake)(struct uart_port *, unsigned int state);
24: void (*wake_peer)(struct uart_port *);
25:
26: /*
27: * Return a string describing the type of the port
28: */
29: const char *(*type)(struct uart_port *);/* 返回一描述串口類型的字符串 */
30:
31: /*
32: * Release IO and memory resources used by the port.
33: * This includes iounmap if necessary.
34: */
35: void (*release_port)(struct uart_port *);/* 釋放串口已申請的IO端口/IO內存資源,必要時還需iounmap */
36:
37: /*
38: * Request IO and memory resources used by the port.
39: * This includes iomapping the port if necessary.
40: */
41: int (*request_port)(struct uart_port *); /* 申請必要的IO端口/IO內存資源,必要時還能夠從新映射串口端口 */
42: void (*config_port)(struct uart_port *, int);/* 執行串口所需的自動配置 */
43: int (*verify_port)(struct uart_port *, struct serial_struct *);/* 驗證串口所需的自動配置 */
44: int (*ioctl)(struct uart_port *, unsigned int, unsigned long);
45: #ifdef CONFIG_CONSOLE_POLL
46: void (*poll_put_char)(struct uart_port *, unsigned char);
47: int (*poll_get_char)(struct uart_port *);
48: #endif
49: };
一、uart_register_driver app
1: / * 功能:uart_register_driver用於將串口驅動uart_driver註冊到內核(串口核心層)中,一般在模塊初始化函數調用該函數。
2: * 參數 drv:要註冊的uart_driver
3: * 返回值: 成功,返回0;不然返回錯誤碼
4: */
5: int uart_register_driver(struct uart_driver *drv)
二、uart_unregister_driver 函數
1: /* 功能: uart_unregister_driver用於註銷咱們已註冊的uart_driver,一般在模塊卸載函數調用該函數
2: * 參數 drv:要註銷的uart_driver
3:
4: * 返回值: 成功,返回0;不然返回錯誤碼
5: */
6: void uart_unregister_driver(struct uart_driver *drv)
7:
三、uart_add_one_port this
1: /* 功能: uart_add_one_port用於爲串口驅動添加一個串口端口,一般在探測到設備後(驅動的設備probe方法)調用該函數
2: * 參數 drv:串口驅動
3: * port:要添加的串口端口
4:
5: * 返回值: 成功,返回0;不然返回錯誤碼
6: */
7: int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
四、uart_remove_one_port spa
1: /* 功能: uart_remove_one_port用於刪除一個已添加到串口驅動中的串口端口,一般在驅動卸載時調用該函數
2: * 參數 drv: 串口驅動
3: * port: 要刪除的串口端口
4: * 返回值: 成功,返回0;不然返回錯誤碼
5: */
6: int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
五、uart_write_wakeup
1: /* 功能: uart_write_wakeup喚醒上層因向串口端口寫數據而阻塞的進程,一般在串口發送中斷處理函數中調用該函數
2: * 參數 port:須要喚醒寫阻塞進程的串口端口
3: */
4: void uart_write_wakeup(struct uart_port *port)
六、uart_suspend_port
1: /* 功能: uart_suspend_port用於掛起特定的串口端口
2: * 參數 drv: 要掛起的串口端口所屬的串口驅動
3: * port:要掛起的串口端口
4: * 返回值: 成功返回0;不然返回錯誤碼
5: */
6: int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
七、uart_resume_port
1: /* 功能: uart_resume_port用於恢復某一已掛起的串口
2: * 參數 drv: 要恢復的串口端口所屬的串口驅動
3: * port:要恢復的串口端口
4: * 返回值: 成功返回0;不然返回錯誤碼
5: */
6: int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
八、uart_get_baud_rate
1: /* 功能: uart_get_baud_rate經過解碼termios結構體來獲取指定串口的波特率
2: * 參數 port: 要獲取波特率的串口端口
3: * termios:當前指望的termios配置(包含串口波特率)
4: * old: 之前的termios配置,能夠爲NULL
5: * min: 可接受的最小波特率
6: * max: 可接受的最大波特率
7: * 返回值: 串口的波特率
8: */
9: unsigned int
10: uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
11: struct ktermios *old, unsigned int min, unsigned int max)
九、uart_get_divisor
1: /* 功能: uart_get_divisor用於計算某一波特率的串口時鐘分頻數(串口波特率除數)
2: * 參數 port:要計算時鐘分頻數的串口端口
3: * baud:指望的波特率
4: *返回值: 串口時鐘分頻數
5: */
6: unsigned int uart_get_divisor(struct uart_port *port, unsigned int baud)
十、uart_update_timeout
1: /* 功能: uart_update_timeout用於更新(設置)串口FIFO超時時間
2: * 參數 port: 要更新超時時間的串口端口
3: * cflag:termios結構體的cflag值
4: * baud: 串口的波特率
5: */
6: void uart_update_timeout(struct uart_port *port, unsigned int cflag, unsigned int baud)
十一、uart_match_port
1: /* 功能:uart_match_port用於判斷兩串口端口是否爲同一端口
2: * 參數 port一、port2:要判斷的串口端口
3: * 返回值:不一樣返回0;不然返回非0
4: */
5: int uart_match_port(struct uart_port *port1, struct uart_port *port2)
十二、uart_console_write
1: /* 功能: uart_console_write用於向串口端口寫一控制檯信息
2:
3: * 參數 port: 要寫信息的串口端口
4: * s: 要寫的信息
5: * count: 信息的大小
6: * putchar: 用於向串口端口寫字符的函數,該函數函數有兩個參數:串口端口和要寫的字符
7: */
8: void uart_console_write(struct uart_port *port, const char *s,
9: unsigned int count,
10: void (*putchar)(struct uart_port *, int))
11: