明白UART 子体系:Linux Kernel 4.9.88 中的核心布局体与设计详解 ...

火影  金牌会员 | 2024-12-1 23:01:37 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 799|帖子 799|积分 2397

往期内容

   本专栏往期内容:Uart子体系
  

  • UART串口硬件介绍
  • 深入明白TTY体系:装备节点与驱动步伐框架详解
  • Linux串口应用编程:从UART到GPS模块及字符装备驱动
  interrupt子体系专栏:
  

  • 专栏地点:interrupt子体系
  • Linux 链式与层级停止控制器讲解:原理与驱动开辟
    – 末片,有专栏内容观看顺序
  pinctrl和gpio子体系专栏:
  

  • 专栏地点:pinctrl和gpio子体系
  • 编写虚拟的GPIO控制器的驱动步伐:和pinctrl的交互使用
    – 末片,有专栏内容观看顺序
  input子体系专栏:
  

  • 专栏地点:input子体系
  • input角度:I2C触摸屏驱动分析和编写一个简单的I2C驱动步伐
    – 末片,有专栏内容观看顺序
  I2C子体系专栏:
  

  • 专栏地点:IIC子体系
  • 具体芯片的IIC控制器驱动步伐分析:i2c-imx.c-CSDN博客
    – 末篇,有专栏内容观看顺序
  总线和装备树专栏:
  

  • 专栏地点:总线和装备树
  • 装备树与 Linux 内核装备驱动模子的整合-CSDN博客
    – 末篇,有专栏内容观看顺序
  


  
1.框图


2.uart_port

