UART子系统(九)UART驱动情景分析_open

简介: UART子系统(九)UART驱动情景分析_open

UART驱动情景分析_open


参考资料

参考代码:
硬件相关:
drivers/tty/serial/imx.c
drivers/tty/serial/stm32-usart.c
串口核心层:
drivers/tty/serial/serial_core.c
TTY层:
drivers/tty/tty_io.c


1. 情景分析大纲


注册过程分析

open过程分析

read过程分析

write过程分析


2. 源码框架回顾


1670938741086.jpg

3. 设备节点是哪个


为什么是/dev/ttymxc、/dev/ttySTM?


为什么是/dev/ttymxc5、/dev/ttySTM3?


4. open过程分析


它要做的事情:


找到tty_driver


分配/设置tty_struct * 行规程相关的初始化

调用tty_driver->ops->open // ops是struct tty_operations指针类型, 就是uart_open

tty_port_open // uart下有多个port, 下面就是打开某个port
port->ops->activate(port, tty); // ops是struct tty_port_operations指针类型
uart_startup(tty, state, 0);
uart_port_startup(tty, state, init_hw);
调用uart_port->ops->startup // ops是struct uart_ops指针类型

图形化说明:有3种ops:

1670938774770.jpg

4.1 tty_open

tty_open
    // 如果设备节点是(5,0)也就是/dev/tty, 表示当前TTY
    // 对于普通串口, 第一次open时必定失败
    tty = tty_open_current_tty(device, filp);
  // 第一次open串口时走这个分支
  if (!tty)
        // 通过driver来open tty,就是找到tty_driver,然后分配/设置tty_struct
    tty = tty_open_by_driver(device, inode, filp);
        // 1. 先找到对应的tty_driver
        driver = tty_lookup_driver(device, filp, &index);
        // 2. 如果曾经open过,会有对应的tty_struct
        tty = tty_driver_lookup_tty(driver, filp, index);
        // 3. 第1打开这个串口时肯定没有对应的tty_struct
                //    所以使用下面的函数初始化设备
        tty = tty_init_dev(driver, index);
              // 3.1 分配tty_strct
              tty = alloc_tty_struct(driver, idx);
                    tty->ops = driver->ops;
              // 3.2 安装tty: 也就是driver->ttys[tty->index] = tty;
              retval = tty_driver_install_tty(driver, tty);
              // 3.3 调用行规程的open函数, 过于复杂,不分析
              //     n_tty.c中的n_tty_open函数
              retval = tty_ldisc_setup(tty, tty->link);
  ......
    // ops是tty_operations类型
    // 对于串口ops就是serial_core.c中的uart_ops
    // uart_open
  if (tty->ops->open)
    retval = tty->ops->open(tty, filp);
  else
    retval = -ENODEV;

4.2 uart_open

uart_open
    tty_port_open
      // ops是tty_port_operations类型,对应serial_core.c中的uart_port_ops
      // uart_port_activate
    if (port->ops->activate) {
      int retval = port->ops->activate(port, tty);
      if (retval) {
        mutex_unlock(&port->mutex);
        return retval;
      }
    }
uart_port_activate
  uart_startup
      uart_port_startup
        // ops是uart_ops类型,在硬件驱动中设置
        // 硬件相关的驱动中uart_port的uart_ops里必须提供startup函数
        retval = uport->ops->startup(uport);
相关文章
|
5月前
|
数据采集 测试技术
常见测试测量接口的比较:PXI、PXIe、PCI、VXI、GPIB、USB
常见测试测量接口的比较:PXI、PXIe、PCI、VXI、GPIB、USB
196 2
|
Linux 芯片
Linux驱动分析之SPI设备
前面我们对SPI控制器驱动进行了分析,接下来来分析SPI设备驱动。我们以DS1302驱动作为分析对象。DS1302是一款RTC芯片,估计很多人在学单片机时用到过。RTC芯片算是比较简单的,也方便分析理解。
Linux驱动分析之SPI设备
|
缓存 Linux API
Linux驱动分析之Uart驱动架构
UART设备驱动可以使用tty驱动的框架来实现,但是因为串口之间有共性,所以Linux在tty接口上封装了一层(serial core)。后面我们再拿一篇文章来解释tty驱动,tty其实就是各种终端设备,串口其实也是终端设备。
Linux驱动分析之Uart驱动架构
|
Linux API
Linux驱动分析之LCD驱动架构
在Linux设备中,LCD显示采用了帧缓冲(framebuffer)技术,所以LCD驱动也叫Framebuffer驱动,所以LCD驱动框架就是围绕帧缓冲展开工作。帧缓冲(framebuffer)是Linux系统为显示设备提供的一个接口,它将显示缓冲区抽象出来,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。对于帧缓冲设备而言,只要在显示缓冲区中与显示点对应的区域写入颜色值,对应的颜色会自动在屏幕上显示。帧缓冲为标准字符设备, 主设备号为29,对应于/dev/fbn。
UART子系统(十)UART驱动情景分析_read
UART子系统(十)UART驱动情景分析_read
207 2
UART子系统(十)UART驱动情景分析_read
UART子系统(八)UART驱动情景分析_注册
UART子系统(八)UART驱动情景分析_注册
80 1
UART子系统(八)UART驱动情景分析_注册
LED模板驱动程序的改造:总线设备驱动模型
LED模板驱动程序的改造:总线设备驱动模型
116 0
|
移动开发 Unix Linux
UART子系统(四) TTY驱动程序框架
UART子系统(四) TTY驱动程序框架
245 1
UART子系统(四) TTY驱动程序框架
|
缓存 Linux 芯片
Linux驱动分析之Uart驱动
之前对Uart驱动的整体架构做了介绍,现在来分析具体的驱动程序。我们以NXP 的 IMX6来进行分析。
高通平台开发系列讲解(UART篇)高速UART IPC调试方法
高通平台开发系列讲解(UART篇)高速UART IPC调试方法
498 0
高通平台开发系列讲解(UART篇)高速UART IPC调试方法