轻AI越影视觉开发板出厂固件开箱_csdn版
轻AI越影视觉开发板出厂固件开箱:显示/触摸/AI检测全链路体验
一、与Hi3519DV500、RK3588怎么选——定位对比
开箱前先回答一个常被问的问题:同为国产视觉AI开发板,这块板子和Hi3519DV500、RK3588(LubanCat5-V2)是什么关系?一句话——不是同档位竞品,是三条不同的产品定位。
-
维度 轻AI越影视觉开发板 Hi3519DV500 RK3588(LubanCat5-V2) 定位 轻智能消费终端(低成本视觉+语音+触控) 超高清智慧视觉SoC(专业IPC/安防) 高性能边缘计算/ARM PC级SBC CPU ARMv7 双核@950MHz ARMv8 双核A55 ARMv8 4×A76+4×A55 八核(NEON) AI算力 1TOPS NPU ~2.5TOPS NPU 6TOPS NPU(INT4~FP16) 内存/存储 128MB DDR3L + 256MB NAND DDR4/LPDDR4/4X接口(GB级)+eMMC LPDDR4X 4~16GB + eMMC 32~128GB 视频能力 4K@20解码 / 6M@30编码 4K@30编解码 8K@60解码 / 8K@30编码 显示输出 SPI小屏DRM(标配2.8寸触控屏,可换) 单路MIPI TX(无HDMI) HDMI2.1×2+MIPI DSI×2,多屏异显 摄像头 2×MIPI CSI 2-Lane(送OS04D10 4MP) MIPI CSI(专业ISP管线) 6×MIPI CSI 无线 WS73星闪扩展板:WiFi+BLE+SLE 三协议 可外接星闪模组或内置(如虹鸥派就内置了) WiFi/BT需mini-PCIe或4G模块 有线 百兆网口 千兆GMAC 千兆自适应 系统/SDK hi_aiot_solution组件化SDK(musl+Linux5.10),出厂六合一demo即跑 海思MPP/SVP专业SDK,ISP工具链重,门槛高 瑞芯微SDK+rknn-toolkit2,生态最成熟 适合场景 AIoT轻终端:视觉门铃/猫眼/陪伴机器人/触控小屏设备 专业安防摄像机、多路高清视频分析 边缘AI盒子、桌面小主机、机器人主控
上手体感差异
- RK3588 是"小电脑":八核+Mali-G610 GPU+6T算力+全接口(HDMI×3/USB3/mini-PCIe),跑桌面系统都够,代价是12V供电+风扇和复杂度;当算力中枢合适,跑轻终端属于杀鸡用牛刀。
- Hi3519DV500 是"专业摄像机芯":ISP画质管线与安防生态是强项,但单VO无HDMI、SDK门槛高,更适合有ISP调优能力的团队做产品。
- 轻AI越影 是"开箱即用的轻智能终端":算力/内存只有前两者的零头,但出厂固件就把"摄像头采集+H.265编码+RTSP+触控UI+BLE配网+AI Agent"六合一跑起来了,还附送了别家没有的星闪WS73三协议——本文接下来的全部内容,都是这盘出厂固件的实测记录。
二、概述
4块板:主板 + WS73扩展板 + OS04D10摄像头 + 2.8寸SPI屏(+线材/亚克力)。
-
部件 规格 主板 A7双核950MHz、128MB DDR3L、256MB NAND、1T NPU、4K@20、6M@30编码 接口:三个Type-C(POWER供电/Debug串口/USB2.0通信兼供电)、两路MIPI CSI 2-Lane(Sensor0背面/Sensor1正面)、40PIN排针、百兆网口、TF卡槽、RTC电池接口、SPI、2×SDIO、2×I2C、1×UART、2路模拟硅麦+喇叭接口+音频回采、复位/升级按键、电源灯、2位DIP拨码(丝印SW1) WS73扩展板 插40PIN排母(不是SDIO专用座!)、板载ES7210 ADC+两路模拟麦+Type-C/UART/按键/LCD FPC座 摄像头 OS04D10 4MP、MIPI 2-Lane、定焦+IRCUT、默认接背面Sensor0,正面Sensor1留给双摄;
上双摄时另一颗接Sensor1,拨码1保持OFF、拨码2拨到ON。ON屏 ×2.8寸方屏SPI;同一接口板兼容2.1寸圆屏/1.28寸双圆屏 -
拨码机制
-
拨码1 拨码2 得到 屏 OFF OFF 场景一:双屏+单摄+WiFi+UART 双屏 OFF ON 场景二:单屏+双摄+WiFi+UART 单屏 ON OFF (官方没列):TF卡+单摄+WiFi+UART 无屏 ON ON 场景三:TF卡+双摄+WiFi+UART 无屏
-
-
硬件连接
-
1.WS73排母对准排针垂直压入 2.屏FPC插扩展板LCD座 3.网线插入网口 4.摄像头FPC插背面Sensor0 5.背面喇叭接线、插tf卡 6.TypeC-DEBUG接调试串口 7.TypeC-POWER接电源 8.拨动拨码开关至ON上电
-
-
三、连接与烧录部署
VMware的安装与环境搭建(略)
1.串口/SSH连接
-
串口连接调试
- 连接:Debug线连接PC(CH343P驱动,设备管理器出COM口)
- 串口配置:波特率115200 8N1无流控 镜像root空密码
-
SSH连接调试:连上串口调整
-
网口直连或者通过交换机连接时
此例使用局域网电脑+交换机的网口
# 1.临时生效(重启会丢) ifconfig eth0 192.168.1.221 netmask 255.255.255.0 up route add default gw 192.168.1.1 # 验证:ifconfig eth0 看 inet addr # 2.持久化(改开机脚本,本镜像就是这么做的) vi /etc/init.d/S80network ipaddr=192.168.1.221 # 这三行改成你的值 gateway=192.168.1.1 netmask=255.255.255.0 autoconf=no ← 关键,关掉DHCP bootp=no # 改完 chmod +x /etc/init.d/S80network保险 # 3.防DHCP兜底抢占(S90ws73_lcd的逻辑:eth0有IP就跳过udhcpc) vi /etc/init.d/S90ws73_lcd /root/set_eth_mac.sh # 固化MAC(否则每次开机随机→DHCP租约漂移) ifconfig eth0 up if ! ifconfig eth0 | grep -q "inet addr"; then # ← 关键判断 /root/eth_dhcp_monitor.sh eth0 & # 只有eth0没IP才起DHCP监控 fi # 4.DNS(S90里已写114.114.114.114+8.8.8.8,确认在) cat /etc/resolv.conf # 5.重启验证 reboot # 起来后 ifconfig eth0 应仍是 192.168.1.221,不再漂移 # ---------- VM侧(可选,仅当VM是NAT模式时需要)---------- # 此场景下板子/PC/VM同处192.168.1.x局域网,VM默认即可直连板子。 # 若VM用NAT模式(VMnet8,IP在别的网段)→ 改桥接模式: # 虚拟机设置 → 网络适配器 → 桥接到物理网卡 # 或VM内加:ip route add 192.168.1.0/24 via <宿主机IP> -
USB拓展坞网口连接时
此例使用自己的电脑+USB拓展坞上的网口
# 拓扑: 板子(192.168.110.221) ─拓展坞网口─ PC(192.168.110.208) └ WLAN(192.168.124.119) ─路由器─ 外网 VM: ens33=192.168.124.220 (VMnet0→WLAN,外网用) ens37=192.168.110.220 (VMnet2→拓展坞网卡,板子用) # 1.VMware(GUI操作,只做一次) # 虚拟网络编辑器(管理员): - VMnet0: 桥接 → Intel Wi-Fi(已有,不动) - 新建 VMnet2: 桥接 → Realtek USB FE Family Controller(拓展坞网卡) # 虚拟机设置 → 添加 → 网络适配器 → 自定义选VMnet2 → VM内出现ens37 # (若用过Windows网桥,ncpa.cpl里删掉,会顶掉VMware桥接) # 2.VM侧(Ubuntu22.04, netplan永久配置) # 文件: /etc/netplan/01-network-manager-all.yaml cat << 'EOF' | sudo tee /etc/netplan/01-network-manager-all.yaml network: version: 2 renderer: networkd ethernets: ens33: dhcp4: false addresses: [192.168.124.220/24] routes: - to: default via: 192.168.124.1 nameservers: addresses: [8.8.8.8, 114.114.114.114] ens37: dhcp4: false addresses: [192.168.110.220/24] EOF sudo netplan apply ip addr # 确认 ens33=.124.220, ens37=.110.220 # 3.板子侧(串口,改S80network持久化) # 先 cat /etc/init.d/S80network 看原脚本写法,本板是变量+ifconfig风格: ipaddr=192.168.110.221 gateway=192.168.110.208 # ← 网关指PC(板子要能回程到VM/PC) netmask=255.255.255.0 autoconf=no bootp=no # 注意: .110网段无DHCP服务器,必须静态;udhcpc拿不到地址。 # 改完reboot生效。 # 4.临时调试用法(板子串口,不写文件) ip link set eth0 up ip addr add 192.168.110.221/24 dev eth0 ip route add default via 192.168.110.208 # 5.验证 # 板子: ping 192.168.110.208 # → PC ping 192.168.110.220 # → VM # VM: ping 192.168.110.221 # → 板子 ssh nancy@192.168.124.220 # PC→VM (走124网段) # 板子上外网: 默认不通(.110无NAT),需要时再在PC上加转发/NAT
-
2.编译烧录
1.环境构建
-
# ============================================================ # 环境:Windows/WSL2 或 VMware VM 编译机 + 轻AI越影视觉开发板 # 覆盖:依赖安装 → 拉源码 → 工具链 → 编译 → 产物校验 → 烧录/热部署 # ============================================================ # 1.系统依赖(Ubuntu 22.04,约1-2GB) export DEBIAN_FRONTEND=noninteractive sudo apt-get update sudo apt-get install -y \ apt-utils make libc6-i386 lib32z1 lib32stdc++6 \ zlib1g-dev liblzo2-dev rename pigz \ libncurses5-dev libncursesw5-dev ncurses-term \ ffmpeg autopoint g++ u-boot-tools texinfo gawk \ libssl-dev openssl bc p7zip-full gperf \ bison flex diffutils git git-lfs openssh-client unzip \ libffi-dev libtool libfreetype6 dos2unix \ uuid-dev pkg-config automake texlive unrar \ vim sudo curl wget po4a fakeroot \ python3-pip cmake ninja-build meson \ libmpc-dev picocom net-tools iputils-ping \ device-tree-compiler mtd-utils \ python3-gi python3-dbus gir1.2-glib-2.0 sudo apt-get clean git lfs install --system # texlive 可去掉;缺包的错往往延迟几十行才爆(openpyxl→mv报错、meson→libdrm失败), # 看日志找第一处 Traceback,别被最后表象带偏 # 2.repo + 拉源码 mkdir -p ~/bin curl -L https://raw.gitcode.com/gitcode-dev/repo/raw/main/repo-py3 -o ~/bin/repo chmod a+x ~/bin/repo pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc && source ~/.bashrc # repo init 卡住时换镜像: # export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo' mkdir -p ~/demb && cd ~/demb repo init -u https://gitcode.com/HiSpark/hi_aiot_solution_manifest.git \ -b main -m chipsets/demb/boards/ev_board.xml -g linux repo sync -c -j8 repo manifest -r -o manifest-pinned.xml # 锁版本留档,复现以这份为准 # 工作树约4.3GB + .repo约2.8GB,预留30GB磁盘 pip3 install -q -i https://repo.huaweicloud.com/repository/pypi/simple \ wheel pycryptodome pyelftools cryptography kconfiglib requests \ openpyxl pdfplumber # 3.交叉工具链(最大坑:.tgz是LFS指针) cd ~/demb/hi_aiot_solution/sdk/demb ls -l prebuilts/gcc-10.3-arm-musl-x86-linux-26.06.1-codesize.tgz file prebuilts/*.tgz # 133字节=ASCII指针;真包≈88MiB(gzip) git lfs install --local git lfs pull --include="prebuilts/*.tgz" ls -lh prebuilts/*.tgz # 应≈88M,file 变 gzip compressed data mkdir -p ~/toolchains tar -xzf prebuilts/gcc-10.3-arm-musl-x86-linux-26.06.1-codesize.tgz -C ~/toolchains # 关键路径: # ~/toolchains/gcc-10.3-arm-musl-x86-linux-26.06.1/arm-v01c02-linux-musleabi-gcc/bin/ # └── arm-v01c02-linux-musleabi-gcc (GCC 10.3.0, musl-1.2.3) # ⚠️ SDK预编译库按musl构建,别用arm-linux-gnueabihf那套glibc工具链,链接必炸
2.编译
-
# PATH三件套缺一不可(非交互ssh尤其):工具链bin + cmake + repo export PATH=$HOME/toolchains/gcc-10.3-arm-musl-x86-linux-26.06.1/arm-v01c02-linux-musleabi-gcc/bin:$HOME/miniconda3/bin:$HOME/bin:$PATH cd ~/demb/hi_aiot_solution # 完整镜像(framework_media,含BSP/内核/rootfs打包): set -o pipefail # 必加!否则 | tee 会把失败退出码吞成0 bash scripts/build.sh build --target demb_ev_board samples framework_media \ 2>&1 | tee ~/demb/build-framework_media.log # 应用级迭代(只编目标二进制,跳过全量)——日常开发用这个: bash scripts/build.sh build --target demb_ev_board references factory_demo/ws73_lcd cd _build && make factory_demo_main # 产物:_build/bin/factory_demo_main # 产物校验 # 完整镜像:_build/install/image/framework_media/(约124MB,ubifs+jffs2+env+uImage) du -sh _build/install/image/framework_media/ sha256sum _build/install/image/framework_media/* > artifacts.sha256 # 留档
3.烧录镜像/部署程序
-
文档 路径 内容 burn.sh使用文档 hi_aiot_solution\sdk\demb\tools\burn\burn.sh使用文档.md(若不在此路径,tools\burn\下找.md)脚本烧录参数、TFTP配置、前置依赖 BurnTool文档 hi_aiot_solution\sdk\demb\docs\zh-CN\tools\BurnTool.mdToolPlatform操作:选芯片→加载 *_burn_table.xml→按分区烧工具包 tools\ToolPlatform\ToolPlatform-CAM-5.7.14-win32-x86_64.zipWindows端烧录工具本体 -
首次烧录整机镜像 → BurnTool(ToolPlatform)
-
日常重复烧录/批量 →
tools/burn/burn.sh -
只改应用代码 → 热部署(不用烧录)
## 1.烧录镜像(换镜像/分区布局时) # 官方三通道: # tools/burn/burn.sh —— 正常态,串口进U-Boot+TFTP拉镜像+按烧录表写NAND # BurnTool(ToolPlatform) —— 砖机/空片救援,串口直打ROM Boot不依赖U-Boot # U-Boot手烧单分区 —— 开发期 tftp xxx.bin → nand write # ⚠️ nand_env.txt是分区唯一事实源(mkenvimage+env2burn.py同源生成); # 分区尺寸按案例变(base=251M rootfs vs ble_wifi=64M),换案例先核对烧录表 # ⚠️ 本板SPI NAND是2K page/128K block,选 *_2k_128k_* 那套,别选4k_256k ## 2.热部署程序 # 传二进制:编译机跑 scp _build/bin/factory_demo_main root@192.168.1.221:/root/factory_demo_main.new # (或 Xftp/拖拽传好后),板端(Xshell)执行: killall factory_demo_main; sleep 3 # SIGTERM停旧进程 chmod +x /root/factory_demo_main.new nohup sh -c "/root/factory_demo_main.new > /root/fd.log 2>&1; echo EXITED rc=\$? >> /root/fd.log" > /dev/null 2>&1 & # ⚠️ 板端注意: # - 停进程用SIGTERM(killall默认),kill -9会弄脏MPP/sensor状态→下次起不来只能reboot # - wrapper写EXITED rc=到日志:rc=139=SIGSEGV,rc=251=初始化失败退出 # - 双镜像切换:/usr/bin/bootsel lcd|tf(刷mtd2+sha校验+reboot约40s) # - mtd2单分区备份/回滚:/root/img/mtdflash /dev/mtd2 /tmp/mtd2.bak
四、出厂功能测试
显示·触摸·影像三链路初步测试
场景:
ws73_lcd(sensor+LCD+RTSP合并案例)| 板端Xshell直跑
- ws73_lcd是sensor+LCD+RTSP合并案例——不插Sensor0,应用VI初始化失败退出→屏亮几秒后灭。触摸独立(i2c-1)不受影响。
- 连接示意图
连接完成后,查看状态
-
LCD(屏亮+DRM节点)
-
ls -l /dev/dri/ # crw------- 1 root root 226,0 card0 ← DRM注册成功 cat /sys/class/drm/*/status # connected ← 面板在线(应用接管后) dmesg | grep -iE "jd9853|panel|drm" # [drm] Initialized jd9853 1.0.0 for spi0.0 # jd9853 spi0.0: JD9853 panel probe done, 240x320 rotation=0 lsmod | grep jd9853 # jd9853 16384 1 驱动在 ps | grep factory # factory_demo_main 驻留=UI在渲染 cat /sys/class/drm/card0-*/modes # 240x320 #2.触摸(event0坐标输出) cat /proc/bus/input/devices # 应见 "hyn_ts" → Handlers=event0 /root/tsread # 无evtest,hexdump不可用,编写程序监测触摸事件 #3.Sensor(摄像头→VI通路) dmesg | grep -iE "sensor_cfg|os04d10" # sensor_cfg,439: ==========sensor0: os04d10========== ps | grep -E "factory|sdk_server" | grep -v grep # 1041 root /root/sdk_server ← MPP UDS守护 # 1063 root /root/factory_demo_main ← 演示应用驻留=VI初始化已过 cat /proc/umap/vi | grep -A3 "pipe status" # pipe_id enable width height int_cnt send_cnt frame_rate # 0 Y 2560 1440 52089 46022 25 # ↑ 真在采数:int_cnt/send_cnt持续增长,25fps netstat -tln | grep 554 # tcp 0 0.0.0.0:554 LISTEN ← RTSP推流端就绪 # PC端VLC拉 rtsp://192.168.1.221:554/livestream/0 出画面=全链最强证据
-
-
触摸(event0坐标输出)
-
cat /proc/bus/input/devices # N: Name="hyn_ts" H: Handlers=event0 ← 触摸注册成功 # B: ABS=6658000 3 ← 带ABS_MT_POSITION_X/Y /root/tsread # evdev监测器(无evtest时自写,源码附后) # 划屏输出:[DOWN] X=120 Y=160 ... [UP] #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <linux/input.h> int main(int argc, char**argv){ const char *dev = argc>1?argv[1]:"/dev/input/event0"; int fd=open(dev,O_RDONLY); if(fd<0){perror(dev);return 1;} struct input_event ev; int x=-1,y=-1; printf("reading %s ... touch the screen (Ctrl-C quit)\n",dev); while(read(fd,&ev,sizeof(ev))==sizeof(ev)){ if(ev.type==EV_ABS){ if(ev.code==ABS_MT_POSITION_X){x=ev.value;printf("X=%d ",x);} else if(ev.code==ABS_MT_POSITION_Y){y=ev.value;printf("Y=%d ",y);} else if(ev.code==ABS_MT_TRACKING_ID&&ev.value<0)printf("[UP]\n"); } else if(ev.type==EV_KEY&&ev.code==BTN_TOUCH) printf("%s ",ev.value?"[DOWN]":"[UP]"); else if(ev.type==EV_SYN)fflush(stdout); } perror("read"); return 2; }板端
hexdump/od读/dev/input/eventN会报Invalid argument——busybox对evdev字符设备不适用。
-
-
Sensor(摄像头→VI通路)
-
dmesg | grep -iE "sensor_cfg|os04d10" # sensor_cfg,439: ==========sensor0: os04d10========== ps | grep -E "factory|sdk_server" | grep -v grep # 1027 /root/sdk_server ← MPP UDS守护 # 1050 /root/factory_demo_main ← 驻留=VI初始化通过 cat /proc/umap/vi | grep -A3 "pipe status" # pipe_id enable width height int_cnt send_cnt frame_rate # 0 Y 2560 1440 33318 33317 30 ← 30fps实采 netstat -tln | grep 554 # tcp 0.0.0.0:554 LISTEN # PC端VLC拉 rtsp://192.168.1.221:554/livestream/0 = 端到端最强证据 ls -l /tmp/osal_uds_server.sock # sdk_server的UDS桥——sock在=应用可调MPP-
# -sensor0 是"选sensor0口"(背面FPC座),不是型号选择; # 型号由mpp配置写死os04d10。双摄要插Sensor1座+拨码2-ON。
-
-
五、Sample实战
1.factory_demo_main
默认就是这个
factory_demo_main(ws73_lcd出厂演示):单进程六合一整机演示——摄像头采集+H.265编码+RTSP点播、SPI屏 LVGL 9页触控UI、BLE手机配网、ZeroClaw AI Agent(NPU检测+拍照技能)、网络自愈(DHCP+NTP)。
2.square_lcd_sample
square_lcd_sample:一个四页 LVGL 演示程序——主屏显示摄像头实时预览,支持触控切换 亮度调节/摄像头控制/倒计时 三个功能页。
1.编译部署
-
#环境准备 (1)开发板(检查即可,不用敲命令) 1.Sensor0摄像头已插(背面FPC触点朝下)——没插=屏亮几秒灭+应用起不来 2.WS73扩展板插在40PIN上、屏FPC插在扩展板LCD座 3.板已刷ws73_lcd镜像、能ssh/串口登录(root@192.168.1.221) 4.factory_demo_main在跑:ps|grep factory;不在先 sh /root/start_ws73_lcd.sh (2) 编译机(一次性) ~/miniconda3/bin/pip install cmake==3.31.10 meson ninja jsonschema jinja2 pyyaml \ -i https://pypi.tuna.tsinghua.edu.cn/simple #1.编译(编译机) cd ~/tmp/hi_aiot_solution export PATH=/home/nancy/miniconda3/bin:$PATH # python3.12+cmake3.31+meson/ninja export PATH=/home/nancy/tools/mtd/sbin:$PATH export PATH=/home/nancy/toolchains/gcc-10.3-arm-musl-x86-linux-26.06.1/arm-v01c02-linux-musleabi-gcc/bin:$PATH bash scripts/build.sh build --target demb_ev_board samples gui/square_lcd_video_ui # 产物:_build/bin/square_lcd_sample #2.部署(编译机→板) cd _build/rootfs/gui_rootfs_tmp/root tar czf /tmp/gui_app.tgz gui scp /tmp/gui_app.tgz root@192.168.1.221:/tmp/ #没密码就设置个密码 # 板端(Xshell): cd /root && tar xzf /tmp/gui_app.tgz # 出/root/gui/square_lcd_sample + param/
2.板端运行(Xshell)
-
# 前置(ws73_lcd镜像启动后都已在位): lsmod | grep -E "jd9853|hynitron" # 驱动在 ps | grep sdk_server # MPP桥在 killall factory_demo_main # 释放DRM master(不杀会冲突) sleep 3 # 等MPP释放完(看ps确认更稳) ps | grep factory | grep -v grep # 无输出=释放完 cd /root/gui && ./square_lcd_sample # 成功标志:日志出现"Press Ctrl+C to quit"且屏显示LVGL界面可触控; # 失败排查:无屏显→查killall是否执行;segmentation fault→查sdk_server。-
若要回到出厂演示
killall square_lcd_sample; /root/factory_demo_main & # 或直接重启
-
3.示意
3.sample_aidetect
sample_aidetect:给一张 YUV 图 + 检测模型,用 NPU 推理出人形/车辆/人脸/宠物/包裹的检测框。
1.编译部署
-
#前提 编译机:同 square_lcd_sample(三行export,已配好不用重弄) 开发板:sdk_server 在跑(ps|grep sdk_server) #1.编译(编译机) cd ~/tmp/hi_aiot_solution export PATH=/home/nancy/miniconda3/bin:$PATH export PATH=/home/nancy/tools/mtd/sbin:$PATH export PATH=/home/nancy/toolchains/gcc-10.3-arm-musl-x86-linux-26.06.1/arm-v01c02-linux-musleabi-gcc/bin:$PATH bash scripts/build.sh build --target demb_ev_board samples ai_component # 产物:_build/bin/sample_aidetect、sample_aivsr # 注意:模型/测试图/musl库不在 _build 里,要从 SDK 源码树拿(见下) #2.部署(编译机→板) # 编译机上组装最小测试集: SDK=~/tmp/hi_aiot_solution/sdk/demb mkdir -p /tmp/ai_test/{soc/libs,out/model/aidetect,samples/mpp/svp/ai_component/aidetect/data} cp _build/bin/sample_aidetect /tmp/ai_test/samples/mpp/svp/ai_component/aidetect/ cp $SDK/samples/mpp/svp/ai_component/aidetect/data/hvf_image_hor_1920x1080.yuv \ /tmp/ai_test/samples/mpp/svp/ai_component/aidetect/data/ cp $SDK/output/mpp/model/aidetect/det_hvf_hor.bin /tmp/ai_test/out/model/aidetect/ cp -rf $SDK/soc/libs/musl /tmp/ai_test/soc/libs/ cd /tmp/ai_test && tar czf /tmp/ai_test.tgz . scp /tmp/ai_test.tgz root@192.168.1.221:/tmp/ # 板端(Xshell): mkdir -p /mnt/test_dir && cd /mnt/test_dir && tar xzf /tmp/ai_test.tgz mkdir -p /run/sdk_server ln -sf /tmp/osal_uds_server.sock /run/sdk_server/osal_uds_server.sock
3.运行测试(板端)
-
ps | grep sdk_server # 确认MPP桥在 killall factory_demo_main; sleep 3 # 释放VB/MMZ ps | grep factory | grep -v grep # 无输出=凉透 #重建运行环境(重启后/tmp保留但/run是tmpfs会丢、env会丢) mkdir -p /run/sdk_server ln -sf /tmp/osal_uds_server.sock /run/sdk_server/osal_uds_server.sock export TEST_PATH=/mnt/test_dir export LD_LIBRARY_PATH=$TEST_PATH/soc/libs/musl:$LD_LIBRARY_PATH # 运行测试 cd $TEST_PATH/samples/mpp/svp/ai_component/aidetect ./sample_aidetect -m /mnt/test_dir/out/model/aidetect/det_hvf_hor.bin \ -i ./data/hvf_image_hor_1920x1080.yuv -s 1920x1080 -v # 成功标志:尾部打印 ==== Frame ==== + type:x conf:0.xx [x,y,w,h] 检测框 # 实测输出:type:1 conf:0.85(人形检测框) -
4.sample_single_sensor
sample_single_sensor:单摄像头整机通路——OS04D10采集→VPSS→H.265编码→RTSP推流 + 屏上240×320实时预览,可选录像到/mnt。
1.编译部署
-
# 编译(编译机)——注意带 -DSENSOR=os04d10 cd ~/tmp/hi_aiot_solution export PATH=/home/nancy/miniconda3/bin:$PATH export PATH=/home/nancy/tools/mtd/sbin:$PATH export PATH=/home/nancy/toolchains/gcc-10.3-arm-musl-x86-linux-26.06.1/arm-v01c02-linux-musleabi-gcc/bin:$PATH bash scripts/build.sh build --target demb_ev_board samples sensor/single -DSENSOR=os04d10 # 产物:_build/bin/sample_single_sensor # 部署(编译机→板) cd _build/rootfs/rootfs_tmp_single/root tar czf /tmp/single_app.tgz single scp /tmp/single_app.tgz root@192.168.1.221:/tmp/ # 板端(Xshell): cd /root && tar xzf /tmp/single_app.tgz # 出 /root/single/sample_single_sensor + param/
2.板端运行
-
killall factory_demo_main; sleep 3 # 同一套:释放VB/MMZ+DRM ps | grep factory | grep -v grep # 无输出=凉透 cd /root/single ./sample_single_sensor -t 0 -n # -t0持续运行 -n不录像(只预览+推流) # 成功标志: # os04d10 24Mclk 4M30fps Init OK # [lcd] 240x320 via DRM # [rtsp] RTSP server ready on port 554, stream=livestream/0 # 屏上显示实时预览画面 # Ctrl+C 退出 → "os04d10 Sensor + LCD success!" -
也可调参
-
命令 效果 ./sample_single_sensor -t 30录30秒H.265到 /mnt/os04d10_*.h265./sample_single_sensor -b 6000 -t 30自定义码率6Mbps ./sample_single_sensor默认录10秒
-
3.RTSP验证(PC端)
-
VLC → 打开网络串流 → rtsp://192.168.1.221:554/livestream/0 出画面 = 采集→编码→推流全链通
与square_lcd_sample的区别
-
square_lcd:VI→VPSS→RGB565→DRM(屏显UI,无RTSP编码路) single_sensor:VI→VPSS双通道→VENC(H.265)→RTSP + 屏预览(录像可选) -
六、语音AI助手
目标:在官方factory_demo/ws73_lcd出厂六合一演示(相机/NPU/RTSP/BLE/WiFi配网/LVGL UI)基础上添加"本地唤醒+云端语音识别+LLM对话+板端技能"的一个助手
-
# 语音AI助手能力(均已实测验证) 【语音输入】 - "你好芯宝"离线唤醒(KWS),唤醒后自动进入15秒命令窗口 - 唤醒后自由说话:自动断句→云端ASR转文字→进输入框 - "语音"按钮按住说话:VAD静音1.2s自动结束(15秒上限) - "直发"开关:识别完直接发给agent,无需审稿 【对话与执行】 - 自由对话:DeepSeek多轮上下文(agent -m + session文件) - 拍照:语音/文字触发,相机实时拍照回显在聊天气泡 - 人员检测:NPU目标检测,语音"打开空调"(KWS命令词)或文字"有没有人"均可触发 - 拼音输入:26键全拼输入法,屏幕键盘+候选条 - 新对话:一键清上下文重来
0.前置条件
-
项 要求 编译环境 SDK hi_aiot_solution可正常编译,PATH含miniconda3/bin+arm-v01c02-linux-musleabi-gcc工具链板子 能跑 factory_demo(相机/显示屏初始化正常),WiFi已配网可上外网火山引擎 控制台开通**“流式语音识别模型2.0”**(有免费额度),API密钥管理里新建一条API Key(不要用"默认体验中心使用"那条) LLM zeroclaw已配好(本例DeepSeek), agent -m能对话-
火山引擎豆包语音开通流式语音识别2.0步骤
-
-
depseek获取API Key:进入deepseek官网———>充值——->获取API Key
-
1.总体架构
-
┌────────────────────────── LVGL 主线程(UI)──────────────────────────┐ │ AI助手页:聊天气泡/26键拼音IME/"语音"按钮/"直发"开关/照片气泡 │ └──────────────▲──────────────────────────────┬───────────────────────┘ │ refresh_ui │ publish ┌──────────────┴──────────── EventHub(SS_EVTHUB)─────────────────────┐ │ EVENT_CMD_ZC_CHAT_SEND EVENT_VOICE_TRIGGER │ │ EVENT_VOICE_ASR_STATE EVENT_VOICE_ASR_TEXT EVENT_ZC_CHAT_DONE │ └──▲───────────────▲───────────────────▲───────────────────▲──────────┘ │ │ │ │ ┌──┴───────┐ ┌─────┴──────┐ ┌──────────┴────────┐ ┌────────┴─────────┐ │ zeroclaw │ │ KWS线程 │ │ 录音+VAD(ACAP回调)│ │ ASR worker线程 │ │ worker │ │(offline_ │ │ │ │ libcurl WS │ │ │ │ voice) │ │ │ │ →火山SAU │ └──┬───────┘ └─────▲──────┘ └──────────▲────────┘ └────────┬─────────┘ │ posix_spawn │ ov_feed_pcm │ 同一批PCM帧 │ HTTPS/WS ▼ │ │ ▼ zeroclaw agent -m └────────── AI dev0(inner ADC 48k)─→AENC hdl0─→ACAP tap --session-state-file (媒体管线已有音频通路,直接旁路取帧) │ ▼ DeepSeek LLM → 文本回复/skill触发(拍照·检测人·系统状态) -
关键设计
新app还是改factory_demo 改factory_demo 相机/NPU/网络/UI全现成,重复造轮子没意义 LLM接入 posix_spawn("zeroclaw agent -m ...")每轮一发不引入长驻LLM进程; --session-state-file保上下文音频源 复用ACAP tap( acap_reg_cb+aenc_start)媒体管线已占AI dev0,硬开第二路会冲突;tap白捡16kHz单声道PCM KWS模式 offline_voice EXTERNAL-PCM模式 组件内部AFE旁路, ov_feed_pcm直接喂帧,零硬件依赖ASR方案 按住说话→批量WS识别(火山SAU) 比流式简单可靠;16k/16bit/mono正好是tap输出格式 线程模型 每环节独立线程+EventHub总线 KWS回调/录音/ASR网络互不阻塞,LVGL只消费事件 UI安全 语音线程绝不直接碰LVGL 一律publish→主线程route_event→UI更新 -
事件清单
事件 生产者→消费者 用途 EVENT_CMD_ZC_CHAT_SENDUI→main 发送聊天(按钮/预设/语音统一入口) EVENT_ZC_CHAT_DONEzeroclaw worker→main LLM回复就绪 EVENT_VOICE_TRIGGERKWS回调→main 唤醒/命令词→映射prompt走发送链 EVENT_VOICE_ASR_STATE录音状态机→main rec/asr/idle同步按钮配色 EVENT_VOICE_ASR_TEXTASR worker→main 识别文本回填输入框(或直发) 注意:事件必须
SS_EVTHUB_Register+Subscribe双侧都加,只定义ID会被静默丢弃。
2.构建流程
-
#1.构建链路 app.defconfig ──Kconfig──▶ .config ──config.cmake生成──▶ .config.cmake │ ▼ ┌── ExternalProject(openssl/curl/lvgl/cjson…) build.sh build ────▶├── components静态库(media/hiai/hichannel…) │ └── apps可执行 → _build/bin/factory_demo_main ▼ 工具链arm-v01c02-linux-musleabi-gcc(C11)必须在PATH #2.配置开关 # app.defconfig增量 CONFIG_HIAI_OFFLINE_VOICE=y # KWS组件(unisound适配器+libkws.a随编译) CONFIG_OS_CURL=y # libcurl 8.9.1(≥7.86才有WS API) CONFIG_OS_OPENSSL=y # curl的TLS依赖(自动select 1.1.1w) #3.常用命令 # 编译机(~/tmp/hi_aiot_solution,PATH需含miniconda3/bin+工具链bin) bash scripts/build.sh build --target demb_ev_board references factory_demo/ws73_lcd # 只编目标(跳过ExternalProject全量,micropython链接失败是既有噪声可无视) cd _build && make factory_demo_main
3.功能适配流程
-
功能适配流程 ├─ 3.1 AI对话页(第一阶段) │ ├─ 页面:page_t加PAGE_AI_CHAT,`navigate_to_page()`管生命周期 │ ├─ UI:ui_module.c气泡列表+输入行+LVGL `lv_ime_pinyin`(换自建全简体词库防豆腐块) │ ├─ LLM:zeroclaw_module.c的`chat_send`→pthread→`posix_spawn agent -m`→截stdout→`EVENT_ZC_CHAT_DONE` │ ├─ 接线:main.c事件Register/Subscribe/route三点 │ └─ 照片:agent回复带`[PHOTO:/path]`标记→UI用`tjpgd`解码成图片气泡 │ ├─ 3.2 KWS离线唤醒(第二阶段) │ ├─ 开关:defconfig开CONFIG_HIAI_OFFLINE_VOICE→liboffline_voice.a+unisound厂商库 │ ├─ 引擎:voice_module.c里`ov_create(ext_audio_fmt={16000,1,16})`(外部喂帧)+`ov_start(callback)` │ ├─ PCM:`acap_reg_cb(0)`+`aenc_start(0)`起feed线程→回调拿virt_addr[0]单声道→`ov_feed_pcm()` │ ├─ 事件:`OV_EVENT_WAKEUP`→`EVENT_VOICE_TRIGGER`→`chat_do_send("你好")`;`OV_EVENT_COMMAND`→`g_voice_cmd_map[]`映射intent→prompt │ └─ 可逆:CMake用`if(TARGET offline_voice)`包住源文件和链接,组件没开应用照常编译 │ └─ 3.3 云端ASR语音输入(第三阶段) ├─ 开关:defconfig开CONFIG_OS_CURL/CONFIG_OS_OPENSSL(首编多编openssl+curl几分钟) ├─ 录音:输入行"语音"按钮→`voice_rec_start()`→ACAP回调里同一批PCM顺带写进480KB bss缓冲 ├─ VAD:帧均值振幅>55记voiced;voiced后连续1.2s静音→自动`voice_rec_end`(15s上限兜底) ├─ 识别:ASR worker线程起一条WS连接→config帧→分块audio帧→end帧→收cJSON结果 ├─ 回填:`EVENT_VOICE_ASR_TEXT`→主线程:"直发"开→`chat_do_send`;关→填输入框+弹键盘审稿 └─ 凭证:板端/root/voice_asr.conf(token/url/res_id),不进代码仓
4.部署与验证
-
1.部署
-
# 传二进制:编译机跑 scp _build/bin/factory_demo_main root@192.168.1.221:/root/factory_demo_main.new # (或Xftp/拖拽),板端(Xshell)执行: killall factory_demo_main.new; sleep 3 # 运行中的文件会text busy,先停(SIGTERM) chmod +x /root/factory_demo_main.new # 起进程:wrapper把退出码写进日志(rc=139=SIGSEGV) nohup sh -c \ "/root/factory_demo_main.new > /root/fd.log 2>&1; echo EXITED rc=\$? >> /root/fd.log" \ > /dev/null 2>&1 &- 注意:停进程一律SIGTERM——
kill -9会把MPP/sensor状态弄脏,下次起不来只能reboot。
- 注意:停进程一律SIGTERM——
-
-
2.日志验证
-
验什么 怎么验 ASR凭证/连通性 本机curl模拟WS握手看101 vs 403,不用等板子测: curl -N -H "Upgrade: websocket" -H "Sec-WebSocket-Version:13" -H "Sec-WebSocket-Key:x3JJHMbDL1EzLkh9GBhXDw==" -H "X-Api-Key: <key>" -H "X-Api-Resource-Id: volc.seedasr.sauc.duration" -H "X-Api-Sequence: -1" https://openspeech.bytedance.com/api/v3/sauc/bigmodel_async录音能量 rec dbg: mean=N voiced=Xms sil=Yms每0.5s一条KWS状态 日志看 Domain: wakeup/ivm切换、[voice] wakeup/cmd/sleep进程死法 EXITED rc=+dmesg的MMB LEAK(异常死必留痕) -
成功标志:日志出现
-
[voice] rec start → rec dbg: mean=172 ... → rec end: NNN samples, ASR started < HTTP/1.1 101 Switching Protocols [asr] sent 77824 bytes, waiting result [asr] text='今天周几?'- 屏幕侧:识别文本进输入框(直发模式直接成用户气泡)→ agent回复。
-
-
-
3.上机验证
-
5.踩坑表
-
坑 一句话教训 printf日志"丢失" nohup重定向后stdout全缓冲——main()开头setvbuf(stdout,NULL,_IOLBF,0)VAD不自动停 实测电平定阈值:这麦底噪15、说话100,拍脑袋写500永远判无声 中文豆腐块 字体是裁剪子集,新文案/符号(连"…")都可能缺字形——F12直接上全GB2312 curl请求没发出就失败 curl_slist_append判空守卫会把首个append也挡住,hdrs永远NULLASR 403 "默认体验中心"key≠业务key要自建; res_id必须匹配开通的模型版本(seedasr=2.0/bigasr=1.0)token进日志 CURLOPT_VERBOSE打全量请求头,调通就关KWS词表改不动 语法编译进libkws.a的FST,定制词要找云知声重训;intent→action映射在自己代码里随便改 UniKws免费版 ~1小时后 out of call limit刷屏停识别,重启进程恢复;商用要授权屏幕黑 多半不是显示bug,是进程死了——先查 ps和EXITED rc=
七、星闪WS73互连测试
开发板板:ws73_lcd案例镜像
Hi3519DV500板:ws73四ko已加载、
test_ws73_sle就位目标:验证两板WS73能否互连,顺带测SLE/BLE/WiFi三协议吞吐
1.环境
-
项 开发板板 Hi3519板DV500 WS73 ExtBoard插SDIO1槽 USB接ws73e模组 工具链 arm-v01c02-linux-musleabi aarch64-v01c01-linux-gnu -
-
查看开发板侧WS73上电状态
-
cat /proc/mci/mci_info # 看MCI1状态——扩展板插好应显示: # MCI1: pluged_connected / Type: SDIO card / 50MHz sh /root/start_wifi.sh # 加载plat_soc/wifi_soc/sle_soc/ble_soc+wpa_supplicant lsmod | grep soc # 四ko应该都在 ip -o link show wlan0 # 应出现wlan0- 若
MCI1: pluged_init_failed→扩展板没插到位,插好后重跑脚本
- 若
-
2.编译测试:
-
移植测试程序到开发板,编译
- 软件环境参考了鸿鸥派hi3519DV500的构建,测试例程在默认基础上调优
-
测试
-
WiFi互测
-
# Hi3519板做AP LD_LIBRARY_PATH=/usr/lib hostapd -B /etc/wireless/hostapd.conf ifconfig wlan0 192.168.49.1 udhcpd -S /etc/wireless/udhcpd.conf & # 开发板连AP(wpa_cli在/ws73/不在PATH!) # —— 另开一个Xshell窗口登开发板板,执行: /ws73/wpa_cli -i wlan0 add_network /ws73/wpa_cli -i wlan0 set_network 1 ssid "HongOU_PI_AP" /ws73/wpa_cli -i wlan0 set_network 1 psk "12345678" /ws73/wpa_cli -i wlan0 select_network 1 sleep 4; ip -o -4 addr show wlan0 # 应拿到192.168.49.x # Hi3519板端窗口1(接收端): /root/tcpperf server -p 5201 -t 12 # 开发板板端窗口2(发送端,先确认server已listen再敲): /root/tcpperf client -a 192.168.49.1 -p 5201 -t 10 # 实测:tx 47.88 Mbps / rx 47.70 Mbps(2.4G HT20@2437MHz)- ps:也可使用iperf3互测
-
-
SLE互测
-
# Hi3519板端窗口1(接收端): /root/test_ws73_sle server -t 45 # 开发板板端窗口2(发送端): /root/test_ws73_sle client -t 15 -n test_ws73_sle -
调参
-
参数组 实测 默认(200B/2ms/conn16slot) avg 16.80/peak 19.73 KB/s 调参( -l 1000 -i 1 -c 8 -M 12)avg 58.88/peak 97.66 KB/s,server稳态68-71KB/s
-
-
-
BLE互测
-
# Hi3519板端窗口1(接收端): /root/test_ws73_ble_hwbt server -t 45 # 开发板板端窗口2(发送端): /root/test_ws73_ble_hwbt client -t 15- 协商MTU 517/PHY 2M/interval 15ms;client TX~98KB/s(队列写入速率),server RX~29-31KB/s(空口实际送达),fail=0。TX/RX不对称是统计口径差异,RX才是空口真实吞吐。
-
-
-
数据汇总表
-
协议 方向 吞吐 说明 WiFi 开发板→Hi3519 47.88 Mbps tcpperf双端互证 WiFi Hi3519→开发板 39.46 Mbps 反向 SLE 开发板→Hi3519 16.80→58.88/97.66 KB/s 默认→调参(conn8slot/1KB包/MCS12) BLE 开发板→Hi3519 ~29-31 KB/s(空口) MTU517/2M PHY
-
八、外设驱动解析
1.hynitron触摸驱动(CST3530,I2C接口)
给开发板2.8寸屏配的海栎创CST3530电容触摸,走"改DTS → 编ko → insmod → probe → input节点 → 用户态坐标"完整链路。
0.硬件链路
-
CST3530触摸IC → 排线 → WS73扩展板 → 40PIN → 主板 i2c-1(0x5A) + 中断GPIO0_0 + 复位GPIO4_2
1.驱动
-
源码:components/adapter/drivers/touch/hynitron/(SDK自带,hyn_core.c+各芯片适配) 产物:/drv/hynitron_touch.ko(约430KB) 匹配:compatible="hyn,66xx" —— readme.txt写明 66xx 兼容 cst35xx 系列
2.DTS节点 apps/demb_ev_board/bsp/dts/panel_config.dtsi(由ws73_lcd_dts.patch在编译期写入),挂在i2c_bus1 下
-
hynitron: hynitron@5a { compatible = "hyn,66xx"; // CST3530 走 66xx 适配 reg = <0x5a>; // I2C 地址 0x5A interrupt-parent = <&gpio_chip0>; interrupts = <0 IRQ_TYPE_EDGE_FALLING>;// 中断脚 GPIO0_0 下降沿 irq-gpios = <&gpio_chip0 0 0>; reset-gpios = <&gpio_chip4 2 0>; // 复位脚 GPIO4_2 max-touch-number = <5>; // 五点触控 display-coords = <0 0 240 320>; // 屏分辨率 pos-swap = <0>; posx-reverse = <1>; // 面板贴装方向→坐标翻转 posy-reverse = <1>; };
3.编译 + 加载
-
# 编译机(ws73_lcd案例内随系统一起编,ko落在镜像/drv/) bash scripts/build.sh build --target demb_ev_board references factory_demo/ws73_lcd # 板端手动加载(开机脚本 start_ws73_lcd.sh 已自动做这一步): insmod /drv/hynitron_touch.ko
4.验证
-
# 1.probe日志——驱动认到芯片没 dmesg | grep -iE "hyn|cst" # [HYN]i2c addr:0x5a read_part_no:0xcaca220e # chip cst3530 match fw success # input: hyn_ts as /devices/.../input0 ← 出现=驱动跑通 # 2.I2C从设备被绑定 i2cdetect -y 1 # 0x5a 位置显示 "UU"(被驱动占用,不是裸地址) cd /sys/devices/platform/soc/soc:amba/11061000.i2c/i2c-1/1-005a/ cat hyntpfwver # 读固件版本——证明I2C双向通信正常 # 3.input节点注册 cat /proc/bus/input/devices # N: Name="hyn_ts" H: Handlers=event0 ls -l /dev/input/event0 # 13:64 # 4.用户态坐标——最终判据 /root/tsread # 自写evdev读取器(hexdump/od读evdev会Invalid argument) # 划屏输出:[DOWN] X=120 Y=160 ... [UP] ← 出坐标=全链通
2.JD9853 SPI屏驱动
0.硬件链路
-
JD9853 驱动IC → 屏FPC → WS73扩展板LCD座 → 40PIN → 主板SPI0 数据线:SPI0_SDO/SDI/CLK/CSN(50MHz,DMA加速) 控制脚:DC=GPIO0_1 / TE=GPIO3_5 / RST=GPIO7_5 / 背光PWM=GPIO7_0
1.驱动
-
源码:components/adapter/drivers/lcd/jd9853/jd9853.c 产物:/drv/jd9853.ko(约16KB) modalias:spi:jd9853-240x320(SPI总线自动匹配)
2.DTS节点 bsp/dts/panel_config.dtsi
-
backlight: backlight { compatible = "pwm-backlight"; pwms = <&pwm1 7 100000>; // PWM1通道7=GPIO7_0,周期100us }; &spi_bus0 { dmas = <&edmacv310_0 7 7>, <&edmacv310_0 6 6>; // SPI-DMA加速 dma-names = "tx","rx"; jd9853:ips@0 { compatible = "fitipower,jd9853-240x320"; // 型号+分辨率写进modalias reg = <0>; // CS0 spi-max-frequency = <50000000>; // 50MHz pl022,com-mode = <2>; // pl022控制器参数 pl022,tx-level-trig = <3>; pl022,rx-level-trig = <3>; rotation = <0>; // 0°(竖屏240×320) dc-gpios = <&gpio_chip0 1 0>; // 命令/数据脚 GPIO0_1 te-gpios = <&gpio_chip3 5 0>; // TE撕屏同步 GPIO3_5 reset-gpios = <&gpio_chip7 5 0>; // 复位 GPIO7_5 backlight = <&backlight>; // 挂上PWM背光 status = "okay"; }; };关于移植:换屏只改
compatible(驱动里对应不同初始化序列)、rotation、dc/te/reset三根 GPIO;spi-max-frequency按屏手册降速。
3.编译 + 加载
-
# 编译机(ws73_lcd案例随系统编出): bash scripts/build.sh build --target demb_ev_board references factory_demo/ws73_lcd # 板端手动加载(开机脚本 start_ws73_lcd.sh 已自动): insmod /drv/lcd_panel.ko
4.验证
-
# 1.查看驱动模块是否加载 lsmod | grep jd9853 # 能出 "jd9853 16384 0"——虽然文件叫 lcd_panel.ko # 模块名≠文件名:ko内部注册的模块名是 jd9853 # 2.probe日志——SPI认到屏+初始化序列发完 dmesg | grep -iE "jd9853|drm" # [drm] Initialized jd9853 1.0.0 for spi0.0 # jd9853 spi0.0: JD9853 panel probe done, 240x320 rotation=0 ← 关键行 # 3.DRM设备注册(Linux显示子系统接管) ls -l /dev/dri/ # card0(主显示设备) cat /sys/class/drm/card0-*/status # connected cat /sys/class/drm/card0-*/modes # 240x320 # 4.modalias匹配(SPI自动绑定证明) cat /sys/bus/spi/devices/spi0.0/modalias # spi:jd9853-240x320 ls -l /sys/bus/spi/devices/spi0.0/driver # → drivers/jd9853 # 实显+背光——最终判据 # 屏显示LVGL界面 = 显示链路全通 # square_lcd_sample的Light页划亮度 → 背光PWM链路通 -
关于背光
-
#demo运行时 ls /sys/class/backlight/backlight/ # brightness actual_brightness max_brightness(=100) bl_power ... echo 100 > /sys/class/backlight/backlight/brightness # 最亮 echo 50 > /sys/class/backlight/backlight/brightness # 半亮 echo 0 > /sys/class/backlight/backlight/brightness # 灭背光(屏还显示,只是没光) cat /sys/class/backlight/backlight/actual_brightness # 回读确认生效
-
对于触摸驱动
-
hynitron:I2C-1(0x5A) + GPIO0_0中断 + GPIO4_2复位 → /dev/input/event0 jd9853: SPI0(CS0,50MHz) + GPIO0_1 DC + GPIO7_5复位 + PWM背光 → /dev/dri/card0
九、外设扩展实战
1.HC-05
1.接线
-
HC-05 引脚 J3 pin SoC GPIO function 方向/说明 VCC 2或4 — — 5V0供电 GND 6或其他(略) — — 共地必须 TXD 10 GPIO0_6 UART1_RXD(func5)模组发→板收 RXD 8 GPIO0_7 UART1_TXD(func5)板发→模组收 EN/STATE/KEY 不接 — — 保留脚,悬空即可 - 上电红灯快闪=正常(等待配对)
2.板上配置
-
方式一:快速配置验证
bspmm 0x11130030 0x1205 # GPIO0_6 → UART1_RXD (pin10) bspmm 0x11130034 0x1205 # GPIO0_7 → UART1_TXD (pin8) stty -F /dev/ttyAMA1 9600 raw -echo -
方式二:改设备树配置验证
#1. 改dtsi pin-cfg@26 { pin = <26>; /* 引脚号: GPIO0_7 -> J3 pin8 UART1_TXD */ gpio-num = "GPIO0_7"; /* GPIO 号 */ function = "UART1_TXD"; /* 功能名 (func5) */ pull = "pull-down"; /* 上下拉: pull-up / pull-down / none */ drive = "I02_level4"; /* 驱动档位 */ slew = "fast"; /* 边沿: fast / slow */ input-enable; /* 输入使能 */ }; pin-cfg@27 { pin = <27>; /* 引脚号: GPIO0_6 -> J3 pin10 UART1_RXD */ gpio-num = "GPIO0_6"; /* GPIO 号 */ function = "UART1_RXD"; /* 功能名 (func5) */ pull = "pull-down"; /* 上下拉: pull-up / pull-down / none */ drive = "I02_level4"; /* 驱动档位 */ slew = "fast"; /* 边沿: fast / slow */ input-enable; /* 输入使能 */ }; #2.编译(以下在编译机 nancy@192.168.1.220 上执行) S=~/tmp/hi_aiot_solution; B=$S/apps/demb_ev_board/bsp/dts A=$S/apps/demb_ev_board/references/factory_demo/ws73_lcd/dts STAGE=/tmp/dts_stage; rm -rf $STAGE && mkdir -p $STAGE for f in demb-flash.dts demb-open.dtsi \ demb_family_usb.dtsi demb.dts panel_config.dtsi; do cp $B/$f $STAGE/ done cp $A/board_io_config.dtsi $STAGE/ # 案例覆盖赢bsp同名 INC=$S/sdk/demb/third_party/linux/linux-5.10.y/include gcc -E -nostdinc -I$STAGE -I$INC -undef -D__DTS__ \ -x assembler-with-cpp -o /tmp/x.tmp $STAGE/demb-flash.dts dtc -I dts -i $STAGE -i $INC -O dtb \ -o /tmp/demb-flash.dtb /tmp/x.tmp # warning刷屏正常;必须带-I dts mkdir -p /tmp/fit cp $S/sdk/demb/third_party/linux/linux-5.10.y/arch/arm/boot/zImage /tmp/fit/ cp /tmp/demb-flash.dtb /tmp/fit/devicetree.dtb cp $S/sdk/demb/boards/dmeb/tools/pc/image_tree_source/linux_image.its /tmp/fit/ cd /tmp/fit && mkimage -f linux_image.its uImage sha256sum uImage # 本次: 5efc91fd... #3.传板+烧录+校验(先把编译机的 /tmp/fit/uImage 传到板端 /tmp/uImage_uart1: # 编译机跑 scp /tmp/fit/uImage root@192.168.1.221:/tmp/uImage_uart1,或Xftp拖拽) # —— 以下在板端(Xshell)执行: sha256sum /tmp/uImage_uart1 # 必须=编译机sha cd /root/img && ./mtdflash /dev/mtd2 /tmp/uImage_uart1 # 烧mtd2(命令不能以 / 开头!) dd if=/dev/mtdblock2 bs=1M count=4 2>/dev/null | head -c $(stat -c%s /tmp/uImage_uart1) | sha256sum # 必须=5efc91fd...,不一致别重启 cp /tmp/uImage_uart1 /root/img/uImage_uart1 && sync # 留档(/tmp 重启会丢) #4.重启验证(同板端) reboot # 等~40s bspmd.l 0x11130030 0x18 # 两个寄存器应=0x1205,固化成功的判据 lsmod | grep board_io # ko 在
3.AT验证
-
cat /dev/ttyAMA1 > /tmp/rx.log & # 后台接收 echo -ne "AT\r\n" > /dev/ttyAMA1; sleep 1 cat /tmp/rx.log # 应见 OK echo -ne "AT+NAME?\r\n" > /dev/ttyAMA1; sleep 1; cat /tmp/rx.log # +NAME:HC-05 echo -ne "AT+ADDR?\r\n" > /dev/ttyAMA1; sleep 1; cat /tmp/rx.log # 蓝牙MAC kill %1 #改蓝牙名/波特率 echo -ne "AT+NAME=YueYing_BT\r\n" > /dev/ttyAMA1 # 改名 echo -ne "AT+UART=115200,0,0\r\n" > /dev/ttyAMA1 # 改波特率(改完stty要跟着换) # AT+PSWD=1234 改配对码;AT+ROLE=1 改主机
4.手机透传测试
-
手机设置→蓝牙→搜
HC-05→配对,PIN 输1234 -
装「蓝牙串口助手/Serial Bluetooth Terminal」类 app,连 HC-05
-
板上
-
cat /dev/ttyAMA1 & # 收手机发的 # 手机端发 "hello" → 串口终端应打印 hello echo -ne "board hi\r\n" > /dev/ttyAMA1 # 手机端应收 "board hi"
-
5.切换/回滚:与tf卡的配置一致,再加一个
-
bootsel lcd # 出厂屏版 bootsel tf # TF卡版 bootsel uart1 # LCD+UART1 版(当前)
2.ST7789V屏适配轻AI越影视觉开发板全流程
目标:在
hi_aiot_solutionSDK的轻AI越影视觉开发板上接入一块通用8pin 1.14"ST7789V SPI TFT模组(135×240,无触摸、无TE引脚),复用已有st7789vDRM驱动与panelsample框架点亮。
- 成果:板端实测通过——
st7789vprobe成功,/dev/dri/card0注册135x240模式,自写DRM测试程序输出彩条+边框画面,SPI传输统计与帧数据量吻合。已知参数
项 值 IC ST7789V(复用 components/adapter/drivers/lcd/st7789v/)分辨率 135×240 尺寸/形状 1.14"方屏 案例名 st7789_135_240_114_50M(命名规则<ic>_<w>_<h>_<尺寸×10>_50M)案例基底 st7789_240_320_28_50MSPI SPI0 @50MHz 触摸 无(模组无触摸,pin_mux/DTS不埋触摸节点) TE 不接(模组没引出TE脚,dts里删 te-gpios)
1.软硬件环境
-
项 值 备注 主控 轻AI越影视觉开发板 NAND 512MB版, mtdparts=512K(boot),512K(env),4M(kernel),198M(rootfs)内核 Linux 5.10.221 FIT打包kernel+dtb,刷mtd2 SDK hi_aiot_solution(WS73场景app框架)编译入口 scripts/build.sh交叉编译链 arm-linux-musleabi-gcc(gcc 10.3,~/toolchains/gcc-10.3-arm-musl-x86-linux-26.06.1)环境初始化 source ~/demb_env.sh显示模组 1.14"ST7789V SPI TFT,8pin排针小板 135×240可视,GRAM 240×320,无触摸无TE 屏驱动 components/adapter/drivers/lcd/st7789v/st7789.c现成DRM驱动,变体用 patches/差分应用框架 LVGL 9.4.0+ lv_linux_drm后端sample源码 source/main.c调试工具 串口COM21@115200、SSH、 in.tftpd(192.168.1.220)、U-Boot TFTP救砖流程见《开发板U-Boot_TFTP_NAND救砖刷机》
2.原理与前期分析
-
ST7789V控制器与135×240的偏置问题
ST7789V:Sitronix单芯片TFT控制器,内部 **GRAM(显存)*固定为*240×320×16bit,通过4线SPI(SCLK/SDA/CS/DC)接收命令与像素流。- 显示窗口:SPI刷屏向GRAM写像素前须先发
CASET/RASET限定地址窗(st7789.c内st7789v_set_window,st7789.c),窗口=可见区映射进GRAM的起止坐标。 - 本模组的偏置:1.14"屏物理像素135×240,但其GRAM可视区不从(0,0)起,居中于240×320 GRAM内——
left_offset=52、top_offset=40(240-135=105,(105-1)/2=52;320-240=80/2=40),即CASET区间[52,186]、RASET区间[40,279]。 TE(Tearing Effect):刷屏同步信号引脚,本模组未引出;驱动对te-gpios做gpiod_get_optional,缺失时打印probed (TE not wired)并跳过TEAR_ON路径(st7789.c)。
-
硬件连接
-
SPI0控制器:spi_bus0: spi@11070000(apps/demb_ev_board/bsp/dts/demb_hisupport.dtsi:),arm,pl022IP,num-cs=<2>,SPI屏挂在spi0.0。-
模组pin 信号 排针pin SoC功能 GND 地 6/9/14/20/25/30/34/39任一 GND VCC 电源 1或17 3.3V SCL SPI时钟 23 GPIO3_7 → SPI0_SCLK SDA MOSI 19 GPIO4_0 → SPI0_SDO RES 复位 27 GPIO7_5 → GPIO DC 数据/命令 11 GPIO0_1 → GPIO CS 片选 26 GPIO7_0 → SPI0_CSN0 BLK 背光 28 GPIO7_4 → PWM1_OUT7
-
-
-
驱动框架
-
samples_panel (LVGL, /dev/dri/card0) │ DRM_IOCTL dumb-buffer + modeset ▼ st7789.ko ── mipi_dbi_dev_init ── drm_simple_display_pipe │ fb刷新 → st7789v_enable_flush → CASET/RASET(+offset) → RAMWR像素流 ▼ spi0.0 (pl022) → SPI0_SCLK/SDO/CSN0 + DC/RST GPIO → ST7789V GRAM → 屏 -
驱动是变体补丁制:
patches/下1/2.4/3.2/3.5寸各一个patch,CMakeLists.txt按ENABLE_*宏选择性打补丁到st7789.c.tmp再编ko(st7789v/CMakeLists.txt:26-58)——不新写驱动,只加一个新patch。 -
sample_panel应用的disp_init直接用lv_linux_drm_create()建LVGL显示,分辨率从DRM connector读,无需改代码(source/main.c)。
-
3.案例克隆与重命名
-
cp -r apps/demb_ev_board/samples/panel/st7789_240_320_28_50M \ apps/demb_ev_board/samples/panel/st7789_135_240_114_50M vi hi_aiot_solution/apps/demb_ev_board/samples/panel/st7789_135_240_114_50M/BUILD.gn -executable("samples_panel_st7789_240_320_28_50M") { +executable("samples_panel_st7789_135_240_114_50M") { vi hi_aiot_solution/apps/demb_ev_board/samples/panel/st7789_135_240_114_50M/oh_product/BUILD.gn - case_dts_dir = "//../apps/demb_ev_board/samples/panel/st7789_240_320_28_50M/dts" + case_dts_dir = "//../apps/demb_ev_board/samples/panel/st7789_135_240_114_50M/dts" - "//../apps/demb_ev_board/samples/panel/st7789_240_320_28_50M:samples_panel_st7789_240_320_28_50M", - "//../apps/demb_ev_board/samples/panel/st7789_240_320_28_50M:sys_config_module", + "//../apps/demb_ev_board/samples/panel/st7789_135_240_114_50M:samples_panel_st7789_135_240_114_50M", + "//../apps/demb_ev_board/samples/panel/st7789_135_240_114_50M:sys_config_module", vi hi_aiot_solution/apps/demb_ev_board/samples/panel/st7789_135_240_114_50M/dts/BUILD.gn # panel/st7789_135_240_114_50M案例dts目录——hispark外部编译dtb时的同名覆盖源 # (覆盖bsp/dts同名文件,如board_io_config.dtsi)。 # 消费点:oh_product/BUILD.gn的board_dtb_uimage实例(case_dts_dir参数指向本目录)。 group("dts") { } vi hi_aiot_solution/apps/demb_ev_board/samples/panel/st7789_135_240_114_50M/app.defconfig -# 功能:ST7789V SPI LCD + Goodix GT911 触摸屏 LVGL UI demo SPI速率50M 尺寸为2.8寸 +# 功能:ST7789V SPI LCD LVGL UI demo SPI速率50M 尺寸为1.14寸(135x240,无触摸无TE) -# - ST7789V LCD 驱动 / Goodix 触摸驱动 +# - ST7789V LCD 驱动(1.14" 135x240 变体,无触摸) CONFIG_DRV_LCD_ST7789V=y CONFIG_DRV_LCD_ST7789V_30FPS=y +CONFIG_DRV_LCD_ST7789V_1_14INCH=y -CONFIG_DRV_TOUCH_GOODIX=y +# CONFIG_DRV_TOUCH_GOODIX is not set vi hi_aiot_solution/apps/demb_ev_board/samples/panel/st7789_135_240_114_50M/oh_product/init_configs/etc/init.d/S82ohos #! /bin/sh insmod /ko/sys_config.ko cd /vendor/adapter/ko insmod ot_board_io_cfg.ko insmod st7789.ko cd /bin/samples/bin ./samples_panel_st7789_135_240_114_50M &
4.驱动补丁
-
vi hi_aiot_solution/components/adapter/drivers/lcd/st7789v/patches/1_14inch.patch From: hi_aiot_solution Subject: [PATCH] st7789v: 1.14" 135x240 module support (geometry + GRAM offsets) --- a/components/adapter/drivers/lcd/st7789v/st7789.c +++ b/components/adapter/drivers/lcd/st7789v/st7789.c @@ -108,7 +108,7 @@ #define ST7789_MADCTL_MY BIT(7) -#define PANEL_WIDTH 240 -#define PANEL_HEIGHT 320 +#define PANEL_WIDTH 135 +#define PANEL_HEIGHT 240 /* pl022 DMA 要求 TX/RX 缓冲区页对齐,用 alloc_pages 保证对齐 */ #define DMA_BUF_BYTES (PANEL_WIDTH * PANEL_HEIGHT * 2) @@ -379,7 +379,7 @@ mipi_dbi_command(dbi, ST7789_INVON); - mipi_dbi_command(dbi, ST7789_CASET, 0x00, 0x00, 0x00, 0xef); - mipi_dbi_command(dbi, ST7789_RASET, 0x00, 0x00, 0x00, 0xc5); + mipi_dbi_command(dbi, ST7789_CASET, 0x00, 0x34, 0x00, 0xba); + mipi_dbi_command(dbi, ST7789_RASET, 0x00, 0x28, 0x01, 0x17); msleep(120); if (priv->te_gpio) { @@ -465,7 +465,7 @@ }; static const struct drm_display_mode st7789v_mode = { - DRM_SIMPLE_MODE(240, 320, 26, 30), + DRM_SIMPLE_MODE(135, 240, 15, 26), }; DEFINE_DRM_GEM_CMA_FOPS(st7789v_fops); @@ -577,6 +577,10 @@ dbi->command = st7789v_command; + /* 1.14" 135x240: visible window inside the 240x320 GRAM */ + dbidev->left_offset = 52; + dbidev->top_offset = 40; + ret = mipi_dbi_dev_init(dbidev, &st7789v_pipe_funcs, &st7789v_mode, rotation); if (ret) { vi hi_aiot_solution/components/adapter/drivers/lcd/Kconfig(DRV_LCD_ST7789V_3_2INCH 之后插入) config DRV_LCD_ST7789V_1_14INCH bool "ST7789V 1.14 寸 135x240 模组(8pin SPI 小板)" default n depends on DRV_LCD_ST7789V help 1.14 寸 ST7789V 模组的显示窗口在 240x320 GRAM 内偏置 left_offset=52 / top_offset=40;分辨率 135x240。 vi hi_aiot_solution/components/adapter/drivers/lcd/st7789v/CMakeLists.txt(3_2inch 的 endif 之后插入) if(ENABLE_DRV_LCD_ST7789V_1_14INCH) list(APPEND _drv_patches "${_ST7789V_SRC_DIR}/patches/1_14inch.patch") endif()
5.设备树
-
vi hi_aiot_solution/apps/demb_ev_board/samples/panel/st7789_135_240_114_50M/dts/panel_config.dtsi /* * ST7789V(1.14" 135x240,50M,无触摸,无 TE)屏幕设备树片段。 * * 通过"同名覆盖"机制覆盖 bsp/dts/panel_config.dtsi(默认 JD9853), * 使 bsp/dts 外部编译 dtb 时切到本屏。 * 模组无触摸 → 不启用 i2c_bus1 触摸节点;模组无 TE 脚 → 不带 te-gpios。 */ / { backlight: backlight { compatible = "pwm-backlight"; pwms = <&pwm1 7 100000>; brightness-levels = <0 27 28 29 31 32 34 35 37 39 40 42 44 46 48 50 51 53 55 57 59 61 63 65 67 69 71 74 76 78 80 82 84 87 89 91 93 95 98 100 102 105 107 109 112 114 116 119 121 123 126 128 130 133 135 138 140 143 145 148 150 153 155 158 160 163 165 168 170 173 175 178 180 183 186 188 191 193 196 199 201 204 206 209 212 214 217 220 222 225 228 230 233 236 239 241 244 247 250 252 255>; default-brightness-level = <100>; status = "okay"; }; }; &pwm1 { #pwm-cells = <2>; }; &i2c_bus1 { /* 总线使能保留(基线行为);本模组无触摸,不挂子节点 */ status = "okay"; }; &spi_bus0 { status = "okay"; dmas = <&edmacv310_0 7 7>, <&edmacv310_0 6 6>; dma-names = "tx","rx"; st7789v_114:ips@0 { compatible = "sitronix,st7789v_240x320"; reg = <0>; pl022,interface = <0>; pl022,com-mode = <2>; spi-max-frequency = <50000000>; pl022,tx-level-trig = <3>; pl022,rx-level-trig = <3>; rotation = <0>; dc-gpios = <&gpio_chip0 1 0>; reset-gpios = <&gpio_chip7 5 0>; debug = <0>; backlight = <&backlight>; status = "okay"; }; };
6.引脚配置:6根屏引脚条目
-
vi apps/demb_ev_board/samples/panel/st7789_135_240_114_50M/dts/board_io_config.dtsi pin-cfg@7{pin=<7>;gpio-num="GPIO0_1";function="GPIO0_1";pull="pull-down"; drive = "I06_level8"; slew = "fast"; }; /* DC → 排针11 */ pin-cfg@18 { pin = <18>; gpio-num = "GPIO7_4"; function = "PWM1_OUT7"; pull = "pull-up"; drive = "I02_level4"; slew = "fast"; }; /* BLK → 排针28 */ pin-cfg@19 { pin = <19>; gpio-num = "GPIO7_5"; function = "GPIO7_5"; pull = "pull-up"; drive = "I02_level4"; slew = "fast"; }; /* RES → 排针27 */ pin-cfg@46 { pin = <46>; gpio-num = "GPIO7_0"; function = "SPI0_CSN0"; pull = "pull-down"; drive = "I06_level8"; slew = "fast"; }; /* CS → 排针26 */ pin-cfg@84 { pin = <84>; gpio-num = "GPIO4_0"; function = "SPI0_SDO"; pull = "pull-down"; drive = "EMMC I0_level16"; slew = "fast"; }; /* SDA → 排针19 */ pin-cfg@85 { pin = <85>; gpio-num = "GPIO3_7"; function = "SPI0_SCLK"; pull = "pull-up"; drive = "EMMC I0_level16"; slew = "fast"; }; /* SCL → 排针23 */
7.集成裁剪
-
vi apps/demb_ev_board/samples/panel/st7789_135_240_114_50M/rootfs/CMakeLists.txt(去掉 _GOODIX_KO 变量与拷贝行) set(_ST7789_KO "${CMAKE_BINARY_DIR}/drivers/lcd/st7789v/st7789.ko") set(_PANEL_BIN "${CMAKE_BINARY_DIR}/bin/samples_panel") add_custom_target(rootfs_panel_prepare COMMAND bash -c "if [ -f '${CMAKE_BINARY_DIR}/.clean_pending' ]; then rm -rf '${_IMAGE_DIR}'; fi" COMMAND ${CMAKE_COMMAND} -E rm -rf "${_ROOTFS_TMP}" COMMAND ${CMAKE_COMMAND} -E make_directory "${_ROOTFS_TMP}" COMMAND bash -c "cp -raf ${_BSP_PUB_ROOT}/rootfs_debug_musl_arm/. ${_ROOTFS_TMP}/" COMMAND ${CMAKE_COMMAND} -E make_directory "${_ROOTFS_TMP}/root/panel" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_PANEL_BIN}" "${_ROOTFS_TMP}/root/panel/samples_panel" # 驱动目录:MPP ko + st7789.ko(无触摸变体:不安装触摸 ko) COMMAND ${CMAKE_COMMAND} -E make_directory "${_ROOTFS_TMP}/drv" COMMAND ${CMAKE_COMMAND} -E copy_directory "${_MPP_OUT}/ko" "${_ROOTFS_TMP}/drv/ko" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_ST7789_KO}" "${_ROOTFS_TMP}/drv/st7789.ko" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_BINARY_DIR}/drivers/board_io_cfg/ot_board_io_cfg.ko" "${_ROOTFS_TMP}/drv/ko/ot_board_io_cfg.ko" DEPENDS samples_panel drv_all board_io_cfg COMMENT "[panel/rootfs] 组装根文件系统..." VERBATIM )
8.编译烧录
-
source ~/demb_env.sh bash scripts/build.sh build --target demb_ev_board samples panel/st7789_135_240_114_50M # 传板(编译机):scp /tmp/mtdflash install/image/panel/uImage root@192.168.1.221:/tmp/ # 板端(Xshell): chmod +x /tmp/mtdflash && mv /tmp/mtdflash /root/ /root/mtdflash /dev/mtd2 /tmp/uImage && reboot- patch打补丁环节在
st7789v/CMakeLists.txt内自动完成;bsp_make_opts的KERNEL_CFG沿用demb_drm_touch_defconfig
- patch打补丁环节在
9.板端验证
-
模块加载与设备注册
-
insmod /drv/ko/sys_config.ko # 已由启动脚本加载可跳 insmod /drv/ko/ot_board_io_cfg.ko # 应用引脚复用(同上) insmod /tmp/st7789.ko- dmesg预期:
st7789v probed (TE not wired)、Initialized st7789v 1.0.0 ... for spi0.0、注册fb0;/dev/dri/card0出现。
- dmesg预期:
-
-
显示验证(自写drmtest)
-
板端无
/dev/fb0节点(fbdev仿真没开),用libdrm写最小测试:dumb buffer填6条横向彩条+2px白框+中央黑十字,drmModeSetCrtc上屏常驻。-
// drmtest.c - minimal DRM dumb-buffer modeset test for the board's SPI panels // Draws color bars + white border so panel offset/orientation can be checked. // 用法: drmtest [秒数(0=常驻)] [/dev/dri/cardN] #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <stdint.h> #include <sys/mman.h> #include <xf86drm.h> #include <xf86drmMode.h> static uint16_t rgb565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } int main(int argc, char **argv) { int secs = argc > 1 ? atoi(argv[1]) : 30; const char *card = argc > 2 ? argv[2] : "/dev/dri/card0"; int fd = open(card, O_RDWR); if (fd < 0) { perror("open"); return 1; } drmModeRes *res = drmModeGetResources(fd); if (!res) { perror("resources"); return 1; } if (!res->count_connectors) { fprintf(stderr, "no connector\n"); return 1; } drmModeConnector *conn = drmModeGetConnector(fd, res->connectors[0]); if (!conn || conn->connection != DRM_MODE_CONNECTED || !conn->count_modes) { fprintf(stderr, "no connected/mode\n"); return 1; } drmModeModeInfo *mode = &conn->modes[0]; uint32_t w = mode->hdisplay, h = mode->vdisplay; printf("mode: %dx%d @%dHz name=%s\n", w, h, mode->vrefresh, mode->name); uint32_t crtc_id = res->crtcs[0]; struct drm_mode_create_dumb creq = {0}; creq.width = w; creq.height = h; creq.bpp = 16; if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq)) { perror("create_dumb"); return 1; } struct drm_mode_map_dumb mreq = {0}; mreq.handle = creq.handle; if (drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq)) { perror("map_dumb"); return 1; } uint16_t *fb = mmap(0, creq.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, mreq.offset); if (fb == MAP_FAILED) { perror("mmap"); return 1; } // pattern: 6 horizontal color bars + 2px white border + center black cross static const uint8_t cols[6][3] = { {255,0,0}, {0,255,0}, {0,0,255}, {255,255,0}, {0,255,255}, {255,0,255} }; for (uint32_t y = 0; y < h; y++) for (uint32_t x = 0; x < w; x++) { int bar = y * 6 / h; uint16_t px = rgb565(cols[bar][0], cols[bar][1], cols[bar][2]); if (x < 2 || y < 2 || x >= w-2 || y >= h-2) px = 0xFFFF; if (x == w/2 || y == h/2) px = 0x0000; fb[y * w + x] = px; } uint32_t fb_id; if (drmModeAddFB(fd, w, h, 16, 16, creq.pitch, creq.handle, &fb_id)) { perror("addfb"); return 1; } if (drmModeSetCrtc(fd, crtc_id, fb_id, 0, 0, &conn->connector_id, 1, mode)) { perror("setcrtc"); return 1; } if (secs <= 0) { printf("displaying forever (Ctrl+C to stop)...\n"); for (;;) sleep(60); } printf("displaying for %ds...\n", secs); sleep(secs); drmModeRmFB(fd, fb_id); struct drm_mode_destroy_dumb dreq = { .handle = creq.handle }; drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); close(fd); return 0; }
-
-
编译运行
-
#编译 TC=~/toolchains/gcc-10.3-arm-musl-x86-linux-26.06.1/arm-v01c02-linux-musleabi-gcc/bin DR=~/tmp/hi_aiot_solution/_build/open_source/drm/release $TC/arm-linux-musleabi-gcc -static -O2 -o /tmp/drmtest /tmp/drmtest.c \ -I$DR/include -I$DR/include/libdrm $DR/lib/libdrm.a # 产物: /tmp/drmtest(~300KB 静态 musl ELF,板端零依赖) #运行测试 # 传板(编译机):scp /tmp/drmtest root@192.168.1.221:/tmp/(或Xftp拖拽) # —— 以下在板端(Xshell)执行: insmod /tmp/st7789.ko # 已加载可跳;成功后/dev/dri/card0出现 killall samples_panel # 若有app占着card0先杀 /tmp/drmtest 0 # 0=常驻显示;给秒数则到时自动退出 -
结果:
mode: 135x240模式设置成功,画面实机可见。 -
-
-
3.TF卡与USB大容量存储
3.1 启用tf卡
环境:ws73_lcd出厂镜像 + 拨码SW1301-1拨到ON(TF模式)+ 插卡重启
现象:能枚举出型号容量(说明CMD通),但一个扇区都读不出(说明数据路断)
-
根因:拨码只管物理路由,SW1301-1不管引脚功能,把SDIO0的8根引脚从"40PIN排针"扳到"TF卡槽"。但SoC在这几根脚上跑什么协议,由pin_mux(iocfg寄存器)决定。
board_io_cfg.ko开机按bsp/dts/board_io_config.dtsi配iocfg寄存器(基址0x10260000`)。实测默认引脚归属:-
偏移 引脚 SDIO0角色 被配成 谁在用 0x34 GPIO4_0 CLK SPI0_SDO 屏 0x30 GPIO3_7 DAT0 SPI0_SCLK 屏 0x28 GPIO3_5 CD GPIO(屏TE) 屏 0x3C GPIO4_2 DAT3 GPIO(触摸RST) 触摸 0x38 GPIO4_1 CMD I2S_BCLK 音频ko(insmod时写) 0x40 GPIO4_3 DAT2 I2S_WS 音频 0x44 GPIO3_4 卡电源 I2S_SD_RX 音频 0x2C GPIO3_6 DAT1 SDIO0 ✓ 唯一幸存
-
-
调整 & 测试
-
方式一:
bspmm运行期改寄存器——免刷机、重启还原、随改随验# ============================================================ # 开发板 TF卡 运行期启用 + 完整测试(免刷机,重启还原) # 前提:拨码 SW1301-1 = ON(物理切到TF卡槽)、TF卡已插 # ============================================================ # 1.修引脚复用(6刀:抢回被屏/触摸/I2S占走的SDIO0脚) bspmm 0x10260030 0x11e1 # GPIO3_7 DAT0 原SPI0_SCLK → SDIO0 bspmm 0x10260034 0x12c1 # GPIO4_0 CLK 原SPI0_SDO → SDIO0 bspmm 0x10260038 0x11e1 # GPIO4_1 CMD 原I2S_BCLK → SDIO0 bspmm 0x1026003C 0x1101 # GPIO4_2 DAT3 原触摸RST → SDIO0 bspmm 0x10260040 0x1101 # GPIO4_3 DAT2 原I2S_WS → SDIO0 bspmm 0x10260044 0x1101 # GPIO3_4 卡电源 原I2S_SD_RX → SDIO0 # 注意:0x10260028 (GPIO3_5,CD) 保持0x1100不改——驱动按GPIO读插拔检测 # 2.验证寄存器(可选,应看到低4位全是1,仅0x28是0) bspmd.l 0x10260028 0x20 # 3.重新枚举卡 echo 10030000.SDIO > /sys/bus/platform/drivers/sdhci_nebula/unbind sleep 1 echo 10030000.SDIO > /sys/bus/platform/drivers/sdhci_nebula/bind sleep 3 # 4.确认卡设备 ls -l /dev/mmcblk* # 应见 mmcblk0 + mmcblk0pN dmesg | tail -6 # 应见 "new high speed SDXC/SDHC card" + pN 分区 # ⚠️ 不要 cat /proc/mci/mci_info ——插拔瞬间读它会kernel panic # 5.读测试 dd if=/dev/mmcblk0 of=/dev/null bs=1M count=4 # 通过标志:4.0MB copied(之前是 dd: I/O error) # 6.看分区/文件系统 fdisk -l /dev/mmcblk0 mkdir -p /mnt/tf mount /dev/mmcblk0p1 /mnt/tf # 已有FAT32直接挂;挂载失败=需格式化 ls -l /mnt/tf && df -h /mnt/tf # 7.写+校验测试 dd if=/dev/urandom of=/mnt/tf/test.bin bs=1M count=10 sync md5sum /mnt/tf/test.bin # 记下哈希 umount /mnt/tf && mount /dev/mmcblk0p1 /mnt/tf md5sum /mnt/tf/test.bin # 两次哈希一致 = 写落盘真实 rm /mnt/tf/test.bin && sync # 8.(可选)格式化 umount /mnt/tf mkfs.vfat /dev/mmcblk0p1 # 整卡单分区FAT32,PC可读 mount /dev/mmcblk0p1 /mnt/tf # 9.还原(不用跑,重启即自动还原) # 本方案是运行期寄存器修改:reboot后全部恢复为屏/触摸/I2S原配置 # 副作用提醒:TF启用期间 喇叭/I2S音频 不可用(脚被夺) -
方式二:dtsi改源码 → 编译 → 刷mtd2——开机原生支持、不可逆(除非回刷)
#1.改源码 demb_ev_board\references\factory_demo\ws73_lcd\dts\board_io_config.dtsi (1)3处function修改 pin-cfg@82 { pin=<82>; gpio-num="GPIO4_2"; - function = "GPIO4_2"; /* 触摸复位 */ + function = "SDIO0_CDATA3"; /* DAT3 */ pin-cfg@84 { pin=<84>; gpio-num="GPIO4_0"; - function = "SPI0_SDO"; /* 屏SPI数据 */ + function = "SDIO0_CCLK_OUT"; /* CLK */ pin-cfg@85 { pin=<85>; gpio-num="GPIO3_7"; - function = "SPI0_SCLK"; /* 屏SPI时钟 */ + function = "SDIO0_CDATA0"; /* DAT0 */ (2)3个pin-cfg整块新增 pin-cfg@79 { pin=<79>; gpio-num="GPIO3_4"; function="SDIO0_CARD_POWER_EN_N"; ... } // 卡电源(原I2S_SD_RX) pin-cfg@81 { pin=<81>; gpio-num="GPIO4_3"; function="SDIO0_CDATA2"; ... } // DAT2(原I2S_WS) pin-cfg@83 { pin=<83>; gpio-num="GPIO4_1"; function="SDIO0_CCMD"; ... } // CMD(原I2S_BCLK) #2.编译 touch sdk/demb/third_party/linux/linux-5.10.y/.scmversion cd sdk/demb/third_party/linux/linux-5.10.y git checkout drivers/vendor/Makefile export PATH=/home/nancy/miniconda3/bin:/home/nancy/toolchains/gcc-10.3-arm-musl-x86-linux-26.06.1/arm-v01c02-linux-musleabi-gcc/bin:$PATH cd ~/tmp/hi_aiot_solution bash scripts/build.sh build --target demb_ev_board references factory_demo/ws73_lcd 2>&1 | tee /tmp/build_tf.log sha256sum sdk/demb/boards/dmeb/pub/demb_image_debug_musl/uImage #3.传板 + 烧录(只刷mtd2) # 传板(编译机): # scp /tmp/mtdflash sdk/demb/boards/dmeb/pub/uImage root@192.168.1.221:/tmp/ # (或Xftp拖拽;uImage到板端改名 /tmp/uImage_new) # —— 以下在板端(Xshell)执行: chmod +x /tmp/mtdflash && mv /tmp/uImage /tmp/uImage_new /tmp/mtdflash /dev/mtd2 /tmp/uImage_new # 回读校验,必须等于编译机哈希: dd if=/dev/mtdblock2 bs=1M count=4 | head -c $(stat -c%s /tmp/uImage_new) | sha256sum #4.重启验证(不打bspmm) ls /dev/mmcblk* # mmcblk0 + p1 dd if=/dev/mmcblk0 of=/dev/null bs=1M count=4 # ~19.7MB/s mount /dev/mmcblk0p1 /mnt/tf # 读写+md5 重挂校验 lsmod | grep ot_ # 修好后MPP ko全栈加载 #5.若提前备份,可快速回滚 # 若备份在 demb_board_backup_20261103\mtd2_lcd.bin,先传到板端 /tmp/mtd2.bak # (编译机:scp mtd2_lcd.bin root@192.168.1.221:/tmp/mtd2.bak,或Xftp),板端执行: /root/img/mtdflash /dev/mtd2 /tmp/mtd2.bak && \ dd if=/dev/mtdblock2 bs=1M count=4 | head -c 4194304 | sha256sum && reboot坑1 vermagic:
ko按5.10.221编 / 内核是5.10.221+——厂 Makefile无条件调setlocalversion,git树无tag就补"+"。- 修复:
touch third_party/linux/linux-5.10.y/.scmversion(空文件,官方旁路)
坑2 dup symbol:vermagic修好后
insmod还挂,真错是exports duplicate symbol sys_ctl (owned by kernel)——drivers/vendor/Makefile被 fastboot/ws53_lp 的 kmod_builtin 残留补丁加了MPPKO_BUILTIN := y,整套MPP驱动编进了vmlinux,ko自然撞车(也解释了新zImage比旧的胖~300KB)。修复:
git checkout drivers/vendor/Makefile→ 重编zImage → 复刻dts→dtb→FIT(暂存6文件+gcc -E+dtc+mkimage)→ 刷入 - 修复:
-
方式三:结合方式一构建脚本自行切换
-
bootsel lcd # 回屏版(刷+sha256校验+reboot) bootsel tf # 回TF版
或可调整
start_ws73_lcd.sh- dtsi默认SDIO0(就用刚刚的TF镜像);
start_ws73_lcd.sh在Step1后试读卡:成功→跳过lcd/touch加载;失败→bspmm把 6 个寄存器写回屏/I2S配置再正常加载
再或者就是优化调整uboot或者硬件(略)
-
-
3.2 Type-C连PC映射U盘(configfs gadget)
目标:Type-C连PC → TF卡映射为U盘
# ============================================================
# 开发板 Type-C连PC → TF卡映射为U盘(纯手工命令)
# 前提:TF镜像 + DIP1=ON + 卡已插(本流程重启后需重跑)
# ============================================================
#1.确认device模式(开机默认就是,保险确认)
cat /proc/wing-usb/10300000.usb20drd/mode # 应回显 device
echo device > /proc/wing-usb/10300000.usb20drd/mode # 不是就写一次
sleep 2
#2.确认卡活着
ls /dev/mmcblk0 # 应有节点
dd if=/dev/mmcblk0 of=/dev/null bs=1M count=1 # 应正常读出
# 若没节点或读失败:执行 unbind/bind 重枚举(见文末B)
#3.板端卸载卡(PC独占,防双写毁文件系统)
umount /dev/mmcblk0p1 2>/dev/null
umount /mnt/tf 2>/dev/null
#4.搭configfs gadget
mount -t configfs none /sys/kernel/config
G=/sys/kernel/config/usb_gadget/g1
mkdir -p $G
echo 0x1d6b > $G/idVendor
echo 0x0104 > $G/idProduct
echo high-speed > $G/max_speed
mkdir -p $G/strings/0x409
echo YueYing > $G/strings/0x409/manufacturer
echo "YueYing TF Card" > $G/strings/0x409/product
echo yytf001 > $G/strings/0x409/serialnumber # Windows必需
mkdir -p $G/configs/c.1/strings/0x409
echo "Config 1" > $G/configs/c.1/strings/0x409/configuration
echo 250 > $G/configs/c.1/MaxPower
mkdir -p $G/functions/mass_storage.0
echo /dev/mmcblk0 > $G/functions/mass_storage.0/lun.0/file
ln -s $G/functions/mass_storage.0 $G/configs/c.1/
#5.绑定UDC(激活)
echo 10300000.dwc3 > $G/UDC
#6.验证
cat /sys/class/udc/10300000.dwc3/state # 插线前 not attached
bspmd.l 0x1030c704 4 # DCTL第1个值应0x8xxxxxxx(上拉已开)
#7.插Type-C到PC
cat /sys/class/udc/10300000.dwc3/state # → configured = PC枚举成功
cat /sys/class/udc/10300000.dwc3/current_speed # → high-speed
# PC资源管理器出现"U盘"
#8.退出/收尾:PC端先"安全弹出"盘符,然后板端
echo "" > /sys/kernel/config/usb_gadget/g1/UDC # 解绑
mount /dev/mmcblk0p1 /mnt/tf # 板子重新用卡
十、体验总结
1.对开发板的体验总结
折腾下来,这块板子给我的感受可以概括为:麻雀虽小,出厂即飞。
让人惊喜的点
- 开箱完成度罕见的高:上电不进命令行,屏直接亮LVGL九页UI——亮度滑条、摄像头控制、倒计时、AI检测、AI助手、设置页全是能点的真功能,不是摆设demo。摄像头+编码+RTSP+触控+BLE配网+ZeroClaw Agent六合一一次点亮,同价位里我没见过第二家。
- AI助手是真能用的:出厂就接了ZeroClaw Agent——屏上打字(拼音IME)、持续会话、“帮我拍张照”"画面里有什么"都能调板子能力,不是只能聊天的玩具。
- 星闪WS73是独家卖点:一块扩展板同时给WiFi/BLE/SLE三协议,SLE调参后avg 58KB/s/peak 97KB/s,BLE空口~30KB/s,和低延迟近场场景很配。
- 硬件留的余量实在:2×MIPI CSI双摄、2路模拟麦+喇叭+回采、40pin排针(SPI/I2C/UART/SDIO/PWM/LSADC全引)、TF卡槽、RTC、DIP拨码——HC-05、TF卡、新屏、USB Gadget都是我自己接出来跑通的。
- SDK是产品级组件化:
hi_aiot_solution按components/samples/references分层,案例即产品(factory_demo直接可当门铃固件雏形),比"一堆松散demo"的SDK强一截。
需要提醒的点
- 内存是硬约束:128MB DDR3L——LVGL+MPP+ZeroClaw同时跑已经很挤,别指望再塞大应用。
- 性能是轻量级:双核950MHz/1TOPS——人脸识别、多路视频、大模型本地推理别想了,它干的是"看得懂有人经过"这类轻活。
- 开发要Linux编译机:SDK全量编译对新手有门槛(本文环境搭建一节就是踩坑记录),不过单文件热部署循环很快。
- 细节糙点:fbdev仿真没开(要用libdrm)、
/tmp重启即清、busybox缺flashcp类工具——都能绕,但会踩一下。
一句话:如果目标是低成本、低功耗、快速落地的视觉+语音+轻交互终端(门铃/猫眼/宠物陪伴/养老看护/智能家居中控屏),这块板子是我玩过"出厂即能用"程度最高的选择;要算力/大屏/桌面生态→看RK3588,要专业安防ISP→看Hi3519DV500。
2.开发板购买链接
-
淘宝购买页:轻AI越影视觉开发板
- 本文这套对应套餐4:主板 + WS73扩展板 + 2.8寸屏 + Sensor模组 + 喇叭;同页另有单板、WS53扩展板、Hi2131 4G扩展板、1.28寸双圆屏/2.1寸圆屏等套餐SKU可选
-
官方资料页(原理图/装配图/Datasheet/SDK文档):开发板产品介绍
十一、附录
1.mtdflash—极简MTD烧录工具
-
用途:板端busybox无
flashcp/nandwrite/mtd_debug时的替代品——把镜像文件写进/dev/mtdN字符设备分区。 -
用法:
mtdflash /dev/mtd2 uImage-
/* mtdflash <mtd> <img> — erase + writesize-aligned write to NAND partition */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <mtd/mtd-abi.h> int main(int argc, char **argv) { if (argc < 3) { fprintf(stderr, "usage: %s /dev/mtdN image\n", argv[0]); return 1; } int mtd = open(argv[1], O_RDWR | O_SYNC); if (mtd < 0) { perror("open mtd"); return 1; } int img = open(argv[2], O_RDONLY); if (img < 0) { perror("open img"); return 1; } struct stat st; fstat(img, &st); size_t imgsz = st.st_size; struct mtd_info_user mi; if (ioctl(mtd, MEMGETINFO, &mi) < 0) { perror("MEMGETINFO"); return 1; } printf("mtd: size=%u erase=%u write=%u img=%zu\n", mi.size, mi.erasesize, mi.writesize, imgsz); if (imgsz > mi.size) { fprintf(stderr, "image too big\n"); return 1; } struct erase_info_user ei = { .start = 0, .length = mi.size }; if (ioctl(mtd, MEMERASE, &ei) < 0) { perror("MEMERASE"); return 1; } printf("erased\n"); size_t chunk = mi.writesize; unsigned char *buf = malloc(chunk); size_t off = 0; int bad = 0; while (off < imgsz) { size_t n = imgsz - off < chunk ? imgsz - off : chunk; memset(buf, 0xFF, chunk); if (read(img, buf, n) != (ssize_t)n) { perror("read"); return 1; } ssize_t w = pwrite(mtd, buf, chunk, off); if (w != (ssize_t)chunk) { perror("pwrite"); bad = 1; break; } off += n; } printf("%s wrote %zu bytes\n", bad ? "FAIL" : "OK", off); return bad; }
-
2.40pin排针引脚功能表
| Pin | 信号/网络 | IOCFG 寄存器 | 可用功能(f#) |
|---|---|---|---|
| 1 | 3.3V | — | 电源 3.3V |
| 2 | 5V | — | 电源 5V |
| 3 | GPIO1_5 | 0x11130000 | f0:GPIO / f1:I2C1_SDA / f2:PWM0_OUT2 / f3:UART2_RXD / f4:LSADC_CH1 |
| 4 | 5V | — | 电源 5V |
| 5 | GPIO1_4 | 0x11130004 | f0:GPIO / f1:I2C1_SCL / f2:PWM0_OUT3 / f3:UART2_TXD / f4:LSADC_CH0 |
| 6 | GND | — | 地 |
| 7 | GPIO0_0 | 0x10260000 | f0:GPIO(UPDATE_MODE 网络,无其他复用) |
| 8 | GPIO0_7 | 0x11130034 | f0:JTAG_TDI / f1:ETH_LINK_ACT_LED / f2:ETH_STA_ACT_LED / f3:I2C0_SDA / f4:USB2_PWREN / f5:UART1_TXD / f6:GPIO / f7:PWM0_OUT2 |
| 9 | GND | — | 地 |
| 10 | GPIO0_6 | 0x11130030 | f0:JTAG_TRSTN / f1:ETH_LINK_STA_LED / f2:GPIO / f3:I2C0_SCL / f5:UART1_RXD / f6:SPI0_CSN1 / f7:PWM0_OUT1 |
| 11 | GPIO0_1 | 0x10260004 | f0:GPIO / f1:PWM0_OUT3 / f2:BOOT_SEL1 |
| 12 | GPIO4_1 ※D | 0x10260038 | f0:GPIO / f1:SDIO0_CCMD / f4:SPI0_SDI / f5:PWM1_OUT4 / f6:I2S_BCLK / f7:UART1_RXD |
| 13 | GPIO1_0 | 0x1113003C | f0:GPIO / f1:SDIO1_CDATA3 / f3:I2S_SD_TX / f5:UART1_CTSN / f6:SPI1_SDI / f7:PWM1_OUT1 |
| 14 | GND | — | 地 |
| 15 | GPIO1_3 | 0x11130044 | f0:JTAG_TCK / f1:SDIO1_CCLK_OUT / f2:GPIO / f3:I2S_WS / f6:SPI1_SCLK / f7:PWM1_OUT3 |
| 16 | GPIO1_2 | 0x11130040 | f0:GPIO / f1:SDIO1_CCMD / f3:I2S_BCLK / f5:SENSOR1_RSTN / f6:SPI1_CSN / f7:PWM1_OUT2 |
| 17 | 3.3V | — | 电源 3.3V |
| 18 | GPIO1_1 | 0x11130048 | f0:GPIO / f1:SDIO1_CDATA0 / f3:I2S_SD_RX / f5:UART2_RXD / f6:SPI0_SDO / f7:PWM1_OUT4 |
| 19 | GPIO4_0 ※D | 0x10260034 | f0:GPIO / f1:SDIO0_CCLK_OUT / f2:TEST_MODE / f4:SPI0_SDO / f5:PWM1_OUT3 / f6:I2S_MCLK |
| 20 | GND | — | 地 |
| 21 | GPIO7_1 | 0x17940094 | f0:GPIO / f1:VI_BT1120_CLK¹ / f3:SPI0_SDI / f4:SENSOR0_RSTN / f5:I2C1_SCL / f7:SENSOR0_VS |
| 22 | GPIO7_6 | 0x1113004C | f0:GPIO / f1:SDIO1_CDATA1 / f5:UART2_TXD / f6:SPI0_SDI / f7:PWM1_OUT5 |
| 23 | GPIO3_7 ※D | 0x10260030 | f0:GPIO / f1:SDIO0_CDATA0 / f4:SPI0_SCLK / f5:PWM1_OUT2 / f7:SENSOR1_RSTN |
| 24 | GPIO3_6 ※D | 0x1026002C | f0:GPIO / f1:SDIO0_CDATA1 / f4:SPI0_CSN1 / f5:PWM1_OUT1 / f6:I2C2_SCL / f7:UART2_TXD |
| 25 | GND | — | 地 |
| 26 | GPIO7_0 | 0x17940090 | f0:GPIO / f1:VI_BT1120_CLK¹ / f3:SPI0_CSN0 / f5:I2C1_SDA / f6:VI_HS / f7:SENSOR0_HS |
| 27 | GPIO7_5 | 0x11130050 | f0:JTAG_TMS / f1:SDIO1_CARD_DETECT / f2:SENSOR1_RSTN / f3:I2C2_SDA / f5:GPIO / f6:SPI0_SCLK / f7:PWM1_OUT6 |
| 28 | GPIO7_4 | 0x11130054 | f0:JTAG_TDO / f1:SDIO1_CARD_POWER_EN_N / f3:I2C2_SCL / f5:GPIO / f6:SPI0_CSN0 / f7:PWM1_OUT7 |
| 29 | GPIO6_3 ※M | 0x1794000C | f0:MIPI_RX_D3P / f1:GPIO / f2:VI_BT1120_DATA11 / f3:VI_DATA8 / f7:PWM0_OUT1 |
| 30 | GND | — | 地 |
| 31 | GPIO6_2 ※M | 0x17940008 | f0:MIPI_RX_D3N / f1:GPIO / f2:VI_BT1120_DATA10 / f3:VI_DATA9 / f7:SENSOR0_RSTN |
| 32 | GPIO3_5 ※D | 0x10260028 | f0:GPIO / f1:SDIO0_CARD_DETECT / f2:EMMC_RST_N / f3:SFC_CSN1 / f5:PWM1_OUT0 / f6:I2C2_SDA / f7:UART2_RXD |
| 33 | GPIO6_1 ※M | 0x17940014 | f0:MIPI_RX_D1P / f1:GPIO / f2:VI_BT1120_DATA13 / f3:VI_DATA7 / f7:PWM0_OUT3 |
| 34 | GND | — | 地 |
| 35 | GPIO4_3 ※D | 0x10260040 | f0:GPIO / f1:SDIO0_CDATA2 / f4:UART2_RXD / f5:PWM1_OUT6 / f6:I2S_WS / f7:UART1_RTSN |
| 36 | GPIO6_0 ※M | 0x17940010 | f0:MIPI_RX_D1N / f1:GPIO / f2:VI_BT1120_DATA12 / f3:VI_CLK / f7:PWM0_OUT2 |
| 37 | GPIO7_7 | 0x11130038 | f0:GPIO / f1:SDIO1_CDATA2 / f3:I2S_MCLK / f5:UART1_RTSN / f6:SPI1_SDO / f7:PWM1_OUT0 |
| 38 | GPIO3_4 ※D | 0x10260044 | f0:GPIO / f1:SDIO0_CARD_POWER_EN_N / f4:UART2_TXD / f5:PWM1_OUT7 / f6:I2S_SD_RX / f7:UART1_CTSN |
| 39 | GND | — | 地 |
| 40 | GPIO4_2 ※D | 0x1026003C | f0:GPIO / f1:SDIO0_CDATA3 / f4:SPI0_CSN0 / f5:PWM1_OUT5 / f6:I2S_SD_TX / f7:UART1_TXD |
3.电容触摸skill
这是我在适配过程中沉淀的一个skill(放在仓库
.agents/skills/下),已单独开源:gitlab.com/moonnancy881-dotcom/touch-bringup-skill,把它作为经验打包形式一并记录在此。
功能:factory_demo/ws73_lcd这类合并应用换一块带电容触摸的新屏模组时的全流程及问题排查
-
拿到一块新屏模组后,skill引导完成全流程
- 参数收集:触摸IC型号、I2C总线/地址、INT/RST接哪个GPIO、触点分辨率——缺项必问不猜
- 驱动匹配:自动探测
components/adapter/drivers/touch/(hynitron/goodix/edt_ft5x06)和内核树,IC不在其中就停止报告,不做从零移植 - 代码落地:改5个点——
panel_config.dtsi(触摸节点)、board_io_config.dtsi(引脚复用,仅接线变时)、app.defconfig(驱动开关)、rootfs/CMakeLists.txt(ko安装,顺带修_HYNITRON_KO硬编码坑)、启动脚本insmod行 - 增量编译 + 构建后四项产物验证
-
板端六层故障定位
-
L0 I2C物理层 → L1 probe → L2 input设备 → L3 事件上报 → L4 LVGL消费 → L5 坐标 → L6 稳定性- 每层给具体命令(
i2cdetect/dmesg//proc/bus/input/devices)和故障对照表,“每层不过就停在该层修,不要跳层”
- 每层给具体命令(
-
-
evdump工具(自研,已实测):板子没有evtest,skill自带
scripts/evdump.c——50行evdev事件打印器,交叉编译静态传板就能看触摸原始事件流。已在真板验证(还顺手修了EVIOCGNAME的bug)。-
# 编译机交叉编译 → 传到板端(scp/Xftp) → 板端跑 arm-v01c02-linux-musleabi-gcc -O2 -static -o evdump evdump.c # 编译机 # scp evdump root@192.168.1.221:/tmp/ (或Xftp拖拽) # —— 以下在板端(Xshell)执行: chmod +x /tmp/evdump /tmp/evdump /dev/input/event0 # 触摸屏幕看 ABS_MT_POSITION_X/Y 事件流
-
-
ko热替换调试:改触摸驱动/dts属性后不用重启不重烧:
rmmod touch_panel.ko→insmod新ko →dmesg看probe,一轮几十秒。
架构
-
hi_aiot_solution/.agents/skills/hi-aiot-demb-touch-bringup/ ├── SKILL.md ← 主入口(Agent 运行指令) ├── README.md ← 说明文档 ├── references/ │ ├── info-collection.md ← 参数收集+EVB接线基线 │ ├── driver-availability.md ← 三驱动匹配 │ ├── integration.md ← 落地集成五步+§9验证 │ └── board-debug.md ← 板端六层故障树 └── scripts/ └── evdump.c ← 板端 evdev 事件打印工具
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐




所有评论(0)