uart_port 布局体包含 UART 端口的具体信息,包罗寄存器地点、锁、端口设置等,UART 核心和底层驱动共同使用此布局体来实现端口的设置、控制和数据传输。下面的成员是有所省略的。
  1. \Linux-4.9.88\include\linux\serial_core.h
  2. /**
  3. * struct uart_port - 描述 UART 端口的硬件配置及控制方法
  4. * @lock: 自旋锁,用于保护端口数据访问的同步
  5. * @iobase: 端口的 IO 基地址,用于 IO 映射
  6. * @membase: 端口的内存映射基地址,用于内存映射方式
  7. * @serial_in: 函数指针,用于读取寄存器中的数据
  8. * @serial_out: 函数指针,用于写入数据到寄存器
  9. * @set_termios: 配置串口的波特率、数据位等参数
  10. * @get_mctrl: 获取控制信号状态(如 CTS、DCD 等)
  11. * @set_mctrl: 设置控制信号(如 RTS、DTR 等)
  12. * @startup: 启动 UART 端口
  13. * @shutdown: 关闭 UART 端口
  14. * @throttle: 降速处理,当缓冲区快满时限制数据传输
  15. * @unthrottle: 恢复数据传输
  16. * @handle_irq: 中断处理函数,处理端口的中断请求
  17. * @pm: 电源管理回调,用于切换电源状态
  18. * @handle_break: 处理中断信号
  19. * @irq: 端口的 IRQ 编号
  20. * @irqflags: IRQ 标志,用于设置中断类型
  21. * @uartclk: UART 基准时钟频率,用于计算波特率
  22. * @fifosize: 发送 FIFO 的大小
  23. * @flags: 端口的控制标志,包含流控制、低延迟等设置
  24. * @status: UART 端口的状态标志
  25. * @ops: 指向 UART 操作的结构体指针,包含各种操作函数
  26. * @dev: 指向此 UART 端口的设备结构体指针
  27. * @private_data: 通用平台数据指针,用于存储私有数据
  28. */
  29. struct uart_port {
  30.     spinlock_t lock;                  // 端口锁,用于保护并发访问
  31.     unsigned long iobase;             // IO 基地址
  32.     unsigned char __iomem *membase;   // 内存映射的基地址
  33.     unsigned int (*serial_in)(struct uart_port *, int);  // 读取寄存器
  34.     void (*serial_out)(struct uart_port *, int, int);    // 写入寄存器
  35.     void (*set_termios)(struct uart_port *, struct ktermios *new, struct ktermios *old); // 配置串口
  36.     unsigned int (*get_mctrl)(struct uart_port *);       // 获取控制信号
  37.     void (*set_mctrl)(struct uart_port *, unsigned int); // 设置控制信号
  38.     int (*startup)(struct uart_port *port);              // 启动 UART 端口
  39.     void (*shutdown)(struct uart_port *port);            // 关闭 UART 端口
  40.     void (*throttle)(struct uart_port *port);            // 数据传输限制
  41.     void (*unthrottle)(struct uart_port *port);          // 恢复数据传输
  42.     int (*handle_irq)(struct uart_port *);               // 中断处理函数
  43.     void (*pm)(struct uart_port *, unsigned int state, unsigned int old); // 电源管理
  44.     void (*handle_break)(struct uart_port *);            // 处理中断信号
  45.     int (*rs485_config)(struct uart_port *, struct serial_rs485 *rs485); // RS485 配置
  46.     unsigned int irq;                     // 中断请求编号
  47.     unsigned long irqflags;               // 中断标志
  48.     unsigned int uartclk;                 // 基准时钟频率
  49.     unsigned int fifosize;                // FIFO 缓冲区大小
  50.     unsigned char x_char;                 // XON/XOFF 字符
  51.     unsigned char regshift;               // 寄存器偏移量
  52.     unsigned char iotype;                 // IO 访问类型
  53.     unsigned int read_status_mask;        // 读取状态掩码
  54.     unsigned int ignore_status_mask;      // 忽略状态掩码
  55.     struct uart_state *state;             // 指向 UART 状态
  56.     struct uart_icount icount;            // UART 统计数据
  57.     struct console *cons;                 // 控制台指针
  58.     upf_t flags;                          // UART 端口的标志
  59.     upstat_t status;                      // 端口状态标志
  60.     int hw_stopped;                       // 硬件停止状态
  61.     unsigned int mctrl;                   // 调制解调控制状态
  62.     unsigned int timeout;                 // 超时设置
  63.     unsigned int type;                    // UART 端口类型
  64.     const struct uart_ops *ops;           // UART 操作接口
  65.     unsigned int custom_divisor;          // 自定义波特率分频器
  66.     unsigned int line;                    // UART 端口编号
  67.     unsigned int minor;                   // 次设备号
  68.     resource_size_t mapbase;              // IO 内存基地址
  69.     resource_size_t mapsize;              // IO 内存大小
  70.     struct device *dev;                   // 设备指针
  71.     unsigned char hub6;                   // Hub6 ISA 卡的配置
  72.     unsigned char suspended;              // 挂起状态
  73.     unsigned char irq_wake;               // IRQ 唤醒状态
  74.     struct attribute_group *attr_group;   // 端口的特定属性
  75.     const struct attribute_group **tty_groups; // 全部 tty 属性
  76.     struct serial_rs485 rs485;            // RS485 协议配置
  77.     void *private_data;                   // 平台特定的私有数据指针
  78. };
复制代码
3.uart_driver

uart_driver 布局体包含了 UART 驱动步伐的相关信息,比方驱动名称、主次装备号等,用于注册和管理 UART 驱动。
  1. \Linux-4.9.88\include\linux\serial_core.h
  2. /**
  3. * struct uart_driver - 描述 UART 驱动信息
  4. * @owner: 指向驱动程序模块的指针,通常设置为 THIS_MODULE
  5. * @driver_name: 驱动程序的名称,通常用于 sysfs 中
  6. * @dev_name: 设备名称前缀,用于生成设备节点名称(如 ttyS)
  7. * @major: 主设备号,用于指定 UART 驱动的主设备号
  8. * @minor: 次设备号,通常用于为多个 UART 设备提供编号
  9. * @nr: 最大支持的 UART 端口数量
  10. * @cons: 与驱动相关联的控制台设备
  11. * @state: 指向每个 UART 端口的状态信息,通常由 UART 核心初始化
  12. * @tty_driver: 指向 tty_driver 结构体的指针,表示与此 UART 驱动关联的 TTY 驱动
  13. */
  14. struct uart_driver {
  15.     struct module *owner;              // 驱动程序模块的指针
  16.     const char *driver_name;           // UART 驱动的名称
  17.     const char *dev_name;              // 设备名称前缀
  18.     int major;                         // 主设备号
  19.     int minor;                         // 次设备号
  20.     int nr;                            // 支持的最大 UART 端口数
  21.     struct console *cons;              // 控制台设备结构体指针
  22.     // 以下字段应由 UART 核心初始化,底层驱动不应直接操作
  23.     struct uart_state *state;          // UART 状态信息
  24.     struct tty_driver *tty_driver;     // TTY 驱动的指针
  25. };
