资讯动态

Zigbee透传驱动开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】

发布时间:2026/10/26 2:24:42 来源:尧图企业网站定制
LoRa 的验收口径清楚了。今天是 Zigbee同样是串口透传。真组网需要协调器和终端一颗模组当不了两头。第 41 章把 UART 打开了第 44、45 章在同一根排针上做过 BLE 和 LoRa。这一章还是/dev/ttyS7115200 8N1换上一颗Zigbee 透传模组。板上这一侧看起来和 LoRa 几乎没区别write几个字节射频侧发出去空中收到的字节从 UART 读回来。没有 Zigbee 协议栈要你在用户态跑没有 AF_INET没有 socket。应用写的是串口。先把三扇错门焊死一块板、一颗模组组不了网。write返回成功只说明 UART FIFO 吃进了字节。对面没有协调器或终端空中没有人接读回来就是空。这不是驱动坏了。模组上的 USB 口常常只供电。没有 D / D-插电脑认不出串口设备。通信走排针上的 TX/RX。波特率不是 9600。GPS、六轴、LoRa 是 9600这边默认115200。写错配置帧的FE头永远对不上。一次能通的路径板上打开ttyS7 115200十六进制发取 ID 命令模组回FE开头的帧串口活着。然后第二套一颗协调器、一颗终端同一信道A 发helloB 在一秒内读到。1. 板上这一侧就是串口应用 write(/dev/ttyS7) │ 115200 8N1 原始模式 ▼ RK3568 uart7 (GPIO3_C4 TX / GPIO3_C5 RX) │ ▼ Zigbee 透传模组 UART │ 射频自组网 ▼ 另一颗模组 UART → 另一块板的 ttyS7透传的意思你写什么对端读什么字节不解释。组网、信道、短地址模组固件自己管。用户态最多发几条厂商配置帧查 ID、查信道不在应用里实现 IEEE 802.15.4。和 BLE 那章的差别BLE 对端是手机 GATTZigbee 对端是另一颗同协议模组。手机 nRF Connect 在这里没用。和 LoRa 那章的共同点单模块只能证明「UART 通了」。无线电要两套。排针和 GPS / BLE / LoRa / 六轴 / 语音共用 uart7。一次插一颗。插着 GPS 再插 Zigbee两颗 TX 短在一起谁都别想通。2. 设备树uart7 用 m1不是 SoC 默认的 m0uart7 { status okay; pinctrl-0 uart7m1_xfer; /* GPIO3_C4 TX / GPIO3_C5 RX */ };SoC 默认uart7m0是另一组球。板级必须覆盖成 m1否则排针是死的/dev/ttyS7节点还在write也成功——字节发到空气里的另一对脚上。核对hdc shell ls -l /dev/ttyS7 hdc shell cat /proc/tty/driver/serial hdc shell cat /proc/device-tree/serialfe6b0000/status要看到字符设备crw、7: uart:16550A、status 里okay。ttyS2是 1500000 调试口应用禁止占用。HAP 不是 root。开机脚本chmod 0666 /dev/ttyS7 /dev/ttyS8 /dev/ttyS3路径按教程约定放在device/board/rk/rk3568_evb/board_perm/board-perm.sh打进 vendor。hdc 临时 chmod重启丢掉。3. 打开串口115200关硬件流控不要 select第 41 章的结论这里直接用。RK3568 的dw-apb-uartDMA 请求失败会回退中断模式。这条回退路径上select的就绪不可靠内核 rx 计数在涨cat /dev/ttyS7 | od能看到字节应用select却永远不返回可读。VTIME在这份内核上也不老实阻塞read可能永不返回ArkTS 主线程一起冻。现在这套打开方式int fd open(path, O_RDWR | O_NOCTTY | O_NONBLOCK); struct termios t; tcgetattr(fd, t); cfsetispeed(t, B115200); cfsetospeed(t, B115200); t.c_cflag (t.c_cflag ~CSIZE) | CS8 | CLOCAL | CREAD; t.c_cflag ~(PARENB | CSTOPB | CRTSCTS); /* 模组没有 RTS/CTS开了会卡死 */ t.c_lflag ~(ICANON | ECHO | ECHOE | ISIG); t.c_iflag ~(IXON | IXOFF | IXANY | INLCR | ICRNL); t.c_oflag ~OPOST; t.c_cc[VMIN] 0; t.c_cc[VTIME] 0; tcflush(fd, TCIOFLUSH); tcsetattr(fd, TCSANOW, t);读用poll(POLLIN, timeout)就绪再read。写之前tcflush(fd, TCIFLUSH)丢掉模组上电乱吐的半帧否则配置帧对不齐。NAPI 封装成libboard.so的uartOpen/uartWrite/uartRead/uartReadAsync。ArkTS 主线程不要跑同步uartRead的长超时六轴那章会把这个坑放大。4. 配置帧单模块能验的那几字节常见 UART-Zigbee 透传模组配置包以FE 05开头、FF结尾。三句够用作用十六进制取 IDFE059021000002FF取短地址FE059021000001FF取信道FE059021000003FF模组在线会回一帧同样以FE开头的数据。回了 UART 通、模组活、波特率对。没回先换 tty、换 115200再查 TX/RX 是否交叉。外设测试应用 Zigbee 页默认十六进制、设备/dev/ttyS7、波特 115200。把取 ID 贴进发送框点发送再点读取。看到FE就算单模块过关。不要在这一步要求「发出去的 hello 自己读回来」。无线不会从自己的天线绕一圈进自己的 RX。那是 RS485 A/B 短接才有的戏第 50 章。5. 组网协调器 终端两套Zigbee 最小闭合是两颗模组一颗工作在协调器建网、分配短地址一颗工作在终端入网、收发两颗上电后固件通常会自组网只要信道一致、距离几米内。用户态两边都当普通串口板 A uart_tool send hello\n │ ▼ 空中 板 B uart_tool recv → 读到 hello角色怎么切看模组说明书有的上电就是透传、自动入网有的要先发进配置态的 AT 或FE帧设角色。应用层不要假设自己在跑一个完整的 Zigbee stack。验收我只认这一条A 发出的那几个字节B 原样读到。短地址、信道能读出来是加分不是组网的判据。只有一颗模组时把验收口径写成「配置帧有应答」不要写成「Zigbee 不通」。口径写错人会在 UART 驱动里翻三天。6. 命令行工具和第 41、44 章同一把uart_tool32 位 musl。交叉编译CLANG源码/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang SYSROOT源码/prebuilts/ohos-sdk/linux/11/native/sysroot $CLANG --targetarm-linux-ohos --sysroot$SYSROOT \ -Wl,--dynamic-linker/system/lib/ld-musl-arm.so.1 \ -O2 -o uart_tool uart_tool.c hdc file send uart_tool /data/local/tmp/uart_tool hdc shell chmod x /data/local/tmp/uart_tool取 IDhdc shell /data/local/tmp/uart_tool /dev/ttyS7 115200 hex FE059021000002FF hdc shell /data/local/tmp/uart_tool /dev/ttyS7 115200 recv 2recv那一下应打出FE...。空的话把命令换成 9600 试一次——如果 9600 出字模组被设过波特应用默认 115200 就要改。出厂这块我用的是 115200。两板对发文本模式即可# 板 A hdc shell /data/local/tmp/uart_tool /dev/ttyS7 115200 send hello # 板 B hdc shell /data/local/tmp/uart_tool /dev/ttyS7 115200 recv 3dmesg里出现path/dev/ttyS7和ioctl 0x5401TCGETS说明uartOpen真的打开了不是应用自己报了个假成功。7. ArkTS 页透传控制台就够协议解析留给 GPS、指纹、语音。Zigbee 页复用串口控制台设备、波特、十六进制开关、发送、单次读、连续读。import board from libboard.so; State curDev: string /dev/ttyS7; State curBaud: string 115200; State hex: boolean true; State tx: string FE059021000002FF; State rx: string (未打开); State opened: boolean false; toggle() { if (this.opened) { board.uartClose(); this.opened false; this.rx (已关闭); return; } let b: number parseInt(this.curBaud); if (board.uartOpen(this.curDev, b) ! 0) { this.rx 打开失败节点、权限、DTS、是不是占用了 ttyS2; return; } this.opened true; this.rx 已打开 this.curDev b; } send() { if (!this.opened) { this.rx 先打开; return; } let n: number board.uartWrite(this.tx, this.hex ? 1 : 0); this.rx TX n 字节; } readOnce() { if (!this.opened) { this.rx 先打开; return; } let s: string board.uartRead(500, this.hex ? 1 : 0); this.rx s.length 0 ? (RX: s) : (500ms 空); }连续读用setInterval调uartRead(200, 1)可以超时别超过间隔。更稳的是await board.uartReadAsync(200, 1)读放进 NAPI 工作线程停按钮还能点。isHex1时 C 层把FE0590...收成二进制再write。文本模式会把FE当两个 ASCII 字母发出去模组当垃圾。配置帧必须勾十六进制。8. NAPI 写十六进制的那几行static int hexval(char c) { if (c 0 c 9) return c - 0; if (c a c f) return c - a 10; if (c A c F) return c - A 10; return -1; } /* uartWrite(data, isHex) */ tcflush(g_uart, TCIFLUSH); if (isHex) { uint8_t out[256]; int o 0; for (size_t i 0; i 1 len o 256; ) { if (buf[i] ) { i; continue; } int hi hexval(buf[i]), lo hexval(buf[i 1]); if (hi 0 || lo 0) break; out[o] (uint8_t)((hi 4) | lo); i 2; } n (int)write(g_uart, out, o); } else { n (int)write(g_uart, buf, len); }空格可跳便于手贴FE 05 90 21 00 00 02 FF。奇数个十六进制字符最后那半个丢掉——这是刻意的不要静默补 0。读侧 hex 模式用%02X拼不要napi_create_string_utf8直接塞二进制FE后面的字节经常不是合法 UTF-8。9. USB 口、供电、TX/RX模组上的 Micro-USB / Type-C原理图经常只接 VBUS 和 GND5 V 转 3.3 V 给芯片。电脑插上去设备管理器不会出现 COM 口。这不是驱动没装。排针VCC、GND、TX、RX 四根TX 接 SoC RXRX 接 SoC TX。接成 TX-TX两边都听不见。5 V 和 3.3 V 别接反。UART 电平是 3.3 V。有的模组标 5 V 供电、IO 仍是 3.3 V以丝印为准。模组上电会从 UART 吐一串启动信息。应用如果一打开就发配置帧可能撞上这串垃圾应答错位。uartOpen里的tcflush(TCIOFLUSH)和写前的TCIFLUSH就是为这个。10. 和同排针其它模组的关系模组tty波特这一侧在干什么GPSttyS79600收 NMEABLE 透传ttyS7115200对手机 GATTLoRattyS79600对另一颗 LoRaZigbeettyS7115200对另一颗 Zigbee六轴ttyS79600收 0x55 帧语音ttyS7115200收 ASR 帧RS485常见 ttyS8115200收发器不是 uart7应用里设备框能改。插错排针、选错 ttywrite仍然成功——成功的是另一颗 UART 控制器。Zigbee 页如果默认 ttyS7 没回FE先改 ttyS3 / ttyS8 试不要先改内核。全局一个g_uart。打开 Zigbee 页等于关掉六轴页的 fd。这是 NAPI 实现的限制不是硬件限制。11. 我踩过的单模块当回环。发 hello连续读空。当时把 termios、DMA、权限全查了一遍。后来拿第二颗模组第一秒就通。单模块只验配置帧。USB 当数据口。插电脑没有 COM以为模组坏了。量排针 TX上电有波形UART 是好的。9600。手顺从 GPS 页抄过来。内核 rx 在涨全是错位字节拼不出FE。改回 115200取 ID 立刻回。select。和第 47 章同一根控制器。cat看得到应用看不到。改poll。CRTSCTS。抄了某份 8250 示例。CTS 悬空write卡住。关硬件流控。占用 ttyS2。应用误填/dev/ttyS2调试窗口雪花板子还活着。断电1500000 回来。两颗模组信道不同。配置帧能回对发空。先两边都读信道不一致就按说明书拉到同一信道。自动入网的模组靠近上电一次。HAP 打开失败、工具成功。权限。ls -l /dev/ttyS7不是 0666。12. 排障顺序1. ls -l /dev/ttyS7 字符设备0666 2. cat /proc/tty/driver/serial 有 7: 16550A 3. 排针上只留这一颗 UART 模组 4. 115200 hex 发 FE059021000002FF2 秒内有没有 FE 应答 5. 第 4 步空换 ttyS3 / ttyS8换 9600 对比一次查 TX/RX 6. 第 4 步成功、对发失败第二套在不在、角色、信道、距离 7. 工具成功、HAP 失败chmod、32 位 so、是不是勾了十六进制第 4 步切开「UART」和「射频」。这一刀值回半天。路径清单用途路径板级 DTS uart7device/board/rk/rk3568_evb/kernel/rk3568-evb-linux.dts节点/dev/ttyS7内核串口表/proc/tty/driver/serial开机放权device/board/rk/rk3568_evb/board_perm/board-perm.shNAPIentry/src/main/cpp/napi_init.cpplibboard.soArkTSentry/src/main/ets/pages/Zigbee.ets工具/data/local/tmp/uart_tool调试口勿占/dev/ttyS21500000系列第 46 篇 · 芯片瑞芯微 RK3568 · OpenHarmony 4.1API 11 · Linux 5.10

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