使用指南
本文档介绍 Quectel Pi H1 单板电脑的常用功能和使用方法,包括音频服务、NPU应用、系统配置工具和机器学习模型部署等内容。
音频与多媒体
PulseAudio 音频服务
PulseAudio 是 Linux 环境下主流的音频服务系统,它介于应用程序和底层音频架构(TinyALSA)之间,负责管理音频流、混合多路音频以及路由到不同的输出设备。
PulseAudio 概述
PulseAudio 是一个跨平台的、可通过网络工作的声音服务,它从一个或多个音源(进程或输入设备)接受声音输入,然后重定向声音到一个或多个槽(声卡,远程网络 PulseAudio 服务,或其他进程)。它与最底层的 ALSA (Advanced Linux Sound Architecture) 交互,并为应用程序提供统一的接口,从而实现多路音频混合、音频转发等高级功能。
查看声卡信息
在终端中输入下面命令,查看声卡的挂载情况:
root@qcm6490-idp:/opt# cat /proc/asound/cards
0 [qcm6490idpsndca]: qcm6490 - qcm6490-idp-snd-card
qcm6490-idp-snd-card
设备查看与管理
查看可用输出设备 (Sinks)
要查看系统当前可用的音频输出设备及其详细信息,可以使用以下命令,此命令会列出所有可用的sink(输出设备)的索引(index)和名称(name)。输出示例:
root@qcm6490-idp:/# pactl list short sinks
0 low-latency0 module-pal-card.c s16le 1ch 16000Hz SUSPENDED
1 deep-buffer0 module-pal-card.c s16le 2ch 48000Hz SUSPENDED
2 offload0 module-pal-card.c s16le 2ch 48000Hz SUSPENDED
3 voip-rx0 module-pal-card.c s16le 2ch 48000Hz SUSPENDED
其中,* 号标记表示当前默认的输出设备。
若要获取更详细的设备信息,请使用:
root@qcm6490-idp:/# pactl list sinks
Sink #0
State: SUSPENDED
Name: low-latency0
Description: pal sink to play via low-latency path
Driver: module-pal-card.c
Sample Specification: s16le 1ch 16000Hz
Channel Map: mono
Owner Module: 1
Mute: no
Volume: mono: 65536 / 100%
balance 0.00
Base Volume: 65536 / 100%
Monitor Source: low-latency0.monitor
Latency: 0 usec, configured 0 usec
Flags: HARDWARE HW_VOLUME_CTRL LATENCY
Properties:
device.string = "low_latency"
device.description = "pal sink to play via low-latency path"
device.icon_name = "audio-card"
Ports:
speaker: speaker (type: Unknown, priority: 200, available)
headset: headset (type: Unknown, priority: 100, available)
Active Port: speaker
Formats:
pcm
Sink #1
State: SUSPENDED
Name: deep-buffer0
Description: pal sink to play via deep buffer path
Driver: module-pal-card.c
Sample Specification: s16le 2ch 48000Hz
Channel Map: front-left,front-right
Owner Module: 1
Mute: no
Volume: front-left: 65536 / 100%, front-right: 65536 / 100%
balance 0.00
Base Volume: 65536 / 100%
Monitor Source: deep-buffer0.monitor
Latency: 0 usec, configured 0 usec
Flags: HARDWARE HW_VOLUME_CTRL LATENCY
Properties:
device.string = "deep_buffer"
device.description = "pal sink to play via deep buffer path"
device.icon_name = "audio-card"
Ports:
speaker: speaker (type: Unknown, priority: 200, available)
headset: headset (type: Unknown, priority: 100, available)
bta2dp-out: BT a2dp source port (type: Unknown, priority: 50, not available)
Active Port: speaker
Formats:
pcm
Sink #2
State: SUSPENDED
Name: offload0
Description: pal sink to play compressed via offload path
Driver: module-pal-card.c
Sample Specification: s16le 2ch 48000Hz
Channel Map: front-left,front-right
Owner Module: 1
Mute: no
Volume: front-left: 65536 / 100%, front-right: 65536 / 100%
balance 0.00
Base Volume: 65536 / 100%
Monitor Source: offload0.monitor
Latency: 0 usec, configured 0 usec
Flags: HARDWARE HW_VOLUME_CTRL LATENCY
Properties:
device.string = "offload"
device.description = "pal sink to play compressed via offload path"
device.icon_name = "audio-card"
Ports:
speaker: speaker (type: Unknown, priority: 200, available)
headset: headset (type: Unknown, priority: 100, available)
bta2dp-out: BT a2dp source port (type: Unknown, priority: 50, not available)
Active Port: speaker
Formats:
mpeg
aac
Sink #3
State: SUSPENDED
Name: voip-rx0
Description: pal sink to play via voip rx path
Driver: module-pal-card.c
Sample Specification: s16le 2ch 48000Hz
Channel Map: front-left,front-right
Owner Module: 1
Mute: no
Volume: front-left: 65536 / 100%, front-right: 65536 / 100%
balance 0.00
Base Volume: 65536 / 100%
Monitor Source: voip-rx0.monitor
Latency: 0 usec, configured 0 usec
Flags: HARDWARE HW_VOLUME_CTRL LATENCY
Properties:
device.string = "voip_rx"
device.description = "pal sink to play via voip rx path"
device.icon_name = "audio-card"
Ports:
speaker: speaker (type: Unknown, priority: 200, available)
headset: headset (type: Unknown, priority: 100, available)
btsco-out: BT SCO sink port (type: Unknown, priority: 50, not available)
Active Port: speaker
Formats:
pcm
查看输入设备 (Sources)
类似地,可以查看音频输入设备(如麦克风):
root@qcm6490-idp:/# pactl list short sources
0 low-latency0.monitor module-pal-card.c s16le 1ch 16000Hz SUSPENDED
1 deep-buffer0.monitor module-pal-card.c s16le 2ch 48000Hz SUSPENDED
2 offload0.monitor module-pal-card.c s16le 2ch 48000Hz SUSPENDED
3 voip-rx0.monitor module-pal-card.c s16le 2ch 48000Hz SUSPENDED
4 regular0 module-pal-card.c s16le 2ch 48000Hz SUSPENDED
5 regular2 module-pal-card.c s16le 2ch 48000Hz SUSPENDED
6 voip-tx0 module-pal-card.c s16le 1ch 48000Hz SUSPENDED
录音
板载 DMIC 录音
root@qcm6490-idp:~# pactl set-source-port 5 speaker-mic
root@qcm6490-idp:~# parec -d 5 --file-format=wav output.wav
3.5mm 耳机录音
使用 3.5mm 耳机录制前需将 gpio8 和 gpio68 电平置高。
root@qcm6490-idp:/opt# rgpiod &
root@qcm6490-idp:/opt# sleep 1
root@qcm6490-idp:/opt# rgs c 999 go 4
root@qcm6490-idp:/opt# rgs c 999 gso 0 8
root@qcm6490-idp:/opt# rgs c 999 gw 0 8 1
root@qcm6490-idp:/opt# rgs c 999 gso 0 68
root@qcm6490-idp:/opt# rgs c 999 gw 0 68 1
- gpio8:耳机国标/美标切换控制开关,置0:欧标,置1:美标
- gpio68:耳机电源供电使能开关,置0:禁用,置1:使能
root@qcm6490-idp:~# pactl set-source-port 5 headset-mic
root@qcm6490-idp:~# parec -d 5 --file-format=wav output1.wav
播放
喇叭播放
GPIO控制PA的使能开关:
rgpiod &
sleep 1
rgs c 999 go 4
rgs c 999 gso 0 142
rgs c 999 gw 0 142 1
root@qcm6490-idp:~# pactl set-sink-port 0 speaker
root@qcm6490-idp:~# paplay output.wav
3.5mm 耳机播放
root@qcm6490-idp:~# pactl set-sink-port 0 headset
root@qcm6490-idp:~# paplay output1.wav
TinyALSA 直连音频测试
Quectel Pi H1 单板电脑支持外置 MIC 录制、3.5mm 耳机录制与播放等多种直连音频链路,以下示例基于 TinyALSA/AGM 工具链说明如何直接访问声卡。
查看声卡信息
- 在终端中输入下面命令,查看声卡的挂载情况:
root@qcm6490-idp:/opt# cat /proc/asound/cards
0 [qcm6490idpsndca]: qcm6490 - qcm6490-idp-snd-card
qcm6490-idp-snd-card
- 在终端中输入下面命令,查看已分配的 pcm 流列表:
root@qcm6490-idp:/opt# cat /proc/asound/pcm
00-00: CODEC_DMA-LPAIF_RXTX-RX-0 multicodec-0 : : playback 1
00-01: CODEC_DMA-LPAIF_RXTX-TX-3 multicodec-1 : : capture 1
00-02: CODEC_DMA-LPAIF_VA-TX-0 va_macro_tx1-2 : : capture 1
外置 MIC 录制
- 停止 PulseAudio 避免占用音频设备,并设置采集链路:
root@qcm6490-idp:/opt# systemctl stop pulseaudio
root@qcm6490-idp:/opt# tinymix set "VA DMIC MUX0" "DMIC0"
root@qcm6490-idp:/opt# tinymix set "VA_AIF1_CAP Mixer DEC0" "1"
root@qcm6490-idp:/opt# tinymix set "VA_DEC0 Volume" "100"
root@qcm6490-idp:/opt# agmcap test1.wav -D 100 -d 101 -c 1 -r 48000 -b 16 -i "CODEC_DMA-LPAIF_VA-TX-0"
-c 1单声道录音-r 48000采样率 48 kHz-b 16采样位深 16-bit-i "CODEC_DMA-LPAIF_VA-TX-0"指定输入设备接口
- 按
Ctrl+C停止录制,当前目录生成test1.wav文件:
root@qcm6490-idp:/opt# ls
cni containerd test1.wav
3.5mm 耳机录制
- 将
gpio8、gpio68置高,打开耳机标准切换与电源:
root@qcm6490-idp:/opt# rgpiod &
root@qcm6490-idp:/opt# sleep 1
root@qcm6490-idp:/opt# rgs c 999 go 4
root@qcm6490-idp:/opt# rgs c 999 gso 0 8
root@qcm6490-idp:/opt# rgs c 999 gw 0 8 1
root@qcm6490-idp:/opt# rgs c 999 gso 0 68
root@qcm6490-idp:/opt# rgs c 999 gw 0 68 1
- 配置录制链路并开始采集:
root@qcm6490-idp:/opt# systemctl stop pulseaudio
root@qcm6490-idp:/opt# tinymix set "TX DEC0 MUX" "SWR_MIC"
root@qcm6490-idp:/opt# tinymix set "TX SMIC MUX0" "ADC1"
root@qcm6490-idp:/opt# tinymix set "TX_AIF1_CAP Mixer DEC0" "1"
root@qcm6490-idp:/opt# tinymix set "ADC2 MUX" "INP2"
root@qcm6490-idp:/opt# tinymix set "ADC2 Switch" "1"
root@qcm6490-idp:/opt# tinymix set "ADC2_MIXER Switch" "1"
root@qcm6490-idp:/opt# tinymix set "TX_DEC0 Volume" "80"
root@qcm6490-idp:/opt# tinymix set "ADC2 Volume" "20"
root@qcm6490-idp:/opt# agmcap test2.wav -D 100 -d 101 -c 1 -r 48000 -b 16 -i "CODEC_DMA-LPAIF_RXTX-TX-3"
- 按
Ctrl+C停止录制,test2.wav文件生成在当前目录:
root@qcm6490-idp:/opt# ls
cni containerd test2.wav
3.5mm 耳机播放
- 同样先拉高
gpio8、gpio68以启用耳机:
root@qcm6490-idp:/opt# rgpiod &
root@qcm6490-idp:/opt# sleep 1
root@qcm6490-idp:/opt# rgs c 999 go 4
root@qcm6490-idp:/opt# rgs c 999 gso 0 8
root@qcm6490-idp:/opt# rgs c 999 gw 0 8 1
root@qcm6490-idp:/opt# rgs c 999 gso 0 68
root@qcm6490-idp:/opt# rgs c 999 gw 0 68 1
- 设置播放路径并使用
agmplay输出音频:
root@qcm6490-idp:/opt# systemctl stop pulseaudio
root@qcm6490-idp:/opt# tinymix set "RX_MACRO RX0 MUX" "AIF1_PB"
root@qcm6490-idp:/opt# tinymix set "RX_MACRO RX1 MUX" "AIF1_PB"
root@qcm6490-idp:/opt# tinymix set "RX INT0_1 MIX1 INP0" "RX0"
root@qcm6490-idp:/opt# tinymix set "RX INT1_1 MIX1 INP0" "RX1"
root@qcm6490-idp:/opt# tinymix set "RX INT0 DEM MUX" "CLSH_DSM_OUT"
root@qcm6490-idp:/opt# tinymix set "RX INT1 DEM MUX" "CLSH_DSM_OUT"
root@qcm6490-idp:/opt# tinymix set "RX_COMP1 Switch" "1"
root@qcm6490-idp:/opt# tinymix set "RX_COMP2 Switch" "1"
root@qcm6490-idp:/opt# tinymix set "HPHL Switch" "1"
root@qcm6490-idp:/opt# tinymix set "HPHR Switch" "1"
root@qcm6490-idp:/opt# tinymix set "HPHL_RDAC Switch" "1"
root@qcm6490-idp:/opt# tinymix set "HPHR_RDAC Switch" "1"
root@qcm6490-idp:/opt# agmplay test.wav -D 100 -d 100 -i "CODEC_DMA-LPAIF_RXTX-RX-0"
- 音频播放完会自动停止,若想提前停止,可按
Ctrl+C。
AI 与机器学习
NPU 应用场景
在 Quectel Pi H1 单板电脑中,NPU 资源应用场景包括:图像分类、目标检测、语义分割等。下面以图像分类中的 ResNeXt50 机器学习模型为例,可以对 Imagenet 数据集中的图像进行分类。它还可以作为构建更复杂模型的主干,用于特定用例。
下载量化模型
部署模型
将模型和标签文件部署到 Quectel Pi H1 中,通过 adb 或者 scp 把这两个部署到 /opt 目录下。
模型特性:
- 模型检查点:Imagenet
- 输入分辨率:224x224
- 参数数量:88.7M
- 模型大小:87.3 MB
连接显示器
准备显示器,并连接显示器到 Quectel Pi H1 上。
运行命令
在设备终端运行以下命令以确保结果显示在连接的显示器上:
export XDG_RUNTIME_DIR=/dev/socket/weston && export WAYLAND_DISPLAY=wayland-1
在设备中运行以下命令:
gst-launch-1.0 -e --gst-debug=2 filesrc location=/opt/video11.mp4 ! qtdemux ! queue ! h264parse ! v4l2h264dec capture-io-mode=5 output-io-mode=5 ! queue ! tee name=split split. ! queue ! qtivcomposer name=mixer sink_1::position="<30, 30>" sink_1::dimensions="<640, 360>" ! queue ! waylandsink sync=true fullscreen=true split. ! queue ! qtimlvconverter ! queue ! qtimltflite delegate=external external-delegate-path=libQnnTFLiteDelegate.so external-delegate-options="QNNExternalDelegate,backend_type=htp;" model=/opt/resnext50_quantized.tflite ! queue ! qtimlvclassification threshold=35.0 results=5 module=mobilenet labels=/opt/imagenet_labels.txt extra-operation=softmax constants="Resnetnet,q-offsets=<30.0>,q-scales=<0.06314703077077866>;" ! video/x-raw,format=BGRA,width=256,height=144 ! queue ! mixer.
命令说明
- gst-launch-1.0:这是 GStreamer 的命令行工具,用于启动一个 GStreamer 管道(pipeline)。-e 参数表示在管道结束时退出,而不是继续运行。
- --gst-debug=2:设置调试级别为 2,显示调试信息
- filesrc location=/opt/video11.mp4:指定输入视频文件路径。
- !:是一个连接符号,用于将前一个元素的输出连接到后一个元素的输入。
- qtdemux:将输入视频文件解析为多个流。
- queue:用于缓冲输入数据。
- h264parse:将输入数据解析为 H.264 格式。
- v4l2h264dec:将 H.264 格式的数据解码为 YUV 格式。
- capture-io-mode=5:指定解码器输入端口(Capture Side)的内存访问模式。
- output-io-mode=5:指定解码器输出端口(Output Side)的内存访问模式。
- tee name=split:将输入数据分割为两个分支。
- split.:第一个分支用于显示原始视频流。
- qtivcomposer:用于组合多个视频流。
- waylandsink:将组合后的视频流显示在屏幕上。
- split.:第二个分支用于进行图像分类。
- qtimlvconverter:用于将输入数据转换为模型输入格式。
- qtimltflite:用于执行模型推理。
- delegate=external:使用外部加速库(即非 TFLite 默认的 CPU 后端)来运行模型推理,通常用于调用硬件加速器。
- external-delegate-path=libQnnTFLiteDelegate.so:指定 TensorFlow Lite 的外部加速库(Delegate)的路径。
- external-delegate-options="QNNExternalDelegate,backend_type=htp;":指定外部加速库的选项,这里指定了后端类型为 HTP(High-Throughput Processing)。
- model=/opt/resnext50_quantized.tflite:指定模型路径。
- qtimlvclassification:用于对模型输出进行分类。
- video/x-raw,format=BGRA,width=256,height=144:指定输出视频格式和尺寸。
- mixer:将两个分支的输出组合在一起。
- threshold=35.0:设置置信度阈值,用于过滤低置信度的分类结果。
- results=5:设置返回的分类结果数量。
- module=mobilenet:指定使用的模型名称。
- labels=/opt/imagenet_labels.txt:指定标签文件路径。
- extra-operation=softmax:对模型输出进行Softmax操作,得到每个类别的概率。
- constants="Resnetnet,q-offsets=<30.0>,q-scales=<0.06314703077077866>;":指定模型量化参数。
运行结果
运行命令后,显示器会显示视频流和图像分类结果。