复制代码
4.tty_port

tty_port 布局体管理 TTY 端口的资源和状态,包罗等待队列、互斥锁、缓冲区等,用于简化驱动层对 TTY 端口的管理。
  1. \Linux-4.9.88\include\linux\tty.h
  2. /**
  3. * struct tty_port - 描述 TTY 端口的信息和状态
  4. * @buf: 缓冲区头,用于管理端口的数据缓冲区,内部锁定保护
  5. * @tty: 指向 tty_struct 的指针,用于指向已分配的 TTY 结构体(回指)
  6. * @itty: 内部指向 tty_struct 的指针,用于指向内部TTY 结构体(内部回指)
  7. * @ops: 指向 tty_port_operations 结构体的指针,定义了端口的操作函数
  8. * @lock: 自旋锁,用于保护 tty 字段的访问
  9. * @blocked_open: 阻塞打开标志,用于表示端口是否正在等待打开
  10. * @count: 使用计数,表示端口被打开的次数
  11. * @open_wait: 等待队列,用于阻塞打开的进程
  12. * @delta_msr_wait: 调制解调器状态变化等待队列,用于等待调制解调器状态改变
  13. * @flags: 用户 TTY 标志,表示端口的属性,例如异步标志
  14. * @iflags: 内部标志,用于表示端口的内部状态(TTY_PORT_ 开头)
  15. * @console: 标志位,表示该端口是否是控制台
  16. * @low_latency: 可选标志位,表示是否调优以降低延迟
  17. * @mutex: 互斥锁,用于端口锁定
  18. * @buf_mutex: 缓冲区分配锁,用于管理缓冲区的分配
  19. * @xmit_buf: 可选发送缓冲区,用于保存传输的数据
  20. * @close_delay: 关闭端口时的延迟,单位为毫秒
  21. * @closing_wait: 输出完成的延迟时间
  22. * @drain_delay: 排空延迟,当无需基于时间的纯排空时设置为零,否则设置为 FIFO 大小
  23. * @kref: 引用计数器,用于控制 tty_port 结构体的引用计数
  24. */
  25. struct tty_port {
  26.     struct tty_bufhead buf;           // 数据缓冲区头,管理端口的缓冲区
  27.     struct tty_struct *tty;           // 指向 tty_struct 的指针(回指)
  28.     struct tty_struct *itty;          // 内部指向 tty_struct 的指针(内部回指)
  29.     const struct tty_port_operations *ops; // 端口的操作函数指针
  30.     spinlock_t lock;                  // 自旋锁,保护 tty 字段
  31.     int blocked_open;                 // 阻塞打开标志
  32.     int count;                        // 使用计数
  33.     wait_queue_head_t open_wait;      // 打开等待队列
  34.     wait_queue_head_t delta_msr_wait; // 调制解调器状态变化等待队列
  35.     unsigned long flags;              // 用户 TTY 标志(如 ASYNC_)
  36.     unsigned long iflags;             // 内部标志(如 TTY_PORT_)
  37.     unsigned char console:1;          // 是否是控制台
  38.     unsigned char low_latency:1;      // 是否调优为低延迟
  39.     struct mutex mutex;               // 端口互斥锁
  40.     struct mutex buf_mutex;           // 缓冲区分配锁
  41.     unsigned char *xmit_buf;          // 可选的发送缓冲区
  42.     unsigned int close_delay;         // 关闭端口时的延迟(毫秒)
  43.     unsigned int closing_wait;        // 输出完成延迟时间
  44.     int drain_delay;                  // 排空延迟
  45.     struct kref kref;                 // 引用计数器
  46. };
复制代码
5.tty_driver

