1

我正在编写一个使用 I2C 与主机通信的设备驱动程序。

下面是我想学习和理解的代码。如果我对以下代码的理解有误,请帮帮我。“//”是我自己的评论和我对代码的理解。

// declare there will be a member struct inside the class example_state. This member is pointing to i2c_client.
struct example_state {
struct i2c_client *client; 
};

static int example_probe(struct i2c_client *client, const struct i2c_device_id *id{

// declare this to be a local struct inside the example_probe
struct example_state *state;

// get "struct device" to be pointed client's member name dev
// Question: is "struct device *dev" part of "struct i2c_client"?
// if "struct device *dev" imported from somewhere that why there is no need to allocate memory?
struct device *dev = &client->dev;

// allocate a memory space for "struct example_state"
// at this point "struct example_state" is still empty/NULL
// **Question:** but what is the relationship of this local "struct example_state"
// with the one declared before entering struct example_state function?
state = kzalloc(sizeof(struct example_state), GFP_KERNEL); 
if (state == NULL) {
    dev_err(dev, "failed to create our state\n");
    return -ENOMEM;
}

    // after memory allocated set the "struct i2c_client" point to "struct example_state"'s member namely "client".
state->client = client; 

   // set the our device I2C driver information to the host.
   // Question: Where to we set our device driver data?
i2c_set_clientdata(client, state); 

/* rest of the initialisation goes here. */

dev_info(dev, "example client created\n");

return 0;
}

static int __devexit example_remove(struct i2c_client *client){
  // get the loaded value from host, i guess is like unregister
  // my device driver information from the host when i exited.
struct example_state *state = i2c_get_clientdata(client);

kfree(state);
return 0;
}

static struct i2c_device_id example_idtable[] = {
{ "example", 0 },
{ }
};
4

1 回答 1

2

我建议您不要研究 Linux 内核的 i2c 支持,而应该再看看K&R 2

// declare there will be a member struct inside the class example_state. This member is pointing to i2c_client.
struct example_state {
struct i2c_client *client; 
};

C 没有类。Linux 内核的sysfs抽象引入了内核自己关于“类”是什么的概念——请参阅drivers/base/class.c——但它与 C++、Java、C# 或您熟悉的任何其他语言中的类完全没有关系。

static int example_probe(struct i2c_client *client, const struct i2c_device_id *id{

// declare this to be a local struct inside the example_probe
struct example_state *state;

这声明state为指向一块内存的指针。struct example_state(我通常在这里使用对象这个词,但我不想抵消上一段中“C 没有类”的言论。它是一块内存,与所需的数量一样大或更大保存 的所有成员,struct example_state编译器知道检查操作的类型一致性。也许我应该说“对象”......)

无论如何,在这行代码中只为指针留出了足够的内存——而不是结构本身。

// get "struct device" to be pointed client's member name dev
// Question: is "struct device *dev" part of "struct i2c_client"?
// if "struct device *dev" imported from somewhere that why there is no need to allocate memory?
struct device *dev = &client->dev;

这一行中的 为指针struct device *dev分配了足够的内存,并告诉编译器该指针将只指向对象。查找参数以查找成员并创建别名以便在此例程中更轻松地使用。struct device=&client->devclientdev

// allocate a memory space for "struct example_state"
// at this point "struct example_state" is still empty/NULL
// **Question:** but what is the relationship of this local "struct example_state"
// with the one declared before entering struct example_state function?
state = kzalloc(sizeof(struct example_state), GFP_KERNEL); 
if (state == NULL) {
    dev_err(dev, "failed to create our state\n");
    return -ENOMEM;
}

struct example_state { .. }前面的from 是一个类型声明。它仅向编译器指示存储在带有 tag 的结构中的成员的名称、大小和类型struct example_state。它不分配任何内存。这里的kzalloc()调用确实分配了内存,我们struct example_state对象的大小,并且它请求使用正常的GFP_KERNEL内存分配池。有关include/linux/gfp.h可用内存的不同“池”的详细信息,请参阅。根据传递给内核内存分配器的标志,内存分配可能仅内核被迫执行各种“垃圾收集”之后发生——将脏内存缓冲区写回磁盘、删除页面缓存、交换进程,也许甚至调用OOM内存杀手来分配内存。这GFP_ATOMIC当内核绝对不能在该点休眠时使用池-非常适合在持有自旋锁或在中断上下文中使用。

虽然可以同时学习 C 和内核内部结构,但在这种环境中犯错是非常无情的。在普通用户空间程序中跟随一个杂散指针会使进程产生段错误,但在内核中跟随一个杂散指针会使机器恐慌或破坏内存、文件系统等。

于 2011-11-18T07:51:06.507 回答