duduru

设备驱动的私有数据设计

IIO子系统的私有数据

私有数据的完整使用流程:

// 定义私有数据结构
struct my_data {
    int calibration;
    u8 buffer[128];
};

// 分配 IIO 设备(包含私有数据空间)
struct iio_dev *indio_dev = devm_iio_device_alloc(dev, sizeof(struct my_data));

// 获取私有数据指针(关键步骤!)
struct my_data *data = iio_priv(indio_dev);

// 初始化私有数据
data->calibration = 0x1234;

在Linux内核设计中(如Input,IIO子系统),通过以上代码操作私有数据的方式十分常见,他的本质是通过指针运算访问连续内存中的相邻区域,在devm_iio_device_alloc中,他会把堆空间设计为如下布局:

|--------------------------|-------------------------------|
| struct iio_dev (设备对象) | 私有数据 (private data)       |
|--------------------------|-------------------------------|
^                          ^
indio_dev                  iio_priv(indio_dev)

这样做能在初始化的时候把私有数据的大小确定,即指定私有数据的空间大小为my_data;而后的读写则通过访问固定偏移的地址即可

static inline void *iio_priv(const struct iio_dev *indio_dev)
{
	return (char *)indio_dev + ALIGN(sizeof(struct iio_dev), IIO_ALIGN);
}

对比包含void*的私有数据

Linux内核的IIO子系统(以及其他类似子系统)选择通过内存布局偏移量(如iio_priv())而不是在结构体中直接包含void*指针来访问私有数据,主要基于以下几个关键考虑:

  1. 内存效率优化
  • 单次分配:通过连续内存布局,设备和私有数据可以一次性分配完成(只需一次kmalloc)
  • 无额外指针开销:省去了void*指针本身占用的内存(在64位系统上节省8字节)
  • 缓存友好性:设备和私有数据物理上相邻,提高CPU缓存命中率
// 当前方案(紧凑):
[iio_dev][padding][private_data]

// 如果使用void*(额外开销):
[iio_dev][void*][private_data]
  1. 性能优势
  • 减少内存访问:直接通过偏移量计算访问私有数据,省去了通过指针间接寻址的步骤

  • 避免二级跳转:传统void*方案需要先读取指针值,再通过指针访问数据,而偏移量方案只需一次地址计算

但void也并非没有优点,相比固定偏移的方案,void能够处理更为灵活的场景,比如私有数据需要动态调整大小的场景;但在内核底层,偏移量方案的优势更为关键。

posted on 2025-07-17 19:43  duduru  阅读(0)  评论(0)    收藏  举报  来源

导航