4. I2C Kconfig 配置:驱动使能、时钟频率与中断参数
在 Zephyr RTOS 中,I2C 外设的使能、时钟频率、中断优先级及驱动模型选择完全通过 Kconfig 符号控制。开发者通过 menuconfig 图形界面或直接编辑 prj.conf 文件完成配置。错误的 Kconfig 设置是 I2C 时序故障的首要根源,例如时钟频率不匹配导致 SCL 周期偏移、中断优先级冲突造成响应延迟。
4.1 核心 Kconfig 符号速查表
下表列出 I2C 驱动配置中最关键的 Kconfig 符号及其默认值、作用域。所有符号均可在 boards/<arch>/<board>/Kconfig.defconfig 或 prj.conf 中覆盖。
| Kconfig 符号 | 类型 | 默认值 | 说明 |
|---|---|---|---|
CONFIG_I2C | bool | n | 全局 I2C 驱动框架使能 |
CONFIG_I2C_INIT_PRIORITY | int | 80 | I2C 驱动初始化优先级(数值越小越早) |
CONFIG_I2C_LOG_LEVEL | int | 0 | I2C 日志等级(0=关闭,4=调试) |
CONFIG_I2C_<DRIVER> | bool | n | 具体 I2C 控制器驱动使能(如 I2C_DW、I2C_STM32) |
CONFIG_I2C_<DRIVER>_INTERRUPT | bool | y | 中断模式使能(若硬件支持) |
CONFIG_I2C_<DRIVER>_CLOCK_FREQ | int | 100000 | SCL 时钟频率(单位 Hz,标准模式 100k,快速模式 400k) |
CONFIG_I2C_<DRIVER>_IRQ_PRIO | int | 由 SoC 定义 | I2C 中断优先级(数值越小优先级越高) |
CONFIG_I2C_LOG_LEVEL 是否 ≥ 3。日志会输出每次传输的起始条件、地址、NACK/ACK 状态及 STOP 条件,是定位 SCL 毛刺或从机无响应的第一手证据。
4.2 通过 prj.conf 快速配置
以下是一个典型的 I2C 配置片段,适用于 STM32 系列 MCU。将内容追加到 prj.conf 中即可生效。
# 使能 I2C 框架
CONFIG_I2C=y
# 使能 STM32 I2C 控制器驱动
CONFIG_I2C_STM32=y
# 使用中断模式(默认开启,若需轮询则设为 n)
CONFIG_I2C_STM32_INTERRUPT=y
# 设置 SCL 时钟频率为 400kHz(快速模式)
CONFIG_I2C_STM32_CLOCK_FREQ=400000
# 设置 I2C 中断优先级为 2(数值越小优先级越高)
CONFIG_I2C_STM32_IRQ_PRIO=2
# 开启 I2C 调试日志(调试阶段建议开启,发布前关闭)
CONFIG_I2C_LOG_LEVEL=4
# 降低 I2C 初始化优先级,确保 GPIO 等外设先初始化
CONFIG_I2C_INIT_PRIORITY=85
CONFIG_I2C_STM32_INTERRUPT=y 但未在设备树中正确绑定中断号,驱动会在初始化时挂起。务必核对 i2c@... interrupts = <...>; 与 SoC 参考手册一致。
4.3 时钟频率配置与 SCL 时序关系
SCL 时钟频率直接影响 I2C 总线的时序窗口。Zephyr 驱动通过 CONFIG_I2C_<DRIVER>_CLOCK_FREQ 设定目标频率,实际频率由硬件分频器计算得出。下表列出常见频率配置与对应时序参数。
| 模式 | 目标频率 | SCL 高电平最小时间 | SCL 低电平最小时间 | 上升时间最大值 |
|---|---|---|---|---|
| 标准模式 (Sm) | 100 kHz | 4.0 µs | 4.7 µs | 1000 ns |
| 快速模式 (Fm) | 400 kHz | 0.6 µs | 1.3 µs | 300 ns |
| 快速模式+ (Fm+) | 1 MHz | 0.26 µs | 0.5 µs | 120 ns |
若配置的时钟频率超出从机支持范围,从机可能无法在规定的 SCL 高电平时间内采样数据,导致数据丢失或 ACK 丢失。调试时使用逻辑分析仪测量实际 SCL 周期,与 Kconfig 设定值对比。
4.4 中断配置与优先级冲突
I2C 中断优先级设置不当会导致以下典型故障:
- 高优先级中断抢占 I2C ISR:若 I2C 中断优先级低于定时器或 DMA 中断,I2C 传输可能被频繁打断,导致 SCL 拉伸超时。
- 优先级反转:I2C ISR 中等待的信号量被低优先级任务持有,造成死锁。
- 中断丢失:在快速模式下,若中断响应延迟超过 SCL 半周期(1.25 µs @ 400kHz),可能错过传输完成标志。
推荐的中断优先级配置原则:
- I2C 中断优先级应高于普通外设(如 UART、GPIO),但低于系统节拍定时器。
- 若使用 DMA 传输,I2C 中断优先级应等于或高于 DMA 中断。
- 在
prj.conf中显式设置CONFIG_I2C_<DRIVER>_IRQ_PRIO,避免依赖默认值。
4.5 I2C Kconfig 配置决策流程图
下图展示了从项目需求到最终 Kconfig 配置的决策路径,帮助开发者快速定位配置遗漏或冲突。
4.6 多实例与设备树覆盖
当 SoC 包含多个 I2C 控制器(如 I2C1、I2C2)时,Kconfig 符号是全局的,但设备树节点可以独立覆盖时钟频率和中断优先级。例如,在设备树 overlay 中为 I2C2 指定不同频率:
/ {
soc {
i2c2: i2c@40005800 {
clock-frequency = <100000>; /* 覆盖 Kconfig 全局频率 */
interrupts = <33 2>; /* 独立中断号与优先级 */
};
};
};
此时 CONFIG_I2C_STM32_CLOCK_FREQ 作为默认值,设备树中的 clock-frequency 属性优先级更高。调试时务必确认实际生效的是 Kconfig 值还是设备树值。
4.7 调试阶段推荐配置清单
CONFIG_I2C=y
CONFIG_I2C_LOG_LEVEL=4
CONFIG_I2C_INIT_PRIORITY=85
CONFIG_I2C_STM32=y
CONFIG_I2C_STM32_INTERRUPT=y
CONFIG_I2C_STM32_CLOCK_FREQ=100000 /* 调试时先用 100kHz 降低时序压力 */
CONFIG_I2C_STM32_IRQ_PRIO=2
CONFIG_I2C_SHELL=y /* 可选:使能 I2C shell 命令 */
使用 CONFIG_I2C_SHELL=y 后,可在终端执行 i2c scan i2c@... 1 127 扫描总线设备,快速验证配置是否正确。