- 增加送丝机及两种焊枪的启动选择,未启用时保留原有简化外设 - 实现外设串口协议、工艺缓存与导入、参数保存、报警输入和独立供电 - 提供外设 WebSocket 状态及控制接口,按连接管理按钮持有和碰撞故障释放 - 添加外设卡片、静态光斑、监控输入与故障操作,统一布局并保存展开状态 - 添加外设协议与固件联动用例,以及点射收尾期间再次出光的回执回归用例 - 整理协议边界及测试条目,记录旧款焊枪驱动和电源报警未被固件转发的现状 - BREAKING CHANGE: 自定义平台实例化 BoardWebSocketServer 时需提供 ExternalDevices 依赖
81 lines
4.6 KiB
Python
81 lines
4.6 KiB
Python
"""解析项目命令行参数,将配置检查、镜像清理和仿真生命周期交给对应模块"""
|
|
import argparse
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
|
|
# 直接执行脚本时也能导入同级的 scripts 包
|
|
if __package__ in (None, ''):
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
|
|
from scripts.environment import RUNTIME, check, format_paths, free_port, set_elf, setting
|
|
from scripts.flash_images import clean
|
|
from scripts.renode_process import exit_previous
|
|
from scripts.settings import as_boolean, as_port
|
|
# 保留现有项目下载脚本使用的 simulation 与 free_port 导入入口
|
|
from scripts.simulation import run, simulation
|
|
from scripts.external_devices import ExternalDevices
|
|
|
|
|
|
def main():
|
|
"""执行子命令并将预期的配置、进程和文件错误转换为非零退出码"""
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
sub = parser.add_subparsers(dest='task', required=True)
|
|
dependencies = sub.add_parser('check')
|
|
dependencies.add_argument('--usb', action='store_true', help='Also check the installed virtual serial-port driver')
|
|
sub.add_parser('format')
|
|
sub.add_parser('stop', help='Stop this project instance and release its virtual COM port')
|
|
cleanup = sub.add_parser('clean', help='Remove persistent Flash images; stop Renode first')
|
|
cleanup.add_argument('target', nargs='?', choices=('flash1', 'flash2'), help='flash1: internal Flash; flash2: external W25Q16; default: both')
|
|
firmware = sub.add_parser('elf')
|
|
firmware.add_argument('path', help='ELF path to save as H723_ELF in .env')
|
|
launch = sub.add_parser('run')
|
|
for device in ('wire', 'laser1', 'laser2'):
|
|
launch.add_argument('--' + device, action=argparse.BooleanOptionalAction, default=None,
|
|
help='Enable the external ' + device + ' device model')
|
|
launch.add_argument('--debug', action=argparse.BooleanOptionalAction, default=None, help='Wait paused for GDB')
|
|
launch.add_argument('--usb', action=argparse.BooleanOptionalAction, default=None, help='Create a project-owned virtual COM port')
|
|
launch.add_argument('--com', default=None, help='Unused virtual COM port for --usb (default: COM12)')
|
|
launch.add_argument('--flash', type=Path, help='External Flash image (default: .runtime/w25q16.bin)')
|
|
launch.add_argument('-f', '--force', action='store_true', help='Quit this project\'s previous instance before starting')
|
|
launch.add_argument('--uart-port', type=as_port, help='Override the network UART port')
|
|
launch.add_argument('--gdb-port', type=as_port, help='Override the GDB port')
|
|
launch.add_argument('--ws-port', type=as_port, help='Override the board WebSocket port (default: 12322)')
|
|
launch.add_argument('--fast-serial', action=argparse.BooleanOptionalAction,
|
|
default=None, help='Accelerate serial timing for protocol and firmware upgrade simulation (default: disabled)')
|
|
args = parser.parse_args()
|
|
try:
|
|
if args.task == 'check':
|
|
return check(args.usb)
|
|
if args.task == 'format':
|
|
format_paths()
|
|
return 0
|
|
if args.task == 'clean':
|
|
return clean(args.target)
|
|
if args.task == 'stop':
|
|
from scripts.virtual_com import cleanup_virtual_com
|
|
stopped = exit_previous()
|
|
removed = cleanup_virtual_com(RUNTIME)
|
|
if removed:
|
|
print(f'Removed {removed} stale project virtual COM port(s).', flush=True)
|
|
elif not stopped:
|
|
print('No project instance or owned virtual COM port is running.', flush=True)
|
|
return 0
|
|
if args.task == 'elf':
|
|
set_elf(args.path)
|
|
return 0
|
|
if args.task == 'run':
|
|
# 显式命令行参数优先,其次为进程环境变量和 .env,最后使用默认值
|
|
debug = args.debug if args.debug is not None else as_boolean(setting('H723_DEBUG', 'false'))
|
|
usb = args.usb if args.usb is not None else as_boolean(setting('H723_USB', 'false'))
|
|
fast_serial = args.fast_serial if args.fast_serial is not None else as_boolean(setting('H723_FAST_SERIAL', 'false'))
|
|
devices = ExternalDevices.resolve(args.wire, args.laser1, args.laser2)
|
|
return run(debug, usb, args.flash, args.force, args.com if args.com is not None else setting('H723_COM', 'COM12'), args.uart_port, args.gdb_port, args.ws_port, fast_serial, devices)
|
|
except (OSError, RuntimeError, ValueError, subprocess.SubprocessError) as error:
|
|
print(f'ERROR: {error}', file=sys.stderr)
|
|
return 1
|
|
|
|
|
|
if __name__ == '__main__':
|
|
raise SystemExit(main())
|