4.9 KiB
4.9 KiB
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 的localStoragekey(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 源码和脚本入口。