【无标题】

OpenHarmony 开发板摆脱 USB 线:开机自动监听 hdc TCP xxx(例如8710) + 网口静态 IP 配置实录

一、痛点

调 OpenHarmony 开发板的同学应该都熟悉这个流程:

  1. 插 USB 线;
  2. hdc list targets 确认设备;
  3. 手动执行 hdc tmode port 8710,让 hdcd 重启并切换到 TCP 监听模式;
  4. 之后才能 hdc tconn <板子IP>:8710 走网络连接。

麻烦在于:tmode 切换是一次性的,板子一重启就打回原形,每次都得插 USB 重新来一遍。板子装在机壳里、放在测试架上、或者要交给别的同事用的时候,来回插线非常折磨。

理想状态是:板子上电、网线一插,PC 直接 hdc tconn 就能连上,USB 线只在刷机和首次配置时才需要。

本文记录我在这块板子上的完整配置过程,包括中途踩的坑和一个重要发现------很多版本的 OpenHarmony 根本不需要自启脚本,两条 param 命令就够了。

环境说明:OpenHarmony 标准系统,hdcd 版本 Ver: 3.2.0c(hdc 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):

json 复制代码
{
    "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 自己的配置,发现新大陆

配置之前先看系统里现成的东西(这个习惯能省很多事):

bash 复制代码
hdc shell "cat /system/etc/init/hdcd.cfg"

hdcd.cfg 是 hdcd 守护进程自己的 init 配置,里面除了服务定义,还有一组 param watcher(参数监视)job,关键片段:

json 复制代码
{
    "name" : "param:persist.hdc.mode.tcp=disable && param:persist.hdc.mode.usb=disable",
    "condition" : "persist.hdc.mode.tcp=disable && persist.hdc.mode.usb=disable",
    "cmds" : [ "stop hdcd" ]
},
{
    "name" : "param:persist.hdc.mode.tcp=enable && param:persist.hdc.mode.usb=disable",
    "condition" : "persist.hdc.mode.tcp=enable && persist.hdc.mode.usb=disable",
    "cmds" : [ "reset hdcd" ]
},
{
    "name" : "param:persist.hdc.mode.tcp=enable && param:persist.hdc.mode.usb=enable",
    "condition" : "persist.hdc.mode.tcp=enable && persist.hdc.mode.usb=enable",
    "cmds" : [ "reset hdcd" ]
}

翻译一下:hdcd 原生支持三个持久化通道参数,任何一个变化都会自动重启 hdcd 使其生效:

参数 含义
persist.hdc.mode.usb USB 通道开关
persist.hdc.mode.tcp TCP 通道开关
persist.hdc.mode.uart 串口通道开关
persist.hdc.port TCP 监听端口

persist. 前缀的参数存在 /data/param,重启不丢。也就是说"开机自动进 TCP 模式"是 hdcd 的原生能力,只需要把参数设上。

再确认当前状态:

bash 复制代码
hdc shell "param get persist.hdc.mode.tcp"   # 我的板子:disable
hdc shell "param get persist.hdc.mode.usb"   # 我的板子:enable
hdc shell "param get persist.hdc.port"       # 注意,见下一节

四、两条命令搞定开机自启(核心)

bash 复制代码
hdc shell "param set persist.hdc.mode.tcp enable"
hdc shell "param set persist.hdc.port 8710"
  • 第一条:开机自动进入 TCP 监听。执行瞬间 param watcher 就会触发 reset hdcd,USB 会闪断几秒然后自己恢复,属于正常现象。
  • 第二条:固定监听端口为 8710。

为什么还要显式设端口?------一个差点漏掉的坑

设置 tcp=enable 之后我用 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:*   LISTEN

TCP 服务器早就开好了,只是不开在 8710。把 persist.hdc.port 设成 8710(改端口参数不会立刻触发重启,重启后生效),问题解决。

顺带一提:如果 param get persist.hdc.mode.tcp 报 errNum 106(参数不存在),说明你的镜像 hdcd 版本较老,不支持参数方式,那就只能走第二节的自启 cfg 方案了。

五、网口静态 IP:netmanager 按网卡存文件

开机 IP 这块也不需要脚本。OpenHarmony 的 netmanager(以太网服务)为每张网卡维护一个独立的配置文件:

复制代码
/data/service/el1/public/netmanager/ethernet/eth0

内容是 key=value 格式,我的板子出厂时是:

复制代码
DEVICE=eth0
BOOTPROTO=STATIC
IPADDR=192.168.1.1
NETMASK=255.255.255.0
GATEWAY=
ROUTE=192.168.1.1
ROUTE_NETMASK=0.0.0.0
DNS=
PROXY_HOST=
PROXY_PORT=0
PROXY_EXCLUSIONS=

几个字段的含义:

字段 说明
BOOTPROTO STATIC 静态 / DHCP 自动获取
IPADDR / NETMASK 板子的 IP 和掩码
GATEWAY 默认网关
ROUTE + ROUTE_NETMASK 静态路由,一般填网关 + 0.0.0.0
DNS DNS 服务器,一般填网关

我的板子出厂 IP 是 192.168.1.1------恰好和常见路由器网关冲突,正好一起改掉。目标:板子 192.168.1.2,掩码 255.255.255.0,网关 192.168.1.1。

写入方法(USB 连着板子,直接一条命令)

bash 复制代码
hdc shell "printf 'DEVICE=eth0\nBOOTPROTO=STATIC\nIPADDR=192.168.1.2\nNETMASK=255.255.255.0\nGATEWAY=192.168.1.1\nROUTE=192.168.1.1\nROUTE_NETMASK=0.0.0.0\nDNS=192.168.1.1\nPROXY_HOST=\nPROXY_PORT=0\nPROXY_EXCLUSIONS=\n' > /data/service/el1/public/netmanager/ethernet/eth0"

再把属主和权限改回和原文件一致(netmanager 以 uid 1099 运行):

bash 复制代码
hdc shell "chown 1099:1099 /data/service/el1/public/netmanager/ethernet/eth0 && chmod 660 /data/service/el1/public/netmanager/ethernet/eth0"

如果不想敲命令:很多量产板预装了"以太网配置"应用,在里面改 IP,写的就是这个文件。二选一。

两个必须知道的特性

  1. 网线没插的时候,eth0 就是没有 IP,这不是配置失败。 netmanager 在链路 UP 时才应用配置。插上网线几秒内 IP 自动出现。我第一次重启后验证差点误判,后来 cat /sys/class/net/eth0/carrier 看到 0(无载波)才反应过来网线是拔着的。
  2. DHCP 和 STATIC 的行为差异在这里也适用:BOOTPROTO=DHCP 时由 DHCP 服务端分配,配置文件里的 IPADDR 等字段不生效。

六、重启,逐项验证

bash 复制代码
hdc shell reboot

等系统起来(USB 目标会自己回来,30 秒左右),逐项检查:

bash 复制代码
# 1. 参数持久化
hdc shell "param get persist.hdc.mode.tcp"    # → enable
hdc shell "param get persist.hdc.port"        # → 8710

# 2. 开机自动 TCP 监听(核心目标)
hdc shell "netstat -an | grep LISTEN | grep 8710"
# → tcp  0  0 0.0.0.0:8710  0.0.0.0:*  LISTEN

# 3. 网口 IP(前提:网线已插)
hdc shell "ifconfig 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/24)
hdc tconn 192.168.1.2:8710
hdc list targets    # 列表出现 192.168.1.2:8710 即成功

之后所有 hdc shell / file send / install 命令照常使用。板子或 PC 重启后,重新 tconn 一次即可。

七、踩坑记录

都是过程中真实撞到的,列出来帮后来人省时间:

  1. hdc file send 失败时返回码仍然是 0。 我第一次推文件时本地路径写错,hdc 打印了 [Fail]Error opening file 但 && 链后面的命令照样执行了。推完文件必须回读验证 (cat / grep 一下),不能信任命令退出码。
  2. Git Bash 下 hdc 的板端路径会被 MSYS 自动转换 ,/data/... 被改写成 D:/Program Files/Git/data/...。加前缀解决:MSYS_NO_PATHCONV=1 hdc file send ...。用 cmd/PowerShell 没这个问题。
  3. toybox 的 netstat 不支持 -o 参数 (Android 上常用的 netstat -ano 会报错),用 netstat -an 就够。
  4. [Fail]ExecuteCommand need connect-key? 有两种成因 :一是 USB 和 TCP 两个目标同时在线,hdc 不知道操作哪个,用 hdc -t <目标> <命令> 指定;二是设备瞬断(我遇到过两次,第二次直接掉了),重插 USB 即可。
  5. 查 hdcd 行为看 hilog ,tag 是 C02d13/HDC_LOG:hdc shell "hilog -x | grep -iE 'hdcd'",参数是否生效、daemon 有没有重启,日志里一目了然。

八、稳定性与兜底

  • 建议保留 USB 通道 (persist.hdc.mode.usb 保持默认 enable)。TCP + USB 可以同时开,网络出问题时插 USB 线还能救。真要纯 TCP(param set persist.hdc.mode.usb disable)请三思------一旦网络不通,就只能重刷了。
  • 所有配置都在 /data 分区:恢复出厂或重刷镜像会全部丢失。把第四、五节的命令存成一个文本,重刷后照着敲一遍(或做成脚本)就恢复了。
  • 一块板子同时只服务一个 hdc 客户端,第二个人连上来会顶掉第一个,团队共用时注意错开。
  • 判断板子是否"网络就绪",别只看能不能 ping 通板子,hdc shell "netstat -an | grep LISTEN" 看到 8710 才算服务真正起来了。

九、命令速查

新板子从零配好(USB 连接状态下,依次执行):

bash 复制代码
# 前置检查:镜像是否支持参数方式(读到值即可,disable 也算支持)
hdc shell "param get persist.hdc.mode.tcp"

# 1. 开机自动 TCP 监听,端口 8710
hdc shell "param set persist.hdc.mode.tcp enable"
hdc shell "param set persist.hdc.port 8710"

# 2. 网口静态 IP:192.168.1.2/24,网关 192.168.1.1
hdc shell "printf 'DEVICE=eth0\nBOOTPROTO=STATIC\nIPADDR=192.168.1.2\nNETMASK=255.255.255.0\nGATEWAY=192.168.1.1\nROUTE=192.168.1.1\nROUTE_NETMASK=0.0.0.0\nDNS=192.168.1.1\nPROXY_HOST=\nPROXY_PORT=0\nPROXY_EXCLUSIONS=\n' > /data/service/el1/public/netmanager/ethernet/eth0"
hdc shell "chown 1099:1099 /data/service/el1/public/netmanager/ethernet/eth0 && chmod 660 /data/service/el1/public/netmanager/ethernet/eth0"

# 3. 重启生效
hdc shell reboot

# 4. PC 侧(网卡先配到 192.168.1.x)
hdc tconn 192.168.1.2:8710

十、总结

  • hdc tmode 是一次性切换,这个"印象"让很多人(包括我)以为必须写开机脚本。实际上新一点的 hdcd 用 persist.hdc.mode.tcp + persist.hdc.port 两个参数就能实现持久 TCP 监听,零文件改动、重启不丢。
  • 网上流传的 Android 风格 init.rc 方案在 OpenHarmony 标准系统上会被静默忽略,OH 的 init 只认 JSON cfg------动手前先看 /system/etc/init/ 里系统自己是怎么写的。
  • 网口静态 IP 就是 netmanager 的一个 key=value 小文件,按网卡名存放在 /data/service/el1/public/netmanager/ethernet/ 下。
  • 排查问题多看日志(hilog)和多翻系统自带配置(/system/etc/init/*.cfg、param get),答案往往系统里早就写好了。
相关推荐
硅谷魔术师5 天前
openHarmony有没有类似安卓的scrcpy连接工具
openharmony
熊猫钓鱼>_>6 天前
Kotlin Multiplatform for OpenHarmony 实战:为 Landscapist 实现图片加载适配
开发语言·kotlin·华为云·ai编程·harmonyos·鸿蒙·openharmony
熊猫钓鱼>_>6 天前
开源鸿蒙平台 KMP 三方库 KStore 适配全流程:从 ohosArm64 target 到真机文件持久化验证
人工智能·华为·开源·ai编程·harmonyos·openharmony·kmp
熊猫钓鱼>_>8 天前
Kotlin Multiplatform for OpenHarmony 实战:为 kotlin-inject 实现依赖注入适配
开发语言·华为·kotlin·ai编程·inject·鸿蒙·openharmony
熊猫钓鱼>_>9 天前
Kotlin Multiplatform for OpenHarmony 实战:为 KMPNotifier 实现 OpenHarmony 本地通知引擎
kotlin·ai编程·harmonyos·鸿蒙·openharmony·适配·kmp
fellow999 天前
Electron + pnpm 在鸿蒙应用里跑起来
electron·harmonyos·openharmony·deepseek·deepseekharness
熊猫钓鱼>_>10 天前
Kotlin Multiplatform for OpenHarmony 实战:为 MVIKotlin 实现单向数据流适配
华为·ai编程·鸿蒙·openharmony·适配·数据流·mvkotlin
EatFan11 天前
Flutter 鸿蒙适配实践 2026:从环境搭建、混合渲染到 OpenTelemetry 性能基建
flutter·华为·harmonyos·openharmony·opentelemetry·鸿蒙适配·impeller
行走的小派14 天前
OpenHarmony 音频应用开发:实时录音、重点标记与本地回放
音视频·openharmony·香橙派