串口驱动程序层次结构

下层为串口驱动层,它直接与硬件相接触,需要填充一个 struct uart_ops 的结构体。上层为tty层,包括tty核心层及线路规程,它们各自都有一个 ops 结构体,用户空间可以通过tty注册的字符设备节点来访问串口设备。涉及到了4个 ops 结构体,层层进行跳转。

uart_driver包含了串口设备名、串口驱动名、主次设备号、串口控制台(可选)等信息
1 2 3 4 5 6 7 8 9 10 11 12 13
| struct uart_driver { struct module *owner; constchar *driver_name; constchar *dev_name; int major; int minor; int nr; struct console *cons; ............................. struct uart_state *state; struct tty_driver *tty_driver; };
|
(1)一个tty驱动程序必须注册/注销tty_driver。
(2)一个uart驱动则变为注册/注销uart_driver。
1 2 3 4
| 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);
|
uart_port用于描述一个UART端口(直接对应于一个串口)的I/O端口或I/O内存地址、FIFO大小、端口类型等信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| struct uart_port { spinlock_t lock; unsignedint iobase; unsignedchar __iomem *membase; unsignedint irq; unsignedint uartclk; unsignedint fifosize; unsignedchar x_char; unsignedchar regshift; unsignedchar iotype; unsignedchar unused1;
#define UPIO_PORT (0) #define UPIO_HUB6 (1) #define UPIO_MEM (2) #define UPIO_MEM32 (3) #define UPIO_AU (4) #define UPIO_TSI (5) #define UPIO_DWAPB (6) #define UPIO_RM9000 (7)
unsignedint read_status_mask; unsignedint ignore_status_mask; struct uart_info *info; struct uart_icount icount;
struct console *cons; #ifdefCONFIG_SERIAL_CORE_CONSOLE unsignedlong sysrq; #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; unsigned int timeout; unsigned int type; const struct uart_ops *ops; unsigned int custom_divisor; unsigned int line; resource_size_t mapbase; struct device *dev; unsigned char hub6; unsigned char suspended; unsigned char unused[2]; void*private_data; };
|