tty_driver 布局体负责管理 TTY 驱动的根本信息,包罗驱动名称、装备编号、TTY 数量等。同时,定义了特定的驱动操作函数接口,以便 TTY 子体系调用这些函数来操作装备。
  1. /**
  2. * struct tty_driver - 描述 TTY 驱动的信息及操作函数
  3. * @magic: 魔数,用于识别 TTY 驱动结构体的合法性
  4. * @kref: 引用计数管理,用于控制结构体的生命周期
  5. * @cdevs: 指向字符设备的指针数组
  6. * @owner: 指向驱动模块的指针,通常为 THIS_MODULE
  7. * @driver_name: 驱动程序的名称,用于标识驱动
  8. * @name: TTY 设备名称,用于生成设备节点名称(例如 ttyS)
  9. * @name_base: 名称基址,用于计算 TTY 设备的完整名称
  10. * @major: 主设备号,用于标识驱动
  11. * @minor_start: 起始次设备号,通常用于为多个 TTY 设备提供编号
  12. * @num: 分配的设备数量
  13. * @type: 驱动类型,用于区分不同类型的 TTY 驱动
  14. * @subtype: 驱动子类型,进一步区分 TTY 驱动的类型
  15. * @init_termios: 初始终端设置,用于初始化 TTY 的终端属性
  16. * @flags: 驱动标志,用于标识驱动的特殊属性
  17. * @proc_entry: 指向 proc 文件系统的条目指针
  18. * @other: 仅用于 PTY 驱动,指向配对的 TTY 驱动
  19. * @ttys: 指向 tty_struct 指针数组,用于管理所有 TTY 设备
  20. * @ports: 指向 tty_port 指针数组,指向所有端口信息
  21. * @termios: 指向 ktermios 指针数组,保存每个 TTY 的终端属性
  22. * @driver_state: 驱动状态指针,用于存储特定的驱动状态信息
  23. * @ops: 指向 tty_operations 的指针,包含驱动操作函数
  24. * @tty_drivers: TTY 驱动列表,用于连接多个 TTY 驱动
  25. */
  26. struct tty_driver {
  27.     int magic;                      // 魔数,确保结构体合法性
  28.     struct kref kref;               // 引用计数管理
  29.     struct cdev **cdevs;            // 字符设备指针数组
  30.     struct module *owner;           // 指向驱动模块(通常为 THIS_MODULE)
  31.     const char *driver_name;        // 驱动程序的名称
  32.     const char *name;               // TTY 设备名称
  33.     int name_base;                  // 名称基址
  34.     int major;                      // 主设备号
  35.     int minor_start;                // 起始次设备号
  36.     unsigned int num;               // 分配的设备数量
  37.     short type;                     // 驱动类型
  38.     short subtype;                  // 驱动子类型
  39.     struct ktermios init_termios;   // 初始终端设置
  40.     unsigned long flags;            // 驱动标志
  41.     struct proc_dir_entry *proc_entry; // /proc 文件系统条目
  42.     struct tty_driver *other;       // 配对的 TTY 驱动(仅用于 PTY 驱动)
  43.     // 指向 TTY 数据结构的指针
  44.     struct tty_struct **ttys;       // TTY 结构体指针数组
  45.     struct tty_port **ports;        // TTY 端口指针数组
  46.     struct ktermios **termios;      // TTY 的终端设置
  47.     void *driver_state;             // 驱动状态信息
  48.     // 驱动方法
  49.     const struct tty_operations *ops; // 驱动操作函数
  50.     struct list_head tty_drivers;   // TTY 驱动列表
  51. };
复制代码
6.uart_state

uart_driver布局体的成员
  1. \Linux-4.9.88\include\linux\serial_core.h
  2. /*
  3. * This is the state information which is persistent across opens.
  4. */
  5. struct uart_state {
  6.         struct tty_port                port;        // 表示与TTY设备相关的端口信息,包含串口的输入输出控制功能。
  7.         enum uart_pm_state        pm_state;   // UART的电源管理状态,指示串口的当前电源状态(如:活动、休眠等)。
  8.         struct circ_buf                xmit;       // 用于存储要发送的字符的循环缓冲区,支持异步传输。
  9.         atomic_t                refcount;    // 引用计数,用于跟踪当前有多少个打开的句柄指向此状态结构体。
  10.         wait_queue_head_t        remove_wait; // 用于进程等待的队列头,如果设备正在被移除,则相应的进程可以等待。
  11.         struct uart_port        *uart_port; // 指向具体的UART端口结构体,包含硬件相关信息,如基地址、IRQ等。
  12. };
  13.         truct circ_buf                xmit;       // 用于存储要发送的字符的循环缓冲区,支持异步传输。
  14.         atomic_t                refcount;    // 引用计数,用于跟踪当前有多少个打开的句柄指向此状态结构体。
  15.         wait_queue_head_t        remove_wait; // 用于进程等待的队列头,如果设备正在被移除,则相应的进程可以等待。
  16.         struct uart_port        *uart_port; // 指向具体的UART端口结构体,包含硬件相关信息,如基地址、IRQ等。
  17. };
