注意

这是最新开发分支配套的文档,可能包含已发布版本中尚未提供的功能。如果您要查看特定版本的文档,请使用左侧的下拉菜单并选择所需要的版本。

K230 Linux 摄像头路数与 Sensor 配置指南#

本文介绍当前 K230 Linux SDK 各板级摄像头的默认配置,以及如何通过设备树 配置单路、双路或三路摄像头。新增一种 Sensor 驱动的方法请参考 K230 Linux SENSOR 移植指南

当前 Linux 板级 Sensor 配置#

基本概念#

K230 最多提供 CSI0、CSI1、CSI2 三个物理 MIPI CSI 控制器。设备树中的 mipi.N 表示逻辑摄像头编号 N,不一定连接同编号的物理 CSI。

下面三个编号容易混淆,阅读配置前应先区分:

名称

示例

含义

逻辑摄像头编号

slot0、slot1、slot2

决定 ISP port 和每路输出分组

VVCAM 输出序号

video_index=08

驱动内部序号,也是 entity 名称最后一段

Linux video 设备号

/dev/video1/dev/video9

内核动态分配的设备节点,不能由 DTS 固定

设备树中两类配置的职责不同:

  • mipi.N 的节点序号 N 决定 /dev/vvcam-mipi.N 和 ISP port N;节点中的 idreginterruptsresets 决定该逻辑端口连接哪个物理 CSI。

  • DTS 标签 &v4l2isp 指向运行时的 v4l2-isp 节点。其中 devN-sensor-namedevN-sensor-modedevN-sensor-i2c-bus 描述 ISP port N 使用的 Sensor 驱动名称、该驱动的 mode 下标和 Linux I2C adapter 编号。它们不决定物理 CSI 映射。

  • 只有 mipi.N 已启用并且对应 devN-sensor-* 完整时,该路才计入摄像头 路数。

可以将数据通路理解为:

物理 CSI(由 id 等资源决定)
    → 逻辑 mipi.N / ISP port N
    → 第 N 组 MP、SP1、SP2 entity
    → 内核动态分配的 /dev/videoX

Sensor 控制信息 devN-sensor-*
    → Sensor 驱动、mode 下标和 /dev/i2c-X

在当前 MCM 配置中,每路 Sensor 注册 MP、SP1、SP2 三个 VVCAM 输出:

逻辑摄像头

MIPI 节点

VVCAM video_index

entity 名称

当前板端设备节点

第 1 路(slot0)

mipi.0

0、1、2

vvcam-video.0.0vvcam-video.0.2

/dev/video1/dev/video3

第 2 路(slot1)

mipi.1

3、4、5

vvcam-video.0.3vvcam-video.0.5

/dev/video4/dev/video6

第 3 路(slot2)

mipi.2

6、7、8

vvcam-video.0.6vvcam-video.0.8

/dev/video7/dev/video9

以上“每路 3 个输出”以加载 vvcam_video mcm_mask=1 为前提。SDK 启动脚本 S31canaan_isp 已按此方式加载模块。若手工加载时不传该参数,会进入旧版 pipeline 布局,单路可能注册包含 RAW 在内的 4 个输出,不适用本文的多路 映射表。

表中的 /dev/video1/dev/video9 是当前板端实测结果,不是固定规则。 代码调用 video_register_device(..., -1) 让内核自动分配设备号;当前系统中 /dev/video0 已被 mvx 占用,所以 VVCAM 从 /dev/video1 开始注册。 如果其它驱动的注册顺序变化,设备号也可能变化。

应用应通过 entity 名称查找对应设备,而不是直接假定某一路永远是 /dev/video1/dev/video4/dev/video7

for d in /sys/class/video4linux/video*; do
    echo "$(basename "$d"): $(cat "$d/name")"
done

# 查看完整 media graph;当前板端 VVCAM media 设备为 media0
media-ctl -d /dev/media0 -p

三路 MP 的稳定标识分别是 vvcam-video.0.0vvcam-video.0.3vvcam-video.0.6

芯片侧 CSI 资源#

物理 CSI

id

reg

IRQ

CSI0

0

0x90009800

115

CSI1

1

0x9000a000

118

CSI2

2

0x9000a800

121

板级设备树可以把任一物理 CSI 映射到逻辑 mipi.0。例如部分板型将 物理 CSI2 映射到 mipi.0,因此它仍属于第 1 路,MP entity 仍是 vvcam-video.0.0

