嘉楠科技
直播中

李军

8年用户 1300经验值
私信 关注
[问答]

求助,关于K230 linux SENSOR 移植读取CIF的RAW数据的疑问?

在K230 linux SENSOR 移植指南中给出了K230移植普通摄像头的教程,mipi读取的时ISP后的数据,但如果我想在k230里面移植自己的摄像头,通过mipi接口读取cif节点的raw数据,然后自己raw数据进行解码处理,请问由人知道如何实现mipi读取cif节点的raw数据吗?
如果有其他系统的移植指导资料,例如RT-Smart、CanMV或者Linux+RT-Smart的都可以

回帖(1)

香脆面

2025-6-19 18:05:07

针对你在K230上通过MIPI读取CIF节点RAW数据的需求,这是嵌入式视觉开发中的核心挑战。你正尝试完全绕过ISP管线,直接获取原始传感器数据。以下是我的方案和操作步骤:




关键目标:直接从CSI控制器输出RAW数据到用户空间


1. 底层框架确认



  • CIF节点本质:Linux内核中的/dev/videoX设备节点,与K230的MIPI CSI控制器(Camera Interface)绑定

  • RAW数据源头:CSI控制器的物理层接口直接接收来自MIPI传感器的原始Bayer Pattern数据

  • ISP绕开点:需让CSI控制器不传递数据给ISP硬件模块,而是直通到DMA缓冲区




关键操作步骤(Linux为例)


1. 设备树(DTS)关键修改


&csi {
    status = "okay";
    // 强制禁用ISP通路
    ports {
        port@0 {
            reg = <0>;
            /* CSI直通到虚拟节点而不经过ISP */
            endpoint {
                remote-endpoint = <&raw_out>;
            };
        };
    };
};

// 建立RAW数据输出节点
vip_raw: vip-raw {
    compatible = "kendryte,vip-raw";
    status = "okay";
};

&vip_raw {
    ports {
        port@0 {
            reg = <0>;
            raw_out: endpoint {
                remote-endpoint = <&csi_out>;
            };
        };
    };
};

2. 传感器驱动配置(以OV5640为例)


在初始化序列中强制设置RAW格式:


// drivers/media/i2c/ov5640.c
static int ov5640_s_power(struct v4l2_subdev *sd, int on) {
    ...
    // 覆盖默认YUV配置
    ov5640_write_reg(client, OV5640_REG_FORMAT, OV5640_RAW_10BIT);
    ...
}

3. CIF驱动修改


修改CSI控制器的数据处理路径(关键文件:drivers/media/platform/kendryte_cif.c):


static int cif_s_fmt_vid_cap(struct file *file, void *priv,
                        struct v4l2_format *f) {
    ...
    // 覆盖格式为RAW
    f->fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR10; // Bayer RGGB
    ...
}

static void cif_capture_frame(struct cif_dev *cif) {
    // 取消ISP数据提交调用
    // isp_submit_frame(cif->isp_dev); // !!! 注释掉这行

    // 直通DMA缓冲区到用户空间
    vb2_buffer_done(&cif->vb.vb2_buf, VB2_BUF_STATE_DONE);
}

4. V4L2应用层采集


使用标准接口但指定RAW格式:


struct v4l2_format fmt = {
    .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
    .fmt.pix = {
        .width = 1920,
        .height = 1080,
        .pixelformat = V4L2_PIX_FMT_SBGGR10, // 必需匹配
        .field = V4L2_FIELD_NONE,
    }
};
ioctl(fd, VIDIOC_S_FMT, &fmt);



其他系统实现参考


RT-Smart方案


由于内核精简,实现更直接:



  1. 重写传感器驱动中的output_format设为SENSOR_OUTPUT_RAW_10BIT

  2. 修改CSI驱动中的transfer_end()回调,直接映射DMA地址

  3. 用户空间通过/dev/csi0节点mmap原始内存块


CanMV/K230优化


在SDK层面提供RAW模式开关:


import sensor
sensor.reset()
sensor.set_pixformat(sensor.RAW10)  # 新增RAW模式
img = sensor.snapshot()
# img.data为Bayer阵列二进制流



调试陷阱排查




  1. 时序失锁问题



    • 现象:采集花屏或无数据

    • 对策:在传感器初始化后增加10ms延迟




  2. 位宽不匹配



    • 现象:图像错位

    • 对策:确认V4L2_PIX_FMT_Sxxx与传感器实际位宽一致(10/12/14 bit)




  3. 内存爆裂



    • RAW数据量极大(10-bit 1080P ≈ 3MB/帧)

    • 对策:
      # 增大DMA内存池
      echo 256M > /sys/module/videobuf2_common/parameters/dma_contig_mem






实战工具推荐



  1. RawDigger:解析Bayer RAW数据的专业工具

  2. dcraw:命令行RAW图像转码
    dcraw -E -T raw_0.raw

  3. KWAROS Profiler:实时监测K230 CSI带宽(在SDK中提供)




总结:本质上是打通 Sensor → CSI Controller → Userspace 的物理通路,关键在于拦截进入ISP的数据流向。K230的全志V85x系列芯片在寄存器层支持CSI直通模式(CIF_CTRL寄存器的ISP_BYPASS位),最终性能取决于CSI控制器的DMA吞吐量。



建议从RT-Smart系统开始实验,因其驱动层次更浅。CanMV社区已有部分RAW采集的PR提交可参考(GitHub搜索关键词:k230 raw capture)。实际项目若需深度优化,可能需要修改V4L2的vb2内存分配器以支持物理连续内存分配。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分