# 设备指令系统 **本文档引用的文件** - [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设备的高效管理和控制。系统设计考虑了单例模式、线程安全和异步操作等性能优化策略,并通过详细的日志记录和错误处理机制保证了系统的稳定性。对于开发者而言,理解这些核心组件的交互方式和设计模式,对于维护和扩展系统功能至关重要。