简介:《全志v3s音视频开发.pdf》面向具备Linux与嵌入式基础的研发人员及音视频方向工程师,围绕全志V3S平台梳理从系统环境搭建到音视频应用落地的完整开发链路。资源包共1个PDF文件,大小约12.26MB,便于集中查阅与按章节实践。内容覆盖源码准备、交叉编译器配置、U-Boot与Linux 5.4.31内核配置、Buildroot根文件系统制作,并逐步展开2.4寸TFT-LED屏、按键、声卡、摄像头等外设驱动配置。后半部分重点讲解SDL2与Qt5的移植方法,以及基于Qt5设计音乐播放器、图片显示、视频播放器和摄像头模块,结合FFmpeg理解音视频解码处理。文中保留设备树修改、menuconfig选项和编译命令等关键细节,适合按顺序搭建实验环境、对照配置外设并完成GUI综合项目。已有329人学习。
1. 全志 V3S 音视频开发:卡住人的从来不是 Qt 代码
全志 V3S 音视频开发这套环境,我第一次搭的时候在交叉编译器和设备树上耗了整整两天。板子能上电,串口也有输出,但一敲make就是arm-linux-gnueabihf-gcc: not found;再往后以太网 PHY 又认不出来,ping 不通宿主机,TFTP 拉不到内核,整条链路就卡死在第一步。
这套环境一共六份源码:buildroot-2021.02.1、gcc-linaro-6.5.0-2018.12 交叉编译器、linux-5.4.31、u-boot-v3s-current、alsa-lib/alsa-utils 1.2.2,以及宿主机上的 Qt 5.14.2。它们之间版本互相咬合,错一个后面全是连锁反应。适合手上已经有 V3S 板子、想从零把音视频界面跑起来的人,也适合之前装到一半放弃、想回来把环境补完整的人。
2. 源码与交叉编译器:gcc-linaro-6.5.0 的路径不能凭感觉写
2.1 六份源码先摆齐,版本对不上就别急着解压
先把要用的东西列成一张表,贴在自己项目的 README 里,比记在脑子里靠谱。版本之间有明确的对应关系:内核是 5.4.31,交叉编译器就得选内核头文件系列能对上的 6.5-2018.12;buildroot 2021.02.1 的 Toolchain 选项里正好能选5.4.x的头文件系列,选早了或选晚了,后面编 Qt 时都会以各种奇怪的方式报错。
| 文件 | 版本 | 用途 | 放置位置 |
|---|---|---|---|
| buildroot-2021.02.1.tar.xz | 2021.02.1 | 生成根文件系统 | ~/qz/tools |
| gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf.tar.xz | 6.5.0-2018.12 | 交叉编译器 | ~/qz/tools |
| linux-5.4.31.tar.gz | 5.4.31 | 内核 | ~/qz/kernel |
| u-boot-v3s-current.zip | current | 引导程序 | ~/qz/tools |
| alsa-lib-1.2.2.tar.bz2 | 1.2.2 | 音频库 | 后续交叉编译 |
| alsa-utils-1.2.2.tar.bz2 | 1.2.2 | aplay/amixer 等工具 | 后续交叉编译 |
| qt-opensource-linux-x64-5.14.2.run | 5.14.2 | 宿主机 Qt Creator | 宿主机安装 |
宿主机的编译依赖要一并装上,常见做法是提前装齐,省得编到一半再回来补:
sudo apt update sudo apt install -y build-essential bison flex libssl-dev \ libncurses5-dev device-tree-compiler unzip bc \ lib32z1 lib32stdc++6 rsyncbison、flex是 U-boot 和内核 Kconfig 解析要用的;libssl-dev影响内核模块签名相关配置;device-tree-compiler提供dtc,编译 dtb 时会调用;lib32z1、lib32stdc++6是跑 32 位工具链辅助程序时要的。少装一个,报错信息通常不会直接告诉你缺的是哪个包。
2.2 目录约定好,后面所有路径都好写
交叉编译环境的路径会出现在~/.bashrc、内核 Makefile、buildroot 的 Toolchain path 三个地方,目录不统一,改起来一定漏。我习惯在用户目录下建一套固定结构:
mkdir -p ~/qz/driver # 自己写的应用程序 mkdir -p ~/qz/tools # U-boot、交叉编译器、buildroot 压缩包 mkdir -p ~/qz/kernel # 内核源码 cd ~/qz/tools tar -xvf gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf.tar.xzx86_64表示这是跑在 64 位宿主机上的版本,arm-linux-gnueabihf表示产出的是 ARM 架构、Linux 系统、gnueabihf硬浮点 ABI 的可执行程序。V3S 是 Cortex-A7 带 VFPv3 硬浮点单元,所以后面所有配置里浮点策略都要选VFPv3,选软浮点会出现程序能跑但音视频解码慢到没法用的情况。
解压完成后,~/qz/tools下会多出一个长名字目录,这就是工具链的根。后面一律以$HOME/qz/tools/gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf表示,不要从别人文章里抄带用户名的绝对路径。
2.3 拿到 pwd 输出,环境变量只能照它写
很多人环境变量配错,就是因为抄了教程里的/home/xxx/...。正确做法是进到 bin 目录,让pwd告诉你真实路径:
cd ~/qz/tools/gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf/bin pwd # 输出示例:/home/dev/qz/tools/gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf/bin拿到这一行之后,再往~/.bashrc末尾追加:
vim ~/.bashrc # 文件末尾追加,路径换成上一步 pwd 的真实输出 export PATH=$PATH:/home/dev/qz/tools/gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf/bin source ~/.bashrcexport PATH=$PATH:...是把新路径追加到原有 PATH 后面,原命令一个不丢。如果你把$PATH:写掉了,变成export PATH=/xxx/bin,当前终端里ls、vim会全部失效,只能重开一个终端。
source ~/.bashrc是让改动立刻在当前 shell 生效,不 source 就得关掉终端重开。改完立刻自检:
which arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc -v要看到两样东西才算过:which指到~/qz/tools/...下的 bin 目录;-v输出里带gcc version 6.5.0 201812xx以及--with-arch=armv7-a --with-fpu=vfpv3-d16这类字样。如果-v显示的是宿主机自带的 gcc,说明 PATH 没生效或者写错了。
2.4 编一个 hello 验证工具链真的产出 ARM 程序
环境变量能查到不等于能编译,这一步别省:
cd ~/qz/driver cat > hello.c <<'EOF' #include <stdio.h> int main(void) { puts("v3s toolchain ok"); return 0; } EOF arm-linux-gnueabihf-gcc hello.c -o hello file hellofile的输出应该是ELF 32-bit LSB executable, ARM, EABI5 version 1, dynamically linked。如果看到x86-64,说明调用到了宿主机 gcc,回头查 PATH 顺序;如果提示找不到libc.so,一般是没有加-static,后面往板子上跑时用hello的静态版本验证更省事:
arm-linux-gnueabihf-gcc -static hello.c -o hello_static-static把 glibc 一起链进可执行文件,板子上根文件系统还没做好的阶段,静态程序是最省心的验证手段。动态链接版本依赖目标板的libc,根文件系统做好之后再验证不迟。
3. U-boot 与内核 5.4.31:一份设备树决定以太网能不能用
3.1 U-boot 解压并跑一遍 defconfig
cd ~/qz/tools unzip u-boot-v3s-current.zip cd u-boot-v3s-current make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LicheePi_Zero_defconfig三个参数各有分工:ARCH=arm告诉构建系统按 ARM 架构挑源码目录;CROSS_COMPILE=arm-linux-gnueabihf-指定工具链前缀,末尾那个短横不能漏,因为构建规则是$(CROSS_COMPILE)gcc拼出来的,少一个短横就会去找一个叫arm-linux-gnueabihf的可执行文件;LicheePi_Zero_defconfig是这块板子的默认配置模板。
终端打出# configuration written to .config才算成功,其它输出都可以先放着。
3.2 设备树里补 emac,两处都要改
U-boot 默认配置里没把以太网打开,得自己补。第一处在板级 dts:
/* arch/arm/dts/sun8i-v3s-licheepi-zero.dts */ aliases { serial0 = &uart0; ethernet0 = &emac; /* 让 U-boot 的 net 子系统能找到这块网卡 */ }; /* 文件末尾追加 */ &emac { phy = <&phy0>; phy-mode = "mii"; allwinner,use-internal-phy; /* 使用芯片内部 PHY,不走外部 PHY 芯片 */ allwinner,leds-active-low; status = "okay"; phy0: ethernet-phy@0 { reg = <1>; /* 内部 PHY 的 MDIO 地址是 1,不是 0 */ }; };第二处在arch/arm/dts/sun8i-v3s.dtsi,补 pinctrl 引脚组和 emac 控制器节点:
/* soc 节点内增加引脚复用 */ emac_rgmii_pins: emac0@0 { allwinner,pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD7", "PD8", "PD9", "PD10", "PD12", "PD13", "PD15", "PD16", "PD17"; allwinner,function = "emac"; allwinner,drive = <SUN4I_PINCTRL_40_MA>; allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; }; emac: ethernet@1c30000 { compatible = "allwinner,sun8i-h3-emac"; reg = <0x01c30000 0x104>, <0x01c00030 0x4>; reg-names = "emac", "syscon"; interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; resets = <&ccu RST_BUS_EMAC>, <&ccu RST_BUS_EPHY>; reset-names = "ahb", "ephy"; clocks = <&ccu CLK_BUS_EMAC>, <&ccu CLK_BUS_EPHY>; clock-names = "ahb", "ephy"; status = "disabled"; };phy-mode = "mii"是最关键的一项,写成rgmii会出现链路协商不上、ping全是 timeout 的现象。allwinner,use-internal-phy是 Allwinner 这套绑定的私有属性,别拿掉。reg = <1>对应内部 PHY 的 MDIO 地址,写成 0 的话 U-boot 会去总线上扫一个不存在的设备。
3.3 menuconfig 打开 sun8i GMAC 驱动
make ARCH=arm menuconfig路径是Device Drivers→Network device support→Ethernet driver support→ 勾上<*>Allwinner sun8i GMAC support。星号是编进内核镜像,M是编成模块——U-boot 阶段没有模块加载机制,必须选星号。
3.4 编译并用 dd 烧到 SD 卡
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- lsblk # 先确认哪块盘是 SD 卡,务必看清楚 sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdc bs=1024 seek=8 syncseek=8表示从设备第 8KB 处开始写,这是 sunxi 平台 SPL 的固定位置约定,改了板子起不来。/dev/sdc千万别凭记忆写,lsblk看清楚容量和挂载点,写错盘号的后果不用多说。sync是保证缓冲区落盘,拔卡前执行一下。
3.5 串口里配网络,ping 通宿主机才算过
接上串口,上电进 U-boot 命令行,把四个网络变量配齐:
=> setenv ipaddr 192.168.10.202 # 开发板自身地址 => setenv gatewayip 192.168.10.1 # 网关 => setenv serverip 192.168.10.201 # 宿主机(TFTP/NFS 服务器)地址 => setenv netmask 255.255.255.0 => saveenv => ping 192.168.10.201saveenv会把变量写进 MMC 的环境分区,下次上电还在。ping成功时输出是Using ethernet@1c30000 device加host 192.168.10.201 is alive;如果只打印No ethernet found,说明 3.2 和 3.3 里至少有一处没生效,回上一节逐条对。
宿主机侧要有对应配置:网线和板子直连或者同一交换机下,宿主机192.168.10.201这个地址要真的配在网卡上,防火墙别拦 ICMP。
3.6 内核 Makefile 改架构与编译器
cd ~/qz/kernel tar -xvf linux-5.4.31.tar.gz cd linux-5.4.31 vim Makefile找到这两行,没有就补上:
ARCH ?= arm CROSS_COMPILE ?= arm-linux-gnueabihf-?=的意思是“变量没定义才赋值”,所以更稳妥的习惯是不改 Makefile,在命令行传参:make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- ...。改 Makefile 的好处是后面敲命令短,坏处是万一哪天要编 x86 版本会莫名其妙出问题。两种都行,别混着用。
3.7 sunxi_defconfig 之后补 GMAC 和 NFS
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- sunxi_defconfig make ARCH=arm menuconfigdefault 配置里网卡和 NFS 都不全,逐项确认:
Device Drivers→Network device support→Ethernet driver support→<*>Allwinner sun8i GMAC support,同时<*>Generic driver for DWMACNetworking support→Networking options→<*>NFS client support,勾上 version 2 / 3 / 4,[*]Root file system on NFS
NFS 根文件系统是调试阶段最省时间的做法:改一个应用重新编,不用重新烧卡,重启板子就生效。等界面调试稳定了,再考虑把根文件系统固化到 SD 卡或者 SPI Flash。
3.8 内核设备树写法与 U-boot 不一样
这是最容易翻车的地方:U-boot 用phy = <&phy0>,内核 5.4 用的是phy-handle加 mdio-mux 的组合,两种写法不能互相抄。
板级 dts 里:
/* arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts */ aliases { serial0 = &uart0; ethernet0 = &emac; }; /* 文件末尾追加 */ &emac { phy-handle = <&int_mii_phy>; phy-mode = "mii"; allwinner,leds-active-low; status = "okay"; };sun8i-v3s.dtsi里补 emac、mdio、mdio-mux 和 syscon:
emac: ethernet@1c30000 { compatible = "allwinner,sun8i-v3s-emac"; syscon = <&syscon>; reg = <0x01c30000 0x10000>; interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "macirq"; resets = <&ccu RST_BUS_EMAC>; reset-names = "stmmaceth"; clocks = <&ccu CLK_BUS_EMAC>; clock-names = "stmmaceth"; phy-handle = <&int_mii_phy>; phy-mode = "mii"; status = "disabled"; mdio: mdio { compatible = "snps,dwmac-mdio"; }; mdio_mux: mdio-mux { compatible = "allwinner,sun8i-h3-mdio-mux"; mdio-parent-bus = <&mdio>; internal_mdio: mdio@1 { compatible = "allwinner,sun8i-h3-mdio-internal"; reg = <1>; int_mii_phy: ethernet-phy@1 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <1>; clocks = <&ccu CLK_BUS_EPHY>; resets = <&ccu RST_BUS_EPHY>; }; }; }; };mdio-mux是这一版内核挂内部 PHY 的必需节点,缺了它,启动日志里会出现no phy at addr -1之类的字样,eth0怎么也起不来。int_mii_phy的reg = <1>和 U-boot 里的phy0: ethernet-phy@0 { reg = <1>; }是同一个地址,两边必须一致。
3.9 编 uImage 与 dtb,拷进 tftp 目录
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12 uImage LOADADDR=0x41000040 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs mkdir -p /tftpboot cp arch/arm/boot/uImage /tftpboot/ cp arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dtb /tftpboot/LOADADDR=0x41000040是内核加载地址,不同文档给出的值可能不一样,跟着自己这套源码的约定走,改错的表现是板子跑到加载内核那一步直接重启。-j12是并行编译核数,按宿主机 CPU 核数调到一半左右,内存小的虚拟机建议降到-j4,否则容易在链接阶段被 OOM kill 掉。
4. buildroot-2021.02.1:外部工具链路径手抄必错
4.1 解压与 Target options 五个选项
cd ~/qz/tools tar -xvf buildroot-2021.02.1.tar.xz cd buildroot-2021.02.1 make ARCH=arm menuconfigTarget options里逐项对齐:
Target Architecture:ARM (little endian)Target Binary Format:ELFTarget Architecture Variant:cortex-A7Target ABI:EABIhfFloating point strategy:VFPv3ARM instruction set:ARM
这六项和 2.2 里提到的硬浮点 ABI 是一一对应的。cortex-A7选成cortex-A9虽然通常还能跑,但生成的指令集不完全匹配;EABIhf选成EABI就会和宿主机上的工具链 ABI 冲突,最终表现是程序编译通过、板子上一跑就Illegal instruction。
4.2 Toolchain 必须选 External + Custom
Toolchain菜单里改动最多,也最容易错:
Toolchain type (External toolchain) # 不用 buildroot 自己编工具链 Toolchain (Custom toolchain) # 用我们自己装的那套 Toolchain origin (Pre-installed toolchain) # 已经装在宿主机上 Toolchain path (/home/dev/qz/tools/gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf) Toolchain prefix (arm-linux-gnueabihf) # 注意:不带末尾的短横 External toolchain gcc version (6.x) External toolchain kernel headers series (5.4.x) External toolchain C library (glibc/eglibc) [*] Toolchain has SSP support? [*] Toolchain has RPC support? [*] Toolchain has C++ support? # 编 Qt 必须勾 [*] Enable MMU supportToolchain path填到工具链根目录,不要带/bin。写成.../bin的后果是 buildroot 拼出.../bin/arm-linux-gnueabihf-gcc这种路径去探测,探测失败时错误信息藏在output/build/toolchain-external-custom/下的日志里,翻半天才能定位。
Toolchain prefix填arm-linux-gnueabihf,不要带末尾短横,buildroot 自己会拼。这一项和CROSS_COMPILE的写法刚好相反,不少人在这里翻车。
kernel headers series选5.4.x,跟 5.4.31 内核对齐。选低版本会导致 glibc 编出来的东西调用不到某些系统调用;选高版本可能引入 5.4.31 里不存在的接口。
C++ support必须勾上,后面 Qt 5.14.2 要用到 C++11 甚至部分 C++14 特性。
4.3 生成的根文件系统在哪,怎么用
配置好之后:
make -j8产物在output/images/下,常见的是rootfs.tar、rootfs.ext4、rootfs.ext2几种格式。用 NFS 挂载调试时,把output/target/整个目录作为 NFS 导出目录即可:
# 宿主机 /etc/exports /home/dev/qz/tools/buildroot-2021.02.1/output/target 192.168.10.0/24(rw,sync,no_root_squash,no_subtree_check) sudo exportfs -rano_root_squash让开发板上的 root 用户保留 root 权限,做应用调试时不用反复 chmod;no_subtree_check关掉子树检查,减少 NFS 路径变更后的异常。这两项在正式发布环境里都该关掉,调试阶段图省事。
4.4 alsa-lib、alsa-utils 与 Qt 5.14.2 各归各位
这里有个容易误解的点:源码清单里那份qt-opensource-linux-x64-5.14.2.run是x64 宿主机版本,装在自己电脑上写代码、做交叉编译工程用的,它不能装到 V3S 板子上。板子上的 Qt 库有两个来源:要么在 buildroot 的Package Selection for the target里勾 Qt5,要么自己用交叉编译器单独编一份 Qt 5.14.2 再放到根文件系统里。
音频侧同理。alsa-lib-1.2.2是应用层要链接的库,alsa-utils-1.2.2提供aplay、arecord、amixer这些命令。调试顺序上,我一般先编 alsa-lib,再编 alsa-utils,最后跑 Qt:
cd ~/qz/driver tar -xjf ~/qz/tools/alsa-lib-1.2.2.tar.bz2 cd alsa-lib-1.2.2 ./configure --host=arm-linux-gnueabihf --prefix=$HOME/qz/driver/alsa-out \ --disable-python --disable-static make -j8 && make install--host=arm-linux-gnueabihf让 configure 用交叉编译器而不是宿主机 gcc;--prefix指到一个临时输出目录,方便统一拷到板子上;--disable-python关掉 Python 绑定,目标板上用不到,关掉能省下不少交叉编译的麻烦。
5. 避坑与排查:这几处报错我踩过不止一次
5.1 现象:终端提示arm-linux-gnueabihf-gcc: command not found
原因:~/.bashrc里写的是别人电脑上的路径,比如/home/farsight/...;或者只在一个终端里export PATH=...,新开终端就丢了。
解决:回到 2.3 节,在工具链 bin 目录下执行pwd拿真实路径,~/.bashrc里改成自己的;改完source ~/.bashrc,然后which arm-linux-gnueabihf-gcc确认。长期做法是把这套路径写进项目里的env.sh,每次开终端source env.sh,不依赖个人家目录。
5.2 现象:U-boot 启动后敲ping提示No ethernet found
原因:两种可能。一是 3.3 节 menuconfig 里Allwinner sun8i GMAC support没勾成星号;二是 dts 里&emac节点的status还是"disabled",或者aliases里没加ethernet0 = &emac;。
解决:先看menuconfig里那项是不是<*>,再grep -n "status" arch/arm/dts/sun8i-v3s-licheepi-zero.dts确认okay,重新make之后重新dd烧录。改完 dts 一定要重烧,只重新编不烧是最常见的“改了没效果”。
5.3 现象:内核启动日志里出现no phy at addr -1,eth0起不来
原因:把 U-boot 的 dts 写法直接抄进了内核。U-boot 用phy = <&phy0>加allwinner,use-internal-phy,内核 5.4 用的是phy-handle = <&int_mii_phy>加mdio-mux套internal_mdio。
解决:按 3.8 节把mdio、mdio_mux、internal_mdio、int_mii_phy四个节点补全,phy-handle指到int_mii_phy。改完make dtbs,只换 dtb 文件就能验证,不用重编整个内核。
5.4 现象:内核挂载 NFS 根文件系统时卡住,最后报VFS: Unable to mount root fs on unknown-block
原因:menuconfig里Root file system on NFS没勾,或者宿主机serverip和 NFS 服务不在同一网段,也可能是/etc/exports改完没exportfs -ra。
解决:按 3.7 节把 NFS 三项勾全;宿主机上showmount -e 192.168.10.201看导出列表是否包含目标目录;再rpcinfo -p确认nfs服务在跑。交叉验证顺序是“U-boot 能 ping 通 → 能 tftp 拉到文件 → 再谈 NFS 挂载”,前两步没过就别折腾 NFS。
5.5 现象:buildroot 编到一半报 toolchain 探测失败,日志里全是No such file
原因:Toolchain path手抄成了带/bin的路径,或者Toolchain prefix末尾多了短横。buildroot 的探测脚本拿到这种路径拼出来的命令一定不存在。
解决:Toolchain path填到gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf这一层为止,Toolchain prefix填arm-linux-gnueabihf不带短横。改完先make clean,再重新make menuconfig保存一次,让探测脚本重跑。这类错误不看日志很难猜,output/build/toolchain-external-custom/下的config.log是唯一线索。
6. 装完怎么验证:从 ping 通到屏幕出声的四步验收
环境装没装好,不看编译有没有报错,看板子跑起来之后这四步能不能连续过。
第一步,串口有完整的启动日志。打开串口工具(115200 8N1),上电后应能看到 U-boot 的U-Boot 20xx.xx版本号,然后Hit any key to stop autoboot倒计时。能停在这里,说明 3.4 节的dd偏移写对了。
第二步,U-boot 里网络通。按 3.5 节配完四个变量,执行:
=> ping 192.168.10.201 Using ethernet@1c30000 device host 192.168.10.201 is alive => tftp 0x41000000 uImageis alive和 tftp 的Bytes transferred = ...都出现了,说明 U-boot 侧设备树、驱动、网络配置三项全对。后面就算内核起不来,也能靠 tftp 反复换镜像调试,不至于每次都要拔卡。
第三步,内核起来、网卡就绪、根文件系统挂上。启动日志里应该出现类似下面的行:
[ 0.000000] Booting Linux on physical CPU 0x0 [ 1.2xxxxx] sun8i-v3s-emac 1c30000.ethernet: PHY ID xxxxxxxx at 0 IRQ POLL [ 2.1xxxxx] VFS: Mounted root (nfs filesystem) on device 0:14.第一行证明内核加载地址正确,第二行证明内部 PHY 挂上了并且认到了 ID,第三行证明 NFS 根文件系统挂载成功。登录进系统后ip addr看到eth0有地址,ifconfig里 RX/TX 计数会随 ping 增长。
第四步,声卡与图形界面。这一步直接决定音视频开发能不能往下走:
# 板子上执行 aplay -l cat /proc/asound/cardsaplay -l能列出 card 0 及 playback 设备,说明 alsa-lib 和内核声卡驱动都到位。然后插一张 48kHz 的 wav,aplay test.wav,耳机口有声音。最后跑 Qt 程序验证:
export QT_QPA_PLATFORM=linuxfb ./your_qt_app -platform linuxfbQT_QPA_PLATFORM=linuxfb让 Qt 走 framebuffer,不需要 X11 或者 Wayland,V3S 这类资源有限的板子基本都是这个跑法。屏幕上出画面、触摸或按键有响应、音频同步出声,这套全志 V3S 音视频开发环境才算真正验收完。
从那以后我每次拿到一块新板子,都先把“串口日志 → ping 通 → aplay -l”这三步强制走一遍,再动 Qt 和音视频代码,中间少走的路比多写几行业务代码省时间得多。希望帮到你。
本文还有配套的精品资源,点击获取