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 总线上的一条具体的消息,并通过设备驱动程序对该消息进行操作。


总结

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


相关文章
|
16天前
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
145 78
|
19天前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
53 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
2月前
|
缓存 Java Linux
如何解决 Linux 系统中内存使用量耗尽的问题?
如何解决 Linux 系统中内存使用量耗尽的问题?
146 48
|
15天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
79 13
|
2月前
|
Ubuntu Linux 网络安全
linux系统ubuntu中在命令行中打开图形界面的文件夹
在Ubuntu系统中,通过命令行打开图形界面的文件夹是一个高效且实用的操作。无论是使用Nautilus、Dolphin还是Thunar,都可以根据具体桌面环境选择合适的文件管理器。通过上述命令和方法,可以简化日常工作,提高效率。同时,解决权限问题和图形界面问题也能确保操作的顺利进行。掌握这些技巧,可以使Linux操作更加便捷和灵活。
47 3
|
16天前
|
Ubuntu Linux C++
Win10系统上直接使用linux子系统教程(仅需五步!超简单,快速上手)
本文介绍了如何在Windows 10上安装并使用Linux子系统。首先,通过应用商店安装Windows Terminal和Linux系统(如Ubuntu)。接着,在控制面板中启用“适用于Linux的Windows子系统”并重启电脑。最后,在Windows Terminal中选择安装的Linux系统即可开始使用。文中还提供了注意事项和进一步配置的链接。
39 0
|
2月前
|
Linux
在 Linux 系统中,`find` 命令
在 Linux 系统中,`find` 命令
40 1
|
2月前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
141 1
|
2月前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
27天前
|
存储 Oracle 安全
服务器数据恢复—LINUX系统删除/格式化的数据恢复流程
Linux操作系统是世界上流行的操作系统之一,被广泛用于服务器、个人电脑、移动设备和嵌入式系统。Linux系统下数据被误删除或者误格式化的问题非常普遍。下面北亚企安数据恢复工程师简单聊一下基于linux的文件系统(EXT2/EXT3/EXT4/Reiserfs/Xfs) 下删除或者格式化的数据恢复流程和可行性。