Linux驱动开发(I2C系统的重要结构体)

简介: Linux驱动开发(I2C系统的重要结构体)

前言

本篇文章来讲解I2C系统的重要结构体,了解这些结构体对于编写I2C驱动来说是至关重要的,所以要想编写好一个I2C驱动程序那么就必须先了解这些结构体。


一、I2C硬件框架

这里使用百问网的一张图片来讲解:

一个芯片中可以有多个I2C控制器,并且一个I2C控制器可以控制多个设备。那么在对应的驱动中I2C控制器和这些设备还有传输的消息都是用什么来表示的呢?

在Linux内核中:

使用i2c_adapter这个结构体来代表一个I2C控制器。

传输的消息使用i2c_msg结构体表示。

设备使用i2c_client结构体表示。


二、i2c_adapter

i2c_adapter结构体:

struct i2c_adapter {
  struct module *owner;
  unsigned int class;     /* classes to allow probing for */
  const struct i2c_algorithm *algo; /* the algorithm to access the bus */
  void *algo_data;
  /* data fields that are valid for all devices */
  const struct i2c_lock_operations *lock_ops;
  struct rt_mutex bus_lock;
  struct rt_mutex mux_lock;
  int timeout;      /* in jiffies */
  int retries;
  struct device dev;    /* the adapter device */
  int nr;
  char name[48];
  struct completion dev_released;
  struct mutex userspace_clients_lock;
  struct list_head userspace_clients;
  struct i2c_bus_recovery_info *bus_recovery_info;
  const struct i2c_adapter_quirks *quirks;
};

在Linux内核中我们能找到这个结构体,下面我们来讲解一下其中比较重要的成员。

nr成员:

这个成员变量代表的是第几个I2C控制器,因为在一个芯片中I2C控制器的数量肯定是不止一个的,所以需要有一个变量来标识具体是第几个I2C控制器。

const struct i2c_algorithm *algo

const struct i2c_algorithm *algo 是指向 I2C 访问算法的结构体指针,该指针指向一个常量类型的 struct i2c_algorithm 结构体,其中定义了 I2C 总线上的访问操作函数指针,包括了 master_xfer、smbus_xfer 以及 functionality 等。通过这些访问函数,可以实现对 I2C 总线上的传感器、EEPROM 和其他设备的读写操作。

在实现 I2C 设备驱动程序时,通常需要根据具体的 I2C 总线访问算法进行编程。而在适配器结构体 struct i2c_adapter 中,通过 algo 指针可以方便地获取到对应的 I2C 总线访问算法信息,从而实现 I2C 设备的访问。

algo结构体:

struct i2c_algorithm {
  /* If an adapter algorithm can't do I2C-level access, set master_xfer
     to NULL. If an adapter algorithm can do SMBus access, set
     smbus_xfer. If set to NULL, the SMBus protocol is simulated
     using common I2C messages */
  /* master_xfer should return the number of messages successfully
     processed, or a negative value on error */
  int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
         int num);
  int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
         unsigned short flags, char read_write,
         u8 command, int size, union i2c_smbus_data *data);
  /* To determine what the adapter supports */
  u32 (*functionality) (struct i2c_adapter *);
#if IS_ENABLED(CONFIG_I2C_SLAVE)
  int (*reg_slave)(struct i2c_client *client);
  int (*unreg_slave)(struct i2c_client *client);
#endif
};

三、i2c_client

i2c_client结构体:

struct i2c_client {
  unsigned short flags;   /* div., see below    */
  unsigned short addr;    /* chip address - NOTE: 7bit  */
          /* addresses are stored in the  */
          /* _LOWER_ 7 bits   */
  char name[I2C_NAME_SIZE];
  struct i2c_adapter *adapter;  /* the adapter we sit on  */
  struct device dev;    /* the device structure   */
  int irq;      /* irq issued by device   */
  struct list_head detected;
#if IS_ENABLED(CONFIG_I2C_SLAVE)
  i2c_slave_cb_t slave_cb;  /* callback for slave mode  */
#endif
};