TensorFlow Lite 简介
TensorFlow Lite 是一套工具,通过帮助开发人员在移动设备、嵌入式设备和边缘设备上运行模型,实现设备机器学习。下面以姿态估计中的 posenet 机器学习模型为例,演示实时推理与显示流程。
下载 posenet 模型
部署模型
- 将模型和标签文件部署到 Quectel Pi H1 中,通过 adb 或者 scp 把文件放在 /opt/ 目录。
- 模型特性:
- 模型检查点:mobilenet_v1_101
- 输入分辨率:513x257
- 参数数量:3.31M
- 模型大小:12.7 MB
连接摄像头和显示器
- 准备 MIPI 摄像头,并连接到第一个 CSI 插槽。
- 准备 HDMI 显示器,并连接至开发板。
使用 TFLite 进行姿势估计和显示
- 设置 Wayland 环境变量:
export XDG_RUNTIME_DIR=/dev/socket/weston && export WAYLAND_DISPLAY=wayland-1
- 启动实时姿势估计:
setprop persist.overlay.use_c2d_blit 2
gst-launch-1.0 -e \
qtiqmmfsrc name=camsrc camera=0 ! video/x-raw\(memory:GBM\),format=NV12,width=1280,height=720,framerate=30/1,compression=ubwc ! queue ! tee name=split \
split. ! queue ! qtimetamux name=metamux ! queue ! qtioverlay ! queue ! waylandsink fullscreen=true sync=false \
split. ! queue ! qtimlvconverter ! queue ! qtimltflite delegate=external external-delegate-path=libQnnTFLiteDelegate.so external-delegate-options="QNNExternalDelegate,backend_type=htp;" model=/opt/posenet_mobilenet_v1.tflite ! queue ! qtimlvpose threshold=51.0 results=2 module=posenet labels=/opt/posenet_mobilenet_v1.labels constants="Posenet,q-offsets=<128.0,128.0,117.0>,q-scales=<0.0784313753247261,0.0784313753247261,1.3875764608383179>;" ! text/x-raw ! queue ! metamux.
关键命令说明
- gst-launch-1.0:构建 GStreamer pipeline,
-e确保结束时释放资源。 - qtiqmmfsrc:基于 QMMF 的摄像头源,
camera=0选择第一个 CSI 接口。 - tee name=split:复制原始视频流,分别用于显示与推理。
- qtimlvconverter:将 NV12 视频帧转换成模型输入张量。
- qtimltflite:调用 TensorFlow Lite + QNN delegate,以 HTP 加速模型推理。
- qtimlvpose:对推理结果做姿态解码并输出人体关键点。
- qtioverlay/qtimetamux:将关键点叠加到视频帧并通过
waylandsink输出。
运行结果
运行命令后,显示器会显示 camera 流和姿势估计结果。测试示例
系统配置与监控
quecpi_config 是一个用于配置 Quectel Pi H1 的工具,提供下列功能:
- 配置板载LED工作模式和亮度
- 配置风扇接口工作模式和风扇转速
- 配置40pin接口工作模式
- 查询系统各组件温度
- 查询系统cpu、内存和存储状态
- 配置wifi
板载LED配置
配置工作模式
quecpi_config led mode <blue|green|red> <heartbeat|none>
配置亮度
quecpi_config led brightness <blue|green|red> <0-511>
风扇配置
配置风扇转速
quecpi_config fan set speed <0-255>
40pin接口工作模式配置
先修改配置文件 /etc/quecpi_config/quecpi_config.ini,再运行以下命令进行配置:
quecpi_config 40pin set
查询系统各组件温度
quecpi_config dump temperature
查询系统cpu、内存和存储状态
quecpi_config dump systemusage
配置wifi
扫描wifi
quecpi_config wifi scan
查看已存在wifi连接
quecpi_config wifi show
查看wifi连接状态
quecpi_config wifi dump <connection uuid>
添加wifi连接
quecpi_config wifi connect <ssid> <password>
删除wifi连接
quecpi_config wifi delete <connection uuid>
40PIN 与接口扩展


40PIN 中部分低速接口(i2c9/spi10/uart12_2w/i2c13/spi14)配置文件位于 /etc/quecpi_config/quecpi_config.ini,配置步骤为:
- 修改 quecpi_config.ini 配置
- 应用配置
quecpi_config 40pin set
- 重启生效
GPIO 测试
选取一个 40pin 的 GPIO 引脚来测试 GPIO 功能,例如选取 40pin 的 pin3 引脚进行测试,pin3 对应的 gpio_num 为 36。各引脚对应的 gpio_num 信息可以从引脚映射表中查找。
连接示意图,其中红色线接万用表正极,白色线接万用表负极:

