海思3516DV300通过mipi_tx驱动st7701s屏幕的配置与调试实战
1. 海思3516DV300与st7701s屏幕的基础认知
第一次拿到海思3516DV300开发板和st7701s屏幕时,我对着密密麻麻的接口引脚发了半天呆。这块芯片是海思面向智能摄像头和边缘计算设备推出的SoC,而st7701s则是常见的480x800分辨率MIPI接口屏幕。要让它们俩顺利"对话",得先理解几个关键点:
MIPI(移动产业处理器接口)是移动设备常用的高速串行接口,包含DSI(显示串行接口)和CSI(摄像头串行接口)两种主要协议。在3516DV300上,我们需要配置的是MIPI_TX(发送端)通过DSI协议驱动屏幕。st7701s作为接收端,支持2-lane或4-lane的MIPI-DSI接口,实际项目中我用的这块屏是2-lane配置。
硬件连接时要注意几个细节:开发板的MIPI_TX接口通常有4对差分线(lane0~lane3),但st7701s只用到了lane0和lane1。记得检查硬件手册确认电压匹配,有些屏幕需要1.8V电平而开发板默认可能是3.3V。我就吃过这个亏,调试时屏幕死活不亮,最后发现是电平转换电路没配置好。
2. 开发环境准备与MPP框架解析
海思提供的MPP(媒体处理平台)框架是开发的核心,最新版本可以从官网下载。解压后目录结构大致如下:
Hi3516DV300_SDK_V1.0.1.0 ├── mpp │ ├── include # 头文件 │ ├── lib # 库文件 │ └── sample # 示例代码 └── osdrv # 内核和驱动建议先用官方示例测试基础功能。我选择的是sample_vdec例程,因为它完整展示了视频解码到显示的流程。重点看SAMPLE_H264_VDEC_VPSS_VO这个demo,其中VO(Video Output)模块正是控制屏幕显示的关键。
编译环境搭建要注意:
# 设置交叉编译工具链 export PATH=/opt/hisi-linux/x86-arm/arm-himix200-linux/bin:$PATH # 编译示例代码 cd mpp/sample make clean && make -j8遇到编译错误时,常见问题包括:
- 工具链路径未正确设置
- 依赖库缺失(如freetype、zlib)
- 内核头文件版本不匹配
3. VO设备配置实战
原始demo是为1080P屏幕设计的,我们需要修改VO配置适配480x800的st7701s。主要改动在SAMPLE_COMM_VO_StartVO函数:
// 定义屏幕参数 RECT_S stDefDispRect = {0, 0, 480, 800}; SIZE_S stDefImageSize = {480, 800}; // 配置VO设备 VO_DEV VoDev = 0; // 通常使用设备0 stVoConfig.VoDev = VoDev; stVoConfig.enVoIntfType = VO_INTF_MIPI; // 接口类型设为MIPI stVoConfig.enIntfSync = VO_OUTPUT_USER; // 自定义时序 stVoConfig.u32DisBufLen = 3; // 显示缓冲区数量 stVoConfig.stDispRect = stDefDispRect; // 显示区域 stVoConfig.stImageSize = stDefImageSize; // 图像尺寸这里有几个容易踩的坑:
enIntfSync必须设为VO_OUTPUT_USER才能使用自定义分辨率u32DisBufLen建议设为3,避免画面撕裂stDispRect和stImageSize要保持一致,否则会出现缩放异常
4. 时序参数计算详解
时序配置是驱动屏幕最复杂的部分,需要计算水平/垂直同步信号的各种参数。海思提供了Excel计算工具(RGB_MIPI屏幕时钟时序计算器.xlsx),但理解原理很重要。
以480x800@60Hz为例,关键参数包括:
| 参数名 | 含义 | 计算值 |
|---|---|---|
| vid_hsa_pixels | 行同步脉冲宽度 | 60 |
| vid_hbp_pixels | 行后肩(水平消隐后沿) | 66 |
| vid_hfp_pixels | 行前肩(水平消隐前沿) | 60 |
| vid_vsa_lines | 场同步脉冲宽度 | 10 |
| vid_vbp_lines | 场后肩(垂直消隐后沿) | 20 |
| vid_vfp_lines | 场前肩(垂直消隐前沿) | 18 |
这些参数需要填入SAMPLE_COMM_VO_StartDev函数:
pstPubAttr->stSyncInfo.u16Vact = 800; // 垂直有效区域 pstPubAttr->stSyncInfo.u16Vbb = 20; // 垂直后肩 pstPubAttr->stSyncInfo.u16Vfb = 18; // 垂直前肩 pstPubAttr->stSyncInfo.u16Hact = 480; // 水平有效区域 pstPubAttr->stSyncInfo.u16Hbb = 66; // 水平后肩 pstPubAttr->stSyncInfo.u16Hfb = 60; // 水平前肩调试时如果屏幕出现花屏、闪烁或偏移,大概率是这些参数不对。建议先用厂家提供的典型值,再微调。
5. MIPI-TX物理层配置
MIPI-TX的物理层配置在SAMPLE_COMM_VO_StartMipiTx中完成,需要定义combo_dev_cfg_t结构体:
combo_dev_cfg_t MIPI_TX_480X800_60_CONFIG = { .devno = 0, // 设备号 .lane_id = {0, 1, -1, -1}, // 使用lane0和lane1 .output_mode = OUTPUT_MODE_DSI_VIDEO, .output_format = OUT_FORMAT_RGB_24_BIT, .video_mode = BURST_MODE, .sync_info = { .vid_pkt_size = 480, // 水平有效像素 .vid_hsa_pixels = 60, // 行同步脉冲 .vid_hbp_pixels = 66, // 行后肩 .vid_hline_pixels = 666, // 总行像素(480+60+66+60) .vid_vsa_lines = 10, // 场同步脉冲 .vid_vbp_lines = 20, // 场后肩 .vid_vfp_lines = 18, // 场前肩 .vid_active_lines = 800, // 垂直有效行 }, .phy_data_rate = 367, // 数据速率(Mbps) .pixel_clk = 30578, // 像素时钟(KHz) };其中phy_data_rate的计算公式为:
data_rate = (h_total * v_total * fps * bpp) / lane_count h_total = hact + hsa + hbp + hfp v_total = vact + vsa + vbp + vfp以我们的配置为例:
(666 * 848 * 60 * 24) / 2 ≈ 367Mbps6. 常见问题排查指南
调试过程中我遇到过各种奇葩问题,这里分享几个典型案例:
问题1:屏幕背光亮但无显示
- 检查MIPI信号线是否接反(lane0和lane1的P/N要对)
- 确认
output_mode设置为OUTPUT_MODE_DSI_VIDEO - 测量MIPI时钟信号是否正常(应有300MHz左右)
问题2:显示画面错位
- 检查时序参数中的前后肩值
- 确认
vid_pkt_size和vid_active_lines与分辨率匹配 - 调整
stDispRect的起始坐标
问题3:屏幕闪烁或有噪点
- 降低phy_data_rate试试
- 检查电源稳定性,MIPI对电源噪声敏感
- 在PCB上增加终端电阻(通常100Ω)
问题4:颜色异常
- 确认
output_format与屏幕一致(RGB24/RGB16等) - 检查像素格式
PIXEL_FORMAT_YVU_SEMIPLANAR_420是否匹配输入数据
7. 性能优化技巧
当系统需要同时处理视频解码和显示时,这几个优化点很实用:
- 内存分配优化:
// 在MPP初始化时设置更大的VB池 VB_CONFIG_S stVbConf; stVbConf.u32MaxPoolCnt = 64; HI_MPI_VB_SetConfig(&stVbConf);- 降低CPU占用:
- 使用硬件加速的缩放模块(VPSS)
- 开启VO的直接渲染模式:
stVoConfig.enVoMode = VO_MODE_1MUX_DIRECT;- 动态调整帧率:
// 根据系统负载动态设置 HI_MPI_VO_SetDevFrameRate(VoDev, target_fps);- 双缓冲策略:
// 在VO配置中设置两个显示缓冲区 stVoConfig.u32DisBufLen = 2;调试时可以查看系统状态:
cat /proc/umap/vo显示信息包括帧率、缓冲区状态、丢帧计数等关键指标。
