12.2 一个缓冲式多进程请求反馈串口模块的通讯修复
(1) 模块架构简述 该模块采用分层设计,自上而下依次为:
- 插件接口层:通过 PLUG_DLL_EXPORT 导出标准函数(newSerial、releaseSerial、serialEat、serialSetOption),便于动态加载与集成。
- 状态机管理层:以有限状态机(FSM)管理串口的整个生命周期(就绪、打开、等待、超时、错误、关闭等)。
- 数据缓冲层:利用双向链表(list_t)缓存待发送的数据包,并提供流量控制能力。
- I/O处理层:支持 select 和 epoll 两种多路复用机制,负责实际的数据读写。
- 线程同步层:通过互斥锁与条件变量协调发送与接收线程,确保线程安全。
#mermaid-svg-dcQPLZt9ZOJP0Qyz{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-dcQPLZt9ZOJP0Qyz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .error-icon{fill:#552222;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .marker.cross{stroke:#333333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dcQPLZt9ZOJP0Qyz p{margin:0;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .cluster-label text{fill:#333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .cluster-label span{color:#333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .cluster-label span p{background-color:transparent;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .label text,#mermaid-svg-dcQPLZt9ZOJP0Qyz span{fill:#333;color:#333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .node rect,#mermaid-svg-dcQPLZt9ZOJP0Qyz .node circle,#mermaid-svg-dcQPLZt9ZOJP0Qyz .node ellipse,#mermaid-svg-dcQPLZt9ZOJP0Qyz .node polygon,#mermaid-svg-dcQPLZt9ZOJP0Qyz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .rough-node .label text,#mermaid-svg-dcQPLZt9ZOJP0Qyz .node .label text,#mermaid-svg-dcQPLZt9ZOJP0Qyz .image-shape .label,#mermaid-svg-dcQPLZt9ZOJP0Qyz .icon-shape .label{text-anchor:middle;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .rough-node .label,#mermaid-svg-dcQPLZt9ZOJP0Qyz .node .label,#mermaid-svg-dcQPLZt9ZOJP0Qyz .image-shape .label,#mermaid-svg-dcQPLZt9ZOJP0Qyz .icon-shape .label{text-align:center;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .node.clickable{cursor:pointer;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .arrowheadPath{fill:#333333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dcQPLZt9ZOJP0Qyz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dcQPLZt9ZOJP0Qyz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dcQPLZt9ZOJP0Qyz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .cluster text{fill:#333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .cluster span{color:#333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz 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-dcQPLZt9ZOJP0Qyz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dcQPLZt9ZOJP0Qyz rect.text{fill:none;stroke-width:0;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .icon-shape,#mermaid-svg-dcQPLZt9ZOJP0Qyz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .icon-shape p,#mermaid-svg-dcQPLZt9ZOJP0Qyz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .icon-shape rect,#mermaid-svg-dcQPLZt9ZOJP0Qyz .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dcQPLZt9ZOJP0Qyz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dcQPLZt9ZOJP0Qyz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dcQPLZt9ZOJP0Qyz :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
应用层
插件接口
状态机管理
数据缓冲队列
发送线程
接收线程
select/epoll
物理串口
串口的工作流程天然具有状态性:打开 → 空闲 → 发送 → 等待响应 → 接收 → 完成/超时/错误 → 关闭。该模块将这一流程抽象为7个明确的状态:
| STATE_SERIAL_READY | 初始就绪,等待打开 |
| STATE_SERIAL_OPENED | 串口已打开,处于空闲 |
| STATE_SERIAL_WAITING | 已发送数据,等待响应 |
| STATE_SERIAL_FINISH | 一轮请求-响应完成 |
| STATE_SERIAL_OVERTIME | 等待响应超时 |
| STATE_SERIAL_ERROR | 发生错误 |
| STATE_SERIAL_CLOSED | 串口已关闭 |
每个状态都绑定了进入函数与离开函数。例如进入 OPENED 状态时会打印日志,离开时则根据触发数据决定下一状态。状态间的转换由条件函数控制,使得逻辑清晰且易于扩展。 初始化时,通过 fsmAddStat 注册各状态,并通过 fsmAddTrans 添加转换条件。这种设计将业务逻辑(如超时处理、错误恢复)封装在对应状态函数中,主流程因此变得异常简洁。
#mermaid-svg-YDTpukPndcYrf8yP{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-YDTpukPndcYrf8yP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YDTpukPndcYrf8yP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YDTpukPndcYrf8yP .error-icon{fill:#552222;}#mermaid-svg-YDTpukPndcYrf8yP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YDTpukPndcYrf8yP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YDTpukPndcYrf8yP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YDTpukPndcYrf8yP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YDTpukPndcYrf8yP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YDTpukPndcYrf8yP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YDTpukPndcYrf8yP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YDTpukPndcYrf8yP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YDTpukPndcYrf8yP .marker.cross{stroke:#333333;}#mermaid-svg-YDTpukPndcYrf8yP svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YDTpukPndcYrf8yP p{margin:0;}#mermaid-svg-YDTpukPndcYrf8yP defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-YDTpukPndcYrf8yP g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-YDTpukPndcYrf8yP g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-YDTpukPndcYrf8yP g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-YDTpukPndcYrf8yP g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-YDTpukPndcYrf8yP g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-YDTpukPndcYrf8yP .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-YDTpukPndcYrf8yP .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-YDTpukPndcYrf8yP .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-YDTpukPndcYrf8yP .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-YDTpukPndcYrf8yP .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-YDTpukPndcYrf8yP .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-YDTpukPndcYrf8yP .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-YDTpukPndcYrf8yP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YDTpukPndcYrf8yP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YDTpukPndcYrf8yP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YDTpukPndcYrf8yP .edgeLabel .label text{fill:#333;}#mermaid-svg-YDTpukPndcYrf8yP .label div .edgeLabel{color:#333;}#mermaid-svg-YDTpukPndcYrf8yP .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-YDTpukPndcYrf8yP .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-YDTpukPndcYrf8yP .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-YDTpukPndcYrf8yP .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-YDTpukPndcYrf8yP .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-YDTpukPndcYrf8yP .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YDTpukPndcYrf8yP .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YDTpukPndcYrf8yP #statediagram-barbEnd{fill:#333333;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YDTpukPndcYrf8yP .cluster-label,#mermaid-svg-YDTpukPndcYrf8yP .nodeLabel{color:#131300;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-YDTpukPndcYrf8yP .note-edge{stroke-dasharray:5;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-note text{fill:black;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram-note .nodeLabel{color:black;}#mermaid-svg-YDTpukPndcYrf8yP .statediagram .edgeLabel{color:red;}#mermaid-svg-YDTpukPndcYrf8yP #dependencyStart,#mermaid-svg-YDTpukPndcYrf8yP #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-YDTpukPndcYrf8yP .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YDTpukPndcYrf8yP :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
T_OPENED
T_ERROR
T_SEND
T_CLOSE
T_ERROR
T_FINISH
T_OVERTIME
网硕互联帮助中心


评论前必须登录!
注册