SoC 基线 k230.dtsi 默认是 mipi.0→CSI0 且启用,mipi.1mipi.2 禁用。板级 DTS 将 CSI2 映射到 slot0 时,会覆盖 mipi0id、寄存器、中断和复位资源,而不是改为启用原生 mipi2

当前板端实测配置#

在当前连接的板子上读取运行时设备树、/proc/vsi/isp_subdev0 和 media 拓扑,得到以下配置:

逻辑摄像头

物理 CSI

Sensor

mode

Linux I2C adapter

MP entity

当前设备节点

第 1 路(slot0)

CSI2

GC2093

0

4

vvcam-video.0.0

/dev/video1

第 2 路(slot1)

CSI0

GC2093

0

0

vvcam-video.0.3

/dev/video4

第 3 路(slot2)

CSI1

GC2093

0

1

vvcam-video.0.6

/dev/video7

运行时还确认:

  • mipi.0mipi.1mipi.2 均为 "okay",物理 id 分别为 2、0、1。

  • /dev/vvcam-mipi.0.2 均存在。

  • 9 个 VVCAM 输出的 entity 为 vvcam-video.0.0vvcam-video.0.8,本次分别映射到 /dev/video1/dev/video9

  • /dev/video0mvx/dev/video10canaan-non-ai-2d,说明 /dev/videoN 的 N 属于系统动态设备号,不等于 VVCAM video_index

可以使用以下命令在目标板上重新核对:

cat /proc/vsi/isp_subdev0
media-ctl -d /dev/media0 -p
ls /dev/vvcam-mipi.*

各板型 SDK 默认配置#

当前 SDK 默认 Sensor 主要为 GC2093,默认 mode 0 对应 1920×1080@30fps。这里描述的是 SDK DTS 默认值,不代表刷入后又被修改过的 板端当前状态:

defconfig / 板型

默认路数

逻辑槽位到物理 CSI

DTS bus → 实际 I2C

说明

k230_canmv_01studio_defconfig

1

slot0→CSI2

4→i2c4

已预置 slot1→CSI0、slot2→CSI1,默认 disabled;CSI2 reset=gpio0_9

k230_canmv_01studio_emmc_defconfig

1

slot0→CSI2

0→i2c4(alias)

未预置三路;CSI2 reset=gpio1_30,与 SD 版不同

k230_canmv_lckfb_defconfig

1

slot0→CSI2

4→i2c4

已预置 slot1→CSI0、slot2→CSI1,默认 disabled;CSI2 reset=gpio0_13

k230_canmv_defconfig

1

slot0→CSI0

0→i2c0

CanMV 1.0/1.1

k230_canmv_v3_defconfig

1

slot0→CSI2

0→i2c4(alias)

k230_canmv_dongshanpi_defconfig

1

slot0→CSI2

0→i2c4(alias)

k230_canmv_gt6700_defconfig

1

slot0→CSI2

0→i2c4(alias)

k230d_canmv_defconfig

1

slot0→CSI2

0→i2c4(alias)

k230d_canmv_ilp32_defconfig

DTS 1,VVCAM 未启用

slot0→CSI2

0→i2c4(alias)

默认未启用 BR2_PACKAGE_VVCAM

BPI-CanMV-K230D-Zero_defconfig

DTS 1,但配置不一致

slot0→CSI2

0→i2c0(无 alias)

defconfig 为 IMX335,DTS 仍为 GC2093,I2C 连接也需核对

BPI-CanMV-K230D-Zero_ilp32_defconfig

DTS 1,VVCAM 未启用

slot0→CSI2

0→i2c0(无 alias)

Sensor 配置不一致,且默认未启用 VVCAM

k230_evb_defconfig

1

slot0→CSI0

0→i2c0

继承 SoC 基线设备树

k230d_canmv_junroc_ai_cam_defconfig

1

slot0→CSI1

0→i2c4(alias)

特殊映射

需要特别注意:

  1. k230_canmv_01studio_defconfigk230_canmv_lckfb_defconfig 已写好 三路 GC2093 配置,但默认仅 mipi.0"okay",所以只注册一路。

  2. BPI-CanMV-K230D-Zero 的 defconfig 默认 Sensor 为 IMX335,而基线 DTS 仍可能是 GC2093,使用前应统一 DTS 和 Buildroot 配置。

  3. 部分 ILP32 配置没有启用 BR2_PACKAGE_VVCAM,仅修改 DTS 不能使摄像头 工作。

