跟其他的驱动一样,当打开串口设备时,uart_open函数得到调用,在tty_open函数中调用了uart_startup函数来启动串口,如下: 在uart_startup函数中通过uport->ops->startup(uport);间接调用到了imx_startup函数,因为我们在前面已经通过sport->port.ops = &imx_pops将相关硬件平台的串口操作函数赋值给了抽象的串口端口...
uart_startup(tty, state, 0); uart_port_startup(tty, state, init_hw); 1. 2. 3. 来到uart_port_startup: static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,int init_hw) uport->ops->startup(uport); --- 已知 uport->ops = &msm_hs_ops;即 msm_hs_...
在前面的一篇文章中: tty初探 — uart驱动框架分析,我们分析了一个 uart_driver 的向上注册过程,主要是 tty 的一些东西,知道了 tty 注册了一个字符设备驱动,在用户空间 open 时将调用到 uart_port.ops.startup ,在用户空间 write 则调用 uart_port.ops.start_tx ,还知道了如何 read 数据等等。 但是,这些都...
startup:获取中断资源并初始化所有底层驱动程序状态。启用接收端口。该函数不应该激活RTS或DTR;这将通过...
serial8250_ports[port->line].port.ops = &serial8250_pops; //对应端口的操作 return 0; } 函数三: static void __init serial8250_isa_init_ports(void) { struct uart_8250_port *up; static int first = 1; int i; if (!first) return; ...
tty_set_operations(normal, &uart_ops); 此句之所以值得关注是因为.在这里将tty_driver的操作集统一设为了uart_ops.这样就使得从用户空间下来的操作可以找到正确的serial_core的操作函数,uart_ops是在serial_core.c中的: 1 static const struct tty_operations uart_ops = { ...
. iotype = UPIO_MEM , /* IO memory */ . flags = UPF_BOOT_AUTOCONF , /* UART port flag */ . ops = & gprs_uart_ops , /* UART operations */ . line = 0 , /* UART port number */ . lock = __SPIN_LOCK_UNLOCKED ( gprs_uart_port . lock ) , ...
整个tty架构大概的样子如图3.1所示,简单来分的话可以说成两层,一层是下层我们的串口驱动层,它直接与硬件相接触,我们需要填充一个 struct uart_ops 的结构体,另一层是上层 tty 层,包括 tty 核心以及线路规程,它们各自都有一个 Ops 结构,用户空通过间是 tty 注册的字符设备节点来访问。
整个tty架构大概的样子如图3.1所示,简单来分的话可以说成两层,一层是下层我们的串口驱动层,它直接与硬件相接触,我们需要填充一个 struct uart_ops 的结构体,另一层是上层 tty 层,包括 tty 核心以及线路规程,它们各自都有一个 Ops 结构,用户空通过间是 tty 注册的字符设备节点来访问。
先看看Serial 子系统的3个重要数据结构uart_driver 、uart_port 和uart_ops 。这几个数据结构都在<include/linux/serial_core.h>文件中定义。了解这几个数据结构非常有助于分析和理解串口驱动。1. uart_driver uart_driver 结构用于描述串口驱动,包含了串口驱动名称、串口设备名称、串口主次设备号、串口控制台等...