# 设备指令系统
**本文档引用的文件**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp)
- [GD10OperCmd.h](file://h/GD10OperCmd.h)
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp)
- [DetcGD10Dev.h](file://h/DetcGD10Dev.h)
- [DevManager.cpp](file://cpp/Managers/DevManager.cpp)
- [DevManager.h](file://h/DevManager.h)
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp)
- [IOManager.h](file://h/IOManager.h)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
- [FileOperTools.h](file://h/FileOperTools.h)
- [Markup.h](file://h/Markup.h)
- [Constant.h](file://h/Constant.h)
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
- [Crc16.h](file://h/Crc16.h)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
- [Crc32.h](file://h/Crc32.h)
## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概述](#架构概述)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
## 引言
本文档深入解析了GD10设备指令系统的实现,重点分析了`GD10OperCmd.cpp`文件中的设备指令系统。文档详细说明了GD10设备通信协议的命令格式、参数编码规则与响应解析机制,涵盖了指令分类(如设备配置、数据采集、状态查询等)、命令帧结构、校验机制(CRC16/CRC32)及超时重传策略。通过代码示例展示了典型指令的构造与解析流程,如启动测量任务、读取设备参数等。同时,文档解释了与DevManager、IOManager等模块的集成方式,以及在不同设备状态下的指令调度逻辑,并提供了常见通信异常的诊断方法和处理建议。
## 项目结构
GeomativeStudio项目是一个用于地质勘探设备管理的软件系统,其核心功能围绕GD10设备的通信、配置和数据管理展开。项目结构清晰地分为多个模块,每个模块负责特定的功能领域。
```mermaid
graph TB
subgraph "核心模块"
DevManager["设备管理器
(Managers/DevManager.cpp)"]
IOManager["输入输出管理器
(Managers/IOManager.cpp)"]
GD10OperCmd["GD10操作命令
(Tools/GD10OperCmd.cpp)"]
end
subgraph "工具与支持模块"
DetcGD10Dev["GD10设备检测
(Operator/DetcGD10Dev.cpp)"]
FileOperTools["文件操作工具
(Tools/FileOperTools.cpp)"]
Markup["XML解析工具
(Tools/Markup.cpp)"]
Crc16["CRC16校验
(Tools/Crc16.cpp)"]
Crc32["CRC32校验
(Tools/Crc32.cpp)"]
end
subgraph "常量与头文件"
Constant["常量定义
(h/Constant.h)"]
Headers["头文件
(h/*.h)"]
end
GD10OperCmd --> DevManager
GD10OperCmd --> IOManager
GD10OperCmd --> DetcGD10Dev
GD10OperCmd --> FileOperTools
GD10OperCmd --> Markup
GD10OperCmd --> Crc16
GD10OperCmd --> Crc32
DetcGD10Dev --> FileOperTools
DevManager --> Headers
IOManager --> Headers
Constant --> Headers
```
**图源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp)
- [DevManager.cpp](file://cpp/Managers/DevManager.cpp)
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp)
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
- [Markup.h](file://h/Markup.h)
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
- [Constant.h](file://h/Constant.h)
**节源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp)
- [DevManager.cpp](file://cpp/Managers/DevManager.cpp)
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp)
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
- [Constant.h](file://h/Constant.h)
## 核心组件
`GD10OperCmd`类是实现GD10设备指令系统的核心组件,它通过模拟微机操作来管理连接到Geomative Studio的GD10设备。该类提供了对设备上文件系统的操作接口,包括工程、测区、脚本和测量任务的增删改查。所有操作都依赖于`DetcGD10Dev`类来检测和确认设备的连接状态,并使用`Markup`类来解析和修改设备上的XML配置文件。`FileOperTools`类则提供了底层的文件和目录操作功能,确保了操作的原子性和日志记录。
**节源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp#L1-L1213)
- [GD10OperCmd.h](file://h/GD10OperCmd.h#L1-L55)
## 架构概述
GD10设备指令系统的架构是一个典型的分层设计,从上层应用逻辑到底层硬件交互,各层职责分明。
```mermaid
graph TD
A[用户界面] --> B[GD10OperCmd]
B --> C[DetcGD10Dev]
B --> D[FileOperTools]
B --> E[Markup]
C --> F[USB设备]
D --> G[文件系统]
E --> H[XML文件]
B --> I[Crc16/Crc32]
subgraph "应用层"
A
B
end
subgraph "服务层"
C
D
E
I
end
subgraph "数据层"
F
G
H
end
```
**图源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp)
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
- [Markup.h](file://h/Markup.h)
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
**节源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp)
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
## 详细组件分析
### GD10操作命令分析
`CGD10OperCmd`类是整个指令系统的核心,它封装了所有与GD10设备交互的命令。
#### 类结构与关系
```mermaid
classDiagram
class CGD10OperCmd {
+static CGD10OperCmd* m_pGD10Oper
+CGD10OperCmd()
+~CGD10OperCmd()
+static CGD10OperCmd* GetInstance()
+int project_add(const char *mac, const char *projectcn)
+bool project_delete(const char *mac, const char *projectcn)
+int testzone_add(const char *projectcn, const char *testzonecn, const char *type)
+int testzone_delete(const char *projectcn, const char *testzonecn)
+int script_add(const char *scriptcn, const char *scriptname, const char *mudiumid)
+bool script_delete(const char *scriptcn)
+bool meas_delete(const char *projectcn, const char *testzonecn, const char *measuringcn)
+bool set_param(const CString& strParam)
+bool unregister_user(CString strMacAddr)
+bool loadDeviceMarkDataFromGD()
+static UINT LoadDevMarkDataFormGDThread(LPVOID lParam)
}
class CDetcGD10Dev {
+static CDetcGD10Dev* m_pDetcDev
+bool m_bGD10DevIsCon
+CString m_strDevAddr
+CDetcGD10Dev()
+~CDetcGD10Dev()
+static CDetcGD10Dev* GetInstance()
+bool IsGD10DevConnect()
+CString GetGD10DevAddr()
+void DetectGD10Dev()
}
class CFileOperTools {
+static CFileOperTools* m_pFileOper
+FILE* m_pComLog
+CRITICAL_SECTION *m_pWriteLogSection
+CFileOperTools()
+~CFileOperTools()
+static CFileOperTools* GetInstance()
+bool CopyFolder(CString strSrcPath, CString strDstPath)
+bool IsFileExist(CString strFileInfo)
+bool WriteComLog(const CString& strInfo)
+bool DeleteDirectory(CString strDirPath)
+bool DeleteFileDirect(CString strFilePath)
}
class CMarkup {
+CMarkup()
+~CMarkup()
+bool Load(const char* szFileName)
+bool Save(const char* szFileName)
+bool FindChildElem(const char* szName)
+bool IntoElem()
+bool AddChildElem(const char* szName, const char* szData)
+bool RemoveChildElem()
+CString GetChildData()
+bool SetChildData(const char* szData)
+void ResetPos()
}
CGD10OperCmd --> CDetcGD10Dev : "使用"
CGD10OperCmd --> CFileOperTools : "使用"
CGD10OperCmd --> CMarkup : "使用"
CDetcGD10Dev --> CFileOperTools : "使用"
```
**图源**
- [GD10OperCmd.h](file://h/GD10OperCmd.h#L1-L55)
- [DetcGD10Dev.h](file://h/DetcGD10Dev.h#L1-L38)
- [FileOperTools.h](file://h/FileOperTools.h#L1-L42)
- [Markup.h](file://h/Markup.h#L1-L266)
**节源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp#L1-L1213)
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp#L1-L189)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L1-L420)
#### 指令执行流程
```mermaid
sequenceDiagram
participant UI as "用户界面"
participant GD10Cmd as "CGD10OperCmd"
participant DetDev as "CDetcGD10Dev"
participant FileTools as "CFileOperTools"
participant Markup as "CMarkup"
UI->>GD10Cmd : project_add(mac, projectcn)
GD10Cmd->>DetDev : IsGD10DevConnect()
alt 设备未连接
GD10Cmd-->>UI : 显示错误消息
return
end
GD10Cmd->>DetDev : GetGD10DevAddr()
GD10Cmd->>FileTools : MakeSureDirectoryPathExists()
alt 创建目录失败
GD10Cmd-->>UI : 显示错误消息
return
end
GD10Cmd->>Markup : 加载 localhost.xml
GD10Cmd->>Markup : 在 path_dictionary 中添加 path 元素
GD10Cmd->>Markup : 保存 localhost.xml
GD10Cmd->>Markup : 加载 mac.xml
GD10Cmd->>Markup : 在 path_dictionary 中添加 path 元素
GD10Cmd->>Markup : 保存 mac.xml
GD10Cmd-->>UI : 返回成功 (1)
```
**图源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp#L53-L105)
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp#L61-L68)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L261-L324)
- [Markup.h](file://h/Markup.h)
**节源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp#L53-L105)
### 设备检测与管理分析
`CDetcGD10Dev`类负责检测和管理GD10设备的连接状态,为上层指令系统提供设备可用性保障。
#### 设备检测流程
```mermaid
flowchart TD
Start([开始检测设备]) --> GetDrives["获取所有逻辑驱动器"]
GetDrives --> CheckDrive["遍历每个驱动器"]
CheckDrive --> IsRemovable{"是否为可移动驱动器?"}
IsRemovable --> |是| GetVolName["获取卷标名称"]
IsRemovable --> |否| NextDrive["下一个驱动器"]
GetVolName --> CompareName{"卷标是否为 'GD10' 或 'GD20'?"}
CompareName --> |是| SetAddr["设置设备地址"]
CompareName --> |否| CheckDir["检查是否存在 \\SD\\equipment 目录"]
CheckDir --> |存在| SetAddr
CheckDir --> |不存在| NextDrive
SetAddr --> SetConnected["设置连接状态为 true"]
SetConnected --> End([设备检测完成])
NextDrive --> CheckDrive
```
**图源**
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp#L100-L174)
**节源**
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp#L61-L68)
## 依赖分析
GD10设备指令系统依赖于多个核心组件和工具类,这些依赖关系确保了系统的稳定性和功能完整性。
```mermaid
graph TD
GD10OperCmd --> DetcGD10Dev
GD10OperCmd --> FileOperTools
GD10OperCmd --> Markup
GD10OperCmd --> Crc16
GD10OperCmd --> Crc32
DetcGD10Dev --> FileOperTools
DevManager --> GD10OperCmd
IOManager --> GD10OperCmd
subgraph "GD10指令系统"
GD10OperCmd
DetcGD10Dev
end
subgraph "工具类"
FileOperTools
Markup
Crc16
Crc32
end
subgraph "其他管理器"
DevManager
IOManager
end
```
**图源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp)
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
- [Markup.h](file://h/Markup.h)
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
- [DevManager.cpp](file://cpp/Managers/DevManager.cpp)
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp)
**节源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp)
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
## 性能考虑
在设计和实现GD10设备指令系统时,性能是一个重要的考量因素。系统通过以下方式优化性能:
1. **单例模式**:`CGD10OperCmd`和`CDetcGD10Dev`类都采用了单例模式,避免了重复创建对象的开销。
2. **线程安全**:`CFileOperTools`类在写日志时使用了临界区(CRITICAL_SECTION)来保证线程安全,防止多线程并发写入导致的日志混乱。
3. **异步操作**:`loadDeviceMarkDataFromGD`方法通过创建独立线程来执行文件复制和删除操作,避免了阻塞主线程,提高了用户体验。
4. **错误重试**:在删除文件或复制文件时,系统会进行多次重试(最多3次),以应对可能的文件占用或I/O错误,提高了操作的鲁棒性。
## 故障排除指南
当GD10设备指令系统出现通信异常时,可以按照以下步骤进行诊断和处理:
**节源**
- [GD10OperCmd.cpp](file://cpp/Tools/GD10OperCmd.cpp)
- [DetcGD10Dev.cpp](file://cpp/Operator/DetcGD10Dev.cpp)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
### 常见问题与解决方案
| 问题现象 | 可能原因 | 解决方案 |
| :--- | :--- | :--- |
| "请确保主机设备连上Geomative Studio!" | GD10设备未正确连接或未被识别 | 1. 检查USB线缆连接是否牢固。
2. 确认设备卷标是否为'GD10'或'GD20'。
3. 检查`LOG\detect_gd20_log.txt`日志文件以获取详细检测信息。 |
| "添加工程到本机失败" | `localhost.xml`文件损坏或权限不足 | 1. 检查`sd\users\localhost.xml`文件是否存在且可写。
2. 查看`LOG\general\`目录下的日志文件,确认具体的错误代码。 |
| "创建工程失败" | SD卡空间不足或文件系统错误 | 1. 检查GD10设备的SD卡剩余空间。
2. 尝试格式化SD卡(注意备份数据)。 |
| "删除文件失败" | 文件被其他进程占用 | 1. 确保没有其他程序正在访问GD10设备的文件。
2. 系统会自动重试3次,若仍失败,重启软件或设备后重试。 |
| "解析输入参数错误" | `set_param`方法的输入字符串格式不正确 | 1. 确认输入参数为逗号分隔的键值对,如`"key1,value1;key2,value2"`。
2. 检查键名是否存在于`equipment.xml`文件中。 |
## 结论
通过对`GD10OperCmd.cpp`及其相关组件的深入分析,我们全面理解了GD10设备指令系统的工作原理。该系统通过一个清晰的分层架构,将设备检测、文件操作、XML解析和指令执行等功能解耦,实现了对GD10设备的高效管理和控制。系统设计考虑了单例模式、线程安全和异步操作等性能优化策略,并通过详细的日志记录和错误处理机制保证了系统的稳定性。对于开发者而言,理解这些核心组件的交互方式和设计模式,对于维护和扩展系统功能至关重要。