Sensor mode 与 I2C bus#

devN-sensor-mode 是对应 Sensor 驱动中 modes[] 数组的下标,不是通用 分辨率枚举。GC2093 当前常用 mode 如下:

mode

分辨率和帧率

MIPI lane

0

1920×1080@30fps

2

1

1920×1080@60fps

2

2

1280×960@90fps

2

3

1280×720@90fps

2

更换 Sensor 后必须查看 buildroot-overlay/package/vvcam/src/<sensor>.c 中该 Sensor 的 modes[], 不能沿用 GC2093 的 mode 含义。

devN-sensor-i2c-bus 表示 Linux adapter 编号,即 /dev/i2c-N 中的 N。 该编号会受到板级 aliases 影响,SDK 中存在两种配置方式。

旧式单摄板常把 Linux adapter 0 映射到硬件 i2c4:

aliases {
    i2c0 = &i2c4;
};

此时 devN-sensor-i2c-bus = <0> 实际访问硬件 i2c4。

01studio SD 和 lckfb 的多摄配置使用真实编号:

aliases {
    i2c0 = &i2c0;
    i2c1 = &i2c1;
    i2c4 = &i2c4;
};

此时预置三路的 bus 4、0、1 分别表示硬件 i2c4、i2c0、i2c1。修改配置前 必须先检查本板 aliases,再填写 bus;同时确保实际 I2C 控制器节点为 "okay"

配置单路、双路或三路摄像头#

配置规则#

驱动从 slot0 开始连续统计摄像头路数。每个启用槽位必须同时满足:

  1. mipi.Nstatus = "okay"

  2. DTS 的 &v4l2isp 节点中存在 devN-sensor-name

  3. 同时配置匹配的 devN-sensor-modedevN-sensor-i2c-bus

  4. 对应 I2C 控制器已启用。

槽位必须从 0 连续配置,不能只启用 slot0 和 slot2。遇到第一个缺失或 disabled 的槽位后,后面的槽位不会计入摄像头路数。可以提前写好 dev1/dev2-sensor-*,只要 mipi.1/mipi.2 保持 disabled,系统仍按单路 注册。

mcm_mask=1 下,逻辑 slot N 的三个输出序号固定为 3N3N+13N+2,依次对应 MP、SP1、SP2。

DTS 源文件中的 &mipi0&mipi1&mipi2 是节点标签引用;系统启动后 对应的节点名称是 mipi.0mipi.1mipi.2。同样,DTS 标签 &v4l2isp 对应运行时的 v4l2-isp 节点。

映射物理 CSI 时,必须成套修改以下字段:

  • id

  • reg

  • interrupts

  • resets

  • reset-gpios

  • 对应的 devN-sensor-i2c-bus

不同 mipi.N 不能使用相同的物理 CSI id。其中 reset-gpios 和 I2C 连接是板级属性,必须以原理图和对应板级 DTS 为准,不能直接照搬其它板型。

修改位置和编译#

编译一次 SDK 后,板级 DTS 位于:

output/<defconfig>/build/linux-*/arch/riscv/boot/dts/canaan/

例如:

output/k230_canmv_01studio_defconfig/build/linux-*/arch/riscv/boot/dts/canaan/k230-canmv-01studio.dts
output/k230_canmv_lckfb_defconfig/build/linux-*/arch/riscv/boot/dts/canaan/k230-canmv-lckfb-lcd.dts

直接修改 output 目录适合调试。正式修改还应同步到 SDK 的板级 DTS 补丁或 overlay 中,避免清理 output 后丢失。

修改后重新编译:

make linux-dirclean
make linux-rebuild
make

然后更新板上的 DTB 或完整镜像。若同时修改了 VVCAM 驱动或 libvvcam.so,还需要更新 vvcam_mipivvcam_isp_subdevvvcam_video 等对应内核模块和用户态库。

单路摄像头#

单路必须使用逻辑 slot0。下面以 01studio / lckfb 已预置的 “slot0→物理 CSI2”为例:

&i2c4 {
    status = "okay";
};

&mipi0 {
    /* id/reg/irq/resets/reset-gpios 使用板级 CSI2 配置 */
    status = "okay";
};

&mipi1 {
    status = "disabled";
};

&mipi2 {
    status = "disabled";
};

