6. USB 转串口驱动

USB 转串口驱动

  • [0. Makefile 编译](#0. Makefile 编译)
  • [1. 驱动整体组成](#1. 驱动整体组成)
  • [2. 核心软件架构](#2. 核心软件架构)
  • [3. 驱动框架](#3. 驱动框架)
    • [3.1 驱动框架 --- 模块加载与注册流程](#3.1 驱动框架 --- 模块加载与注册流程)
    • [3.2 驱动框架 --- USB 插入和 probe 流程](#3.2 驱动框架 --- USB 插入和 probe 流程)
    • [3.3 驱动框架 --- 打开串口流程](#3.3 驱动框架 --- 打开串口流程)
    • [3.4 驱动框架 --- 发送数据流程](#3.4 驱动框架 --- 发送数据流程)
    • [3.5 驱动框架 --- 接收数据流程](#3.5 驱动框架 --- 接收数据流程)
    • [3.6 驱动框架 --- 各具体驱动特点](#3.6 驱动框架 --- 各具体驱动特点)
      • [3.6.1 CP210x](#3.6.1 CP210x)
      • [3.6.2 Option / GSM Modem](#3.6.2 Option / GSM Modem)
      • [3.6.3 ZTE EV](#3.6.3 ZTE EV)
    • [3.7 驱动框架 --- 关闭、拔出和电源管理](#3.7 驱动框架 --- 关闭、拔出和电源管理)
  • [4. 加载顺序](#4. 加载顺序)
  • [5. 验证加载](#5. 验证加载)

0. Makefile 编译

编译过程

1. 驱动整体组成

Linux内核中的USB转串口驱动由多个文件协同工作,每个文件承担不同的职责。理解这些文件的作用和相互关系,有助于深入掌握驱动的工作原理和调试方法。

2. 核心软件架构

3. 驱动框架

3.1 驱动框架 --- 模块加载与注册流程

3.2 驱动框架 --- USB 插入和 probe 流程


#mermaid-svg-PiCwRdmbMcywxbX3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-PiCwRdmbMcywxbX3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-PiCwRdmbMcywxbX3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-PiCwRdmbMcywxbX3 .error-icon{fill:#552222;}#mermaid-svg-PiCwRdmbMcywxbX3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-PiCwRdmbMcywxbX3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-PiCwRdmbMcywxbX3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-PiCwRdmbMcywxbX3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-PiCwRdmbMcywxbX3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-PiCwRdmbMcywxbX3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-PiCwRdmbMcywxbX3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-PiCwRdmbMcywxbX3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-PiCwRdmbMcywxbX3 .marker.cross{stroke:#333333;}#mermaid-svg-PiCwRdmbMcywxbX3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-PiCwRdmbMcywxbX3 p{margin:0;}#mermaid-svg-PiCwRdmbMcywxbX3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-PiCwRdmbMcywxbX3 .cluster-label text{fill:#333;}#mermaid-svg-PiCwRdmbMcywxbX3 .cluster-label span{color:#333;}#mermaid-svg-PiCwRdmbMcywxbX3 .cluster-label span p{background-color:transparent;}#mermaid-svg-PiCwRdmbMcywxbX3 .label text,#mermaid-svg-PiCwRdmbMcywxbX3 span{fill:#333;color:#333;}#mermaid-svg-PiCwRdmbMcywxbX3 .node rect,#mermaid-svg-PiCwRdmbMcywxbX3 .node circle,#mermaid-svg-PiCwRdmbMcywxbX3 .node ellipse,#mermaid-svg-PiCwRdmbMcywxbX3 .node polygon,#mermaid-svg-PiCwRdmbMcywxbX3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-PiCwRdmbMcywxbX3 .rough-node .label text,#mermaid-svg-PiCwRdmbMcywxbX3 .node .label text,#mermaid-svg-PiCwRdmbMcywxbX3 .image-shape .label,#mermaid-svg-PiCwRdmbMcywxbX3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-PiCwRdmbMcywxbX3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-PiCwRdmbMcywxbX3 .rough-node .label,#mermaid-svg-PiCwRdmbMcywxbX3 .node .label,#mermaid-svg-PiCwRdmbMcywxbX3 .image-shape .label,#mermaid-svg-PiCwRdmbMcywxbX3 .icon-shape .label{text-align:center;}#mermaid-svg-PiCwRdmbMcywxbX3 .node.clickable{cursor:pointer;}#mermaid-svg-PiCwRdmbMcywxbX3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-PiCwRdmbMcywxbX3 .arrowheadPath{fill:#333333;}#mermaid-svg-PiCwRdmbMcywxbX3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-PiCwRdmbMcywxbX3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-PiCwRdmbMcywxbX3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PiCwRdmbMcywxbX3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-PiCwRdmbMcywxbX3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PiCwRdmbMcywxbX3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-PiCwRdmbMcywxbX3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-PiCwRdmbMcywxbX3 .cluster text{fill:#333;}#mermaid-svg-PiCwRdmbMcywxbX3 .cluster span{color:#333;}#mermaid-svg-PiCwRdmbMcywxbX3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-PiCwRdmbMcywxbX3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-PiCwRdmbMcywxbX3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-PiCwRdmbMcywxbX3 .icon-shape,#mermaid-svg-PiCwRdmbMcywxbX3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PiCwRdmbMcywxbX3 .icon-shape p,#mermaid-svg-PiCwRdmbMcywxbX3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-PiCwRdmbMcywxbX3 .icon-shape .label rect,#mermaid-svg-PiCwRdmbMcywxbX3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PiCwRdmbMcywxbX3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-PiCwRdmbMcywxbX3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-PiCwRdmbMcywxbX3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否



USB设备插入
Linux USB Core枚举
读取VID/PID和接口描述符
匹配具体驱动?
设备保持未绑定
usb_serial_probe
创建usb_serial对象
调用子驱动probe
probe接受?
释放对象并返回失败
扫描USB端点
Bulk IN
Bulk OUT
Interrupt IN/OUT
创建usb_serial_port
分配读写URB和缓冲区
调用attach/port_probe
分配tty minor
注册ttyUSB设备
生成/dev/ttyUSBx

3.3 驱动框架 --- 打开串口流程


#mermaid-svg-sB0tprMWQK7jsvoq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-sB0tprMWQK7jsvoq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-sB0tprMWQK7jsvoq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-sB0tprMWQK7jsvoq .error-icon{fill:#552222;}#mermaid-svg-sB0tprMWQK7jsvoq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sB0tprMWQK7jsvoq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-sB0tprMWQK7jsvoq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sB0tprMWQK7jsvoq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sB0tprMWQK7jsvoq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-sB0tprMWQK7jsvoq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sB0tprMWQK7jsvoq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sB0tprMWQK7jsvoq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sB0tprMWQK7jsvoq .marker.cross{stroke:#333333;}#mermaid-svg-sB0tprMWQK7jsvoq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sB0tprMWQK7jsvoq p{margin:0;}#mermaid-svg-sB0tprMWQK7jsvoq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-sB0tprMWQK7jsvoq .cluster-label text{fill:#333;}#mermaid-svg-sB0tprMWQK7jsvoq .cluster-label span{color:#333;}#mermaid-svg-sB0tprMWQK7jsvoq .cluster-label span p{background-color:transparent;}#mermaid-svg-sB0tprMWQK7jsvoq .label text,#mermaid-svg-sB0tprMWQK7jsvoq span{fill:#333;color:#333;}#mermaid-svg-sB0tprMWQK7jsvoq .node rect,#mermaid-svg-sB0tprMWQK7jsvoq .node circle,#mermaid-svg-sB0tprMWQK7jsvoq .node ellipse,#mermaid-svg-sB0tprMWQK7jsvoq .node polygon,#mermaid-svg-sB0tprMWQK7jsvoq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sB0tprMWQK7jsvoq .rough-node .label text,#mermaid-svg-sB0tprMWQK7jsvoq .node .label text,#mermaid-svg-sB0tprMWQK7jsvoq .image-shape .label,#mermaid-svg-sB0tprMWQK7jsvoq .icon-shape .label{text-anchor:middle;}#mermaid-svg-sB0tprMWQK7jsvoq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-sB0tprMWQK7jsvoq .rough-node .label,#mermaid-svg-sB0tprMWQK7jsvoq .node .label,#mermaid-svg-sB0tprMWQK7jsvoq .image-shape .label,#mermaid-svg-sB0tprMWQK7jsvoq .icon-shape .label{text-align:center;}#mermaid-svg-sB0tprMWQK7jsvoq .node.clickable{cursor:pointer;}#mermaid-svg-sB0tprMWQK7jsvoq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-sB0tprMWQK7jsvoq .arrowheadPath{fill:#333333;}#mermaid-svg-sB0tprMWQK7jsvoq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-sB0tprMWQK7jsvoq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-sB0tprMWQK7jsvoq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sB0tprMWQK7jsvoq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-sB0tprMWQK7jsvoq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sB0tprMWQK7jsvoq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-sB0tprMWQK7jsvoq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-sB0tprMWQK7jsvoq .cluster text{fill:#333;}#mermaid-svg-sB0tprMWQK7jsvoq .cluster span{color:#333;}#mermaid-svg-sB0tprMWQK7jsvoq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-sB0tprMWQK7jsvoq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-sB0tprMWQK7jsvoq rect.text{fill:none;stroke-width:0;}#mermaid-svg-sB0tprMWQK7jsvoq .icon-shape,#mermaid-svg-sB0tprMWQK7jsvoq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sB0tprMWQK7jsvoq .icon-shape p,#mermaid-svg-sB0tprMWQK7jsvoq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-sB0tprMWQK7jsvoq .icon-shape .label rect,#mermaid-svg-sB0tprMWQK7jsvoq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sB0tprMWQK7jsvoq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-sB0tprMWQK7jsvoq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-sB0tprMWQK7jsvoq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} open /dev/ttyUSBx
serial_open
根据minor查找usb_serial_port
获取USB电源引用
具体驱动
generic_open
cp210x_open
option/usb_wwan_open
zte_ev_open
USB控制请求:使能UART
读取/设置波特率和线路参数
启动Bulk IN URB
启动Interrupt IN URB
发送ZTE专用控制命令
调用generic_open
提交接收URB
串口进入可收发状态

3.4 驱动框架 --- 发送数据流程


#mermaid-svg-igqDmYTpoBLOK7go{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-igqDmYTpoBLOK7go .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-igqDmYTpoBLOK7go .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-igqDmYTpoBLOK7go .error-icon{fill:#552222;}#mermaid-svg-igqDmYTpoBLOK7go .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-igqDmYTpoBLOK7go .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-igqDmYTpoBLOK7go .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-igqDmYTpoBLOK7go .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-igqDmYTpoBLOK7go .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-igqDmYTpoBLOK7go .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-igqDmYTpoBLOK7go .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-igqDmYTpoBLOK7go .marker{fill:#333333;stroke:#333333;}#mermaid-svg-igqDmYTpoBLOK7go .marker.cross{stroke:#333333;}#mermaid-svg-igqDmYTpoBLOK7go svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-igqDmYTpoBLOK7go p{margin:0;}#mermaid-svg-igqDmYTpoBLOK7go .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-igqDmYTpoBLOK7go .cluster-label text{fill:#333;}#mermaid-svg-igqDmYTpoBLOK7go .cluster-label span{color:#333;}#mermaid-svg-igqDmYTpoBLOK7go .cluster-label span p{background-color:transparent;}#mermaid-svg-igqDmYTpoBLOK7go .label text,#mermaid-svg-igqDmYTpoBLOK7go span{fill:#333;color:#333;}#mermaid-svg-igqDmYTpoBLOK7go .node rect,#mermaid-svg-igqDmYTpoBLOK7go .node circle,#mermaid-svg-igqDmYTpoBLOK7go .node ellipse,#mermaid-svg-igqDmYTpoBLOK7go .node polygon,#mermaid-svg-igqDmYTpoBLOK7go .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-igqDmYTpoBLOK7go .rough-node .label text,#mermaid-svg-igqDmYTpoBLOK7go .node .label text,#mermaid-svg-igqDmYTpoBLOK7go .image-shape .label,#mermaid-svg-igqDmYTpoBLOK7go .icon-shape .label{text-anchor:middle;}#mermaid-svg-igqDmYTpoBLOK7go .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-igqDmYTpoBLOK7go .rough-node .label,#mermaid-svg-igqDmYTpoBLOK7go .node .label,#mermaid-svg-igqDmYTpoBLOK7go .image-shape .label,#mermaid-svg-igqDmYTpoBLOK7go .icon-shape .label{text-align:center;}#mermaid-svg-igqDmYTpoBLOK7go .node.clickable{cursor:pointer;}#mermaid-svg-igqDmYTpoBLOK7go .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-igqDmYTpoBLOK7go .arrowheadPath{fill:#333333;}#mermaid-svg-igqDmYTpoBLOK7go .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-igqDmYTpoBLOK7go .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-igqDmYTpoBLOK7go .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-igqDmYTpoBLOK7go .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-igqDmYTpoBLOK7go .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-igqDmYTpoBLOK7go .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-igqDmYTpoBLOK7go .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-igqDmYTpoBLOK7go .cluster text{fill:#333;}#mermaid-svg-igqDmYTpoBLOK7go .cluster span{color:#333;}#mermaid-svg-igqDmYTpoBLOK7go div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-igqDmYTpoBLOK7go .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-igqDmYTpoBLOK7go rect.text{fill:none;stroke-width:0;}#mermaid-svg-igqDmYTpoBLOK7go .icon-shape,#mermaid-svg-igqDmYTpoBLOK7go .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-igqDmYTpoBLOK7go .icon-shape p,#mermaid-svg-igqDmYTpoBLOK7go .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-igqDmYTpoBLOK7go .icon-shape .label rect,#mermaid-svg-igqDmYTpoBLOK7go .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-igqDmYTpoBLOK7go .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-igqDmYTpoBLOK7go .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-igqDmYTpoBLOK7go :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

用户write
serial_write
子驱动write
generic_write
写入kfifo
查找空闲write URB
拷贝FIFO数据
usb_submit_urb
Bulk OUT发送
write_bulk_callback
释放URB并继续发送
usb_wwan_write
选择空闲输出URB
获取USB自动休眠引用
设备是否挂起
放入delayed anchor
提交URB
Bulk OUT发送
释放busy标志和电源引用

3.5 驱动框架 --- 接收数据流程


#mermaid-svg-r6ezxM76REhnNejc{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-r6ezxM76REhnNejc .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-r6ezxM76REhnNejc .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-r6ezxM76REhnNejc .error-icon{fill:#552222;}#mermaid-svg-r6ezxM76REhnNejc .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-r6ezxM76REhnNejc .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-r6ezxM76REhnNejc .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-r6ezxM76REhnNejc .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-r6ezxM76REhnNejc .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-r6ezxM76REhnNejc .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-r6ezxM76REhnNejc .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-r6ezxM76REhnNejc .marker{fill:#333333;stroke:#333333;}#mermaid-svg-r6ezxM76REhnNejc .marker.cross{stroke:#333333;}#mermaid-svg-r6ezxM76REhnNejc svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-r6ezxM76REhnNejc p{margin:0;}#mermaid-svg-r6ezxM76REhnNejc .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-r6ezxM76REhnNejc .cluster-label text{fill:#333;}#mermaid-svg-r6ezxM76REhnNejc .cluster-label span{color:#333;}#mermaid-svg-r6ezxM76REhnNejc .cluster-label span p{background-color:transparent;}#mermaid-svg-r6ezxM76REhnNejc .label text,#mermaid-svg-r6ezxM76REhnNejc span{fill:#333;color:#333;}#mermaid-svg-r6ezxM76REhnNejc .node rect,#mermaid-svg-r6ezxM76REhnNejc .node circle,#mermaid-svg-r6ezxM76REhnNejc .node ellipse,#mermaid-svg-r6ezxM76REhnNejc .node polygon,#mermaid-svg-r6ezxM76REhnNejc .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-r6ezxM76REhnNejc .rough-node .label text,#mermaid-svg-r6ezxM76REhnNejc .node .label text,#mermaid-svg-r6ezxM76REhnNejc .image-shape .label,#mermaid-svg-r6ezxM76REhnNejc .icon-shape .label{text-anchor:middle;}#mermaid-svg-r6ezxM76REhnNejc .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-r6ezxM76REhnNejc .rough-node .label,#mermaid-svg-r6ezxM76REhnNejc .node .label,#mermaid-svg-r6ezxM76REhnNejc .image-shape .label,#mermaid-svg-r6ezxM76REhnNejc .icon-shape .label{text-align:center;}#mermaid-svg-r6ezxM76REhnNejc .node.clickable{cursor:pointer;}#mermaid-svg-r6ezxM76REhnNejc .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-r6ezxM76REhnNejc .arrowheadPath{fill:#333333;}#mermaid-svg-r6ezxM76REhnNejc .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-r6ezxM76REhnNejc .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-r6ezxM76REhnNejc .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-r6ezxM76REhnNejc .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-r6ezxM76REhnNejc .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-r6ezxM76REhnNejc .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-r6ezxM76REhnNejc .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-r6ezxM76REhnNejc .cluster text{fill:#333;}#mermaid-svg-r6ezxM76REhnNejc .cluster span{color:#333;}#mermaid-svg-r6ezxM76REhnNejc div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-r6ezxM76REhnNejc .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-r6ezxM76REhnNejc rect.text{fill:none;stroke-width:0;}#mermaid-svg-r6ezxM76REhnNejc .icon-shape,#mermaid-svg-r6ezxM76REhnNejc .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-r6ezxM76REhnNejc .icon-shape p,#mermaid-svg-r6ezxM76REhnNejc .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-r6ezxM76REhnNejc .icon-shape .label rect,#mermaid-svg-r6ezxM76REhnNejc .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-r6ezxM76REhnNejc .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-r6ezxM76REhnNejc .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-r6ezxM76REhnNejc :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否

USB设备发送串口数据
Bulk IN URB
接收完成回调
URB状态正常?
记录错误/停止或重试
读取actual_length
写入TTY flip buffer
tty_flip_buffer_push
用户read返回
重新提交IN URB

3.6 驱动框架 --- 各具体驱动特点

3.6.1 CP210x

3.6.2 Option / GSM Modem

3.6.3 ZTE EV

3.7 驱动框架 --- 关闭、拔出和电源管理


#mermaid-svg-Dz1OldUrm6kSdDVI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Dz1OldUrm6kSdDVI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Dz1OldUrm6kSdDVI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Dz1OldUrm6kSdDVI .error-icon{fill:#552222;}#mermaid-svg-Dz1OldUrm6kSdDVI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Dz1OldUrm6kSdDVI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Dz1OldUrm6kSdDVI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Dz1OldUrm6kSdDVI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Dz1OldUrm6kSdDVI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Dz1OldUrm6kSdDVI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Dz1OldUrm6kSdDVI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Dz1OldUrm6kSdDVI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Dz1OldUrm6kSdDVI .marker.cross{stroke:#333333;}#mermaid-svg-Dz1OldUrm6kSdDVI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Dz1OldUrm6kSdDVI p{margin:0;}#mermaid-svg-Dz1OldUrm6kSdDVI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Dz1OldUrm6kSdDVI .cluster-label text{fill:#333;}#mermaid-svg-Dz1OldUrm6kSdDVI .cluster-label span{color:#333;}#mermaid-svg-Dz1OldUrm6kSdDVI .cluster-label span p{background-color:transparent;}#mermaid-svg-Dz1OldUrm6kSdDVI .label text,#mermaid-svg-Dz1OldUrm6kSdDVI span{fill:#333;color:#333;}#mermaid-svg-Dz1OldUrm6kSdDVI .node rect,#mermaid-svg-Dz1OldUrm6kSdDVI .node circle,#mermaid-svg-Dz1OldUrm6kSdDVI .node ellipse,#mermaid-svg-Dz1OldUrm6kSdDVI .node polygon,#mermaid-svg-Dz1OldUrm6kSdDVI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Dz1OldUrm6kSdDVI .rough-node .label text,#mermaid-svg-Dz1OldUrm6kSdDVI .node .label text,#mermaid-svg-Dz1OldUrm6kSdDVI .image-shape .label,#mermaid-svg-Dz1OldUrm6kSdDVI .icon-shape .label{text-anchor:middle;}#mermaid-svg-Dz1OldUrm6kSdDVI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Dz1OldUrm6kSdDVI .rough-node .label,#mermaid-svg-Dz1OldUrm6kSdDVI .node .label,#mermaid-svg-Dz1OldUrm6kSdDVI .image-shape .label,#mermaid-svg-Dz1OldUrm6kSdDVI .icon-shape .label{text-align:center;}#mermaid-svg-Dz1OldUrm6kSdDVI .node.clickable{cursor:pointer;}#mermaid-svg-Dz1OldUrm6kSdDVI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Dz1OldUrm6kSdDVI .arrowheadPath{fill:#333333;}#mermaid-svg-Dz1OldUrm6kSdDVI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Dz1OldUrm6kSdDVI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Dz1OldUrm6kSdDVI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Dz1OldUrm6kSdDVI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Dz1OldUrm6kSdDVI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Dz1OldUrm6kSdDVI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Dz1OldUrm6kSdDVI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Dz1OldUrm6kSdDVI .cluster text{fill:#333;}#mermaid-svg-Dz1OldUrm6kSdDVI .cluster span{color:#333;}#mermaid-svg-Dz1OldUrm6kSdDVI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Dz1OldUrm6kSdDVI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Dz1OldUrm6kSdDVI rect.text{fill:none;stroke-width:0;}#mermaid-svg-Dz1OldUrm6kSdDVI .icon-shape,#mermaid-svg-Dz1OldUrm6kSdDVI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Dz1OldUrm6kSdDVI .icon-shape p,#mermaid-svg-Dz1OldUrm6kSdDVI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Dz1OldUrm6kSdDVI .icon-shape .label rect,#mermaid-svg-Dz1OldUrm6kSdDVI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Dz1OldUrm6kSdDVI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Dz1OldUrm6kSdDVI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Dz1OldUrm6kSdDVI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} USB拔出
usb_serial_disconnect
设置disconnected
挂断TTY
停止并poison所有URB
删除ttyUSB设备
调用子驱动release
释放minor和端口对象

4. 加载顺序

正确的模块加载顺序至关重要:

bash 复制代码
# 先加载核心模块
sudo insmod usbserial.ko

# 再加载特定芯片驱动
sudo insmod cp210x.ko

# 或者使用modprobe自动处理依赖
sudo modprobe cp210x

5. 验证加载

加载后可通过以下命令验证:

bash 复制代码
# 查看已加载模块
lsmod | grep -E "usbserial|cp210x"

# 查看设备节点
ls -l /dev/ttyUSB*

# 查看内核消息
dmesg | tail -20
相关推荐
rest102440 分钟前
对jemalloc的理解
linux
发光的沙子1 小时前
嵌入式系统架构师----Ubuntu如何安装不在列表内的软件?
linux·运维·ubuntu
C+ 安口木1 小时前
Alibaba Cloud Linux 3 服务器环境搭建实战记录
linux·运维·服务器
come112343 小时前
剪映零基础教程
java·linux·运维
飘忽不定的bug3 小时前
ubuntu20.04交叉编译QT5.15.12(RK3562+ubuntu20.04)
linux·qt·ubuntu
库玛西4 小时前
深入浅出Linux select网络模型:从底层位图原理到C++面向对象高级封装
linux·服务器·网络·c++·ubuntu
Tingjct4 小时前
线程详细讲解---聚焦linux
linux·服务器·jvm
ComputerInBook4 小时前
linux包管理工具——yum(YellowdogUpdaterModified)
linux·运维·服务器·yum·dnf
霸道流氓气质4 小时前
通义千问 Chat 模型高级用法:Function Calling / Structured Output / 多轮对话
linux·运维·windows