Zynq 图像处理实战:基于 MIPI CSI-2 RX 的图像采集与处理系统

前言

在嵌入式视觉应用中,Xilinx Zynq-7000 SoC 凭借其 FPGA+ARM 的异构架构,成为图像处理领域的热门选择。本文将详细介绍如何使用 Xilinx 官方 IP 核搭建一个完整的 MIPI 图像采集与处理系统。


系统架构

┌──────────────┐    ┌─────────────────┐    ┌─────────────┐    ┌──────────────┐
│  图像传感器   │───▶│ MIPI CSI-2 RX  │───▶│  Demosaic    │───▶│  Gamma LUT   │
│   (OV5640)   │    │    Subsystem    │    │   去马赛克   │    │   色彩校正   │
└──────────────┘    └─────────────────┘    └─────────────┘    └──────────────┘
                                                                      │
                                                                      ▼
┌──────────────┐    ┌─────────────────┐    ┌─────────────┐    ┌──────────────┐
│   HDMI/VGA   │◀───│   Video Timing  │◀───│  AXI4-Stream│◀───│   AXI4 总线   │
│    显示器     │    │    Controller   │    │   to Video  │    │   (PS 端)    │
└──────────────┘    └─────────────────┘    └─────────────┘    └──────────────┘

一、MIPI CSI-2 RX Subsystem IP

1.1 IP 功能概述

MIPI CSI-2 RX Subsystem 是 Xilinx 提供的 MIPI 接口接收端完整解决方案,支持:

  • 1/2/4 Lane 配置,最高速率 1.5Gbps/lane
  • YUV420/YUV422/RGB 格式支持
  • 自动 D-PHY 时钟检测
  • AXI4-Stream 接口输出,便于后续处理

1.2 IP 配置要点

Clock Mode:          Shared Clock
Number of Lanes:     2 Lanes
Pixel Format:        YUV422 8-bit / RGB888
Line Rate:           1.0 Gbps
Video Format:        1920x1080 @ 30fps

1.3 关键信号说明

信号名 方向 说明
mipi_phy_clk 输入 MIPI 时钟 lane 差分输入
mipi_phy_data 输入 MIPI 数据 lane 差分输入
s_axi_* 输入 AXI-Lite 配置接口
m_axis_video 输出 AXI4-Stream 视频数据输出
irq 输出 中断信号(帧完成、错误等)

1.4 Vivado 配置截图位置

Block Design → MIPI CSI-2 Rx Subsystem → Re-customize IP
→ Stream Interface → TUSER width: 8 (用于传输数据类型标识)

二、Demosaic IP(去马赛克模块)

2.1 功能说明

当使用 Bayer 格式传感器(如 OV5640)时,输出为单通道 Bayer 数据,需要通过 Demosaic 算法转换为 RGB 三通道数据。

Xilinx 官方 Demosaic IP 支持:

  • Bayer 转 RGB 插值算法
  • 双线性插值自适应插值模式
  • AXI4-Stream 接口,易于集成

2.2 IP 配置

Input Format:        BAYER8 (8-bit Bayer)
Output Format:       RGB888
Interpolation:       Bilinear (资源占用少) / Adaptive (效果更好)
Max Resolution:      1920x1080

2.3 算法原理

Bayer 排列示例 (RGGB):
R G R G R G
G B G B G B
R G R G R G
G B G B G B

双线性插值计算 G 分量:
G(x,y) = (G(x-1,y) + G(x+1,y) + G(x,y-1) + G(x,y+1)) / 4

2.4 资源占用 (Artix-7 XC7A35T)

资源 占用
LUT ~1,200
FF ~800
BRAM 2

三、Gamma LUT IP(色彩校正模块)

3.1 Gamma 校正原理

人眼对亮度的感知是非线性的,Gamma 校正用于补偿显示设备的非线性响应:

输出 = 输入 ^ (1/γ)

典型 γ 值:2.2 (sRGB 标准)

3.2 Xilinx Gamma LUT IP 配置

Input Depth:         10-bit
Output Depth:        10-bit
LUT Size:            256 entries (可配置)
Gamma Value:         2.2 (可动态配置)
Color Space:         RGB

3.3 LUT 表生成 (Python 示例)

import numpy as np

gamma = 2.2
lut_size = 256
input_depth = 10  # 0-1023

lut = []
for i in range(lut_size):
    normalized = i / (lut_size - 1)
    corrected = normalized ** (1/gamma)
    lut_value = int(corrected * ((2**input_depth) - 1))
    lut.append(lut_value)

# 导出为 COE 文件
with open('gamma_lut.coe', 'w') as f:
    f.write('memory_initialization_radix=10;n')
    f.write('memory_initialization_vector=n')
    f.write(','.join(map(str, lut)) + ';')

