# 如何配置 Sensor 驱动

## 概述

K230 RTOS SDK 中，Sensor 驱动是否编入固件、挂在哪一路 CSI、是否使用片内 MCLK、是否启用 4-lane 模式，以及 ISP 参数如何打包与加载，均由 **MPP Kconfig** 与 VICAP API 共同决定。

配置入口统一走 SDK 根目录：

```bash
make menuconfig
# Docker 流程：k230 make menuconfig
```

相关代码与配置位置：

| 内容 | 路径 |
| :--- | :--- |
| Sensor / CSI / ISP 安装开关 | `src/rtsmart/mpp/Kconfig` → `MPP Configuration` → `Sensor Configuration` |
| Sensor 驱动与模式表 | `src/rtsmart/mpp/kernel/sensor/` |
| 板端 `list_sensor` 命令 | `src/rtsmart/mpp/kernel/sensor/src/sensor_dev.c` |
| 应用层 Sensor 信息表 | `src/rtsmart/mpp/userapps/src/sensor/mpi_sensor.c` |
| ISP 标定 / 调优源文件 | `src/rtsmart/mpp/userapps/src/sensor/config/` |
| ISP 安装规则 | `src/rtsmart/mpp/userapps/src/sensor/Makefile` |
| ISP 加载与解析模式 | `src/rtsmart/mpp/userapps/src/vicap/src/mpi_vicap.c` |

型号与分辨率一览见 [图像传感器支持列表](../hardware_compatibility/sensor_list.md)。从零接入新型号见 [如何增加 Sensor](../advanced_development_guide/how_to_add_sensor.md)。

## 打开 menuconfig

- 先选择板级 defconfig（示例）：

   ```bash
   make k230_rtos_01studio_defconfig
   ```

- 进入交互配置：

   ```bash
   make menuconfig
   ```

- 导航到：

   ```text
   MPP Configuration
     └── Sensor Configuration
   ```

- 重新编译并烧录后生效：

   ```bash
   make
   ```

菜单示意（`Sensor Configuration`）：

