设备驱动设计模式 【ChatGPT】

简介: 设备驱动设计模式 【ChatGPT】

设备驱动设计模式

这份文档描述了设备驱动中常见的设计模式。子系统维护者可能会要求驱动开发者遵循这些设计模式。

  1. 状态容器
  2. container_of()

1. 状态容器

虽然内核中包含一些设备驱动,假定它们只会在特定系统上被 probed() 一次(单例模式),但通常假定驱动绑定的设备会出现多个实例。这意味着 probe() 函数和所有回调函数都需要是可重入的。

实现这一点最常见的方式是使用状态容器设计模式。通常采用以下形式:

struct foo {
spinlock_t lock; /* 示例成员 */
    (...)
};
static int foo_probe(...)
{
struct foo *foo;
    foo = devm_kzalloc(dev, sizeof(*foo), GFP_KERNEL);
if (!foo)
return -ENOMEM;
    spin_lock_init(&foo->lock);
    (...)
}

每次调用 probe() 都会在内存中创建一个 struct foo 的实例。这就是该设备驱动实例的状态容器。当然,随后需要将该状态实例传递给所有需要访问状态及其成员的函数。

例如,如果驱动正在注册中断处理程序,你需要这样传递指向 struct foo 的指针:

static irqreturn_t foo_handler(int irq, void *arg)
{
struct foo *foo = arg;
    (...)
}
static int foo_probe(...)
{
struct foo *foo;
    (...)
    ret = request_irq(irq, foo_handler, 0, "foo", foo);
}

这样你就能在中断处理程序中始终获得指向正确的 foo 实例的指针。

2. container_of()

在上面的示例中,我们添加了一个 offloaded work:

struct foo {
spinlock_t lock;
struct workqueue_struct *wq;
struct work_struct offload;
    (...)
};
static void foo_work(struct work_struct *work)
{
struct foo *foo = container_of(work, struct foo, offload);
    (...)
}
static irqreturn_t foo_handler(int irq, void *arg)
{
struct foo *foo = arg;
    queue_work(foo->wq, &foo->offload);
    (...)
}
static int foo_probe(...)
{
struct foo *foo;
    foo->wq = create_singlethread_workqueue("foo-wq");
    INIT_WORK(&foo->offload, foo_work);
    (...)
}

对于 hrtimer 或类似的东西,返回的单一参数是指向回调中的结构成员的指针,设计模式是相同的。

container_of() 是在 <linux/kernel.h> 中定义的宏。

container_of() 的作用是通过使用标准 C 中的 offsetof() 宏进行简单的减法运算,从成员指针中获取包含结构的指针,这允许类似面向对象的行为。请注意,被包含的成员不能是指针,而必须是实际的成员才能起作用。

通过这种方式,我们避免了全局指针指向我们的 struct foo * 实例,同时仍然将传递给工作函数的参数数量保持为单一指针。

相关文章
|
3月前
|
存储 安全 Linux
I/O设备的运行时电源管理框架【ChatGPT】
I/O设备的运行时电源管理框架【ChatGPT】
|
3月前
|
Linux API 调度
设备的能量模型【ChatGPT】
设备的能量模型【ChatGPT】
|
3月前
|
Linux
设备电源管理数据类型【ChatGPT】
设备电源管理数据类型【ChatGPT】
|
3月前
|
Linux
消费者设备驱动程序的调节器接口【ChatGPT】
消费者设备驱动程序的调节器接口【ChatGPT】
|
3月前
|
存储 安全 IDE
设备电源管理基础 【ChatGPT】
设备电源管理基础 【ChatGPT】
|
3月前
|
Linux API
Linux里的高精度时间计时器(HPET)驱动 【ChatGPT】
Linux里的高精度时间计时器(HPET)驱动 【ChatGPT】
|
3月前
|
测试技术 Linux API
GPIO 驱动接口 【ChatGPT】
GPIO 驱动接口 【ChatGPT】
|
3月前
|
缓存 安全 Linux
访问与总线无关的设备 【ChatGPT】
访问与总线无关的设备 【ChatGPT】
|
3月前
|
安全 Linux 测试技术
VFIO中介设备 【ChatGPT】
VFIO中介设备 【ChatGPT】
|
3月前
|
测试技术 API 异构计算
设备链接 【ChatGPT】
设备链接 【ChatGPT】