3.4 动态配置 Gamma 值

通过 AXI-Lite 接口可实时修改 Gamma 曲线,实现不同场景的色彩适配:

// PS 端配置代码示例
void gamma_lut_set_gamma(u32 base_addr, float gamma)
{
    u32 lut[256];
    for(int i = 0; i < 256; i++) {
        float normalized = (float)i / 255.0f;
        float corrected = powf(normalized, 1.0f/gamma);
        lut[i] = (u32)(corrected * 1023.0f);
    }
    
    // 通过 AXI-Lite 写入 LUT
    for(int i = 0; i < 256; i++) {
        Xil_Out32(base_addr + i*4, lut[i]);
    }
}

四、完整系统集成

4.1 Block Design 连接图

[MIPI CSI-2 RX] ──▶ [Demosaic] ──▶ [Gamma LUT] ──▶ [AXI4-Stream to Video]
      │                                              │
      │ (AXI-Lite)                                   │ (AXI4-Stream)
      ▼                                              ▼
  [AXI Interconnect]                            [Video Timing Ctrl]
      │                                              │
      ▼                                              ▼
  [Zynq PS]                                      [HDMI/VGA]

4.2 时钟约束

# MIPI 参考时钟 (通常 24MHz 或 27MHz)
create_clock -period 37.037 [get_ports mipi_ref_clk]

# 像素时钟 (1080p30 = 74.25MHz)
create_clock -period 13.468 [get_clocks clk_pixel]

# 约束 MIPI D-PHY 时钟
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets mipi_phy_clk]

4.3 中断处理

// 中断服务函数示例
void MIPI_Intr_Handler(void *CallbackRef)
{
    u32 status = Xil_In32(MIPI_BASE + 0x20); // 中断状态寄存器
    
    if(status & 0x01) {
        // 帧接收完成
        frame_ready = 1;
    }
    if(status & 0x02) {
        // 包错误
        error_count++;
    }
    
    // 清除中断
    Xil_Out32(MIPI_BASE + 0x20, status);
}

五、PS 端软件配置

5.1 设备树配置

&axi_mipi_csi2_rx_0 {
    status = "okay";
    clocks = <&clkc 15>, <&clkc 16>;
    clock-names = "lite_aclk", "pixel_clk";
    interrupts = <0 29 4>;
};

&axi_demosaic_0 {
    status = "okay";
};

&axi_gamma_lut_0 {
    status = "okay";
};

5.2 V4L2 驱动配置

// 传感器配置 (通过 I2C)
struct ov5640_config {
    u16 width = 1920;
    u16 height = 1080;
    u8  format = V4L2_PIX_FMT_YUV422;
    u8  fps = 30;
};

// MIPI Lane 配置
mipi_config.lanes = 2;
mipi_config.bitrate = 1000000; // 1Gbps

六、调试技巧

6.1 ILA 抓取关键信号

触发条件:m_axis_video_tvalid == 1 && m_axis_video_tready == 1
抓取信号:
  - m_axis_video_tdata[23:0]  (RGB 数据)
  - m_axis_video_tvalid
  - m_axis_video_tready
  - m_axis_video_tuser[7:0]   (数据类型)

6.2 常见问题排查

问题 可能原因 解决方案
无图像输出 MIPI 时钟未锁定 检查 D-PHY 时钟约束
图像花屏 像素格式不匹配 确认 Sensor 输出与 IP 配置一致
颜色异常 Gamma LUT 未初始化 检查 AXI 配置是否完成
帧率不稳定 时钟不同步 使用同一时钟源

七、性能优化建议

  1. 使用 4-Lane MIPI 提升带宽(如需 4K 分辨率)
  2. 启用 AXI Cache 提高 PS 端访问速度
  3. 使用 DDR 缓存 实现帧缓冲(VDMA 模块)
  4. 硬件加速 添加 3A 算法(AWB、AE、AF)

结语

本文介绍了基于 Xilinx 官方 IP 搭建 Zynq 图像处理系统的完整流程。通过 MIPI CSI-2 RX、Demosaic、Gamma LUT 三个核心模块的配合,可实现从图像采集到显示的完整链路。该方案已在多个项目中验证,具有良好的稳定性和可扩展性。


参考资源:

  • Xilinx MIPI CSI-2 RX Subsystem Product Guide (PG232)
  • Xilinx Demosaic IP Product Guide (PG102)
  • Xilinx Gamma LUT IP Product Guide (PG107)
  • Zynq-7000 SoC Technical Reference Manual

欢迎关注公众号,第一时间收到更新

本文首发于 monykate.com · 全文与代码格式以博客为准

通讯更新

请输入您的电子邮件地址进行订阅

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注