&v4l2isp {
    dev0-sensor-name = "gc2093";
    dev0-sensor-mode = <0>;
    dev0-sensor-i2c-bus = <4>;
};

如果板级 alias 为 i2c0 = &i2c4,则上例的 bus 应写 <0>。若希望第一路 使用 CSI0,应将 mipi0 的整套物理资源改为 CSI0,同时修改 reset GPIO 和 I2C bus,而不是启用 mipi1

单路配置会注册 3 个 VVCAM 输出:

  • 内部 video_index:0~2。

  • entity:vvcam-video.0.0vvcam-video.0.2

  • 当前实测板端:/dev/video1/dev/video3;其它系统可能不同。

双路摄像头#

下面以 01studio / lckfb 的预置顺序为例:

  • slot0 → 物理 CSI2

  • slot1 → 物理 CSI0

&i2c0 {
    status = "okay";
};

&i2c4 {
    status = "okay";
};

&mipi0 {
    /* 板级 CSI2 资源 */
    status = "okay";
};

&mipi1 {
    /* 板级 CSI0 资源 */
    status = "okay";
};

&mipi2 {
    status = "disabled";
};

&v4l2isp {
    dev0-sensor-name = "gc2093";
    dev0-sensor-mode = <0>;
    dev0-sensor-i2c-bus = <4>; /* CSI2 */

    dev1-sensor-name = "gc2093";
    dev1-sensor-mode = <0>;
    dev1-sensor-i2c-bus = <0>; /* CSI0 */
};

对于已经预置三路配置的 01studio 和 lckfb,需要确认 I2C 已启用,并将 mipi1status"disabled" 改为 "okay"。其它板型还需要补充 mipi1 的 CSI0 物理资源、reset GPIO 和 dev1-sensor-*

只修改 mipi1 而没有启用实际对应的 i2c0,会出现第二路节点已经注册、 但 Sensor 无法访问和出图的情况。

双路配置会注册 6 个 VVCAM 输出:

  • 内部 video_index:0~5。

  • entity:vvcam-video.0.0vvcam-video.0.5

  • 两路 MP entity:vvcam-video.0.0vvcam-video.0.3

  • 按当前板端设备注册顺序,通常对应 /dev/video1/dev/video6, 但应用仍应按 entity 名称查找。

三路摄像头#

01studio / lckfb 的预置顺序是:

  • slot0 → 物理 CSI2

  • slot1 → 物理 CSI0

  • slot2 → 物理 CSI1

这是这两类板型的预置 remap 顺序,不是芯片强制顺序。若使用 slot0→CSI0、slot1→CSI1、slot2→CSI2 的原生顺序,需要同时替换每个 mipi.N 的物理 CSI 资源、reset GPIO 和对应 devN-sensor-i2c-bus

&i2c0 {
    status = "okay";
};

&i2c1 {
    status = "okay";
};

&i2c4 {
    status = "okay";
};

&mipi0 {
    /* 板级 CSI2 资源 */
    status = "okay";
};

&mipi1 {
    /* 板级 CSI0 资源 */
    status = "okay";
};

&mipi2 {
    /* 板级 CSI1 资源 */
    status = "okay";
};

&v4l2isp {
    dev0-sensor-name = "gc2093";
    dev0-sensor-mode = <0>;
    dev0-sensor-i2c-bus = <4>; /* CSI2 */

    dev1-sensor-name = "gc2093";
    dev1-sensor-mode = <0>;
    dev1-sensor-i2c-bus = <0>; /* CSI0 */

    dev2-sensor-name = "gc2093";
    dev2-sensor-mode = <0>;
    dev2-sensor-i2c-bus = <1>; /* CSI1 */
};

对于已预置三路配置的板型,确认 I2C 后将 mipi1mipi2 都改为 "okay" 即可。未预置的板型必须补齐两个 MIPI 节点的全部物理资源和 dev1/dev2 配置。

三路预置方案需要硬件 i2c4、i2c0、i2c1 全部可用;&i2c0&i2c1 未设置 status = "okay" 时,对应摄像头不能正常工作。

三路配置会注册 9 个 VVCAM 输出:

  • 内部 video_index:0~8。

  • entity:vvcam-video.0.0vvcam-video.0.8

  • 三路 MP entity:vvcam-video.0.0vvcam-video.0.3vvcam-video.0.6

  • 当前板端实际设备节点为 /dev/video1/dev/video9