复制代码
uart_state布局体用于表示UART(通用异步收发传输)装备的状态信息,生存了关于装备操作的多个重要参数,如当前的电源管理状态、待发送的数据缓冲区、引用计数等。这些信息在装备打开和关闭时保持不变。
7.tty_operations

tty_driver布局体的成员
  1. struct tty_operations {
  2.         struct tty_struct * (*lookup)(struct tty_driver *driver, // 查找TTY结构体的操作函数
  3.                         struct file *filp, int idx);             // 根据驱动、文件和索引返回相应的tty_struct。
  4.         int  (*install)(struct tty_driver *driver,              // 安装TTY设备的操作函数
  5.                         struct tty_struct *tty);                   // 初始化tty_struct。
  6.         void (*remove)(struct tty_driver *driver,               // 移除TTY设备的操作函数
  7.                         struct tty_struct *tty);                   // 清理tty_struct资源。
  8.         int  (*open)(struct tty_struct * tty,                   // 打开TTY设备的操作函数
  9.                         struct file * filp);                        // 对应于打开文件的系统调用。
  10.         void (*close)(struct tty_struct * tty,                  // 关闭TTY设备的操作函数
  11.                         struct file * filp);                        // 对应于关闭文件的系统调用。
  12.         void (*shutdown)(struct tty_struct *tty);               // 关闭TTY设备并清理资源的操作函数。
  13.         void (*cleanup)(struct tty_struct *tty);                // 清理TTY设备资源的操作函数。
  14.         int  (*write)(struct tty_struct * tty,                  // 写入数据到TTY设备的操作函数
  15.                       const unsigned char *buf, int count);     // 将缓冲区中的数据写入tty。
  16.         int  (*put_char)(struct tty_struct *tty,               // 向TTY设备发送单个字符的操作函数
  17.                       unsigned char ch);                         // 字符。
  18.         void (*flush_chars)(struct tty_struct *tty);           // 刷新TTY设备中的字符(清空缓冲区)。
  19.         int  (*write_room)(struct tty_struct *tty);            // 获取TTY设备的写入空间大小。
  20.         int  (*chars_in_buffer)(struct tty_struct *tty);       // 获取TTY设备缓冲区中字符的数量。
  21.         int  (*ioctl)(struct tty_struct *tty,                   // 处理TTY设备的控制命令的操作函数
  22.                     unsigned int cmd, unsigned long arg);      // 控制命令和参数。
  23.         long (*compat_ioctl)(struct tty_struct *tty,           // 处理兼容性的ioctl命令的操作函数
  24.                              unsigned int cmd, unsigned long arg);
  25.         void (*set_termios)(struct tty_struct *tty,            // 设置TTY设备的终端属性
  26.                              struct ktermios * old);             // 旧的终端属性。
  27.         void (*throttle)(struct tty_struct * tty);             // 暂停TTY设备的输出。
  28.         void (*unthrottle)(struct tty_struct * tty);           // 恢复TTY设备的输出。
  29.         void (*stop)(struct tty_struct *tty);                  // 停止TTY设备的操作。
  30.         void (*start)(struct tty_struct *tty);                 // 启动TTY设备的操作。
  31.         void (*hangup)(struct tty_struct *tty);                // 挂断TTY设备的操作。
  32.         int (*break_ctl)(struct tty_struct *tty, int state);   // 控制TTY设备的断开状态。
  33.         void (*flush_buffer)(struct tty_struct *tty);          // 刷新TTY设备的缓冲区。
  34.         void (*set_ldisc)(struct tty_struct *tty);             // 设置TTY设备的线路设备。
  35.         void (*wait_until_sent)(struct tty_struct *tty, int timeout); // 等待TTY设备发送完毕。
  36.         void (*send_xchar)(struct tty_struct *tty, char ch);   // 向TTY设备发送控制字符。
  37.         int (*tiocmget)(struct tty_struct *tty);                // 获取TTY设备的状态位。
  38.         int (*tiocmset)(struct tty_struct *tty,                 // 设置TTY设备的状态位。
  39.                         unsigned int set, unsigned int clear);    // 要设置和清除的位。
  40.         int (*resize)(struct tty_struct *tty,                  // 调整TTY设备窗口大小的操作函数。
  41.                         struct winsize *ws);                       // 新的窗口大小。
  42.         int (*set_termiox)(struct tty_struct *tty,             // 设置扩展终端参数的操作函数。
  43.                         struct termiox *tnew);                    // 新的终端参数。
  44.         int (*get_icount)(struct tty_struct *tty,              // 获取TTY设备中输入计数的操作函数。
  45.                                 struct serial_icounter_struct *icount); // 输入计数结构体。
  46. #ifdef CONFIG_CONSOLE_POLL
  47.         int (*poll_init)(struct tty_driver *driver, int line, char *options); // 初始化轮询的操作函数。
  48.         int (*poll_get_char)(struct tty_driver *driver, int line);             // 获取字符的轮询操作函数。
  49.         void (*poll_put_char)(struct tty_driver *driver, int line, char ch);   // 发送字符的轮询操作函数。
  50. #endif
  51.         const struct file_operations *proc_fops;               // 指向文件操作的结构体,用于处理proc文件系统。
  52. };
