您的位置:首页 > 其它

【I2C设备驱动】必须将id_table[]数组的最后一个元素设置为空的原因

2017-06-26 15:28 323 查看
  忘记了在哪本书上看到过,说必须给 I2C 设备驱动的 id 表数组添加上一个空元素作为最后一个元素,就像下面的代码所展示的那样:

struct i2c_device_id {
char name[I2C_NAME_SIZE];
kernel_ulong_t driver_data;  /* Data private to the driver */
}

static const struct i2c_device_id rt5677_i2c_id[] = {
{ "rt5677", 0 },
{ }    // 末尾需要是一个空元素
};

struct i2c_driver rt5677_i2c_driver = {
.driver = {
.name = "rt5677",
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &rt5677_pm_ops,
#endif
#ifdef RTACPI_I2C
.acpi_match_table = ACPI_PTR(rt5677_acpi_match),
#endif
},
.probe = rt5677_i2c_probe,
.remove   = rt5677_i2c_remove,
.shutdown = rt5677_i2c_shutdown,
.id_table = rt5677_i2c_id,    // 指定id_table
};


  那么原因是什么呢?这样的声明方式一定和它的使用方式有关,所以我们一起在代码中看看 id_table[] 数组被使用的地方:

/**
* hda_match - bind hda device to hda driver.
* @dev: device.
* @drv: driver.
*
*/
static int soc_hda_match(struct device *dev, struct device_driver *drv)
{
struct snd_soc_hda_device *pdev = to_soc_hda_device(dev);
struct snd_soc_hda_driver *pdrv = to_soc_hda_driver(drv);

/* Then try to match against the id table */
if (pdrv->id_table)
return soc_hda_match_id(pdrv->id_table, pdev) != NULL;    // 传入 id_table 指针进行匹配

/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}


  从上方我们看到 id_table 被 soc_hda_match_id() 函数作为入口参数使用,继续深入查看该函数中的操作:

static const struct snd_soc_hda_device_id *soc_hda_match_id(
const struct snd_soc_hda_device_id *id,
struct snd_soc_hda_device *pdev)
{
while (id->name[0]) {  // 如果 name 不为空,则执行下列匹配
if (pdev->id == id->id) {
pdev->id_entry = id;
return id;
} else if (strcmp(pdev->name, id->name) == 0) {
pdev->id_entry = id;
return id;
}
id++;  // 继续处理 id_table 中的下一个元素
}
return NULL;
}


  看到这里,原因就很清楚了:
while
语句只有在检测到 id_table 中某一个元素的 name 成员为空时,才会跳出循环,所以在定义 id_table 时必须使用一个空元素
{}
来作为结束标记。这个用法就类似字符数组必须使用
\0
字符来作为结束符一样(或者表述为:字符串必须以
\0
字符结尾),否则程序在处理字符串时将不知何时终止而出现错误。


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: