 + 网口静态 IP 配置实录)
一、痛点调 OpenHarmony 开发板的同学应该都熟悉这个流程插 USB 线hdc list targets确认设备手动执行hdc tmode port 8710让 hdcd 重启并切换到 TCP 监听模式之后才能hdc tconn 板子IP:8710走网络连接。麻烦在于tmode切换是一次性的板子一重启就打回原形每次都得插 USB 重新来一遍。板子装在机壳里、放在测试架上、或者要交给别的同事用的时候来回插线非常折磨。理想状态是板子上电、网线一插PC 直接hdc tconn就能连上USB 线只在刷机和首次配置时才需要。本文记录我在这块板子上的完整配置过程包括中途踩的坑和一个重要发现——很多版本的 OpenHarmony 根本不需要自启脚本两条param命令就够了。环境说明OpenHarmony 标准系统hdcd 版本Ver: 3.2.0chdc shell param get const.hdc.version可查。不同版本的 hdcd 行为可能不同动手前建议先按本文第六节确认你的镜像支持。二、先排雷网上流传的 init.rc 自启方案在标准系统上是无效的搜OpenHarmony hdc 开机自动 TCP很容易搜到这样的方案我一开始也打算这么做service hdc_tcp_start /system/bin/sh -c sleep 3; /system/bin/hdc tmode port 8710 class: late user: root group: root oneshot on boot start hdc_tcp_start这是 Android init 的.rc语法。OpenHarmony 标准系统的 init 进程只解析 JSON 格式的.cfg文件也就是/system/etc/init/下那一大堆xxx.cfg。把上面这种 rc 文件放进板子不会报错、不会有任何提示——它就是被静默忽略。你只会以为服务起来了但没生效然后在错误的方向上浪费一下午。正确的 OH 服务配置长这样供对比hdc_tcp.cfg{services:[{name:hdc_tcp_start,path:[/system/bin/sh,/system/bin/hdc_tcp_start.sh],uid:root,gid:[root],once:1,seclabel:u:r:shell:s0}],jobs:[{name:boot,cmds:[start hdc_tcp_start]}]}这套方案需要 remount/system为可写、推两个文件上去还有 sleep 等网卡的玄学时序问题。但幸运的是往下看你大概率一个文件都不用推。三、翻 hdcd 自己的配置发现新大陆配置之前先看系统里现成的东西这个习惯能省很多事hdc shellcat /system/etc/init/hdcd.cfghdcd.cfg是 hdcd 守护进程自己的 init 配置里面除了服务定义还有一组param watcher参数监视job关键片段{name:param:persist.hdc.mode.tcpdisable param:persist.hdc.mode.usbdisable,condition:persist.hdc.mode.tcpdisable persist.hdc.mode.usbdisable,cmds:[stop hdcd]},{name:param:persist.hdc.mode.tcpenable param:persist.hdc.mode.usbdisable,condition:persist.hdc.mode.tcpenable persist.hdc.mode.usbdisable,cmds:[reset hdcd]},{name:param:persist.hdc.mode.tcpenable param:persist.hdc.mode.usbenable,condition:persist.hdc.mode.tcpenable persist.hdc.mode.usbenable,cmds:[reset hdcd]}翻译一下hdcd 原生支持三个持久化通道参数任何一个变化都会自动重启 hdcd 使其生效参数含义persist.hdc.mode.usbUSB 通道开关persist.hdc.mode.tcpTCP 通道开关persist.hdc.mode.uart串口通道开关persist.hdc.portTCP 监听端口persist.前缀的参数存在/data/param重启不丢。也就是说开机自动进 TCP 模式是 hdcd 的原生能力只需要把参数设上。再确认当前状态hdc shellparam get persist.hdc.mode.tcp# 我的板子disablehdc shellparam get persist.hdc.mode.usb# 我的板子enablehdc shellparam get persist.hdc.port# 注意见下一节四、两条命令搞定开机自启核心hdc shellparam set persist.hdc.mode.tcp enablehdc shellparam set persist.hdc.port 8710第一条开机自动进入 TCP 监听。执行瞬间 param watcher 就会触发reset hdcdUSB 会闪断几秒然后自己恢复属于正常现象。第二条固定监听端口为 8710。为什么还要显式设端口——一个差点漏掉的坑设置tcpenable之后我用netstat检查发现 8710 端口上只有 UDP没有 TCP LISTEN$ hdc shell netstat -an | grep 8710 udp 0 0 0.0.0.0:8710 0.0.0.0:*一度以为方案失败了。后来param get | grep hdc翻参数列表才发现persist.hdc.port 35129真相8710 端口上的 UDP 是 hdcd 的设备发现广播同网段hdc list targets能自动扫到就是靠它而 TCP 真正监听的端口由persist.hdc.port决定——我的板子上这个参数残留着35129$ hdc shell netstat -an | grep 35129 tcp 0 0 0.0.0.0:35129 0.0.0.0:* LISTENTCP 服务器早就开好了只是不开在 8710。把persist.hdc.port设成 8710改端口参数不会立刻触发重启重启后生效问题解决。顺带一提如果param get persist.hdc.mode.tcp报errNum 106参数不存在说明你的镜像 hdcd 版本较老不支持参数方式那就只能走第二节的自启 cfg 方案了。五、网口静态 IPnetmanager 按网卡存文件开机 IP 这块也不需要脚本。OpenHarmony 的 netmanager以太网服务为每张网卡维护一个独立的配置文件/data/service/el1/public/netmanager/ethernet/eth0内容是 keyvalue 格式我的板子出厂时是DEVICEeth0 BOOTPROTOSTATIC IPADDR192.168.1.1 NETMASK255.255.255.0 GATEWAY ROUTE192.168.1.1 ROUTE_NETMASK0.0.0.0 DNS PROXY_HOST PROXY_PORT0 PROXY_EXCLUSIONS几个字段的含义字段说明BOOTPROTOSTATIC静态 /DHCP自动获取IPADDR/NETMASK板子的 IP 和掩码GATEWAY默认网关ROUTEROUTE_NETMASK静态路由一般填网关 0.0.0.0DNSDNS 服务器一般填网关我的板子出厂 IP 是192.168.1.1——恰好和常见路由器网关冲突正好一起改掉。目标板子192.168.1.2掩码255.255.255.0网关192.168.1.1。写入方法USB 连着板子直接一条命令hdc shellprintf DEVICEeth0\nBOOTPROTOSTATIC\nIPADDR192.168.1.2\nNETMASK255.255.255.0\nGATEWAY192.168.1.1\nROUTE192.168.1.1\nROUTE_NETMASK0.0.0.0\nDNS192.168.1.1\nPROXY_HOST\nPROXY_PORT0\nPROXY_EXCLUSIONS\n /data/service/el1/public/netmanager/ethernet/eth0再把属主和权限改回和原文件一致netmanager 以 uid 1099 运行hdc shellchown 1099:1099 /data/service/el1/public/netmanager/ethernet/eth0 chmod 660 /data/service/el1/public/netmanager/ethernet/eth0如果不想敲命令很多量产板预装了以太网配置应用在里面改 IP写的就是这个文件。二选一。两个必须知道的特性网线没插的时候eth0 就是没有 IP这不是配置失败。netmanager 在链路 UP 时才应用配置。插上网线几秒内 IP 自动出现。我第一次重启后验证差点误判后来cat /sys/class/net/eth0/carrier看到0无载波才反应过来网线是拔着的。DHCP 和 STATIC 的行为差异在这里也适用BOOTPROTODHCP时由 DHCP 服务端分配配置文件里的 IPADDR 等字段不生效。六、重启逐项验证hdc shellreboot等系统起来USB 目标会自己回来30 秒左右逐项检查# 1. 参数持久化hdc shellparam get persist.hdc.mode.tcp# → enablehdc shellparam get persist.hdc.port# → 8710# 2. 开机自动 TCP 监听核心目标hdc shellnetstat -an | grep LISTEN | grep 8710# → tcp 0 0 0.0.0.0:8710 0.0.0.0:* LISTEN# 3. 网口 IP前提网线已插hdc shellifconfig eth0# → inet addr:192.168.1.2 Bcast:192.168.1.255 Mask:255.255.255.0# 4. PC 侧连接PC 网卡必须先配到 192.168.1.x比如 192.168.1.100/24hdc tconn192.168.1.2:8710 hdc list targets# 列表出现 192.168.1.2:8710 即成功之后所有hdc shell/file send/install命令照常使用。板子或 PC 重启后重新tconn一次即可。七、踩坑记录都是过程中真实撞到的列出来帮后来人省时间hdc file send失败时返回码仍然是 0。我第一次推文件时本地路径写错hdc 打印了[Fail]Error opening file但链后面的命令照样执行了。推完文件必须回读验证cat/grep一下不能信任命令退出码。Git Bash 下 hdc 的板端路径会被 MSYS 自动转换/data/...被改写成D:/Program Files/Git/data/...。加前缀解决MSYS_NO_PATHCONV1 hdc file send ...。用 cmd/PowerShell 没这个问题。toybox 的 netstat 不支持-o参数Android 上常用的netstat -ano会报错用netstat -an就够。[Fail]ExecuteCommand need connect-key?有两种成因一是 USB 和 TCP 两个目标同时在线hdc 不知道操作哪个用hdc -t 目标 命令指定二是设备瞬断我遇到过两次第二次直接掉了重插 USB 即可。查 hdcd 行为看 hilogtag 是C02d13/HDC_LOGhdc shell hilog -x | grep -iE hdcd参数是否生效、daemon 有没有重启日志里一目了然。八、稳定性与兜底建议保留 USB 通道persist.hdc.mode.usb保持默认enable。TCP USB 可以同时开网络出问题时插 USB 线还能救。真要纯 TCPparam set persist.hdc.mode.usb disable请三思——一旦网络不通就只能重刷了。所有配置都在/data分区恢复出厂或重刷镜像会全部丢失。把第四、五节的命令存成一个文本重刷后照着敲一遍或做成脚本就恢复了。一块板子同时只服务一个 hdc 客户端第二个人连上来会顶掉第一个团队共用时注意错开。判断板子是否网络就绪别只看能不能 ping 通板子hdc shell netstat -an | grep LISTEN看到 8710 才算服务真正起来了。九、命令速查新板子从零配好USB 连接状态下依次执行# 前置检查镜像是否支持参数方式读到值即可disable 也算支持hdc shellparam get persist.hdc.mode.tcp# 1. 开机自动 TCP 监听端口 8710hdc shellparam set persist.hdc.mode.tcp enablehdc shellparam set persist.hdc.port 8710# 2. 网口静态 IP192.168.1.2/24网关 192.168.1.1hdc shellprintf DEVICEeth0\nBOOTPROTOSTATIC\nIPADDR192.168.1.2\nNETMASK255.255.255.0\nGATEWAY192.168.1.1\nROUTE192.168.1.1\nROUTE_NETMASK0.0.0.0\nDNS192.168.1.1\nPROXY_HOST\nPROXY_PORT0\nPROXY_EXCLUSIONS\n /data/service/el1/public/netmanager/ethernet/eth0hdc shellchown 1099:1099 /data/service/el1/public/netmanager/ethernet/eth0 chmod 660 /data/service/el1/public/netmanager/ethernet/eth0# 3. 重启生效hdc shellreboot# 4. PC 侧网卡先配到 192.168.1.xhdc tconn192.168.1.2:8710十、总结hdc tmode是一次性切换这个印象让很多人包括我以为必须写开机脚本。实际上新一点的 hdcd 用persist.hdc.mode.tcppersist.hdc.port两个参数就能实现持久 TCP 监听零文件改动、重启不丢。网上流传的 Android 风格 init.rc 方案在 OpenHarmony 标准系统上会被静默忽略OH 的 init 只认 JSON cfg——动手前先看/system/etc/init/里系统自己是怎么写的。网口静态 IP 就是 netmanager 的一个 keyvalue 小文件按网卡名存放在/data/service/el1/public/netmanager/ethernet/下。排查问题多看日志hilog和多翻系统自带配置/system/etc/init/*.cfg、param get答案往往系统里早就写好了。