![menuconfig Sensor Configuration](https://www.kendryte.com/api/imagecdn/zh/sensorconfig.png)

> 上图为 menuconfig 界面示意，具体条目以当前 SDK 的 `mpp/Kconfig` 为准。

## 如何查看当前支持的 Sensor

### 方法一：menuconfig 查看（编译前）

在 `Sensor Configuration` 下找到 **`Sensor Drivers Configuration`**，每一项 `Enable <型号>` 对应已接入 SDK 的一种驱动，例如：

- `Enable GC2093`
- `Enable OV5647`

- **勾选**：驱动编入内核，对应模式会出现在板端 `list_sensor` 中，且匹配的 ISP 配置会按规则安装进镜像。
- **未勾选**：该型号不会出现在当前固件中。

列表以 `src/rtsmart/mpp/Kconfig` 为准，会随版本增加。

### 方法二：查看板级 defconfig

```bash
grep CONFIG_MPP_ENABLE_SENSOR_ configs/<your_board>_defconfig
```

示例：

```text
CONFIG_MPP_ENABLE_SENSOR_IMX335=y
CONFIG_MPP_ENABLE_SENSOR_GC2093=y
```

### 方法三：板端 `list_sensor`（确认驱动是否打开）

`list_sensor` 是 RT-Smart `msh` 命令，由 `sensor_dev.c` 导出，打印当前固件编译进去的 **sensor type 枚举值与名称**。

在串口进入 `msh` 后执行：

```bash
list_sensor
```

示意输出：

![list_sensor 输出示意](https://www.kendryte.com/api/imagecdn/zh/list_sensor.png)

用法说明：

| 现象 | 含义 |
| :--- | :--- |
| 列表中有目标型号 / 分辨率 / lane 模式 | 对应驱动与 Kconfig 已打开并编进固件 |
| 完全没有某型号 | menuconfig 未 `Enable` 该 Sensor，或未重新编译烧录 |
| 只有 2LANE、没有 4LANE | 驱动已开，但未打开 `Enable 4LANE Configure` |
| 有 type 但预览黑屏 | 驱动已加载，问题更可能在硬件接线、MIPI 链路或 ISP 参数 |

应用层选 sensor 时，应使用 `list_sensor` 打出的 **名称 / type**，不要硬编码易变的数字序号（序号随 Kconfig 组合变化）。

## 如何切换成 4LANE 模式

K230 CSI0 的 4-lane 会借用 PHY1 的 data lane（PHY1 即 CSI1 所用 PHY）。因此启用 4LANE 时必须同时：

- **关闭 `Enable CSI1`**（`CONFIG_MPP_ENABLE_CSI_DEV_1=n`），避免 CSI1 口与其它 Sensor 再占用 PHY1。
- 不要把任何 Sensor 配到 CSI1。

目前提供 4-lane 开关的型号包括 **IMX335**、**OV13850**。

### menuconfig 步骤（以 IMX335 为例）

- `make menuconfig`
- 进入并按如下配置：

   ```text
   MPP Configuration
     └── Sensor Configuration
           ├── [*] Enable CSI0          # 必须打开
           ├── [ ] Enable CSI1          # 必须关闭（4LANE 借用 PHY1）
           ├── Enable CSI2              # 可按需，与 4LANE 无 PHY 冲突
           └── [*] Enable IMX335        # 打开后进入子菜单
                 └── [*] IMX335 Enable 4LANE Configure
   ```

- 保存退出，`make` 后重新烧录。

IMX335 子菜单示意：

![IMX335 4LANE menuconfig](https://www.kendryte.com/api/imagecdn/zh/imx335config.png)

OV13850 同理：

```text
[*] Enable CSI0
[ ] Enable CSI1          # 必须关闭
[*] Enable OV13850
  └── [*] OV13850 Enable 4LANE Configure
```

对应 Kconfig 宏：

| 选项 | 宏 |
| :--- | :--- |
| IMX335 4-lane | `CONFIG_MPP_SENSOR_IMX335_ENABLE_4LANE_CONFIGURE` |
| OV13850 4-lane | `CONFIG_MPP_SENSOR_OV13850_ENABLE_4LANE_CONFIGURE` |
| 关闭 CSI1 | 取消 `CONFIG_MPP_ENABLE_CSI_DEV_1` |

### 打开后如何确认

- 确认 defconfig / `.config` 中 **没有** `CONFIG_MPP_ENABLE_CSI_DEV_1=y`（或为 `n` / 未设置）。
- 板端执行 `list_sensor`，应能看到名称中带 `4LANE` 的条目，例如：
  - `IMX335_MIPI_CSI0_4LANE_2592X1944_30FPS_12BIT_LINEAR`
  - `OV13850_MIPI_CSI0_4LANE_3840X2160_27FPS_10BIT_LINEAR`
- 应用 / demo 选择该 type（例如 `sample_vicap_sensor` 的 `-stype`）。
- 模组与排线必须真实支持 4-lane；仅软件打开而硬件只有 2-lane 时，会出现链路错误或黑屏。

> 4K Sensor（如 OV13850 4K）还受 VICAP 工作模式限制，见 [sensor_list.md](../hardware_compatibility/sensor_list.md)。

## CSI 与驱动公共选项

### 默认 CSI

- **`Default SENSOR on CSI`**：默认 CSI 口（0 / 1 / 2）。

### Sensor Hardware Configuration

分别配置 `Enable CSI0` / `CSI1` / `CSI2`：

| 选项 | 含义 |
| :--- | :--- |
| PowerDown GPIO | 电源脚；无则设 `-1` |
| Reset GPIO | 复位脚；无则设 `-1` |
| I2c Bus | 如 `i2c0` |
| MCLK num | 片内 MCLK1/2/3，或外部晶振 |

### Sensor 子选项

| 选项 | 含义 |
| :--- | :--- |
| `On CSI0/1/2 Use CHIP MCLK` | 该 Sensor 在对应 CSI 上是否用片内 MCLK |
| `Enable 4LANE Configure` | 额外编译 4-lane 模式（见上一节） |

### AutoFocus（可选）

`Enable AutoFocus` → 可再勾选音圈马达驱动（如 DW9714P），仅硬件有 AF 时需要。

## ISP 配置：bin 与 XML/JSON 切换

### 源文件与安装

ISP 参数源文件目录：

```text
src/rtsmart/mpp/userapps/src/sensor/config/
```

命名约定（以 IMX335 2592×1944 为例）：

| 文件 | 用途 |
| :--- | :--- |
| `imx335-2592x1944_auto.json` | 自动档；生成 `.bin` 的输入之一 |
| `imx335-2592x1944_manual.json` | 手动档 |
| `imx335-2592x1944.xml` | XML 标定 / 调优参数 |

`Sensor Configuration` 顶部两个安装开关：

| 选项 | 宏 | 作用 |
| :--- | :--- | :--- |
| Install binary ISP configurations | `CONFIG_MPP_ISP_CONFIG_INSTALL_BIN` | 生成并安装 `*.bin` 到镜像 `bin/` |
| Install JSON and XML ISP configurations | `CONFIG_MPP_ISP_CONFIG_INSTALL_JSON_XML` | 拷贝匹配的 `.json` / `.xml` 到镜像 `bin/` |

只有 **已 Enable 的 Sensor**，其前缀匹配的 ISP 文件才会被安装（见 `userapps/src/sensor/Makefile`）。

编译产物一般在：

```text
output/<defconfig>/images/bin/
```

板端路径通常为 `/bin/`，例如 `/bin/imx335-2592x1944.bin`、`/bin/imx335-2592x1944.xml`。

### 为何 bin 模式无法“实时换 ISP 文件”

默认逻辑（未显式指定解析模式时）：

- `kd_mpi_vicap_init()` 会探测 `/bin/<database_name>.bin`。
- 若 `.bin` 存在且加载成功，则走 **bin 模式**（内部枚举为 `VICAP_DATABASE_PARSE_HEADER`）。
- bin 是编译期由 `gen_isp_config_bin` 把 xml/json **固化** 后的二进制；运行时再改板端 `.xml` / `.json` **不会**自动反映到已加载的 bin 里。
- 要让新参数进 bin，必须改源文件 → 重新 `make` 生成 bin → 重新烧录 / 替换 `/bin/*.bin` → 再启动应用。

因此：**调优阶段若需要频繁改 ISP 参数，应切换到 XML/JSON 解析模式。**

### 如何切换成 XML/JSON 模式（代码）

在 **`kd_mpi_vicap_init()` 之前** 调用：

```c
#include "mpi_vicap_api.h"
#include "k_vicap_comm.h"

k_vicap_dev vicap_dev = VICAP_DEV_ID_0;

/* 强制从 /bin/<database>.xml 与 *_auto.json / *_manual.json 加载 */
ret = kd_mpi_vicap_set_database_parse_mode(vicap_dev, VICAP_DATABASE_PARSE_XML_JSON);
if (ret) {
    printf("set_database_parse_mode failed, ret=%d\n", ret);
    return ret;
}

ret = kd_mpi_vicap_init(vicap_dev);
```

枚举含义（`k_vicap_comm.h`）：

| 枚举 | 值 | 实际行为 |
| :--- | :--- | :--- |
| `VICAP_DATABASE_PARSE_XML_JSON` | 0 | 使用 XML + JSON，**不优先加载 bin** |
| `VICAP_DATABASE_PARSE_HEADER` | 1 | 强制 bin；bin 不存在则初始化失败 |

> API 注释里 HEADER 曾表示“头文件模式”；当前实现中它对应 **二进制 bin 配置**。

SDK 中大量示例（如 `examples/ai/yolo/src/pipeline.cc`）在 `vicap_init` 前显式设置为 XML/JSON：

```c
ret = kd_mpi_vicap_set_database_parse_mode(vicap_dev, VICAP_DATABASE_PARSE_XML_JSON);
ret = kd_mpi_vicap_init(vicap_dev);
```

而 `sample_vicap_sensor` 等未调用该接口时，会在有 `.bin` 的情况下自动走 bin。

### XML/JSON 模式下如何更换参数

- menuconfig 保持 **`Install JSON and XML ISP configurations`** 为 y，确保镜像里有 xml/json。
- 应用里按上一节切换到 `VICAP_DATABASE_PARSE_XML_JSON`。
- 修改并替换板端文件，例如：

   ```bash
   # 主机侧推送（路径以实际文件系统为准）
   adb push imx335-2592x1944.xml /bin/
   adb push imx335-2592x1944_auto.json /bin/
   adb push imx335-2592x1944_manual.json /bin/
   ```

- **重新运行应用**（需再次 `vicap_init`）。ISP 在 init 时加载，**不能**在保持同一路 stream 的情况下热替换已生效的 bin 内存镜像。

默认加载路径由 `database_name`（如 `imx335-2592x1944`）与 ISP config path（默认 `/bin/`）拼出：

```text
/bin/imx335-2592x1944.xml
/bin/imx335-2592x1944_auto.json
/bin/imx335-2592x1944_manual.json
```

### 模式选择建议

| 场景 | 建议 |
| :--- | :--- |
| 量产 / 快速启动 | bin（默认探测即可），参数固化 |
| ISP 标定 / 调优 / 频繁改参 | 代码设为 `VICAP_DATABASE_PARSE_XML_JSON`，改 xml/json 后重启应用 |
| 显式要求必须用 bin | `kd_mpi_vicap_set_database_parse_mode(..., VICAP_DATABASE_PARSE_HEADER)` |

标定与调优细节：

- [如何进行 ISP 标定](../advanced_development_guide/how_to_calibrate_isp.md)
- [如何进行 ISP 调优](../advanced_development_guide/how_to_tune_isp.md)

## 配置检查清单

- `Enable CSIx` 与板级接线一致（GPIO / I2C / MCLK）。
- 勾选目标 `Enable <Sensor>`。
- 需要 4-lane：打开 `Enable 4LANE Configure`，并**关闭 `Enable CSI1`**，确认模组支持 4-lane。
- ISP：量产用 bin；调优用代码切到 XML/JSON，并保证 json/xml 已安装到 `/bin/`。
- `make` → 烧录 → **`list_sensor`** 确认 type 出现 → 再跑 VICAP / Sensor 示例。

## 相关文档

- [图像传感器支持列表](../hardware_compatibility/sensor_list.md)
- [如何增加 Sensor](../advanced_development_guide/how_to_add_sensor.md)
- [如何编译固件](./how_to_build.md)
- [如何运行示例程序](./how_to_run_samples.md)
