Linux I2C驱动怎么写?i2c_driver和probe怎么填?用户态怎么访问?嵌入式Linux面试

浏览量:20
时间: 2026-09-22 09:02:00
一句话答案

I2C 驱动框架:i2c_driver 结构填 probe/remove/id_table,设备树里 compatible 匹配;probe 里用 i2c_smbus_read_byte_data 等函数读写寄存器;用户态通过 /dev/i2c-X 或 sysfs 访问,也可以封装成字符设备。

本文概述

I2C 是 Linux 最常用外设驱动,面试常考:i2c_driver、probe、设备树、读写函数。回答要给代码骨架。

核心要点

  • I2C 驱动用 i2c_driver 结构,和 platform_driver 类似

  • 设备树里 compatible 匹配,probe 里初始化

  • 读写用 i2c_master_send/recv 或 i2c_smbus_* 函数

  • 用户态:/dev/i2c-X + ioctl,或封装成字符设备/sysfs

  • I2C 地址 7 位,注意读写位和地址左移

终端显示 Linux I2C 驱动代码,i2c_driver 结构和设备树,开发板

面试官:写一个 I2C 温度传感器驱动,框架是什么?

面试官考察点

驱动开发基础题。面试官看你是否写过 I2C 驱动。重点听:i2c_driver、probe、读写。

回答思路

给最小骨架,讲 probe 里做什么,读写函数。

参考回答

驱动骨架。

#include <linux/i2c.h>
#include <linux/module.h>

static int temp_probe(struct i2c_client *c, const struct i2c_device_id *id){
  /* 读芯片 ID 验证 */
  u8 id = i2c_smbus_read_byte_data(c, 0x0D);
  /* 注册字符设备/sysfs */
  return 0;
}

static int temp_remove(struct i2c_client *c){
  /* 注销设备 */
  return 0;
}

static const struct i2c_device_id temp_id[] = {
  { "temp_sensor", 0 }, {}
};

static const struct of_device_id temp_of_match[] = {
  { .compatible = "fanyi,temp-sensor" }, {}
};

static struct i2c_driver temp_driver = {
  .probe = temp_probe,
  .remove = temp_remove,
  .id_table = temp_id,
  .driver = { .name = "temp_sensor", .of_match_table = temp_of_match },
};
module_i2c_driver(temp_driver);

I2C 读写函数。

函数作用
i2c_master_send(client, buf, len)写 len 字节
i2c_master_recv(client, buf, len)读 len 字节
i2c_smbus_read_byte_data(client, reg)读寄存器 1 字节
i2c_smbus_write_byte_data(client, reg, val)写寄存器 1 字节
i2c_smbus_read_word_data(client, reg)读寄存器 2 字节

设备树。

&i2c1 {
  temp@48 {
    compatible = "fanyi,temp-sensor";
    reg = <0x48>;
  };
};

用户态访问。

  • /dev/i2c-X:用 ioctl(I2C_RDWR) 直接读写,适合调试;

  • sysfs:驱动里创建属性文件,cat/echo 访问;

  • 字符设备:封装成 /dev/temp0,read 直接读温度;

  • IIO 子系统:传感器推荐用 IIO 框架。

注意。

  • I2C 地址是 7 位,Linux 驱动里直接写 7 位(内核自动处理读写位);

  • 多设备共享总线,驱动要能区分(不同地址或 id_table);

  • probe 里先读芯片 ID,确认设备存在且型号对;

  • I2C 读写可能睡眠,不能在中断上下文调用。

面试官可能追问

追问 1:i2c_driver 和 platform_driver 区别?
i2c_driver 匹配 I2C 总线上的设备(地址+compatible),platform_driver 匹配内存映射设备。框架类似。
追问 2:I2C 地址 0x48 为什么不左移?
Linux i2c_client.addr 存 7 位地址,i2c_master_send 内部自动左移加读写位。用户态 ioctl 要自己处理。
追问 3:probe 里怎么确认设备存在?
读芯片 ID 寄存器,和预期值比较。不存在返回 -ENODEV。
追问 4:I2C 总线挂多个同型号设备怎么办?
每个设备地址不同(ADDR 引脚配置),dts 里每个节点 reg 不同,驱动 probe 多次。
追问 5:IIO 是什么?
Industrial I/O 子系统,专为 ADC/DAC/传感器设计,统一了 sysfs 接口和缓冲。新驱动推荐用 IIO。

常见失分表达

✗ probe 里不验证设备 — 地址冲突或设备不存在时驱动乱初始化。
✗ 在中断里调用 I2C 读写 — I2C 读写会睡眠,中断上下文不能用。用工作队列或线程化中断。
✗ 地址左移一位再传给内核 — 内核要 7 位地址,左移后地址错。

准备动作

1
写一个最小 I2C 驱动(读温度传感器)
2
用 i2cdetect/i2cget 调试过 I2C 设备
3
准备一个 I2C 通信失败最终定位是上拉电阻的案例

核心关键词

I2C驱动i2c_driverprobei2c_smbus设备树IIO


声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。仅供学习交流使用,不构成商业目的。版权归原作者所有,如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时删除。侵权投诉
相关推荐HOT
嵌入式Linux根文件系统与Flash分区怎么设计?UBIFS、JFFS2与MTD怎么理解?嵌入式Linux面试

嵌入式Linux中高级技术基础题本文概述Flash上的文件系统选择决定数据的可靠性和寿命,是嵌入式Linux系统设计的关键,也是面试的进阶题。面试官想听的不是“... 详情>>

2026-09-09 13:32:01
电子工程师项目经验怎么讲?STAR法则怎么用?面试问答策略

一句话答案讲项目用 STAR 法则:Situation 背景→Task 任务→Action 你做了什么→Result 量化结果;技术面试要突出你的技术决策和踩坑... 详情>>

2026-09-16 10:13:19
Linux内核定时器和延时机制有什么区别?嵌入式Linux面试内核计时方案对比

Linux内核定时器和延时机制有什么区别?嵌入式Linux面试内核计时方案对比分类:嵌入式Linux经验级别:中级难度:中等题型:概念辨析题本文概述Linux内... 详情>>

2026-08-24 10:04:05
Linux字符设备驱动开发完整流程是怎样的?嵌入式Linux面试字符设备驱动详解

分类:嵌入式Linux经验级别:中级难度:中等题型:流程+原理题本文概述字符设备驱动是Linux驱动开发的入门基础,也是嵌入式Linux面试的必考点。本文以面试... 详情>>

2026-08-21 10:44:30
为了减少开关噪声引起的PCB传导和辐射发射,请选择具有▁▁▁▁▁▁▁▁▁尽可能小的DC-DC转换器。

为了减少开关噪声引起的PCB传导和辐射发射,请选择具有▁▁▁▁▁▁▁▁▁尽可能小的DC-DC转换器。开关频率封装静态电流输出电流正确答案:b为了减少开关电源电路... 详情>>

2024-03-20 14:52:15
开班信息