更换 Sensor#

将某一路由 GC2093 更换为其它 Sensor 时,需要同步完成:

  1. devN-sensor-name 改为 VVCAM 支持的名称。

  2. 根据该 Sensor 驱动的 modes[] 设置 devN-sensor-mode

  3. 根据实际连接修改 I2C bus、reset GPIO、lane 数和 MIPI 频率。

  4. 确认 Buildroot 的 BR2_PACKAGE_VVCAM_DEF_SENSORlibvvcam.so 已包含 该 Sensor,并准备 /etc/vvcam/ 下对应的 ISP 标定文件。

  5. 多路同型号且 I2C 地址相同时,优先使用不同 I2C 控制器,避免地址冲突。

板上验证#

启动后依次检查:

# MIPI 逻辑设备数量
ls /dev/vvcam-mipi.*

# I2C adapter 是否存在
ls /dev/i2c-*

# DTS 中的 sensor、mode、I2C bus 是否被正确解析
cat /proc/vsi/isp_subdev0

# 物理 CSI 与逻辑 DVP/ISP port 的绑定
dmesg | grep -E 'bind SOURCE_CSI|misc_id|sensor_count'

# 根据 entity 名称查找动态分配的 /dev/video*
for d in /sys/class/video4linux/video*; do
    echo "$(basename "$d"): $(cat "$d/name")"
done

预期结果如下。“当前板端设备节点”一列用于说明本次实测映射,不应作为 应用程序的固定设备号:

路数

MIPI 设备

VVCAM entity

MP entity

当前板端设备节点

1

/dev/vvcam-mipi.0

vvcam-video.0.0vvcam-video.0.2

vvcam-video.0.0

/dev/video1/dev/video3

2

/dev/vvcam-mipi.0/dev/vvcam-mipi.1

vvcam-video.0.0vvcam-video.0.5

vvcam-video.0.0vvcam-video.0.3

/dev/video1/dev/video6

3

/dev/vvcam-mipi.0/dev/vvcam-mipi.1/dev/vvcam-mipi.2

vvcam-video.0.0vvcam-video.0.8

vvcam-video.0.0vvcam-video.0.3vvcam-video.0.6

/dev/video1/dev/video9

如果某一路没有图像,优先检查该路的 I2C adapter、reset-gpiosdevN-sensor-mode 和 MIPI lane 配置。如果 /dev/vvcam-mipi.* 数量或 vvcam-video.* entity 数量不符合预期,检查 mipi.N 是否从 0 连续启用, 以及 devN-sensor-* 是否完整;不要根据 /dev/videoN 的最大编号判断路数。

配置与代码的对应关系#

文档中的配置规则来自以下实现(路径相对于 buildroot-overlay/):

文件

实际作用

package/vvcam/v4l2/common/vvcam_sensor_dt.h

从 slot0 开始,按“devN-sensor-name 存在且 mipi.N 已启用”连续统计路数

package/vvcam/mipi/vvcam_mipi_driver.c

mipi.N 节点序号映射到 DVP/ISP port N,id 映射到物理 CSI

package/vvcam/v4l2/isp/vvcam_isp_driver.c

解析 devN-sensor-name、mode 和 I2C bus

package/vvcam/v4l2/video/vvcam_pipeline_link.h

定义每路 MP、SP1、SP2 对应的 video_index 和 ISP pad

package/vvcam/v4l2/video/vvcam_video_driver.c

MCM 模式按 sensor_count × 3 注册 VVCAM 输出

package/vvcam/v4l2/video/vvcam_video_register.c

使用 video_register_device(..., -1) 动态申请 /dev/videoN

package/vvcam/src/gc2093.c

定义 GC2093 的 modes[]、分辨率、帧率、lane 和 MIPI 频率

board/canaan/k230-soc/rootfs_overlay/etc/init.d/S31canaan_isp

使用 mcm_mask=1 加载 vvcam_video,启用本文描述的多路布局

因此配置时不要用 /dev/videoN 的 N 推导逻辑端口或物理 CSI。推荐顺序是:

  1. 先用 mipi.N 确定第几路逻辑摄像头。

  2. 再用 id 和整套 CSI 资源确定物理接口。

  3. 用同编号的 devN-sensor-* 配置 Sensor 控制信息。

  4. 启动后根据 vvcam-video.0.K entity 名称查找实际 /dev/videoN

评论列表
条评论
登录