在 Linux 内核中,i2c_client 是 I2C 从设备的设备结构体,表示连接到 I2C 总线上的一个 I2C 从设备。它包含了该从设备的一些信息,例如设备地址、从设备驱动程序、从设备所在的 I2C 适配器等。

重要的成员:

unsigned short addr:I2C 从设备的地址,存储在 7 位中。注意,这个地址不包括 I2C 地址的读写位,即 7 位地址用于标识从设备的身份。

struct i2c_adapter *adapter:指向从设备所连接的 I2C 适配器的指针。有了适配器信息,可以通过适配器的接口访问连接的从设备。


四、i2c_msg

i2c_msg结构体:

struct i2c_msg {
  __u16 addr; /* slave address      */
  __u16 flags;
#define I2C_M_RD    0x0001  /* read data, from slave to master */
          /* I2C_M_RD is guaranteed to be 0x0001! */
#define I2C_M_TEN   0x0010  /* this is a ten bit chip address */
#define I2C_M_RECV_LEN    0x0400  /* length will be first received byte */
#define I2C_M_NO_RD_ACK   0x0800  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK  0x1000  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR  0x2000  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART   0x4000  /* if I2C_FUNC_NOSTART */
#define I2C_M_STOP    0x8000  /* if I2C_FUNC_PROTOCOL_MANGLING */
  __u16 len;    /* msg length       */
  __u8 *buf;    /* pointer to msg data      */
};

struct i2c_msg 是 Linux 内核中 I2C/SMBus 消息的结构体,用于描述 I2C 总线上的一条消息。

重要的成员:

__u16 addr:I2C 从设备的地址,用于指定消息要发送到哪个从设备上。

__u16 flags:消息的标志参数,包括多种不同的位掩码:

通过这些参数,struct i2c_msg 结构体可以描述出 I2C 总线上的一条具体的消息,并通过设备驱动程序对该消息进行操作。


总结

有了这些重要结构体的知识我们就可以开始编写驱动程序了。


相关文章
|
1天前
|
存储 负载均衡 网络协议
在Linux中优化系统性能的实用指南
【4月更文挑战第30天】本文是关于Linux系统性能优化的指南,涵盖硬件选择、系统及软件更新、调整Swap分区、内核参数优化、使用性能分析工具、文件系统优化、网络服务优化和定期维护等方面。通过这些方法,可提升系统响应速度,降低资源消耗,延长硬件寿命。注意,优化需根据具体系统和应用需求进行。
|
1天前
|
前端开发 Linux iOS开发
【Flutter前端技术开发专栏】Flutter在桌面应用(Windows/macOS/Linux)的开发实践
【4月更文挑战第30天】Flutter扩展至桌面应用开发,允许开发者用同一代码库构建Windows、macOS和Linux应用,提高效率并保持平台一致性。创建桌面应用需指定目标平台,如`flutter create -t windows my_desktop_app`。开发中注意UI适配、性能优化、系统交互及测试部署。UI适配利用布局组件和`MediaQuery`,性能优化借助`PerformanceLogging`、`Isolate`和`compute`。
【Flutter前端技术开发专栏】Flutter在桌面应用(Windows/macOS/Linux)的开发实践
|
1天前
|
弹性计算 Shell Linux
|
1天前
|
存储 缓存 Linux
linux几种典型应用对系统资源使用的特点
【4月更文挑战第22天】几种典型应用对系统资源使用的特点
7 0
|
2天前
|
Web App开发 监控 Unix
Linux 常用命令汇总(七):进程管理 & 系统权限 & 用户授权
Linux 常用命令汇总(七):进程管理 & 系统权限 & 用户授权
|
2天前
|
Unix 大数据 Linux
Linux系统简介与开源精神
Linux系统简介与开源精神
15 3
|
2天前
|
存储 Unix Linux
【Linux系统编程】基础指令(三)
【Linux系统编程】基础指令(三)
|
2天前
|
Linux
【Linux系统编程】基础指令(二)(下)
【Linux系统编程】基础指令(二)
|
2天前
|
Linux C语言
【Linux系统编程】基础指令(二)(上)
【Linux系统编程】基础指令(二)
|
2天前
|
Linux
【Linux系统编程】基础指令(一)(下)
【Linux系统编程】基础指令(一)