使用 SHELL 命令控制
系统已默认启用 lgpiod 服务,依次执行如下命令来测试 40pin 的 pin3 引脚的 gpio功能:
rgs c 999 go 4#使用 go 命令打开文件 /dev/gpiochip4rgs c 999 gso 0 36#使用 gso 命令设置 gpio 36 为输出模式,这条命令里的 0 是上一条命令的返回内容,根据实际情况修改rgs c 999 gw 0 36 0#设置 gpio 36 为低电平,这个时候测试引脚电压值为 0Vrgs c 999 gw 0 36 1#设置 gpio 36 为高电平,这个时候测试引脚电压值为 3.3V
使用 C 代码控制
新建 gpio.c 文件,内容如下:
#include <stdlib.h> #include <lgpio.h> int main(int argc, char **argv) { int gpio_num = atoi(argv[1]); int pin_level = atoi(argv[2]); int handle = lgGpiochipOpen(4); lgGpioClaimOutput(handle, 0, gpio_num, 0); lgGpioWrite(handle, gpio_num, pin_level); }编译:gcc -o gpio gpio.c -llgpio
执行:./gpio 36 0 #设置 gpio 36 为低电平,这个时候测试引脚电压值为 0V
执行:./gpio 36 1 #设置 gpio 36 为高电平,这个时候测试引脚电压值为 3.3V
I2C 测试
40PIN 的 pin3 和 pin5 默认是 I2C 的 data 和 clock 引脚,对应设备节点 /dev/i2c9,若节点没出来可以先使用本章开头部分的 quecpi_config 进行配置使能。
测试 I2C 接口需要外接一个 I2C 设备,这里选择微雪环境传感器扩展板,通过 40pin 接口进行连接。
连接示意图:
微雪环境传感器扩展板
QuecPi 40PIN引脚
插上环境传感器扩展板的Quectel Pi H1
使用 C 代码控制
测试步骤:
新建 envtest.c 文件,内容如下:
#include <stdio.h> #include <lgpio.h> #define I2C_DEV_NUM 9 #define BME280_ADDR 0x76 int32_t digT[3],digP[9],digH[6]; int32_t t_fine = 0.0; double compensate_P(int32_t adc_P) { double pressure = 0.0; double v1,v2; v1 = (t_fine / 2.0) - 64000.0; v2 = (((v1 / 4.0) * (v1 / 4.0)) / 2048) * digP[5]; v2 = v2 + ((v1 * digP[4]) * 2.0); v2 = (v2 / 4.0) + (digP[3] * 65536.0); v1 = (((digP[2] * (((v1 / 4.0) * (v1 / 4.0)) / 8192)) / 8) + ((digP[1] * v1) / 2.0)) / 262144; v1 = ((32768 + v1) * digP[0]) / 32768; if(v1 == 0) return 0; pressure = ((1048576 - adc_P) - (v2 / 4096)) * 3125; if (pressure < 0x80000000) pressure = (pressure * 2.0) / v1; else pressure = (pressure / v1) * 2; v1 = (digP[8] * (((pressure / 8.0) * (pressure / 8.0)) / 8192.0)) / 4096; v2 = ((pressure / 4.0) * digP[7]) / 8192.0; pressure = pressure + ((v1 + v2 + digP[6]) / 16.0) ; return (pressure/100); } double compensate_T(int32_t adc_T) { double temperature = 0.0; double v1,v2; v1 = (adc_T / 16384.0 - digT[0] / 1024.0) * digT[1]; v2 = (adc_T / 131072.0 - digT[0] / 8192.0) * (adc_T / 131072.0 - digT[0] / 8192.0) * digT[2]; t_fine = v1 + v2; temperature = t_fine / 5120.0; return temperature; } double compensate_H(int32_t adc_H) { double var_h = t_fine - 76800.0; if (var_h == 0) return 0; var_h = (adc_H - (digH[3] * 64.0 + digH[4]/16384.0 * var_h)) * (digH[1] / 65536.0 * (1.0 + digH[5] / 67108864.0 * var_h * (1.0 + digH[2] / 67108864.0 * var_h))); var_h = var_h * (1.0 - digH[0] * var_h / 524288.0); if (var_h > 100.0) var_h = 100.0; else if (var_h < 0.0) var_h = 0.0; return var_h; } void get_calib_param(int handle) { uint8_t calib[32]; for(int i=0;i<24;i++) { calib[i] = lgI2cReadByteData(handle, 0x88 + i); } calib[24] = lgI2cReadByteData(handle, 0xA1); for(int i=25,o=0;i<32;i++,o++) { calib[i] = lgI2cReadByteData(handle, 0xE1 + o); } digT[0] = (calib[1] << 8) | calib[0]; digT[1] = (calib[3] << 8) | calib[2]; digT[2] = (calib[5] << 8) | calib[4]; digP[0] = (calib[7] << 8) | calib[6]; digP[1] = (calib[9] << 8) | calib[8]; digP[2] = (calib[11] << 8) | calib[10]; digP[3] = (calib[13] << 8) | calib[12]; digP[4] = (calib[15] << 8) | calib[14]; digP[5] = (calib[17] << 8) | calib[16]; digP[6] = (calib[19] << 8) | calib[18]; digP[7] = (calib[21] << 8) | calib[20]; digP[8] = (calib[23] << 8) | calib[22]; digH[0] = calib[24]; digH[1] = (calib[26] << 8) | calib[25]; digH[2] = calib[27]; digH[3] = (calib[28] << 4) | (0x0f & calib[29]); digH[4] = (calib[30] << 4) | ((calib[29] >> 4) & 0x0f); digH[5] = calib[31]; for(int i=1;i<2;i++) if((digT[i] & 0x8000) != 0) digT[i] = (-digT[i] ^ 0xFFFF) + 1; for(int i=1;i<8;i++) if ((digP[i] & 0x8000) != 0) digP[i]=(-digP[i] ^ 0xFFFF) + 1 ; for(int i=0;i<6;i++) if ((digH[i] & 0x8000) != 0) digH[i] = (-digH[i] ^ 0xFFFF) + 1; } int main(int argc, char **argv) { uint8_t data[8]; double value[3]; int handle = lgI2cOpen(I2C_DEV_NUM, BME280_ADDR, 0); lgI2cWriteByteData(handle, 0xF2, 0x01); lgI2cWriteByteData(handle, 0xF4, 0x27); lgI2cWriteByteData(handle, 0xF5, 0xA0); get_calib_param(handle); for(int i=0;i<8;i++) { data[i] = lgI2cReadByteData(handle, 0xF7 + i); } value[0] = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4); value[1] = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4); value[2] = (data[6] << 8) | data[7]; value[0] = compensate_P(value[0]); value[1] = compensate_T(value[1]); value[2] = compensate_H(value[2]); printf("pressure: %7.2f hPa\n", value[0]); printf("temperature: %7.2f C\n" , value[1]); printf("humidity: %7.2f %\n" , value[2]); lgI2cClose(handle); }编译:gcc -o envtest envtest.c -llgpio
运行:./envtest #输出内容包含采集的气压、温度和湿度信息
SPI 测试
使用微雪 2.23 寸 OLED 显示器测试40pin中的SPI功能,对应设备节点 /dev/spi10,若节点没出来可以先使用本章开头部分的 quecpi_config 进行配置使能。
连接示意图:
微雪环境传感器扩展板
QuecPi 40PIN引脚
测试步骤:
wget http://www.waveshare.net/w/upload/c/c5/2.23inch-OLED-HAT-Code.7z #下载微雪提供的源码
7z x 2.23inch-OLED-HAT-Code.7z #解压源码
cd 2.23inch-OLED-HAT-Code/Without\ scrolling/Raspberry\ Pi/SPI/c #切换到源码目录
按照下列补丁的内容修改源码:
diff -r -u "2.23inch-OLED-HAT-Code/Without scrolling/Raspberry Pi/c/examples/main.c" quecpi/c/examples/main.c --- "2.23inch-OLED-HAT-Code/Without scrolling/Raspberry Pi/c/examples/main.c" 2023-12-20 03:19:38.000000000 +0000 +++ quecpi/c/examples/main.c 2025-08-15 07:34:39.959415415 +0000 @@ -17,10 +17,13 @@ char value[10]={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; time_t now; struct tm *timenow; - - if(DEV_ModuleInit() != 0) { - return -1; - } + extern int GPIO_Handle; + extern int SPI_Handle; + GPIO_Handle = lgGpiochipOpen(4); if (GPIO_Handle < 0) { printf( "gpiochip4 Export Failed\n"); return -1; } + lgGpioClaimOutput(GPIO_Handle, 0, 119 , LG_LOW); //enable OLED_DC mode + lgGpioClaimOutput(GPIO_Handle, 0, OLED_RST, LG_LOW); + lgGpioClaimOutput(GPIO_Handle, 0, OLED_DC , LG_LOW); + SPI_Handle = lgSpiOpen(10, 0, 10000000, 0); SSD1305_begin(); SSD1305_bitmap(7, 0, waveshare_ch,112,32); SSD1305_display(); Only in quecpi/c/lib/Config: .DEV_Config.h.un~ diff -r -u "2.23inch-OLED-HAT-Code/Without scrolling/Raspberry Pi/c/lib/Config/DEV_Config.h" quecpi/c/lib/Config/DEV_Config.h --- "2.23inch-OLED-HAT-Code/Without scrolling/Raspberry Pi/c/lib/Config/DEV_Config.h" 2023-12-20 03:23:11.000000000 +0000 +++ quecpi/c/lib/Config/DEV_Config.h 2025-08-15 07:32:05.844626084 +0000 @@ -41,8 +41,8 @@ //OLED Define #define OLED_CS 8 -#define OLED_RST 25 -#define OLED_DC 24 +#define OLED_RST 19 +#define OLED_DC 33编译: make
运行: ./main
运行效果如下图:

UART 测试
40PIN 的 pin8 和 pin10 默认配置为 uart 功能,对应设备节点 /dev/ttyHS2,若节点没出来可以先使用本章开头部分的 quecpi_config 进行配置使能。
将电脑的 USB 转串口的 rx 接 pin8、tx 接 pin10。
连接示意图: 
使用 C 代码控制
新建 uart.c 文件,内容如下:
#include <stdio.h> #include <string.h> #include <lgpio.h> int strip_head_and_tail(char *data, int data_len) { int found_tail = 0; if (data_len > 0 && data[0] == '\r') { bcopy(data + 1, data, data_len-1); data_len--; } if (data_len > 0 && data[0] == '\n') { bcopy(data + 1, data, data_len-1); data_len--; } if (data_len > 0 && data[data_len - 1] == '\r') { data_len--; data[data_len] = 0; found_tail = 1; } if (data_len > 0 && data[data_len - 1] == '\n') { data_len--; data[data_len] = 0; found_tail = 1; } return found_tail; } int main(int argc, char **argv) { int handle = lgSerialOpen("/dev/ttyHS2", 115200, 0); char data[512]; int data_len = 0; for (;;) { int read_len = lgSerialRead(handle, data + data_len, sizeof(data) - data_len); if (read_len > 0) { data_len += read_len; } if (strip_head_and_tail(data, data_len)) { printf("received: %s\n", data); lgSerialWrite(handle, "Received.\r\n", 11); } lguSleep(100); } lgSerialClose(handle); }编译: gcc -o uart uart.c -llgpio
运行: ./uart #此时 USB 转串口模块与 PC 连接,使用 putty 等支持串口通行的软件与该串口服务程序通行,putty 等客户端输入内容并以回车键结尾,服务端程序会打印用户输入的内容并返回“Received.”给客户端。
使用 Python 脚本控制
创建服务端程序 uart.py,文件内容如下:
import serial import threading PORT = '/dev/ttyHS2' BAUDRATE = 115200 TIMEOUT = 1 ser = serial.Serial(PORT, BAUDRATE, timeout=TIMEOUT) def read_and_echo(ser): while True: data = ser.readline() if data: print(f"Received: {data.decode().strip()}") ser.write(“Received.\r\n”) def main(): if ser.is_open: print(f"Serial port {PORT} is open. Echo service started.") thread = threading.Thread(target=read_and_echo, args=(ser,)) thread.daemon = True thread.start() try: while True: pass except KeyboardInterrupt: print("Exiting program.") else: print(f"Failed to open serial port {PORT}.") ser.close() print(f"Serial port {PORT} is closed.") if __name__ == "__main__": main()运行: python test.py #此时 USB 转串口模块与 PC 连接,使用 putty 等支持串口通行的软件与该串口服务程序通行,putty 等客户端输入内容并以回车键结尾,服务端程序会打印用户输入的内容并返回“Received.”给客户端。
PWM 测试
40 PIN 的 pin33 默认配置为 pwm 功能,这里选择微雪的 4pin PWM 协议的调速风扇做为测试设备。
使用 C 代码控制
创建 pwm.c 文件,文件内容如下:
#include <stdio.h> #include <lgpio.h> int main(int argc, char **argv) { int h; int gpio = 78; float pwmFrequency = 1000; float pwmDutyCycle = 50; h = lgGpiochipOpen(4); if (h < 0) { printf("ERROR: %s (%d)\n", lguErrorText(h), h); return 1; } int e = lgGpioClaimOutput(h, 0, gpio, 0); if (e < 0) { printf("ERROR: %s (%d)\n", lguErrorText(e), e); return 1; } e = lgTxPwm(h, gpio, pwmFrequency, pwmDutyCycle, 0, 0); if (e < 0) { printf("ERROR: %s (%d)\n", lguErrorText(e), e); return 1; } lguSleep(5); lgGpioFree(h, gpio); lgGpiochipClose(h); return 0; }编译: gcc pwm.c -o pwm -llgpio
执行:./pwm #风扇会以中等转速运转,可以调整代码中的 pwmDutyCycle 值来调整风扇转速。
网络与通信
蓝牙测试
Quectel Pi H1 单板电脑支持 QCA1023 HCI UART 蓝牙模块,可以连接常见蓝牙外设,以下流程演示与键鼠配对的方法。
蓝牙模块启动
蓝牙模块为 HCI UART 连接主控, 通过HCI H4协议进行通信。
首先通过设备节点给外设供电,当往节点echo 0 时,则给蓝牙外设下电。
echo 1 > /sys/devices/platform/rfkill/bt_en
通过 hciattach 命令,通过串口初始化蓝牙模块。
hciattach /dev/ttyHS1 qca 3000000 flow
通过 hciconfig 命令,查询并且启用 hci 蓝牙设备。
hciconfig hci0 up
查询 hci 设备状态,通过 hciconfig 查询,当状态为 UP RUNNING 的情况下,说明hci蓝牙设备已经启用。
root@qcm6490-idp:~# hciconfig
hci0: Type: Primary Bus: UART
BD Address: 00:00:00:00:5A:AD ACL MTU: 1024:7 SCO MTU: 60:8
UP RUNNING
RX bytes:783665 acl:1106 sco:0 events:18678 errors:0
TX bytes:4072 acl:57 sco:0 commands:305 errors:0
连接蓝牙外设
执行 bluetoothctl 命令,进入蓝牙配置工具,命令提示符变成[bluetooth]#,表示已经进入蓝牙控制模式。
root@qcm6490-idp:~# bluetoothctl
[bluetooth]#
执行 scan on 命令,此时会执行蓝牙扫描命令,会显示周边蓝牙设备信息,此时需要打开蓝牙设备的配对模式 ,放在旁边。
[bluetooth]# scan on
扫描到一定时间后,执行 scan off,停止 scan。
[bluetooth]# scan off
执行 devices 指令,列出扫描到的设备,找到你的蓝牙外设,此处以蓝牙鼠标为例。
[bluetooth]# devices
Device C3:3E:68:5E:E7:1F MX Master 2S
使用 pair 命令,进行连接,地址为你的外设地址。
[bluetooth]# pair C3:3E:68:5E:E7:1F
当输出 CHG 的日志时,说明pair成功。此时可以发现,我们的鼠标被注册到 input 设备下,这里是input5(根据实际注册地址为准)。
[CHG] Device C3:3E:68:5E:E7:1F Modalias: usb:v046DpB019d0006
[MX Master 2S]# [ 1157.381232][ T1737] input: MX Master 2S Keyboard as /devices/virtual/misc/uhid/0005:046D:B019.0001/input/input4
[ 1157.392409][ T1737] input: MX Master 2S Mouse as /devices/virtual/misc/uhid/0005:046D:B019.0001/input/input5
将设备添加为 trust 并且连接(可选:如果设备自动连接则可跳过)。
[MX Master 2S]# trust C3:3E:68:5E:E7:1F
Changing C3:3E:68:5E:E7:1F trust succeeded
[MX Master 2S]# connect C3:3E:68:5E:E7:1F
Attempting to connect to C3:3E:68:5E:E7:1F
Connection successful
验证外设
此时,我们可以用 evtest工具来验证外设是否可用,输入 evtest 命令,会显示可使用的 event 设备,这时我们选择我们的鼠标编号 5。
root@qcm6490-idp:~# evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0: pm8xxx_vib_ffmemless
/dev/input/event1: gpio-keys
/dev/input/event2: pmic_pwrkey
/dev/input/event3: pmic_resin
/dev/input/event4: MX Master 2S Keyboard
/dev/input/event5: MX Master 2S Mouse
Select the device event number [0-5]:
当出现如下打印则大功告成,可以通过移动鼠标按键来测试是否有事件上报。
Input driver version is 1.0.1
Input device ID: bus 0x5 vendor 0x46d product 0xb019 version 0x6
Input device name: "MX Master 2S Mouse"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 272 (BTN_LEFT)
Event code 273 (BTN_RIGHT)
Event code 274 (BTN_MIDDLE)
Event code 275 (BTN_SIDE)
Event code 276 (BTN_EXTRA)
Event code 277 (BTN_FORWARD)
Event code 278 (BTN_BACK)
Event code 279 (BTN_TASK)
Event code 280 (?)
Event code 281 (?)
Event code 282 (?)
Event code 283 (?)
Event code 284 (?)
Event code 285 (?)
Event code 286 (?)
Event code 287 (?)
Event type 2 (EV_REL)
Event code 0 (REL_X)
Event code 1 (REL_Y)
Event code 6 (REL_HWHEEL)
Event code 8 (REL_WHEEL)
Event code 11 (REL_WHEEL_HI_RES)
Event code 12 (REL_HWHEEL_HI_RES)
Event type 4 (EV_MSC)
Event code 4 (MSC_SCAN)
Properties:
Testing ... (interrupt to exit)
Event: time 2618.445029, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
Event: time 2618.445029, type 1 (EV_KEY), code 272 (BTN_LEFT), value 1
Event: time 2618.445029, -------------- SYN_REPORT ------------
Event: time 2618.610162, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
Event: time 2618.610162, type 1 (EV_KEY), code 272 (BTN_LEFT), value 0
Event: time 2618.610162, -------------- SYN_REPORT ------------
有线网络(eth0)
Quectel Pi H1 单板电脑支持 1 路自适应千兆以太网,以太网对网线的要求:仅支持直连网线,不支持交叉网线。
网络配置
系统默认开启 NetworkManager 服务来管理网络。
查看网络配置
使用 ifconfig 命令查看网络接口地址:

使用 route -n 命令查看网络路由信息,里面包含默认网关地址信息:

通过查看 /etc/resolv.conf 文件内容检查 DNS 服务器地址:

自动获取网络配置
【如果是通过网络远程连接到设备中修改网络,会有风丢失网络连接的风险,请确保有方法(如通过调试串口或显示器)查看修改后的网络配置】
系统默认设置为自动获取网络配置,使用网线将设备接入局域网,设备会自动获取网络配置(前提条件需要局域网中存在可用的 DHCP 服务)。
故障排除:
- 查看连接信息:执行命令
nmcli c,观察输出的结果中 DEVICE 列是否有包含 eth0,如果有先删除再重建。

- 删除旧的连接信息:执行命令
nmcli c del 'Wired connection 1'#这里的 'Wired connection 1' 是从上一步中查询出的连接的 NAME。【删除后默认会自动创建一个 NAME 为 eth0 连接,这个时候会自动获取网络配置】

- 新建连接并使能:执行命令
nmcli c add type ethernet con-name eth0 ifname eth0来创建连接,这里指定了连接名为 eth0,使用的网络接口也是 eth0;再执行nmcli connection up eth0来让名为 eth0 的连接生效。【一般上一步删除旧连接后,会自动创建一个 NAME 为 eth0 的连接,这个时候会自动获取网络配置,如果某些情况下新的连接迟迟没有自动创建,可以执行该步骤来创建和使能新的连接】

手动配置网络
【如果是通过网络远程连接到设备中修改网络,会有风丢失网络连接的风险,请确保有方法(如通过调试串口或显示器)查看修改后的网络配置】
- 查看连接信息:执行命令
nmcli c,观察输出的结果中 DEVICE 列是否有包含 eth0,如果有记下其 NAME 值,后面需要用到。如果没有,则先创建一个 eth0 连接,执行命令nmcli c add type ethernet con-name 'Wired connection 1' ifname eth0

- 手动配置网络:执行命令
修改完成后执行nmcli c modify 'Wired connection 1' \ ipv4.addresses 192.168.1.100/24 \ ipv4.gateway 192.168.1.1 \ ipv4.dns 192.168.1.1 \ ipv4.method manualnmcli c up 'Wired connection 1'使能连接【示例中的 IP 地址、网关地址、DNS 地址根据实际需要修改】。
测试网络
执行 ping 命令测试网络连接:
- 执行
ping 192.168.1.1命令,如果 ping 通则表示局域网网络连接正常【这里的目的 ip 需要修改为实际网络的网关地址】。 - 执行
ping 114.114.114.114命令,如果 ping 通则表示外网网络连接正常。 - 执行
ping baidu.com命令,如果 ping 通则表示外网网络连接正常且 DNS 解析功能正常。
WiFi 网络测试
Quectel Pi H1 单板电脑支持 QCA1023 SDIO Wifi。本文介绍如何使用 Network Manager 连接Wi-Fi热点。
nmcil 是一个用户空间的程序,是 Linux 系统中 NetworkManager 提供的命令行工具,用于管理网络连接,特别适用于图形界面不可用或自动化脚本环境下。可以用它来配置以太网、Wi-Fi、VLAN、桥接、代理、VPN 等连接。以下教程将演示如何通过 nmcli 连接到 Wi-Fi 热点。
PCIe 5G 模块连接
Quectel Pi H1 单板电脑可以通过PCIE接口,通过转接板连接5G网卡,本文介绍使用PCIE转接板连接RG520NGL-AA PCIE网卡的使用方法。
PCIE 模块配置
使用PCIE直通转接卡, 需要把模块设置成PCIE-EP模式, 这样才能和Quectel Pi H1的PCIE接口通信 ,安装模块驱动后 ,通过转接板的USB口连接到5G模块, 输入AT指令, 将其切换到PCIE-EP模式。
1.使用一根TYPE-C To USB接入windows电脑(此时您可能需要安装驱动,驱动文件由模块技术支持提供,请按照对应模组选择合适的驱动文件安装)。

2.使用串口工具,打开模组AT端口
可以在设备管理器上查看端口,出现“Quectel USB AT Port(COM***)”端口。
AT+QCFG="data_interface",1,0
AT+QCFG="pcie/mode",0
AT+QCFG="usbnet",2
AT+CFUN=1,1
执行完指令, 拔掉PC端口USB, 重新给QuecPI上电之后, 通过shell口使用如下命令, 判断设备是否正常识别并连接。
root@qcm6490-idp:~# lspci
0000:00:00.0 PCI bridge: Qualcomm Device 010b
0000:01:00.0 Ethernet controller: Device 1f0a:6801 (rev 01)
0001:00:00.0 PCI bridge: Qualcomm Device 010b
0001:01:00.0 Unassigned class [ff00]: Qualcomm Device 0308
root@qcm6490-idp:~# ls /dev/mhi*
/dev/mhi_BHI /dev/mhi_DIAG /dev/mhi_DUN /dev/mhi_LOOPBACK /dev/mhi_QMI0
如果以上是设备均识别出来, 则可以正常进行拨号操作。
拨号上网
使用quectel-CM工具进行拨号上网,首先为5G模块连接天线,插入SIM卡, 避免信号较差无法注网。

确认无误后,直接后台运行quectel-CM指令进行拨号。
root@qcm6490-idp:~# quectel-CM &
[2] 1303
root@qcm6490-idp:~# [01-01_00:07:55:168] QConnectManager_Linux_V1.6.7
[01-01_00:07:55:179] network interface '' or qmidev '' is not exist
[01-01_00:07:55:179] netcard driver = pcie_mhi, driver version = V1.3.7
[01-01_00:07:55:179] qmap_mode = 1, qmap_version = 9, qmap_size = 15360, muxid = 0x81, qmap_netcard = rmnet_mhi0.1
[01-01_00:07:55:179] Modem works in QMI mode
[01-01_00:07:55:193] /proc/1273/fd/7 -> /dev/mhi_QMI0
[01-01_00:07:55:193] /proc/1273/exe -> /usr/bin/quectel-CM
[01-01_00:07:55:193] requestDeactivateDefaultPDP WdsConnectionIPv4Handle
[01-01_00:07:55:424] ip link set dev rmnet_mhi0 down
[01-01_00:07:55:431] ip addr flush dev rmnet_mhi0.1
[01-01_00:07:55:436] ip link set dev rmnet_mhi0.1 down
[01-01_00:07:55:457] QmiWwanThread exit
[01-01_00:07:55:459] qmi_main exit
[01-01_00:07:57:196] cdc_wdm_fd = 7
[01-01_00:07:57:208] Get clientWDS = 15
[01-01_00:07:57:212] Get clientDMS = 1
[01-01_00:07:57:215] Get clientNAS = 4
[01-01_00:07:57:219] Get clientUIM = 3
[01-01_00:07:57:224] Get clientWDA = 1
[01-01_00:07:57:229] requestBaseBandVersion RM520NGLABR03A02M8G
[01-01_00:07:57:232] qmap_settings.rx_urb_size = 15360
[01-01_00:07:57:233] qmap_settings.ul_data_aggregation_max_datagrams = 11
[01-01_00:07:57:233] qmap_settings.ul_data_aggregation_max_size = 8192
[01-01_00:07:57:233] qmap_settings.dl_minimum_padding = 0
[01-01_00:07:57:248] requestGetSIMStatus SIMStatus: SIM_READY
[01-01_00:07:57:257] requestGetProfile[pdp:1 index:1] ctnet///0/IPV4V6
[01-01_00:07:57:261] requestRegistrationState2 MCC: 460, MNC: 11, PS: Attached, DataCap: 5G_SA
[01-01_00:07:57:265] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
[01-01_00:07:57:265] ip link set dev rmnet_mhi0 down
[01-01_00:07:57:272] ip addr flush dev rmnet_mhi0.1
[01-01_00:07:57:277] ip link set dev rmnet_mhi0.1 down
[01-01_00:07:57:768] requestSetupDataCall WdsConnectionIPv4Handle: 0xe27891d0
[01-01_00:07:57:783] ip link set dev rmnet_mhi0 up
[ 473.062494][ T1311] [I][mhi_netdev_open] Opened net dev interface
[01-01_00:07:57:797] ip link set dev rmnet_mhi0.1 up
[01-01_00:07:57:803] busybox udhcpc -f -n -q -t 5 -i rmnet_mhi0.1
udhcpc: started, v1.35.0
udhcpc: broadcasting discover
udhcpc: broadcasting select for 100.98.134.67, server 100.98.134.68
udhcpc: lease of 100.98.134.67 obtained from 100.98.134.68, lease time 7200
[01-01_00:07:57:883] /etc/udhcpc.d/50default: Adding DNS 202.102.213.68
[01-01_00:07:57:883] /etc/udhcpc.d/50default: Adding DNS 61.132.163.68
当最下面udhcpc获取到IP地址以后, 说明已经可以正常获取到基站分配的IP, 可以上网。
使用ifconfig 和 ping命令验证网络:
root@qcm6490-idp:~# ifconfig
eth0 Link encap:Ethernet HWaddr 00:55:7B:B5:7D:F7
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:166
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:50 errors:0 dropped:0 overruns:0 frame:0
TX packets:50 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4632 (4.5 KiB) TX bytes:4632 (4.5 KiB)
p2p0 Link encap:Ethernet HWaddr 02:03:7F:D6:00:01
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
rmnet_mhi0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet6 addr: fe80::6921:e40e:336d:a80e/64 Scope:Link
UP RUNNING NOARP MTU:1500 Metric:1
RX packets:14 errors:0 dropped:0 overruns:0 frame:0
TX packets:23 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4464 (4.3 KiB) TX bytes:5204 (5.0 KiB)
rmnet_mhi0.1 Link encap:Ethernet HWaddr 02:50:F4:00:00:01
inet addr:100.98.134.67 Mask:255.255.255.248
inet6 addr: fe80::50:f4ff:fe00:1/64 Scope:Link
UP RUNNING NOARP MTU:1500 Metric:1
RX packets:14 errors:0 dropped:0 overruns:0 frame:0
TX packets:23 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4330 (4.2 KiB) TX bytes:5334 (5.2 KiB)
wlan0 Link encap:Ethernet HWaddr 00:03:7F:50:00:01
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
root@qcm6490-idp:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=113 time=5006.075 ms
64 bytes from 8.8.8.8: seq=5 ttl=113 time=485.806 ms
64 bytes from 8.8.8.8: seq=6 ttl=113 time=190.026 ms
64 bytes from 8.8.8.8: seq=13 ttl=113 time=628.962 ms
64 bytes from 8.8.8.8: seq=14 ttl=113 time=542.605 ms
64 bytes from 8.8.8.8: seq=15 ttl=113 time=585.632 ms
64 bytes from 8.8.8.8: seq=16 ttl=113 time=796.018 ms
64 bytes from 8.8.8.8: seq=17 ttl=113 time=95.139 ms
64 bytes from 8.8.8.8: seq=18 ttl=113 time=837.369 ms
64 bytes from 8.8.8.8: seq=19 ttl=113 time=41.186 ms
图形与显示
GPU 性能测试
背景
在当今数字化时代,图形处理能力已成为衡量开发板性能的关键指标之一, Quectel Pi H1 单板电脑,凭借其内置的高通 Adreno 642L/643 GPU,在图形处理领域展现出了令人瞩目的实力,想象一下,在智慧交通场景中,Quectel Pi H1 单板电脑能够凭借其强大的 GPU 性能,快速且精准地识别并标注车辆、车牌以及行人等目标物体,为交通管理提供实时且准确的数据支持。又或者在智能安全领域,面对复杂多变的监控画面,它能借助 GPU 卓越的运算能力,迅速完成图像识别与分析,及时发现潜在风险。这一切高效且精准的图形处理背后,正是 Quectel Pi H1 GPU 性能的生动体现。它不仅能轻松应对日常的多媒体处理任务,更在对图形运算要求极高的复杂应用场景中,表现得游刃有余。以下通过 glmark2 基准测试工具,用于评估 Quectel Pi H1 的图形渲染性能。
glmark2 是一款开源的 OpenGL ES 和 EGL 基准测试工具,主要用于评估设备的图形渲染性能。它通过运行一系列标准化测试场景(如纹理填充、光照计算、像素处理等),量化 GPU 的帧率(FPS)、延迟(FrameTime)和稳定性,适用于嵌入式设备、手机、开发板等平台的图形性能分析和调优。
测试环境
glmark2 默认已集成到系统镜像并安装。进入设备终端可直接测试性能。
- 准备显示器,并连接显示器到 Quectel Pi H1 上。
运行命令
- 在设备终端运行以下命令以确保结果显示在连接的显示器上:
export XDG_RUNTIME_DIR=/dev/socket/weston && export WAYLAND_DISPLAY=wayland-1
- 运行 glmark2 命令以测试图形渲染性能:
glmark2-es2-wayland
测试结果
QUALCOMM build : a4d6ce04e1, I363e8f8d61
Build Config : G ESX_C_COMPILER_OPT 4.4.0 AArch64
Driver Path : /usr/lib/libGLESv2_adreno.so
Driver Version : 0808.0
Process Name : glmark2-es2-wayland
GBM_INFO::msmgbm_mapper(262)::gbm mapper instantiated
gbm_create_device(224): Info: backend name is: msm_drm
PFP: 0x016dc112, ME: 0x00000000
I/Adreno-UNKNOWN (1382,1382): <ReadGpuID:1042>: Reading chip ID through GSL
Pre-rotation disabled !!!
EGL updater thread started
=======================================================
glmark2 2021.12
=======================================================
OpenGL Information
GL_VENDOR: Qualcomm
GL_RENDERER: Adreno (TM) 643
GL_VERSION: OpenGL ES 3.2
=======================================================
[build] use-vbo=false: FPS: 516 FrameTime: 1.938 ms
[build] use-vbo=true: FPS: 679 FrameTime: 1.473 ms
[texture] texture-filter=nearest: FPS: 748 FrameTime: 1.337 ms
[texture] texture-filter=linear: FPS: 722 FrameTime: 1.385 ms
[texture] texture-filter=mipmap: FPS: 231 FrameTime: 4.329 ms
[shading] shading=gouraud: FPS: 220 FrameTime: 4.545 ms
[shading] shading=blinn-phong-inf: FPS: 679 FrameTime: 1.473 ms
[shading] shading=phong: FPS: 221 FrameTime: 4.525 ms
[shading] shading=cel: FPS: 688 FrameTime: 1.453 ms
[bump] bump-render=high-poly: FPS: 693 FrameTime: 1.443 ms
[bump] bump-render=normals:[ 606.705365][ T943] smcinvoke: process_accept_req: Setting pid:943, server id : 23 state to defunct
[ 606.714752][ T944] smcinvoke: process_accept_req: Setting pid:944, server id : 23 state to defunct
[ 606.724315][ T945] smcinvoke: process_accept_req: Setting pid:945, server id : 23 state to defunct
[ 606.734878][ T946] smcinvoke: process_accept_req: Setting pid:946, server id : 23 state to defunct
[ 606.751381][ T943] smcinvoke: process_tzcb_req: server is defunct, state= 1 tzhandle = -2147483625
[ 606.760794][ T943] smcinvoke: process_tzcb_req: server invalid, res: -90
FPS: 714 FrameTime: 1.401 ms
[bump] bump-render=height: FPS: 674 FrameTime: 1.484 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 373 FrameTime: 2.681 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 251 FrameTime: 3.984 ms
[pulsar] light=false:quads=5:texture=false: FPS: 213 FrameTime: 4.695 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 559 FrameTime: 1.789 ms
[desktop] effect=shadow:windows=4: FPS: 466 FrameTime: 2.146 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 238 FrameTime: 4.202 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[ideas] speed=duration: FPS: 578 FrameTime: 1.730 ms
[jellyfish] <default>: FPS: 642 FrameTime: 1.558 ms
[terrain] <default>: FPS: 74 FrameTime: 13.514 ms
[shadow] <default>: FPS: 527 FrameTime: 1.898 ms
[refract] <default>: FPS: 418 FrameTime: 2.392 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 679 FrameTime: 1.473 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 686 FrameTime: 1.458 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 230 FrameTime: 4.348 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 680 FrameTime: 1.471 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 693 FrameTime: 1.443 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 691 FrameTime: 1.447 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 240 FrameTime: 4.167 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 685 FrameTime: 1.460 ms
=======================================================
glmark2 Score: 506
=======================================================
EGL updater thread exited
性能分析
glmark2 基准测试报告显示的 Quectel Pi H1 的 OpenGL ES 图形性能,最终得分为 506,总体表现不错。主要性能表现如下:
VBO(顶点缓冲对象)优化
- use-vbo=false → 516 FPS
- use-vbo=true → 679 FPS(提升 31.6%)
结论:启用 VBO 能显著提升渲染效率,减少 CPU-GPU 数据传输开销。
纹理过滤模式
- nearest(最近邻)→ 748 FPS(最快)
- linear(线性)→ 722 FPS(轻微性能损失)
- mipmap(多级渐远)→ 231 FPS(性能下降 69%)
结论:mipmap 因额外计算开销导致帧率大幅下降,适合高质量纹理但代价高。
着色模型(Shading)
- blinn-phong-inf(优化版布林-冯模型)→ 679 FPS
- cel(卡通渲染)→ 688 FPS
- phong/gouraud(传统光照模型)→ 220 FPS(性能极低)
结论:现代着色器(如 blinn-phong-inf)比传统模型(如 phong)更高效。
HDMI 屏测试
Quectel Pi H1 单板电脑支持 HDMI 接口显示屏。
HDMI 屏连接
按照下图进行连接:
11.6寸HDMI显示屏
连接上HDMI显示屏后的QuecPi
HDMI 屏显示 Weston 桌面
连接上 HDMI 显示器并上电开机后,启动显示服务: systemctl start init_display,HDMI 屏会显示Weston 桌面。
显示效果如下图:

利用 HDMI 屏播放视频
执行视频回放命令:
mount -o rw,remount /
export XDG_RUNTIME_DIR=/dev/socket/weston
export WAYLAND_DISPLAY=wayland-1
gst-launch-1.0 -e filesrc location=/root/quectel.mp4 ! qtdemux ! \
queue ! h264parse ! v4l2h264dec capture-io-mode=5 output-io-mode=5 ! \
waylandsink enable-last-sample=false fullscreen=true
#其中location后的参数根据实际视频路径进行修改
命令说明:
gst-launch-1.0这是 GStreamer 的命令行工具,用于启动一个 GStreamer 管道(pipeline)。-e 参数表示在管道结束时退出,而不是继续运行。filesrc location=/root/quectel.mp4filesrc 用于从文件中读取数据, location=/root/quectel.mp4 指定要读取的文件路径。! qtdemux! 是一个连接符号,用于将前一个元素的输出连接到后一个元素的输入,qtdemux 用于解复用 MP4 文件。MP4 文件通常包含视频流和音频流,qtdemux 的作用是将这些流分离出来,以便后续处理。! queuequeue 是一个缓冲队列元素,用于在管道中缓冲数据。它可以缓解数据处理速度不一致的问题,例如,当解码器处理速度较慢时,queue 可以暂存数据,避免数据丢失。! h264parseh264parse 用于解析 H.264 视频流。它会将 H.264 视频流中的数据重新组织成适合解码器处理的格式。! v4l2h264dec capture-io-mode=5 output-io-mode=5v4l2h264dec 用于解码 H.264 视频流,capture-io-mode=5:设置捕获输入模式为 5,这通常与硬件加速有关,具体含义取决于硬件和驱动程序;output-io-mode=5 设置输出模式为 5,同样与硬件加速相关。! waylandsink enable-last-sample=false fullscreen=truewaylandsink 用于将解码后的视频输出到 Wayland 显示服务器上,enable-last-sample=false 禁用“最后样本”功能,这通常是用于优化性能或避免某些问题;fullscreen=true 将视频以全屏模式显示。
视频回放效果如下图:

MIPI 屏测试
Quectel Pi H1 单板电脑支持 MIPI 接口显示屏,下面选取微雪的一款 8 寸 DSI 接口 ISP 电容触摸屏为例进行测试。
MIPI 屏连接
按照下图进行连接:
注:此屏幕共有4处接口可供电,任选一处即可,示例选择“1”处供电。
- 即 type-C 接口
- I2C 通讯与供电接口
- 5V 输入输出接口
- I2C 通讯与供电接口,需将螺丝孔对准 Quectel Pi H1 单板电脑拧紧,让顶针与 40PIN 连接牢固
微雪8寸MIPI显示屏背面
连接上MIPI显示屏后的QuecPi
MIPI 屏显示 Weston 桌面
连接上 MIPI 显示器并上电开机后,启动显示服务: systemctl start init_display,MIPI 屏会显示 Weston 桌面。
显示效果如下图:

利用 MIPI 屏播放视频
执行视频回放命令:
mount -o rw,remount /
export XDG_RUNTIME_DIR=/dev/socket/weston
export WAYLAND_DISPLAY=wayland-1
gst-launch-1.0 -e filesrc location=/root/quectel.mp4 ! qtdemux ! \
queue ! h264parse ! v4l2h264dec capture-io-mode=5 output-io-mode=5 ! \
waylandsink enable-last-sample=false fullscreen=true
#其中location后的参数根据实际视频路径进行修改
命令说明:
gst-launch-1.0这是 GStreamer 的命令行工具,用于启动一个 GStreamer 管道(pipeline)。-e 参数表示在管道结束时退出,而不是继续运行。filesrc location=/root/quectel.mp4filesrc 用于从文件中读取数据, location=/root/quectel.mp4 指定要读取的文件路径。! qtdemux! 是一个连接符号,用于将前一个元素的输出连接到后一个元素的输入,qtdemux 用于解复用 MP4 文件。MP4 文件通常包含视频流和音频流,qtdemux 的作用是将这些流分离出来,以便后续处理。! queuequeue 是一个缓冲队列元素,用于在管道中缓冲数据。它可以缓解数据处理速度不一致的问题,例如,当解码器处理速度较慢时,queue 可以暂存数据,避免数据丢失。! h264parseh264parse 用于解析 H.264 视频流。它会将 H.264 视频流中的数据重新组织成适合解码器处理的格式。! v4l2h264dec capture-io-mode=5 output-io-mode=5v4l2h264dec 用于解码 H.264 视频流,capture-io-mode=5:设置捕获输入模式为 5,这通常与硬件加速有关,具体含义取决于硬件和驱动程序;output-io-mode=5 设置输出模式为 5,同样与硬件加速相关。! waylandsink enable-last-sample=false fullscreen=truewaylandsink 用于将解码后的视频输出到 Wayland 显示服务器上,enable-last-sample=false 禁用“最后样本”功能,这通常是用于优化性能或避免某些问题;fullscreen=true 将视频以全屏模式显示。
视频回放效果如下图:

DP 屏测试
Quectel Pi H1 单板电脑支持通过 Type-C 转 DP 接口的方法接显示屏。
DP 屏连接
按照下图进行连接:

DP 屏显示 Weston 桌面
连接上 DP 显示器并上电开机后,启动显示服务: systemctl start init_display ,DP 屏会显示 Weston 桌面。
显示效果如下图:

利用 DP 屏播放视频
执行视频回放命令:
mount -o rw,remount /
export XDG_RUNTIME_DIR=/dev/socket/weston
export WAYLAND_DISPLAY=wayland-1
gst-launch-1.0 -e filesrc location=/root/quectel.mp4 ! qtdemux ! \
queue ! h264parse ! v4l2h264dec capture-io-mode=5 output-io-mode=5 ! \
waylandsink enable-last-sample=false fullscreen=true
#其中location后的参数根据实际视频路径进行修改
命令说明:
gst-launch-1.0这是 GStreamer 的命令行工具,用于启动一个 GStreamer 管道(pipeline)。-e 参数表示在管道结束时退出,而不是继续运行。filesrc location=/root/quectel.mp4filesrc 用于从文件中读取数据, location=/root/quectel.mp4 指定要读取的文件路径。! qtdemux! 是一个连接符号,用于将前一个元素的输出连接到后一个元素的输入,qtdemux 用于解复用 MP4 文件。MP4 文件通常包含视频流和音频流,qtdemux 的作用是将这些流分离出来,以便后续处理。! queuequeue 是一个缓冲队列元素,用于在管道中缓冲数据。它可以缓解数据处理速度不一致的问题,例如,当解码器处理速度较慢时,queue 可以暂存数据,避免数据丢失。! h264parseh264parse 用于解析 H.264 视频流。它会将 H.264 视频流中的数据重新组织成适合解码器处理的格式。! v4l2h264dec capture-io-mode=5 output-io-mode=5v4l2h264dec 用于解码 H.264 视频流,capture-io-mode=5:设置捕获输入模式为 5,这通常与硬件加速有关,具体含义取决于硬件和驱动程序;output-io-mode=5 设置输出模式为 5,同样与硬件加速相关。! waylandsink enable-last-sample=false fullscreen=truewaylandsink 用于将解码后的视频输出到 Wayland 显示服务器上,enable-last-sample=false 禁用"最后样本"功能,这通常是用于优化性能或避免某些问题;fullscreen=true 将视频以全屏模式显示。
视频回放效果如下图:

摄像头方案
MIPI 摄像头(IMX219)测试
Quectel Pi H1 单板电脑支持 MIPI 接口摄像头,下面选取微雪的一款 imx219 CSI 接口 CMOS 摄像头为例进行测试。
摄像头连接
按照下图进行连接,连接时向上拉开连接器的黑色锁扣部分,将 FPC 排线插入第一个 CSI 卡槽,注意金属接触面朝向板内金属接触面,按下锁扣,确认 FPC 排线稳定没有松动。

前提条件
在 SSH 终端中运行以下命令:
mount -o rw,remount /
export XDG_RUNTIME_DIR=/dev/socket/weston
export WAYLAND_DISPLAY=wayland-1
单摄像头流启动
- 在 device 终端中运行以下命令
gst-launch-1.0 -e qtiqmmfsrc name=camsrc ! 'video/x-raw(memory:GBM),format=NV12,width=1280,height=720,framerate=30/1' ! fakesink
- 此示例说明如何使用 720p@30 FPS 配置启动摄像头。来自摄像头传感器的帧被 fakesink 丢弃。如果 gst pipeline 状态更改为 “PLAYING”,如下所示,则表示摄像头正在运行。由于此命令会将摄像头帧转储到 fakesink,因此不会在设备上保存任何内容。
gbm_create_device(187): Info: backend name is: msm_drm
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
- 如果想实时显示摄像头捕捉的画面,需提前连接好 HDMI 屏幕,并执行以下命令:
gst-launch-1.0 -e qtiqmmfsrc name=camsrc camera=0 ! 'video/x-raw(memory:GBM),format=NV12,width=1280,height=720,framerate=30/1' ! waylandsink
- camera=0 表示使用第一个 CSI 接口摄像头,camera=1 表示使用第二个 CSI 接口摄像头
- 如果想全屏显示,请在命令后面加上
fullscreen=true - 如果要停止摄像头流,请按下
CTRL+C
预览+视频录制
- 在 device 终端中运行以下命令:
gst-launch-1.0 -e qtiqmmfsrc name=camsrc camera=0 video_1::type=preview ! 'video/x-raw,format=NV12,width=1280,height=720,framerate=30/1',compression=ubwc,interlace-mode=progressive,colorimetry=bt601 ! tee name=t ! queue ! waylandsink fullscreen=true t. ! queue ! v4l2h264enc capture-io-mode=5 output-io-mode=5 extra-controls="controls,video_bitrate=6000000,video_bitrate_mode=0;" ! queue ! h264parse ! mp4mux ! filesink location=/opt/mux_avc.mp4
- 此命令以 720p 30 FPS 配置启动相机,并在 h264 视频编码后将其另存为视频文件。如果 gst 管道状态更改为 “PLAYING”,则表示摄像头正在运行。
- 如果要停止摄像头录制,请按下
CTRL+C - MP4 文件保存在 /opt/ 目录
命令说明:
! 是一个连接符号,用于将前一个元素的输出连接到后一个元素的输入
gst-launch-1.0这是 GStreamer 的命令行工具,用于启动一个 GStreamer 管道(pipeline)。-e 参数表示在管道结束时退出,而不是继续运行。qtiqmmfsrc name=camsrc camera=0高通平台专用的摄像头源插件,从设备 camera=0(主摄像头)采集视频。video_1::type=preview这是 qtiqmmfsrc 元素的属性配置,针对 video_1 流(不同摄像头可能输出多路流,比如预览流、抓拍流等 ),设置其类型为 preview(预览流 ),表示后续处理的是用于实时预览场景的视频流,一般帧率、分辨率等参数会适配预览需求。video/x-raw,format=NV12,width=1280,height=720,framerate=30/1video/x-raw(原始视频),NV12(YUV 4:2:0,单平面格式,常见于视频编码),分辨率 1280×720(720p),帧率 30fps。compression=ubwc,interlace-mode=progressive,colorimetry=bt601启用高通的UBWC(Ultra Bandwidth Compression) 技术,通过硬件压缩减少内存带宽需求,逐行扫描(非隔行),色彩空间为 ITU-R BT.601(适用于标清视频)。tee name=t分流器(tee)元素,作用是将一路输入数据复制成多路输出,方便对同一视频流进行多种不同处理(这里一路用于预览显示,一路用于编码存储 )。 name=t 给这个 tee 元素命名为 t,后续其他分支通过名字引用它来获取视频流 。queue ! waylandsink fullscreen=truequeue:队列元素,用于在 pipeline 中创建一个缓冲队列,起到解耦上下游元素、异步处理的作用。可以缓解上下游处理速度不一致的问题,避免因一方处理慢导致另一方阻塞或丢帧 。
waylandsink:输出 sink 元素,用于在 Wayland 显示服务器环境下,将视频画面渲染显示到屏幕上 。
fullscreen=true:设置 waylandsink 以全屏模式显示视频画面 。
t. ! queuet.:通过 . 语法引用之前命名为 t 的 tee 元素,获取视频流进行后续处理 。
queue:再次使用队列元素,缓冲数据,保证编码等环节的流畅性 。
v4l2h264enc capture-io-mode=5 output-io-mode=5 extra-controls="controls,video_bitrate=6000000 video_bitrate_mode=0;"使用 DMABUF(直接内存访问缓冲区)进行输入,优化数据传输效率,同样使用 DMABUF 输出编码后数据,目标比特率为 6 Mbps,使用 CBR(固定比特率) 模式,适合网络流媒体或需要稳定带宽的场景。queue ! h264parse ! mp4mux ! filesink location=/opt/mux_avc.mp4queue:又一个队列元素,继续缓冲编码后的数据,协调后续处理速度。解析 H.264 流,添加必要的 NAL 单元头部,使其符合 MP4 封装要求,将 H.264 视频流封装为 MP4 格式,将数据写入文件 /opt/mux_avc.mp4。
预览+拍照
- 在 device 终端中运行以下命令:
gst-pipeline-app -e qtiqmmfsrc name=camsrc camera=0 ! 'video/x-raw(memory:GBM),format=NV12,width=1280,height=720,framerate=30/1' ! waylandsink camsrc.image_1 ! "image/jpeg,width=1280,height=720,framerate=30/1" ! multifilesink location=/opt/frame%d.jpg async=false sync=true
- 按
Enter键。此命令将打印以下菜单并等待用户输入。
##################################### MENU #####################################
============================== Pipeline Controls==============================
(0) NULL: Set the pipeline into NULL state
(1) READY: Set the pipeline into READY state
(2) PAUSED: Set the pipeline into PAUSED state
(3) PLAYING: Set the pipeline into PLAYING state
==================================== Other====================================
(p) Plugin Mode: Choose a plugin which to control
(q) Quit : Exit the application
Choose an option:
- 使用以下菜单步骤在预览时拍摄快照。
(1) ready -> (3) Playing -> (Enter)-> (p)Plugin Mode : Select (5)camerasrc ->(36) capture-image -> (1): still – Snapshot ->(1) Snapshot count ('guint' value for arg1)
- 要停止相机,请按
Enter,按b(返回),然后按q(退出)。拍摄的快照图像保存在 /opt/ 中。通过在主机 PC 上运行以下scp命令,可以从设备中提取录制的内容:
scp -r root@[ip-addr]:/opt/<file name> .
- 生成文件如下图所示:

MIPI 摄像头(IMX477)测试
Quectel Pi H1 单板电脑支持 MIPI 接口摄像头,下面选取微雪的一款 imx477 CSI 接口 CMOS 摄像头为例进行测试。
摄像头连接
按照下图进行连接,连接时向上拉开连接器的黑色锁扣部分,将 FPC 排线插入第二个 CSI 卡槽,注意金属接触面朝向板内金属接触面,按下锁扣,确认 FPC 排线稳定没有松动。

前提条件
在 SSH 终端中运行以下命令:
mount -o rw,remount /
export XDG_RUNTIME_DIR=/dev/socket/weston
export WAYLAND_DISPLAY=wayland-1
单摄像头流启动
- 在 device 终端中运行以下命令
gst-launch-1.0 -e qtiqmmfsrc name=camsrc camera=1 ! 'video/x-raw(memory:GBM),format=NV12,width=1280,height=720,framerate=30/1' ! fakesink
- 此示例说明如何使用 720p@30 FPS 配置启动摄像头。来自摄像头传感器的帧被 fakesink 丢弃。如果 gst pipeline 状态更改为 “PLAYING”,如下所示,则表示摄像头正在运行。由于此命令会将摄像头帧转储到 fakesink,因此不会在设备上保存任何内容。
gbm_create_device(187): Info: backend name is: msm_drm
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
- 如果想实时显示摄像头捕捉的画面,需提前连接好 HDMI 屏幕,并执行以下命令:
gst-launch-1.0 -e qtiqmmfsrc name=camsrc camera=1 ! 'video/x-raw(memory:GBM),format=NV12,width=1280,height=720,framerate=30/1' ! waylandsink
- camera=0 表示使用第一个 CSI 接口摄像头,camera=1 表示使用第二个 CSI 接口摄像头
- 如果想全屏显示,请在命令后面加上
fullscreen=true - 如果要停止摄像头流,请按下
CTRL+C
预览+视频录制
- 在 device 终端中运行以下命令:
gst-launch-1.0 -e qtiqmmfsrc name=camsrc camera=1 video_1::type=preview ! 'video/x-raw,format=NV12,width=1280,height=720,framerate=30/1',compression=ubwc,interlace-mode=progressive,colorimetry=bt601 ! tee name=t ! queue ! waylandsink fullscreen=true t. ! queue ! v4l2h264enc capture-io-mode=5 output-io-mode=5 extra-controls="controls,video_bitrate=6000000,video_bitrate_mode=0;" ! queue ! h264parse ! mp4mux ! filesink location=/opt/mux_avc.mp4
- 此命令以 720p 30 FPS 配置启动相机,并在 h264 视频编码后将其另存为视频文件。如果 gst 管道状态更改为 “PLAYING”,则表示摄像头正在运行。
- 如果要停止摄像头录制,请按下
CTRL+C - MP4 文件保存在 /opt/ 目录
命令说明:
! 是一个连接符号,用于将前一个元素的输出连接到后一个元素的输入
gst-launch-1.0这是 GStreamer 的命令行工具,用于启动一个 GStreamer 管道(pipeline)。-e 参数表示在管道结束时退出,而不是继续运行。qtiqmmfsrc name=camsrc camera=1高通平台专用的摄像头源插件,从设备 camera=1(副摄像头)采集视频。video_1::type=preview这是 qtiqmmfsrc 元素的属性配置,针对 video_1 流(不同摄像头可能输出多路流,比如预览流、抓拍流等 ),设置其类型为 preview(预览流 ),表示后续处理的是用于实时预览场景的视频流,一般帧率、分辨率等参数会适配预览需求。video/x-raw,format=NV12,width=1280,height=720,framerate=30/1video/x-raw(原始视频),NV12(YUV 4:2:0,单平面格式,常见于视频编码),分辨率 1280×720(720p),帧率 30fps。compression=ubwc,interlace-mode=progressive,colorimetry=bt601启用高通的UBWC(Ultra Bandwidth Compression) 技术,通过硬件压缩减少内存带宽需求,逐行扫描(非隔行),色彩空间为 ITU-R BT.601(适用于标清视频)。tee name=t分流器(tee)元素,作用是将一路输入数据复制成多路输出,方便对同一视频流进行多种不同处理(这里一路用于预览显示,一路用于编码存储 )。 name=t 给这个 tee 元素命名为 t,后续其他分支通过名字引用它来获取视频流 。queue ! waylandsink fullscreen=truequeue:队列元素,用于在 pipeline 中创建一个缓冲队列,起到解耦上下游元素、异步处理的作用。可以缓解上下游处理速度不一致的问题,避免因一方处理慢导致另一方阻塞或丢帧 。
waylandsink:输出 sink 元素,用于在 Wayland 显示服务器环境下,将视频画面渲染显示到屏幕上 。
fullscreen=true:设置 waylandsink 以全屏模式显示视频画面 。
t. ! queuet.:通过 . 语法引用之前命名为 t 的 tee 元素,获取视频流进行后续处理 。
queue:再次使用队列元素,缓冲数据,保证编码等环节的流畅性 。
v4l2h264enc capture-io-mode=5 output-io-mode=5 extra-controls="controls,video_bitrate=6000000 video_bitrate_mode=0;"使用 DMABUF(直接内存访问缓冲区)进行输入,优化数据传输效率,同样使用 DMABUF 输出编码后数据,目标比特率为 6 Mbps,使用 CBR(固定比特率) 模式,适合网络流媒体或需要稳定带宽的场景。queue ! h264parse ! mp4mux ! filesink location=/opt/mux_avc.mp4queue:又一个队列元素,继续缓冲编码后的数据,协调后续处理速度。解析 H.264 流,添加必要的 NAL 单元头部,使其符合 MP4 封装要求,将 H.264 视频流封装为 MP4 格式,将数据写入文件 /opt/mux_avc.mp4。
预览+拍照
- 在 device 终端中运行以下命令:
gst-pipeline-app -e qtiqmmfsrc name=camsrc camera=1 ! 'video/x-raw(memory:GBM),format=NV12,width=1280,height=720,framerate=30/1' ! waylandsink camsrc.image_1 ! "image/jpeg,width=1280,height=720,framerate=30/1" ! multifilesink location=/opt/frame%d.jpg async=false sync=true
- 按
Enter键。此命令将打印以下菜单并等待用户输入。
##################################### MENU #####################################
============================== Pipeline Controls==============================
(0) NULL: Set the pipeline into NULL state
(1) READY: Set the pipeline into READY state
(2) PAUSED: Set the pipeline into PAUSED state
(3) PLAYING: Set the pipeline into PLAYING state
==================================== Other====================================
(p) Plugin Mode: Choose a plugin which to control
(q) Quit : Exit the application
Choose an option:
- 使用以下菜单步骤在预览时拍摄快照。
(1) ready -> (3) Playing -> (Enter)-> (p)Plugin Mode : Select (5)camerasrc ->(36) capture-image -> (1): still – Snapshot ->(1) Snapshot count ('guint' value for arg1)
- 要停止相机,请按
Enter,按b(返回),然后按q(退出)。拍摄的快照图像保存在 /opt/ 中。通过在主机 PC 上运行以下scp命令,可以从设备中提取录制的内容:
scp -r root@[ip-addr]:/opt/<file name> .
- 生成文件如下图所示:

双摄像头流拼接显示
从主摄像头和辅助摄像头获取的两个流(均为 720p)。两个流被发送以并排组合,然后显示。
gst-launch-1.0 -e qtivcomposer name=mixer sink_0::position="<0, 0>" sink_0::dimensions="<640, 360>" sink_1::position="<640, 0>" sink_1::dimensions="<640, 360>" mixer. ! queue ! waylandsink enable-last-sample=false fullscreen=true qtiqmmfsrc name=camsrc_0 camera=0 ! video/x-raw\(memory:GBM\), format=NV12, width=1280, height=720, framerate=30/1, compression=ubwc ! mixer. qtiqmmfsrc name=camsrc_1 camera=1 ! video/x-raw\(memory:GBM\), format=NV12, width=1280, height=720, framerate=30/1, compression=ubwc ! mixer.
- 如果要停止摄像头流,请按下
CTRL+C
USB 摄像头测试
Quectel Pi H1 单板电脑支持 USB 接口摄像头,下面选取微雪的一款 OV5693 5MP USB 接口摄像头为例进行测试。
摄像头连接
将 USB 摄像头的连接线插入 Quectel Pi H1 的 type-A 接口。
查看相关信息
- 在 SSH 终端中运行以下命令,可查看系统识别到的 USB 设备信息:
dmesg | grep usb

- 在 SSH 终端中运行以下命令,可查看新增设备节点:
v4l2-ctl --list-devices

- /dev/video2 —— 主视频节点,后面gst命令主要操作这个节点
- /dev/video3 —— 元数据节点
- /dev/media3 —— 硬件拓扑控制器,控制整个 pipeline
- 在 SSH 终端中运行以下命令,可查看 video 节点支持的格式:
v4l2-ctl --list-formats-ext --device /dev/video2

- 由图可知,该摄像头支持 MJPG 和 YUYV 两种格式的图片输出。
前提条件
连接好 HDMI 屏幕,在 SSH 终端中运行以下命令:
mount -o rw,remount /
export XDG_RUNTIME_DIR=/dev/socket/weston
export WAYLAND_DISPLAY=wayland-1
实时预览
- 在 device 终端中运行以下命令:
- MJPG 格式(分辨率、帧率需符合摄像头支持的模式)
gst-launch-1.0 v4l2src device=/dev/video2 ! image/jpeg,width=1280,height=720,framerate=30/1 ! jpegdec ! videoconvert ! waylandsink fullscreen=true
- YUV 格式(分辨率、帧率需符合摄像头支持的模式)
gst-launch-1.0 v4l2src device=/dev/video2 ! video/x-raw,format=YUY2,width=1280,height=720,framerate=10/1 ! videoconvert ! waylandsink fullscreen=true
命令说明:
- gst-launch-1.0 -e
启动管线;-e 保证按 Ctrl+C 停止时能正确收尾(EOS)。
- v4l2src device=/dev/video2
从 V4L2 设备 /dev/video2 采集数据。
- image/jpeg,width=1280,height=720,framerate=30/1
要求摄像头输出 1280×720@30 fps 的 MJPEG;若摄像头不支持,pipeline 会直接报错。
- jpegdec
将 MJPEG 帧解码成原始 YUV/RGB 像素数据。
- videoconvert
把像素格式转成 waylandsink 能接受的格式(通常是 NV12/BGRx)。
- waylandsink fullscreen=true
用 Wayland 作为显示后端,并把窗口设置为 全屏(无标题栏、铺满屏幕)。
预览+视频录制
- 在 device 终端中运行以下命令:
gst-launch-1.0 -e v4l2src device=/dev/video2 io-mode=2 ! \
image/jpeg,width=1280,height=720,framerate=30/1 ! \
jpegdec ! videoconvert ! tee name=t \
t. ! queue ! v4l2h264enc ! h264parse ! mp4mux ! filesink location=/opt/out.mp4 \
t. ! queue ! videoconvert ! waylandsink fullscreen=true sync=false
- 此命令以 720p 30 FPS 配置启动相机,并在 h264 视频编码后将其另存为视频文件。如果 gst 管道状态更改为 "PLAYING",则表示摄像头正在运行。
- 如果要停止摄像头录制,请按下
CTRL+C。 - MP4 文件保存在 /opt/ 目录。
命令说明:
- v4l2src device=/dev/video2 io-mode=2
从 /dev/video2 设备捕获视频流,io-mode=2 表示使用内存映射(mmap)模式,提高性能。
- image/jpeg,width=1280,height=720,framerate=30/1
指定捕获的视频流格式为 MJPEG,分辨率为 1280×720,帧率为 30fps。
- jpegdec
解码 MJPEG 格式的视频流,将其转换为原始的 RGB/YUV 格式。
- videoconvert
将解码后的视频格式转换为适合后续处理的格式(例如,从 YUV 转换为 RGBA)。
- tee name=t
将一路视频流分成两路,后续可以通过 t. 引用这两路流。
- t. ! queue
从 tee 元素中取出一路流,并通过 queue 元素进行缓冲。
- v4l2h264enc
将视频流编码为 H.264 格式。
- h264parse
解析 H.264 编码的视频流,使其符合 MP4 文件格式的要求。
- mp4mux
将 H.264 视频流封装为 MP4 文件格式。
- filesink location=/opt/out.mp4:
将封装好的 MP4 文件保存到 /opt/out.mp4。
- t. ! queue
从 tee 元素中取出另一路流,并通过 queue 元素进行缓冲。
- videoconvert
将视频格式转换为适合 Wayland 显示器显示的格式。
- waylandsink fullscreen=true sync=false
将视频流输出到 Wayland 显示器,以全屏模式显示视频,禁用同步模式,避免 Wayland 显示器等待数据流,从而提高显示性能。
- 播放视频文件,请在 device 终端中运行以下命令:
gst-launch-1.0 -e filesrc location=/opt/out.mp4 ! qtdemux ! queue ! h264parse ! v4l2h264dec capture-io-mode=5 output-io-mode=5 ! videocrop top=0 bottom=40 left=0 right=0 ! videoconvert ! waylandsink fullscreen=true enable-last-sample=false
命令说明:
- filesrc location=/opt/out.mp4
从 /opt/out.mp4 文件读取数据。
- qtdemux
将 MP4 文件中的视频和音频流分离出来。
- queue
缓冲数据,避免处理过程中的数据丢失。
- h264parse
解析视频流中的 H.264 编码数据。
- v4l2h264dec capture-io-mode=5 output-io-mode=5
使用 V4L2 解码器解码 H.264 视频流,capture-io-mode=5 和 output-io-mode=5 是硬件加速相关的参数。
- videocrop top=0 bottom=40 left=0 right=0
由于视频流自动对齐,填充额外的像素信息。导致视频底部有绿边,因此裁剪底部 40 像素。
- videoconvert
格式转换元素,确保裁剪后的视频流格式适合 Wayland 显示器。
- waylandsink fullscreen=true enable-last-sample=false
将解码后的视频输出到 Wayland 显示器上,并设置为全屏模式,同时禁用最后一帧显示。
预览+拍照
- 在 device 终端中运行以下命令:
gst-launch-1.0 -e v4l2src device=/dev/video2 io-mode=2 ! \
image/jpeg,width=1280,height=720,framerate=30/1 ! \
tee name=t \
t. ! queue ! jpegdec ! videoconvert ! waylandsink sync=false \
t. ! queue ! multifilesink location=/opt/shot-%05d.jpg max-files=5
- 按下
CTRL+C,自动保存最后5张图片。
命令说明:
- v4l2src device=/dev/video2 io-mode=2
从 USB 摄像头采集 MJPEG 数据。
- image/jpeg,width=1280,height=720,framerate=30/1
要求摄像头输出 1280×720@30 fps 的 MJPEG 流。
- tee name=t
把同一路流 一分为多,后面用 t. 引用。
- t. ! queue ! jpegdec ! videoconvert ! waylandsink sync=false
预览分支:解码 MJPEG → 转成 RGB → 送到 Wayland 窗口实时显示。sync=false 减少延迟。
- t. ! queue ! multifilesink location=shot-%05d.jpg max-files=5
拍照分支:每一帧原封不动保存为 JPG,文件名自动编号 %05d(5 位数字)。max-files=5 只保留最近 5 张,旧文件被自动删除。
- 查看照片请在 device 终端中输入以下命令:
gst-launch-1.0 filesrc location=/opt/shot-00036.jpg ! jpegdec ! imagefreeze ! waylandsink fullscreen=true
- 退出查看,请按下
CTRL+C。
命令说明:
- filesrc location=/opt/shot-00036.jpg
从文件系统读取 /opt/shot-00036.jpg。
- jpegdec
把 JPEG 压缩数据解码成原始 RGB/YUV 像素帧。
- imagefreeze
只保留第一帧,后续不断重复这一帧 → 实现"静止图片"效果。
- waylandsink fullscreen=true
把图像送到 Wayland 合成器全屏显示。
存储设备
NVMe SSD 分区、格式化与挂载
本文介绍如何在 Linux 系统中对 NVMe 固态硬盘(以 /dev/nvme0n1 为例)进行分区、格式化、挂载及性能测试的完整流程,适用于 Quectel Pi H1 。
分区操作(使用 fdisk)
通过 fdisk 工具对 NVMe 设备进行分区,步骤如下:
进入分区交互界面
执行以下命令,启动 fdisk 并指定目标 NVMe 设备:
fdisk /dev/nvme0n1
交互界面操作步骤
进入 fdisk 交互模式后,按以下顺序执行命令:
创建 GPT 分区表
输入 g 并回车,创建 GUID 分区表(GPT),适用于大容量设备(推荐):
Command (m for help): g
Created a new GPT disklabel (GUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
新建分区
输入 n 并回车,创建一个新分区。后续参数(分区号、起始扇区、结束扇区)保持默认即可(默认会使用全部可用空间):
Command (m for help): n
Partition number (1-128, default 1):
First sector (2048-xxxxxxxxx, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-xxxxxxxxx, default xxxxxx):
Created a new partition 1 of type 'Linux filesystem' and of size XX GiB.
写入分区表并退出
输入 w 并回车,将分区配置写入设备并退出 fdisk:
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
操作完成后,系统会生成新分区 /dev/nvme0n1p1(p1 表示第一个分区)。
格式化分区(EXT4 格式)
使用 mkfs.ext4 工具将新分区格式化为 EXT4 文件系统(适用于大多数 Linux 环境):
mkfs.ext4 /dev/nvme0n1p1
执行后会显示格式化进度,完成后输出类似信息:
mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 12345678 4k blocks and 3456789 inodes
Filesystem UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Superblock backups stored on blocks:
32768, 98304, 163840, ...
Allocating group tables: done
Writing inode tables: done
Creating journal (65536 blocks): done
Writing superblocks and filesystem accounting information: done
手动挂载分区
创建挂载目录
使用 mkdir 命令创建一个用于挂载 SSD 的目录(示例路径为 /mnt/myssd):
mkdir -p /mnt/myssd
挂载分区
将 /dev/nvme0n1p1 分区挂载到 /mnt/myssd 目录:
mount /dev/nvme0n1p1 /mnt/myssd
可通过 df -h 命令验证挂载是否成功,若输出中包含 /dev/nvme0n1p1 和 /mnt/myssd 则表示挂载正常:
df -h
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p1 100G 5G 95G 5% /mnt/myssd
配置自动挂载(重启后生效)
通过修改 /etc/fstab 文件实现系统启动时自动挂载分区:
编辑 fstab 文件
使用编辑器打开 /etc/fstab:
添加挂载配置
在文件末尾添加以下行,指定分区、挂载点、文件系统类型及挂载参数:
/dev/nvme0n1p1 /mnt/myssd ext4 defaults 0 2
性能测试(读写速度验证)
使用 dd 命令测试 SSD 的读写性能(测试时确保分区已挂载):
读取速度测试
创建一个临时测试文件(若已存在),并通过读取该文件到空设备(/dev/null)测试读取速度:
dd if=/mnt/myssd/testfile of=/dev/null bs=1G iflag=direct
说明:iflag=direct 表示绕过系统缓存,测试真实读取速度。
输出示例:
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.852345 s, 1.3 GB/s
写入速度测试
生成一个 1GB 的空文件(/dev/zero 为零数据来源),测试写入速度:
dd if=/dev/zero of=/mnt/myssd/testfile bs=1G count=1 oflag=direct
输出示例:
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.245678 s, 862 MB/s
测试完成后可删除临时文件:
rm /mnt/myssd/testfile
UFS 存储
Quectel Pi H1 内嵌 128GB UFS 存储芯片,相比 eMMC,UFS 读写速度更快、支持全双工通信和命令队列,性能更优。
查看容量
通过 fdisk -l 命令可以查询到 ufs 分区信息及容量。
root@qcm6490-idp:/opt/bc-1.08.1# fdisk -l
Disk /dev/sda: 116.09 GiB, 124646326272 bytes, 30431232 sectors
Disk model: C2G072
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 49B3A77D-3D7D-22A5-0A10-6A2ECDDEA256
Device Start End Sectors Size Type
/dev/sda1 6 131077 131072 512M EFI System
/dev/sda2 131078 138757 7680 30M Linux filesystem
/dev/sda3 138758 30431226 30292469 115.6G Linux root (ARM-64)
查看分区信息
通过 df 命令可以查询到 ufs 分区信息,使用情况,挂载目录等信息。
root@qcm6490-idp:/opt/bc-1.08.1# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 109G 3.3G 101G 4% /sysroot
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 3.6G 0 3.6G 0% /dev/shm
tmpfs 1.5G 31M 1.5G 3% /run
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup
tmpfs 3.6G 12K 3.6G 1% /tmp
tmpfs 3.6G 0 3.6G 0% /var/volatile
/dev/sda1 511M 136M 376M 27% /boot
/dev/sda2 25M 892K 22M 4% /var/persist
tmpfs 737M 0 737M 0% /run/user/0
性能测试
性能测试主要测试 ufs 在 linux 系统下对文件的读写速度,一般结合 time 与 dd 双命令进行测试。
写文件测试
root@qcm6490-idp:/opt# time dd if=/dev/zero of=tempfile bs=1M count=100 conv=fdatasync
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.2874 s, 365 MB/s
real 0m0.316s
user 0m0.000s
sys 0m0.122s
使用 dd 命令写文件时,需要加 conv=fdatasync 参数,表示当 dd 写 N 次结束之后,会 flush cache 同步到磁盘。因为对磁盘的写一般是先写到缓存还没有写到磁盘就返回了。这里测试出写磁盘速度为 365MB/s 。
读文件测试
在嵌入式系统中,经常需要测试系统文件读写性能,读文件时忽略 cache 的影响。这时可以指定参数 iflag=direct ,nonblock 。
root@qcm6490-idp:/opt# time dd if=tempfile of=/dev/null bs=1M count=100 iflag=direct,nonblock
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.196993 s, 532 MB/s
real 0m0.201s
user 0m0.001s
sys 0m0.041s
可知,从磁盘直接读取读速度为532MB/s。
核心资源与性能
CPU 指标与测试
Quectel Pi H1 单板电脑采用高通 QCS6490 作为核心处理器,基于 Arm v8 Cortex ,主频高达 2.7GHz 。
- 查看 CPU 信息命令
root@qcm6490-idp:/# cat /proc/cpuinfo
processor : 0
BogoMIPS : 38.40
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x2
CPU part : 0xd05
CPU revision : 0
processor : 1
BogoMIPS : 38.40
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x2
CPU part : 0xd05
CPU revision : 0
- processor :系统中逻辑处理核的编号,对于多核处理器则可以是物理核、或者使用超线程技术虚拟的逻辑核
- BogoMIPS :在系统内核启动时粗略测算的CPU 每秒运行百万条指令数( Million Instructions Per Second )
- 查看 CPU 使用率
执行top之后,按1显示各CPU核使用率
root@qcm6490-idp:/# top
top - 00:20:05 up 20 min, 1 user, load average: 0.04, 0.07, 0.06
Tasks: 340 total, 1 running, 339 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.5 us, 1.6 sy, 0.0 ni, 97.3 id, 0.0 wa, 0.5 hi, 0.0 si, 0.0 st
%Cpu1 : 0.5 us, 0.0 sy, 0.0 ni, 98.9 id, 0.0 wa, 0.5 hi, 0.0 si, 0.0 st
%Cpu2 : 1.6 us, 0.0 sy, 0.0 ni, 97.3 id, 0.5 wa, 0.0 hi, 0.0 si, 0.5 st
%Cpu3 : 0.0 us, 0.5 sy, 0.0 ni, 98.4 id, 0.0 wa, 0.5 hi, 0.0 si, 0.5 st
%Cpu4 : 1.1 us, 0.0 sy, 0.0 ni, 98.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.5 st
%Cpu5 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu6 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu7 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 7366.7 total, 6386.2 free, 498.6 used, 481.9 buff/cache
MiB Swap: 5395.5 total, 5395.5 free, 0.0 used. 6698.9 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 162028 9468 6524 S 1.1 0.1 0:07.64 systemd
594 message+ 20 0 6904 3712 3328 S 1.1 0.0 0:06.46 dbus-daemon
1087 root 20 0 1794556 61472 30848 S 1.1 0.8 0:05.56 containerd
1816 root 20 0 5768 2688 2048 R 1.1 0.0 0:00.04 top
40 root 20 0 0 0 0 I 0.5 0.0 0:00.48 kworker/3:0-mm_percpu_wq
50 root 20 0 0 0 0 S 0.5 0.0 0:00.55 rcuop/4
127 root 20 0 0 0 0 I 0.5 0.0 0:00.47 kworker/u16:6-events_unbound
280 root 20 0 34988 15176 14792 S 0.5 0.2 0:05.38 systemd-journal
925 root 20 0 630136 72200 53256 S 0.5 1.0 0:06.65 weston
- %us :表示用户空间程序的 CPU 使用率(没有通过 nice 调度)
- %sy :表示系统空间的 CPU 使用率,主要是内核程序
- %ni :表示用户空间且通过 nice 调度过的程序的 CPU 使用率
- %id :空闲 CPU
- %wa : 等待输入输出的 CPU 时间百分比
- %hi : CPU 处理硬中断的数量
- %si : CPU 处理软中断的数量
- %st : 实时
- 获取 CPU 温度信息
root@qcm6490-idp:/# cat /sys/class/thermal/thermal_zone0/temp
37000
- 上面显示数字为千分之一度,除以 1000 就是当前温度值。
- CPU 压力测试
CPU 的压力的测试方式有很多,可通过 bc 命令来计算圆周率方法来测试 CPU 在运算过程中的稳定性。
root@qcm6490-idp:/# echo "scale=5000; 4*a(1)" | bc -l -q &
[1] 1592
上述命令将在后台计算的 PI,并精确到小数点后 5000 位,计算过程需要一段时间。
此时,我们可以通过 top 命令检查 CPU 利用率的变化,如下所示:
root@qcm6490-idp:/# top
top - 06:42:14 up 8 min, 1 user, load average: 0.29, 0.16, 0.09
Tasks: 326 total, 3 running, 323 sleeping, 0 stopped, 0 zombie
%Cpu(s): 12.7 us, 0.2 sy, 0.0 ni, 86.8 id, 0.0 wa, 0.1 hi, 0.0 si, 0.2 st
MiB Mem : 7366.9 total, 6540.2 free, 439.5 used, 387.2 buff/cache
MiB Swap: 5395.7 total, 5395.7 free, 0.0 used. 6770.1 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1592 root 20 0 3052 1792 1536 R 99.7 0.0 0:14.37 bc
588 message+ 20 0 6908 3584 3200 S 0.7 0.0 0:03.06 dbus-da+
1 root 20 0 162064 9324 6380 S 0.3 0.1 0:04.26 systemd
...
约 15 秒后,PI 结果被计算出来。在此期间 CPU 使用率达到 100% ,没有发生异常,说明 CPU 压力测试通过。还可以继续增加精确值,可进一步提高测试压力。
root@qcm6490-idp:/# 3.141592653589793238462643383279502884197169399375105820974944592307\
81640628620899862803482534211706798214808651328230664709384460955058\
22317253594081284811174502841027019385211055596446229489549303819644\
...
Memory 状态
- 查看内存信息
root@qcm6490-idp:/opt/bc-1.08.1# cat /proc/meminfo
MemTotal: 7543736 kB
MemFree: 6664720 kB
MemAvailable: 6928688 kB
Buffers: 19768 kB
Cached: 380520 kB
SwapCached: 0 kB
Active: 52044 kB
Inactive: 462332 kB
Active(anon): 3588 kB
Inactive(anon): 142568 kB
Active(file): 48456 kB
Inactive(file): 319764 kB
- MemTotal:所有可用的RAM 大小,物理内存减去预留位和内核使用
- MemFree :LowFree + HighFree
- Buffers:用来给块设备做缓存的大小
- Cached:文件的缓冲区大小
- SwapCached:已经被交换出来的内存。与I/O 相关
- Active:经常(最近)被使用的内存
- Inactive:最近不常使用的内存
- 获取内存使用率
root@qcm6490-idp:/opt/bc-1.08.1# free -m
total used free shared buff/cache available
Mem: 7366 437 6504 31 424 6763
Swap: 5395 0 5395
- total :内存总量
- used :被使用的内存量
- free :可使用的内存量
- 内存压力测试
通过给定测试内存的大小和次数, 可以对系统现有的内存进行压力上的测试。可使用系统工具 memtester 进行测试,如指定内存大小 300MB ,测试次数为 1 ,测试命令为 "memtester 300M 1" 。
下列以使用 300MB 内存空间,单次测试为例:
root@qcm6490-idp:/# memtester 300M 1
memtester version 4.5.1 (64-bit)
Copyright (C) 2001-2020 Charles Cazabon.
Licensed under the GNU General Public License version 2 (only).
pagesize is 4096
pagesizemask is 0xfffffffffffff000
want 300MB (314572800 bytes)
got 300MB (314572800 bytes), trying mlock ...locked.
Loop 1/1:
Stuck Address : ok
Random Value : ok
Compare XOR : ok
Compare SUB : ok
Compare MUL : ok
Compare DIV : ok
Compare OR : ok
Compare AND : ok
Sequential Increment: ok
Solid Bits : ok
Block Sequential : ok
Checkerboard : ok
Bit Spread : ok
Bit Flip : ok
Walking Ones : ok
Walking Zeroes : ok
Done.
电源与功耗
PMIC 休眠唤醒
Linux 内核一般提供了三种 Suspend: Freeze、Standby 和STR( Suspend to RAM ),在用户空间向 /sys/power/state 文件分别写入 "freeze"、"standby" 和 "mem" , 即可触发它们。 Quectel Pi H1 支持 freeze 、mem 2 种方式,disk 暂不支持,以下将以 mem 为例进行测试说明。
- 查看当前 Quectel Pi H1 支持的模式
root@qcm6490-idp:/# cat /sys/power/state
freeze mem disk
- 设置唤醒源
测试休眠唤醒需要先设置唤醒源,设置 Debug 串口( ttySC0 )为唤醒源。
root@qcm6490-idp:/# echo enabled > /sys/devices/platform/soc@0/9c0000.geniqup/994000.serial/tty/ttyMSM0/power/wakeup
- 休眠到内存
在用户空间向 /sys/power/state 写入字符串即进入相应的电源管理模式,休眠到内存的方式如下:
root@qcm6490-idp:/# echo mem > /sys/power/state
[15219.746797] PM: suspend entry (s2idle)
[15219.760424] Filesystems sync: 0.013 seconds
[15219.780574] Freezing user space processes
[15219.781589] process_accept_req: 22 callbacks suppressed
[15219.781600] smcinvoke: process_accept_req: Server id :17 interrupted probaby due to suspend, pid:897
[15219.791806] smcinvoke: process_accept_req: Server id :24 interrupted probaby due to suspend, pid:962
[15219.801969] smcinvoke: process_accept_req: Server id :18 interrupted probaby due to suspend, pid:903
[15219.812240] smcinvoke: process_accept_req: Server id :17 interrupted probaby due to suspend, pid:898
[15219.822590] smcinvoke: process_accept_req: Server id :18 interrupted probaby due to suspend, pid:902
[15219.832962] smcinvoke: process_accept_req: Server id :26 interrupted probaby due to suspend, pid:969
[15219.843391] smcinvoke: process_accept_req: Server id :21 interrupted probaby due to suspend, pid:929
[15219.853728] smcinvoke: process_accept_req: Server id :21 interrupted probaby due to suspend, pid:930
[15219.864031] smcinvoke: process_accept_req: Server id :17 interrupted probaby due to suspend, pid:899
[15219.874482] smcinvoke: process_accept_req: Server id :22 interrupted probaby due to suspend, pid:935
[15219.900228] Freezing user space processes completed (elapsed 0.119 seconds)
- 通过 debug 串口唤醒
输入休眠命令后 Quectel Pi H1 休眠,将运行状态数据存到内存,并关闭外设,进入等待模式,此时因为设置的是 debug 唤醒,键盘随意输入字符即能成功唤醒系统,如下:
[15221.270632] process_accept_req: 3 callbacks suppressed
[15221.270636] smcinvoke: process_accept_req: process_accept_req txn 4 either invalid or removed from Q
[15221.270655] smcinvoke: process_accept_req: process_accept_req txn 2 either invalid or removed from Q
[15221.270668] smcinvoke: process_accept_req: process_accept_req txn 3 either invalid or removed from Q
[15221.270742] smcinvoke: process_accept_req: process_accept_req txn 2 either invalid or removed from Q
[15221.270870] smcinvoke: process_accept_req: process_accept_req txn 1 either invalid or removed from Q
[15221.270924] smcinvoke: process_accept_req: process_accept_req txn 4 either invalid or removed from Q
[15221.270981] smcinvoke: process_accept_req: process_accept_req txn 3 either invalid or removed from Q
[15221.270982] done.
[15221.271044] smcinvoke: process_accept_req: process_accept_req txn 1 either invalid or removed from Q
[15221.271059] smcinvoke: process_accept_req: process_accept_req txn 3 either invalid or removed from Q
[15221.271078] smcinvoke: process_accept_req: process_accept_req txn 2 either invalid or removed from Q
[15221.371963] PM: suspend exit
USB 与扩展外设
USB Host 测试
USB Host 是指能够控制和管理 USB 设备的系统或硬件,它负责为连接的 USB 设备(如U盘、键盘、鼠标等)提供电源、数据传输和管理功能。以下是一些常见的 USB Host 的功能和应用场景。
插入示例:

U 盘挂载
当 U 盘插入到 Quectel Pi H1 上的 USB Host 上时,系统检测到一个USB 闪存盘,并已成功初始化为存储设备。通过 dmesg -n 8 查看日志:
usb 1-1.2: new high-speed USB device number 7 using xhci-hcd
[ 806.667878][ T162] usb-storage 1-1.2:1.0: USB Mass Storage device detected
[ 806.676812][ T162] scsi host1: usb-storage 1-1.2:1.0
[ 808.172742][ T162] scsi 1:0:0:0: Direct-Access USB Flash Disk 1100 PQ: 0 ANSI: 4
[ 808.189763][ T74] sd 1:0:0:0: [sdg] 15730688 512-byte logical blocks: (8.05 GB/7.50 GiB)
[ 808.200512][ T74] sd 1:0:0:0: [sdg] Write Protect is off
[ 808.207624][ T74] sd 1:0:0:0: [sdg] Mode Sense: 43 00 00 00
[ 808.216028][ T74] sd 1:0:0:0: [sdg] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 808.244091][ T74] sdg: sdg1
- 确认设备节点
lsblk
输出信息如下:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 116.1G 0 disk
|-sda1 8:1 0 512M 0 part /boot
|-sda2 8:2 0 30M 0 part /var/persist
`-sda3 8:3 0 115.6G 0 part /var
/usr
/
/sysroot
sdb 8:16 0 8M 0 disk
|-sdb1 8:17 0 3.5M 0 part
|-sdb2 8:18 0 512K 0 part
`-sdb3 8:19 0 3.5M 0 part
sdc 8:32 0 8M 0 disk
|-sdc1 8:33 0 3.5M 0 part
|-sdc2 8:34 0 512K 0 part
`-sdc3 8:35 0 3.5M 0 part
sdd 8:48 0 32M 0 disk
|-sdd1 8:49 0 104K 0 part
|-sdd2 8:50 0 128K 0 part
|-sdd3 8:51 0 1M 0 part
|-sdd4 8:52 0 1M 0 part
`-sdd5 8:53 0 1M 0 part
sde 8:64 0 3G 0 disk
|-sde1 8:65 0 512K 0 part
|-sde2 8:66 0 64M 0 part
|-sde3 8:67 0 256K 0 part
|-sde4 8:68 0 2M 0 part
|-sde5 8:69 0 5M 0 part
|-sde6 8:70 0 4M 0 part
|-sde7 8:71 0 8M 0 part
|-sde8 8:72 0 4M 0 part
|-sde9 8:73 0 32M 0 part
|-sde10 8:74 0 128K 0 part
|-sde11 8:75 0 80K 0 part
|-sde12 8:76 0 2M 0 part
|-sde13 8:77 0 2M 0 part
|-sde14 8:78 0 128K 0 part
|-sde15 8:79 0 32K 0 part
|-sde16 259:0 0 1M 0 part
|-sde17 259:1 0 256K 0 part
|-sde18 259:2 0 512K 0 part
|-sde19 259:3 0 256K 0 part
|-sde20 259:4 0 64M 0 part
|-sde21 259:5 0 2M 0 part
|-sde22 259:6 0 5M 0 part
|-sde23 259:7 0 4M 0 part
|-sde24 259:8 0 8M 0 part
|-sde25 259:9 0 4M 0 part
|-sde26 259:10 0 32M 0 part
|-sde27 259:11 0 128K 0 part
|-sde28 259:12 0 80K 0 part
|-sde29 259:13 0 2M 0 part
|-sde30 259:14 0 2M 0 part
|-sde31 259:15 0 128K 0 part
|-sde32 259:16 0 32K 0 part
|-sde33 259:17 0 1M 0 part
|-sde34 259:18 0 256K 0 part
|-sde35 259:19 0 4K 0 part
|-sde36 259:20 0 4K 0 part
|-sde37 259:21 0 4K 0 part
|-sde38 259:22 0 16M 0 part
|-sde39 259:23 0 30M 0 part
|-sde40 259:24 0 1M 0 part
|-sde41 259:25 0 32.6M 0 part
|-sde42 259:26 0 4K 0 part
|-sde43 259:27 0 4K 0 part
|-sde44 259:28 0 1M 0 part
|-sde45 259:29 0 8M 0 part
|-sde46 259:30 0 40M 0 part
|-sde47 259:31 0 512M 0 part
|-sde48 259:32 0 28K 0 part
|-sde49 259:33 0 512K 0 part
|-sde50 259:34 0 1M 0 part
`-sde51 259:35 0 32.6M 0 part
sdf 8:80 0 32M 0 disk
|-sdf1 8:81 0 3M 0 part
|-sdf2 8:82 0 3M 0 part
|-sdf3 8:83 0 3M 0 part
`-sdf4 8:84 0 128K 0 part
sdg 8:96 1 7.5G 0 disk
`-sdg1 8:97 1 7.5G 0 part
zram0 253:0 0 5.3G 0 disk [SWAP]
- 创建挂载点
mkdir -p /mnt/usb
- 挂载分区
mount /dev/sdg1 /mnt/usb
- 验证挂载
df -h
输出信息如下:
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 109G 3.3G 101G 4% /sysroot
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 3.6G 0 3.6G 0% /dev/shm
tmpfs 1.5G 19M 1.5G 2% /run
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup
tmpfs 3.6G 20K 3.6G 1% /tmp
tmpfs 3.6G 0 3.6G 0% /var/volatile
/dev/sda1 511M 136M 376M 27% /boot
/dev/sda2 25M 44K 22M 1% /var/persist
tmpfs 737M 0 737M 0% /run/user/0
/dev/sdg1 7.5G 1.9G 5.7G 25% /var/rootdirs/mnt/usb
- 访问U盘内容
ls /mnt/usb
- 卸载U盘
umount /mnt/usb
键盘、鼠标
当 Logitech USB 无线接收器插入到 Quectel Pi H1 上的 USB Host 上时,键盘鼠标可以正常使用。具体细节可以通过 dmesg -n 8 查看日志,显示了一个 Logitech USB 无线接收器(型号 046D:C534,罗技键盘/鼠标套装)被 Linux 系统成功识别并初始化的过程。
usb 1-1.1: new full-speed USB device number 6 using xhci-hcd
[ 478.273171][ T1373] input: Logitech USB Receiver as /devices/platform/soc@0/8c00000.usb/xhci-hcd.0.auto/usb1/1-1/1-1.1/1-1.1:1.0/0003:046D:C534.0003/input/input10
[ 478.350114][ T1373] hid-generic 0003:046D:C534.0003: input: USB HID v1.11 Keyboard [Logitech USB Receiver] on usb-xhci-hcd.0.auto-1.1/input0
[ 478.367447][ T1373] input: Logitech USB Receiver Mouse as /devices/platform/soc@0/8c00000.usb/xhci-hcd.0.auto/usb1/1-1/1-1.1/1-1.1:1.1/0003:046D:C534.0004/input/input11
[ 478.383765][ T1373] input: Logitech USB Receiver Consumer Control as /devices/platform/soc@0/8c00000.usb/xhci-hcd.0.auto/usb1/1-1/1-1.1/1-1.1:1.1/0003:046D:C534.0004/input/input12
[ 478.458989][ T1373] input: Logitech USB Receiver System Control as /devices/platform/soc@0/8c00000.usb/xhci-hcd.0.auto/usb1/1-1/1-1.1/1-1.1:1.1/0003:046D:C534.0004/input/input13
[ 478.475639][ T1373] hid-generic 0003:046D:C534.0004: input,hiddev96: USB HID v1.11 Mouse [Logitech USB Receiver] on usb-xhci-hcd.0.auto-1.1/input1
USB OTG 测试
利用 qusb 命令设置 USB 工作模式,qusb 支持的参数如下:
init 初始化 USB 配置(挂载 configfs,创建设备节点,加载默认 PID)
bind 绑定 USB 设备到配置(激活当前配置)
unbind 解绑 USB 设备(停止当前配置)
setpid <PID> 切换到指定 PID 的 USB 组合模式(如 setpid 901D 启用 DIAG+ADB)
setpid -p <PID> 设置 PID 为默认模式(持久化到 /etc/usb/usb_pid,重启后生效
showpid 显示所有支持的 PID 及其对应功能组合
persist <PID> 仅持久化 PID(不立即切换)
利用 qusb 测试 USB 口模拟网卡的功能
- 查看 usb 支持的所有功能:
root@qcm6490-idp:/# qusb showpid A4A1: NCM 4EE7: ADB 900E: DIAG 901C: DIAG,UAC2 901D: DIAG,ADB 9015: MASS_STORAGE,ADB 9024: RNDIS,ADB 902A: RNDIS,MASS_STORAGE 902B: RNDIS,ADB,MASS_STORAGE 902C: RNDIS,DIAG 902D: RNDIS,DIAG,ADB 902F: RNDIS,DIAG,MASS_STORAGE 908C: NCM,ADB 90CA: DIAG,UAC2,ADB 90CB: DIAG,UVC,ADB 90CC: DIAG,UAC2,UVC,ADB 90DF: DIAG,UVC 90E0: DIAG,UAC2,UVC 9135: DIAG,QDSS,ADB 9136: DIAG,QDSS F000: MASS_STORAGE F00E: RNDIS - 切换 USB 模式:
qusb setpid 908C# 启用 NCM+ADB,此时中设备的 shell 里执行ifconfig -a可以查看到 usb0 接口 - 将板卡的 Type-C 口与 PC 的 USB 口连接[PC 的系统建议是 linux]
- 为板卡的 usb0 接口设置 IP 地址:
ip addr add dev usb0 192.168.0.5/24 - 为 PC 上新识别出来的 USB 网卡设置地址:
ip addr add dev enp0s20f0u13 192.168.0.6/24#这里的 enp0s20f0u13 需要根据实际情况进行修改 - 测试网络:在 PC 的 SHELL 中执行
ping 192.168.0.5#可以观察到能程序 ping 通目的地址
连接 WiFi 的一般步骤及示例
打开无线功能
使用命令来打开无线功能,相当于桌面版的 “打开 Wi-Fi 开关”。
nmcli radio wifi on
查看可用 WiFi 列表
执行命令,扫描并列出当前无线网卡探测到的 Wi-Fi 网络。该命令会显示附近的 WiFi 网络以及它们的名称(SSID)、信号强度、频道和加密方式等信息。
nmcli dev wifi list ifname wlan0
返回如下,可以看到周围的热点信息。
root@QuecPi:~# nmcli dev wifi list ifname wlan0
IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS SECURITY
64:09:80:76:42:BE Xiaomi_42BD Infra 11 130 Mbit/s 100 ▂▄▆█ WPA1 WPA2
* F8:5E:3C:01:F8:18 xiupax Infra 11 130 Mbit/s 100 ▂▄▆█ --
9C:9D:7E:F7:30:5E tdz Infra 2 130 Mbit/s 97 ▂▄▆█ WPA1 WPA2
E2:F1:E1:57:D5:C6 gms-wifi Infra 1 0 Mbit/s 95 ▂▄▆█ WPA1 WPA2
E2:F1:E1:57:D5:C8 cit-test-5g Infra 1 0 Mbit/s 94 ▂▄▆█ WPA2
48:5F:08:BB:BA:41 TP-LINK_BA41 Infra 11 270 Mbit/s 87 ▂▄▆█ --
64:09:80:76:42:BF Xiaomi_42BD_5G Infra 157 270 Mbit/s 82 ▂▄▆█ WPA1 WPA2
B4:2F:03:DA:23:B5 5G_RRO_A23B5 Infra 157 135 Mbit/s 79 ▂▄▆_ WPA1 WPA2
A2:A7:90:A7:5B:A0 LSMate30 Infra 149 270 Mbit/s 77 ▂▄▆_ WPA2
A4:00:E2:EF:F7:83 Quectel-HF Infra 1 260 Mbit/s 74 ▂▄▆_ WPA1 WPA2 802.1X
F0:2F:74:2A:41:78 odmtest Infra 1 260 Mbit/s 74 ▂▄▆_ WPA3
2C:CF:67:6B:4A:86 HW-676B4A85 Infra 36 117 Mbit/s 74 ▂▄▆_ WPA1
A4:00:E2:EF:F7:82 Quectel-HF-2.4G Infra 1 260 Mbit/s 72 ▂▄▆_ WPA1 WPA2 802.1X
A4:00:E2:EF:F7:80 Quectel-Customer-2.4G Infra 1 260 Mbit/s 72 ▂▄▆_ WPA1 WPA2
66:D6:9A:C6:6D:21 PAXWIFIAP_2.4G Infra 1 130 Mbit/s 72 ▂▄▆_ WPA2
A4:00:E2:EF:F7:90 Quectel-Customer Infra 44 540 Mbit/s 72 ▂▄▆_ WPA1 WPA2
A4:00:E2:EF:F7:92 Quectel-HF Infra 44 540 Mbit/s 72 ▂▄▆_ WPA1 WPA2 802.1X
9C:9D:7E:F7:30:5F tdz Infra 149 270 Mbit/s 70 ▂▄▆_ WPA1 WPA2
34:CE:00:09:E5:A8 SW_test Infra 6 130 Mbit/s 69 ▂▄▆_ WPA1 WPA2
E2:F1:E1:57:D5:CA gms-wifi_5G Infra 149 270 Mbit/s 69 ▂▄▆_ WPA1 WPA2
E2:F1:E1:57:D5:CE cit-test-5g Infra 149 270 Mbit/s 69 ▂▄▆_ WPA2
F0:2F:74:2A:41:7C odmtest-5G Infra 161 540 Mbit/s 65 ▂▄▆_ WPA2
A4:00:E2:EF:F8:52 Quectel-HF Infra 36 540 Mbit/s 57 ▂▄▆_ WPA1 WPA2 802.1X
A4:00:E2:EF:F8:50 Quectel-Customer Infra 36 540 Mbit/s 57 ▂▄▆_ WPA1 WPA2
3C:7C:3F:0B:94:FC HWTEST Infra 161 540 Mbit/s 52 ▂▄__ WPA2
A4:00:E2:EF:F4:50 Quectel-Customer Infra 149 540 Mbit/s 49 ▂▄__ WPA1 WPA2
A4:00:E2:EF:F4:52 Quectel-HF Infra 149 540 Mbit/s 47 ▂▄__ WPA1 WPA2 802.1X
连接 WiFi 网络
选择要连接的 WiFi 网络,并执行命令nmcli dev wifi connect "你的WiFi名称" password "你的密码"来连接到该网络。例如,nmcli dev wifi connect "MyHomeWiFi" password "12345678"。如果网络没有密码,则不需要提供password参数。
连接加密热点:
root@QuecPi:~# nmcli dev wifi connect "SSID" password "12345678" ifname wlan0
Device 'wlan0' successfully activated with 'd0ef4183-ac40-41d5-8822-2cc174107c77'.
连接开放热点:
root@QuecPi:~# nmcli dev wifi connect "SSID" ifname wlan0
Device 'wlan0' successfully activated with 'd0ef4183-ac40-41d5-8822-2cc174107c77'.
使用 ifconfig 命令查看网络接口地址:
root@qcm6490-idp:~# ifconfig
eth0 Link encap:Ethernet HWaddr 32:C0:A2:09:FE:40
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:167 Base address:0x1000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:75 errors:0 dropped:0 overruns:0 frame:0
TX packets:75 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:6301 (6.1 KiB) TX bytes:6301 (6.1 KiB)
p2p0 Link encap:Ethernet HWaddr 02:03:7F:D6:00:01
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
wlan0 Link encap:Ethernet HWaddr 00:03:7F:50:00:01
inet addr:192.168.253.211 Bcast:192.168.253.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3421 errors:0 dropped:0 overruns:0 frame:0
TX packets:61 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3000
RX bytes:151273 (147.7 KiB) TX bytes:7300 (7.1 KiB)
可以发现 wlan0 口已经获取 IP。
测试无线网络
执行 ping 命令测试网络连接:
- 执行
ping 192.168.1.1命令,如果 ping 通则表示局域网网络连接正常【这里的目的 ip 需要修改为实际网络的网关地址】。 - 执行
ping 114.114.114.114命令,如果 ping 通则表示外网网络连接正常。 - 执行
ping baidu.com命令,如果 ping 通则表示外网网络连接正常且 DNS 解析功能正常。