复制代码
tty_operations布局体定义了与TTY(终端)装备相关的操作函数的指针。这些函数用于管理TTY装备的生命周期、数据读写、状态控制等。每个函数的实现可以根据差别的TTY驱动进行定制,提供与硬件相关的操作接口。
8.uart_ops

uart_port布局体的成员
  1. \Linux-4.9.88\include\linux\serial_core.h
  2. /*
  3. * This structure describes all the operations that can be done on the
  4. * physical hardware.  See Documentation/serial/driver for details.
  5. */
  6. struct uart_ops {
  7.         unsigned int        (*tx_empty)(struct uart_port *); // 检查传输寄存器是否为空的操作函数。
  8.         void                (*set_mctrl)(struct uart_port *, unsigned int mctrl); // 设置控制线的操作函数。
  9.         unsigned int        (*get_mctrl)(struct uart_port *); // 获取控制线状态的操作函数。
  10.         void                (*stop_tx)(struct uart_port *); // 停止数据发送的操作函数。
  11.         void                (*start_tx)(struct uart_port *); // 开始数据发送的操作函数。
  12.         void                (*throttle)(struct uart_port *); // 暂停数据发送的操作函数。
  13.         void                (*unthrottle)(struct uart_port *); // 恢复数据发送的操作函数。
  14.         void                (*send_xchar)(struct uart_port *, char ch); // 发送一个特定字符的操作函数。
  15.         void                (*stop_rx)(struct uart_port *); // 停止数据接收的操作函数。
  16.         void                (*enable_ms)(struct uart_port *); // 启用调制解调器信号的操作函数。
  17.         void                (*break_ctl)(struct uart_port *, int ctl); // 控制断开信号的操作函数。
  18.         int                (*startup)(struct uart_port *); // 启动UART设备的操作函数。
  19.         void                (*shutdown)(struct uart_port *); // 关闭UART设备的操作函数。
  20.         void                (*flush_buffer)(struct uart_port *); // 刷新缓冲区的操作函数。
  21.         void                (*set_termios)(struct uart_port *, struct ktermios *new,
  22.                                        struct ktermios *old); // 设置终端属性的操作函数。
  23.         void                (*set_ldisc)(struct uart_port *, struct ktermios *); // 设置线路设备的操作函数。
  24.         void                (*pm)(struct uart_port *, unsigned int state,
  25.                               unsigned int oldstate); // 进行电源管理的操作函数。
  26.         /*
  27.          * Return a string describing the type of the port
  28.          */
  29.         const char        *(*type)(struct uart_port *); // 返回描述端口类型的字符串的操作函数。
  30.         /*
  31.          * Release IO and memory resources used by the port.
  32.          * This includes iounmap if necessary.
  33.          */
  34.         void                (*release_port)(struct uart_port *); // 释放端口使用的IO和内存资源的操作函数。
  35.         /*
  36.          * Request IO and memory resources used by the port.
  37.          * This includes iomapping the port if necessary.
  38.          */
  39.         int                (*request_port)(struct uart_port *); // 请求端口使用的IO和内存资源的操作函数。
  40.         void                (*config_port)(struct uart_port *, int); // 配置端口的操作函数。
  41.         int                (*verify_port)(struct uart_port *, struct serial_struct *); // 验证端口配置的操作函数。
  42.         int                (*ioctl)(struct uart_port *, unsigned int, unsigned long); // 处理IO控制命令的操作函数。
  43. #ifdef CONFIG_CONSOLE_POLL
  44.         int                (*poll_init)(struct uart_port *); // 初始化轮询的操作函数。
  45.         void                (*poll_put_char)(struct uart_port *, unsigned char); // 轮询发送字符的操作函数。
  46.         int                (*poll_get_char)(struct uart_port *); // 轮询接收字符的操作函数。
  47. #endif
  48. };
