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);
相关文章
|
算法
经典控制算法——PID算法原理分析及优化
这篇文章介绍了PID控制算法,这是一种广泛应用的控制策略,具有简单、鲁棒性强的特点。PID通过比例、积分和微分三个部分调整控制量,以减少系统误差。文章提到了在大学智能汽车竞赛中的应用,并详细解释了PID的基本原理和数学表达式。接着,讨论了数字PID的实现,包括位置式、增量式和步进式,以及它们各自的优缺点。最后,文章介绍了PID的优化方法,如积分饱和处理和微分项优化,以及串级PID在电机控制中的应用。整个内容旨在帮助读者理解PID控制的原理和实际运用。
1977 1
|
Linux 内存技术
U-BOOT小全(六):BootLoader源码(UBoot-Kernel 1)
U-BOOT小全(六):BootLoader源码(UBoot-Kernel 1)
212 0
|
存储 缓存 安全
U-BOOT小全(五):BootLoader源码(SPL-UBoot 2)
U-BOOT小全(五):BootLoader源码(SPL-UBoot 2)
574 0
|
Linux 编译器 C语言
U-BOOT小全(四):BootLoader源码(SPL-UBoot 1)
U-BOOT小全(四):BootLoader源码(SPL-UBoot 1)
540 0
|
监控 Linux 芯片
Watchdog是什么?为什么要在系统初始化时候关闭什么是 watchdog?
Watchdog是什么?为什么要在系统初始化时候关闭什么是 watchdog?
933 0
|
Shell Linux
uboot启动流程源码分析(二)
uboot启动流程源码分析(二)
269 0
|
存储 Linux 芯片
【启动】芯片启动过程全解析
【启动】芯片启动过程全解析
478 0
Linux线程总结---线程的创建、退出、取消、回收、分离属性
Linux线程总结---线程的创建、退出、取消、回收、分离属性
|
编解码 定位技术 Python
Google Earth Engine谷歌地球引擎GEE批量下载ImageCollection遥感影像数据合集的方法
Google Earth Engine谷歌地球引擎GEE批量下载ImageCollection遥感影像数据合集的方法
897 2
|
存储 编译器 vr&ar
U-BOOT小全(二)
U-BOOT小全(二)
221 0