Files

4.9 KiB
Raw Permalink Blame History

ESP32 DCU 调试控制台 — 配置系统

1. 系统与分层

本仓库没有集中式的配置文件(无 *.yaml、*.toml、*.env),采用三层组合方式完成运行时配置:

  • 用户偏好层:浏览器端 localStorage,用于持久化设备 IP、电机传输链路、刷新率、CAN DBC 设置等。
  • 进程/工具层:Python 服务通过 argparse 解析命令行参数(--port、--window、--no-browser);Windows 批处理/VBScript 再提供默认值与启动入口。
  • 外部依赖层:通过调用外部子进程(tools/ecat/build_native/ecat_native.exe)并传入 --parent-pid 等方式传递进程间通信所需配置。

2. 关键文件

  • esp32_server.py:服务端核心。HTTP 服务器(端口探测/绑定)、EtherCAT 反向代理、pywebview 窗口外壳、子进程生命周期管理,均通过 argparse 与模块级常量硬编码控制。
  • serve.bat:控制台模式启动器,设 PORT=2625 后执行 python esp32_server.py --port %PORT%。
  • esp32_web.vbs / esp32_app.vbs:分别以隐藏窗口/桌面窗(pywebview)方式启动 esp32_server.py,区别仅在于是否传 --window。
  • js/common/base-url.js:统一封装设备 IP 的 localStorage key(dcu_esp_ip)与默认值(DEFAULT_ESP_IP = '192.168.31.127')。注释明确“各页面共用”“只负责公共实现”。
  • js/motor/transport.js:维护 ECAT/WiFi 传输切换状态,key 为 dcu_motor_transport。
  • js/motor/transport-ecat.js:ECAT 传输配置,含网卡适配器、周期时间(4ms→250us 迁移标记 LS_PERIOD_MIG、LS_SPIN)等,全部落 localStorage。
  • js/can/persist.js、js/ota/file-handle.js:各自功能页的偏好持久化(DBC、刷新目标 LS_FLASH_TARGET、最近固件元数据 LS_FILE_META)。
  • js/app.js:主标签外壳页面,读写主页的共享设备 IP。

3. 架构与设计约定

3.1 设备发现与连接

  • 所有页面向设备发起 API 请求的目标由 getBaseUrl() 计算:http:// + 当前设备 IP,IP 从 localStorage['dcu_esp_ip'] 取,无有效值回退到 192.168.31.127。
  • 代码注释强调 “每个页面一致”“空值忽略”,对 localStorage 的访问被 try/catch 包裹(兼容隐私模式)。

3.2 端口与服务启动

  • 端口优先级:serve.bat → --port → 默认 2625 → _bind_server 自动递增重试(若占用则打印 端口 xxx 已被占用, 尝试 xxx+1)。
  • 默认监听 127.0.0.1(不暴露公网)。
  • Windows 下通过 Job Object 绑定子进程生命周期,父进程退出时内核连带杀掉服务子进程。

3.3 EtherCAT 后端自动发现与启动

  • 使用内置端口数组 ECAT_PORTS = (8090..8095) 轮询检测正在运行的 ecat_native.exe。
  • 首次需要时在 g_ecat_lock 保护下拉起子进程并传入 --parent-pid,避免独立实例清理逻辑误杀旧进程。
  • 已运行实例通过 _port_taken(p) 复用,不再重复拉起。

3.4 多语言环境配置

  • 所有中文字符串(日志、UI 文案、提示、注释中的路径与说明)均以 UTF-8 输出:serve.bat 先执行 chcp 65001 并将 PYTHONUTF8=1 写入子进程环境;esp32_web.vbs / esp32_app.vbs 同样设置 PYTHONUTF8=1。
  • 前端 JS 侧无多语言文件,所有文案直接嵌入 HTML/JS 源文件中。

4. 约束与规则

  • 设备 IP 键名唯一:dcu_esp_ip 由 js/common/base-url.js 统一定义并通过 export 导出,所有功能页通过该共享 key 协作(OTA/CAN/电机页注释明确声明此约定)。
  • 无外部配置文件的强制要求:整个项目未使用 .env/.yaml/*.cfg/*.ini 等任何集中配置格式,如需调参必须修改源码常量或命令行参数。esp32_server.py 中除 argparse 外,其余行为均通过模块级变量(如 ECAT_DIR、ECAT_PORTS、BASE_DIR)与命令行参数组织。
  • 安全边界:服务默认仅监听 127.0.0.1;EtherCAT 原生后端也绑 127.0.0.1 且无 CORS,故页面需经本服务同源反向代理(/ecat/api/*)访问,避免跨域预检失败。
  • 前端本地存储可容错:每次 localStorage.setItem/getItem 都包裹 try/catch(应对无痕/隐私模式抛出异常);写前做 trim 校验,空值即忽略。
  • 进程边界配置不可穿透:VBScript 层通过命令行参数(--window)切换模式,但 Python 内部不会反查环境变量;子进程通过标准输出打印 PORT={...} 供父进程解析,而非通过共享配置文件通信。

5. 总结

这是一个纯前端 + 简易 Python 静态服务器场景下的轻量配置系统:设备地址和界面偏好完全落在浏览器的 localStorage 中,服务进程本身通过命令行参数与模块内常量硬编码驱动,不存在 YAML/环境变量等集中式配置机制。其优点是无依赖、可直连浏览器调试;代价是新增配置项需要同时修改多处 JS/Python 源码和脚本入口。