复制代码


  • uart_ops 布局体用于定义与物理UART硬件相关的全部操作。这些操作涵盖了UART装备的根本功能,如数据传输、控制线管理、端口设置、资源请求等。
  • 每个函数指针代表一种操作,具体的实现由对应的UART驱动提供。这样,uart_ops 布局体使得差别的UART硬件可以或许通过统一的接口进行操作,从而简化了驱动步伐的开辟。
  • 比方,start_tx 和 stop_tx 用于控制数据发送,而 set_termios 则用于设置UART的终端参数。这些函数的实现可以根据具体的硬件特性进行调解,确保在差别平台上能有用地控制UART装备。
必要额外注意的是不要和tty_operations混淆,由于驱动步伐中常常这样去定义:struct tty_operations uar_ops和struct uart_ops imx_xxxxx,是不是很容易混淆,这点一定要注意。
9.接洽


10.tty_truct

  1. /*
  2. * 该结构体存储与TTY相关的所有状态信息,当TTY处于打开状态时。
  3. * 由于termios状态在TTY关闭后仍应保留(例如波特率等),
  4. * 因此不会在此存储,而是存储指向真实状态的指针。
  5. * winsize结构可能应采取相同的处理,但(1)默认的80x24通常是正确的,
  6. * 并且(2)它最常由窗口系统使用,每次创建或调整窗口大小时都会设置正确的大小。
  7. *                                                 - TYT, 9/14/92
  8. */
  9. struct tty_operations; // 前向声明TTY操作结构
  10. struct tty_struct {
  11.         int magic; // 结构的魔术值,用于识别TTY结构的有效性
  12.         struct kref kref; // 引用计数,用于管理TTY结构的生命周期
  13.         struct device *dev; // 关联的设备结构指针
  14.         struct tty_driver *driver; // 指向驱动程序的指针
  15.         const struct tty_operations *ops; // TTY操作的指针
  16.         int index; // TTY设备的索引
  17.         /* 保护线路纪律变化:锁定TTY而不是PTY */
  18.         struct ld_semaphore ldisc_sem; // 用于保护线路纪律的信号量
  19.         struct tty_ldisc *ldisc; // 指向线路纪律的指针
  20.         struct mutex atomic_write_lock; // 保护原子写入的互斥锁
  21.         struct mutex legacy_mutex; // 旧代码的互斥锁
  22.         struct mutex throttle_mutex; // 用于控制流的互斥锁
  23.         struct rw_semaphore termios_rwsem; // 保护termios的读写信号量
  24.         struct mutex winsize_mutex; // 保护窗口大小的互斥锁
  25.         spinlock_t ctrl_lock; // 控制状态的自旋锁
  26.         spinlock_t flow_lock; // 控制流的自旋锁
  27.         /* termios值由termios_rwsem保护 */
  28.         struct ktermios termios, termios_locked; // termios结构,保存串口设置
  29.         struct termiox *termiox; // 可能为NULL,表示不支持的扩展设置
  30.         char name[64]; // TTY的名称
  31.         struct pid *pgrp; // 进程组ID,由ctrl_lock保护
  32.         struct pid *session; // 会话ID
  33.         unsigned long flags; // 状态标志位
  34.         int count; // 当前打开的引用计数
  35.         struct winsize winsize; // 窗口大小,受winsize_mutex保护
  36.         unsigned long stopped:1, // 表示流是否停止
  37.                       flow_stopped:1, // 表示流是否已停止
  38.                       unused:BITS_PER_LONG - 2; // 未使用的位
  39.         int hw_stopped; // 硬件停止标志
  40.         unsigned long ctrl_status:8, // 控制状态
  41.                       packet:1, // 表示是否为数据包
  42.                       unused_ctrl:BITS_PER_LONG - 9; // 未使用的位
  43.         unsigned int receive_room; // 接收队列的可用字节数
  44.         int flow_change; // 流控制变化标志
  45.         struct tty_struct *link; // 指向其他TTY结构的链接
  46.         struct fasync_struct *fasync; // 异步通知结构
  47.         int alt_speed; // 用于38400 bps的魔法替代
  48.         wait_queue_head_t write_wait; // 写等待队列头
  49.         wait_queue_head_t read_wait; // 读等待队列头
  50.         struct work_struct hangup_work; // 处理挂断的工作结构
  51.         void *disc_data; // 线路纪律的私有数据
  52.         void *driver_data; // 驱动程序的私有数据
  53.         spinlock_t files_lock; // 保护tty_files列表的自旋锁
  54.         struct list_head tty_files; // 关联的打开文件列表
  55. #define N_TTY_BUF_SIZE 4096 // 定义TTY缓冲区大小
  56.         int closing; // 指示TTY是否正在关闭
  57.         unsigned char *write_buf; // 写入缓冲区指针
  58.         int write_cnt; // 写入计数
  59.         /* 如果TTY有待处理的do_SAK,将其排队在此 - akpm */
  60.         struct work_struct SAK_work; // 处理SAK的工作结构
  61.         struct tty_port *port; // 指向TTY端口的指针
  62. };
