The*_*ble 7 linux-device-driver linux-kernel embedded-linux sysfs
我为我们开发的外围设备编写了一个平台驱动程序,并希望向sysfs公开一些配置选项.我已设法使用属性结构(见下文)和sysfs_create_file探测函数创建适当的文件,但我无法弄清楚如何将show/store函数附加到平台驱动程序中的结构.
我在网上找到的大多数资源使用了一个device_attribute结构或类似的东西来创建他们的文件,这也适合吗?还有另一种方法可以为平台驱动程序执行此操作吗?
我的属性struct看起来像这样:
struct attribute subkey_attr = {
.name = "subkeys",
.mode = S_IWUGO | S_IRUGO,
};
Run Code Online (Sandbox Code Playgroud)
我使用此调用注册该文件:
riddler_kobject = &pdev->dev.kobj;
ret_val = sysfs_create_file(riddler_kobject, &subkey_attr);
Run Code Online (Sandbox Code Playgroud)
Sam*_*nko 20
归结为下一个:
struct device(从你的struct platform_device)重用现有的kobject sysfs_create_group()(而不是创建你自己的kobject)DEVICE_ATTR()声明struct device_attribute代替普通__ATTR(),它创建struct kobj_attribute.以下是我为平台驱动程序创建sysfs属性的方法.
创建您将用作sysfs属性(文件)的show()/ store()operations中的私有数据的结构.例如:
struct mydrv {
struct device *dev;
long myparam;
};
Run Code Online (Sandbox Code Playgroud)在你的驱动程序中分配这个结构probe():
static int mydrv_probe(struct platform_device *pdev)
{
struct mydrv *mydrv;
mydrv = devm_kzalloc(&pdev->dev, sizeof(*mydrv), GFP_KERNEL);
mydrv->dev = &pdev->dev;
platform_set_drvdata(pdev, mydrv);
...
}
Run Code Online (Sandbox Code Playgroud)创建show()/ store()功能:
static ssize_t mydrv_myparam_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct mydrv *mydrv = dev_get_drvdata(dev);
int len;
len = sprintf(buf, "%d\n", mydrv->myparam);
if (len <= 0)
dev_err(dev, "mydrv: Invalid sprintf len: %d\n", len);
return len;
}
static ssize_t mydrv_myparam_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct mydrv *mydrv = dev_get_drvdata(dev);
kstrtol(buf, 10, &mydrv->myparam);
return count;
}
Run Code Online (Sandbox Code Playgroud)为这些函数创建设备属性(在这些函数之后):
static DEVICE_ATTR(myparam, S_IRUGO | S_IWUSR, mydrv_myparam_show,
mydrv_myparam_store);
Run Code Online (Sandbox Code Playgroud)声明属性表(实际上列出了驱动程序的sysfs文件):
static struct attribute *mydrv_attrs[] = {
&dev_attr_myparam.attr,
NULL
};
Run Code Online (Sandbox Code Playgroud)声明属性组(实际上为驱动程序指定sysfs目录):
static struct attribute_group mydrv_group = {
.name = "mydrv",
.attrs = mydrv_attrs,
};
static struct attribute_group *mydrv_groups[] = {
&mydrv_group,
NULL
}
Run Code Online (Sandbox Code Playgroud)
实际上可以用一行代替:
ATTRIBUTE_GROUPS(mydrv);
Run Code Online (Sandbox Code Playgroud)在驱动程序的probe()函数中创建sysfs目录和文件:
static int mydrv_probe(struct platform_device *pdev)
{
int ret;
...
ret = sysfs_create_group(&pdev->dev.kobj, &mydrv_group);
if (ret) {
dev_err(&pdev->dev, "sysfs creation failed\n");
return ret;
}
...
}
Run Code Online (Sandbox Code Playgroud)删除驱动程序remove()函数中的sysfs文件:
static int mydrv_remove(struct platform_device *pdev)
{
sysfs_remove_group(&pdev->dev.kobj, &mydrv_group);
...
}
Run Code Online (Sandbox Code Playgroud)正如@FranzForstmayr正确指出的那样,在使用in 添加sysfs文件时可能存在竞争条件.这是因为在调用之前已经通知用户空间这些文件存在(这些文件实际上是由函数创建的).这个问题在Greg Kroah-Hartman的"如何正确创建sysfs文件"一文中有详细介绍.sysfs_create_group()mydrv_probe()mydrv_probe()sysfs_create_group()
因此,在我们的情况下,您可以使用默认属性组platform_device,而不是调用sysfs_create_group()(及其对应方sysfs_remove_group()).为此,您需要将相应的字段分配给属性组变量:.groupsstruct device
static int mydrv_probe(struct platform_device *pdev)
{
...
pdev->dev.groups = mydrv_groups;
...
}
Run Code Online (Sandbox Code Playgroud)
免责声明:我没有测试此代码,但它应该工作,因为这个代码.
有关上述竞争条件的更多见解,请参阅[1,2,3]链接.
有关更多示例,请在内核源目录中运行next命令:
$ git grep -l --all-match -e platform_device -e attribute -e '\.groups =' -- drivers/
Run Code Online (Sandbox Code Playgroud)
您也可以在提交消息中通过"default attribute"进行搜索:
$ git log --no-merges --oneline --grep="default attribute" -- drivers/
Run Code Online (Sandbox Code Playgroud)
我发现了一些提交:[4,5,6,7].
[1] 我的属性过于活泼,我该怎么办?
[2] PATCH:sysfs:添加devm_sysfs_create_group()和朋友
[3] [GIT PATCH] 3.11-rc2的驱动核心补丁
[4] 承诺1
[5] 承诺2
[6] 承诺3
[7] 承诺4
没有足够的声誉来发表评论,但我只想对已接受答案中的默认属性组注释进行评论。我的理解是,不应将其添加到探针函数中,如示例中所示,而应在设备结构中设置(或 device_driver、类或总线,具体取决于您的驱动程序),通常在您的设备末尾定义文件。例如:
static struct device iio_evgen_dev = {
.bus = &iio_bus_type,
.groups = iio_evgen_groups,
.release = &iio_evgen_release,
};
Run Code Online (Sandbox Code Playgroud)
从这个例子
奇怪的是,据此,它DEVICE_INT_ATTR在用于创建属性时无法正常工作,因此不确定这是什么意思。
另外,我不是 100% 确定,但我认为这是在加载驱动程序时调用的,而不是在探测设备时调用的。
| 归档时间: |
|
| 查看次数: |
5806 次 |
| 最近记录: |