复制代码


  • 此布局体用于生存与TTY装备的状态信息和相关数据。它在TTY装备打开时保持运动状态。
  • 包含对TTY装备的各种信息,如引用计数、装备驱动、操作函数、窗口巨细、流控制状态等。
  • 通过差别的锁和信号量掩护其各个部分的并发访问,确保在多线程环境中操作的安全性。
11.tty_port_operaion

tty_port的成员
  1. struct tty_port_operations {
  2.         /*
  3.          * 返回 1 如果载波(carrier)信号被抬起。
  4.          * 这个函数用于检查串行端口的载波状态。
  5.          */
  6.         int (*carrier_raised)(struct tty_port *port);
  7.         /*
  8.          * 控制 DTR(数据终端就绪)和 RTS(请求发送)线路。
  9.          * 通过设置参数来抬起或放下这两条控制线路。
  10.          */
  11.         void (*dtr_rts)(struct tty_port *port, int raise);
  12.         /*
  13.          * 当最后一个关闭操作完成或挂起操作结束时调用,
  14.          * 仅在端口已初始化的情况下调用。
  15.          * 注意:不要在此处释放资源,因为它是在端口互斥锁下调用的,
  16.          * 用于序列化激活和关闭操作。
  17.          */
  18.         void (*shutdown)(struct tty_port *port);
  19.         /*
  20.          * 在 tty_port_open 函数中在端口互斥锁下调用,
  21.          * 用于初始化设备。长远来看,希望将 tty 参数移出此函数,
  22.          * 以提高通用性(特别是对于控制台)。
  23.          */
  24.         int (*activate)(struct tty_port *port, struct tty_struct *tty);
  25.         /*
  26.          * 在端口的最后一次释放(put)时调用。
  27.          * 这个函数用于清理与端口相关的资源。
  28.          */
  29.         void (*destruct)(struct tty_port *port);
  30. };
复制代码
tty_port_operations 是一个函数指针布局体,定义了一组与TTY端口操作相关的回调函数。这些函数由具体的端口实现提供,以支持差别的串行装备。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表