如何将文件操作附加到平台驱动程序中的 sysfs 属性?

2023-11-23

我为我们开发的外围设备编写了一个平台驱动程序,并希望向 sysfs 公开一些配置选项。我已设法使用属性结构创建适当的文件(见下文)并且sysfs_create_file在探针函数中,但我不知道如何将显示/存储函数附加到平台驱动程序中的结构。

我在网上找到的大多数资源都使用device_attributestruct 或类似的东西来创建他们的文件,这在这里也合适吗?对于平台驱动程序还有另一种方法吗?

我的属性结构如下所示:

struct attribute subkey_attr = {
    .name = "subkeys",
    .mode = S_IWUGO | S_IRUGO,
};

我使用此调用注册文件:

riddler_kobject = &pdev->dev.kobj;
ret_val = sysfs_create_file(riddler_kobject, &subkey_attr);

归结为下一个:

  • 重用现有的 kobjectstruct device(从你的struct platform_device) for sysfs_create_group()(而不是创建自己的kobject)
  • use DEVICE_ATTR()声明struct device_attribute而不是常规的__ATTR(),这会创建struct kobj_attribute.

以下是我为平台驱动程序创建 sysfs 属性的方法。

  1. 创建您将用作私有数据的结构show() / store()sysfs 属性(文件)的操作。例如:

    struct mydrv {
        struct device *dev;
        long myparam;
    };
    
  2. 在您的驱动程序中分配此结构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);
    
        ...
    }
    
  3. Create 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;
    }
    
  4. 为这些函数创建设备属性(就在这些函数之后):

    static DEVICE_ATTR(myparam, S_IRUGO | S_IWUSR, mydrv_myparam_show,
                       mydrv_myparam_store);
    
  5. 声明属性表(实际上列出系统文件系统文件给你的司机):

    static struct attribute *mydrv_attrs[] = {
        &dev_attr_myparam.attr,
        NULL
    };
    
  6. 声明属性组(实际上指定sysfs目录为您的司机):

    static struct attribute_group mydrv_group = {
        .name = "mydrv",
        .attrs = mydrv_attrs,
    };
    
    static struct attribute_group *mydrv_groups[] = {
        &mydrv_group,
        NULL
    }
    

    实际上可以用一行替换:

    ATTRIBUTE_GROUPS(mydrv);
    
  7. 在驱动程序中创建 sysfs 目录和文件probe()功能:

    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;
        }
    
        ...
    }
    
  8. 删除驱动程序中的 sysfs 文件remove()功能:

    static int mydrv_remove(struct platform_device *pdev)
    {
        sysfs_remove_group(&pdev->dev.kobj, &mydrv_group);
        ...
    }
    

竞赛条件注释

正如@FranzForstmayr 正确指出的那样,可能有竞争条件添加 sysfs 文件时sysfs_create_group() in mydrv_probe()。这是因为用户空间已经可以被通知这些文件之前存在mydrv_probe()调用(这些文件实际上是由sysfs_create_group()功能)。这个问题在《如何正确创建 sysfs 文件》格雷格·克罗哈特曼的文章。

所以在我们的例子中platform_device,而不是调用sysfs_create_group()(及其对应的sysfs_remove_group()), 您可以使用默认属性组。为此,您需要分配相应的.groups你的领域struct device到您的属性组变量:

static int mydrv_probe(struct platform_device *pdev)
{
    ...

    pdev->dev.groups = mydrv_groups;

    ...
}

免责声明:我没有测试这段代码,尽管它应该可以工作,因为this code.

有关上述竞争条件的更多见解,请参阅 [1,2,3] 链接。

有关更多示例,请在内核源目录中运行下一个命令:

$ git grep -l --all-match -e platform_device -e attribute -e '\.groups =' -- drivers/

您还可以在提交消息中按“默认属性”进行搜索:

$ git log --no-merges --oneline --grep="default attribute" -- drivers/

我发现的一些提交是这样的:[4,5,6,7]。

参考

[1] 我的属性太活泼了,我该怎么办?

[2] 补丁:sysfs:添加 devm_sysfs_create_group() 和朋友

[3] [GIT PATCH] 3.11-rc2的驱动核心补丁

[4] commit 1

[5] commit 2

[6] commit 3

[7] commit 4

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将文件操作附加到平台驱动程序中的 sysfs 属性? 的相关文章

  • Linux 下签名的可执行文件

    出于安全原因 最好在执行之前检查代码的完整性 避免软件被篡改由攻击者发起 所以 我的问题是 如何在Linux下对可执行代码进行签名并仅运行受信任的软件 我读过范杜姆的作品et al Linux 签名可执行文件的设计和实现 以及 IBM 的T
  • 这是 Linux 内核代码中的任何类型的宏吗?

    我在linux内核代码中找到了这个http gitorious org pandroid kernel omap blobs 5ed7607d45b300a37dd13ad1c79adea56f6687ce arch arm mach om
  • 如何执行 GitHub 上的 hello_world 示例:linuxkit/linuxkit?

    情况与问题 我正在尝试跟随本指南 https medium com notsinge making your own linuxkit with docker for mac 5c1234170fb1关于 如何使用 docker for m
  • 在设备驱动程序中使用 select()/poll()

    我有一个驱动程序 它可以处理多个 TCP 连接 有没有一种方法可以在给定列表的情况下执行类似于内核中用户空间应用程序 api 的 select poll epoll 的操作struct sock s Thanks 您可能想编写自己的自定义s
  • ARM Linux 如何模拟 PTE 的脏位、访问位和文件位?

    As per pgtable 2 level h https git kernel org cgit linux kernel git torvalds linux git tree arch arm include asm pgtable
  • Linux 中的直接内存访问

    我正在尝试直接访问嵌入式 Linux 项目的物理内存 但我不确定如何最好地指定内存供我使用 如果我定期启动设备并访问 dev mem 我就可以轻松地读写任何我想要的位置 然而 在这里 我访问的是可以轻松分配给任何进程的内存 我不想做 我的
  • Kubernetes Node 中的内核内存使用率较高

    我非常绝望地寻找解决方案 我正在 AWS 上运行 Kubernetes 集群 v1 16 7 节点规格为 它是一个亚马逊 EC2 t3 medium实例与4GB RAM和 AMI k8s 1 11 debian stretch amd64
  • 物理地址、设备地址和虚拟地址的区别

    有什么区别设备地址 实际地址 and 虚拟地址 其实我正在努力mmap在驱动程序中 我一直坚持这个概念 The 文档 https www kernel org doc Documentation DMA API HOWTO txt says
  • 尝试将 GCC 特定的 asm goto 移植到 Clang

    我一直在尝试将一些 GNU 扩展转换为实际的标准 C 这样它就可以在 clang 上运行 知道标准 C 而不是 GNU 扩展 我有点不知所措 asm goto 1 STATIC KEY INITIAL NOP pushsection jum
  • /dev/mem的访问权限

    我有一系列关于 dev mem 网上很多文章 好像都提到了 dev mem作为通往 Physical RAM 但如果我是对的 dev mem是通往 Physical Address Space 处理器的控制寄存器可能包括许多硬件外设的控制寄
  • 如何在嵌入式Linux中高效地在VFAT分区上创建大文件

    我正在尝试在嵌入式 Linux 盒子中使用 dd 命令在 VFAT 分区上创建一个大的空文件 dd if dev zero of mnt flash file bs 1M count 1 seek 1023 目的是跳过前 1023 个块并在
  • 如何用 C 语言从串行(SPI)连接读取数据?

    我正在尝试编写一个程序 该程序将安装在 Linux MCU Raspberry Pi 上 该程序将读取从另一个 MCU 我将自己构建的自制程序 发送到它的串行数据 我研究了如何做到这一点 并认为我有 大局 但仍然缺少一些东西 其一 我需要启
  • syn队列和accept队列的混淆

    在阅读TCP源码时 我发现一个困惑的事情 我知道 TCP 在 3 次握手中有两个队列 第一个队列存储服务器收到的连接SYN并发回ACK SYN 我们称之为同步队列 第二个队列存储3WHS成功并建立连接的连接 我们称之为接受队列 但在阅读代码
  • I2C 驱动程序应如何在 ACPI 中与 HID PRP0001 匹配

    我正在尝试实例化这个传感器 https elixir bootlin com linux v5 2 source drivers iio proximity vl53l0x i2c c在 ACPI 中使用设备特定数据 即Name DSD 并
  • 如何在Linux内核中启用CONFIG_PREEMPT选项?

    我是 Linux 内核编程的新手 尝试在 x86 64 上使用旧内核 Linux 2 6 32 我想启用其中的 CONFIG PREEMPT 选项 但找不到有关如何执行此操作的信息 我可以使用我的首选选项编译新内核 但不知道在这种情况下我需
  • 如何在 Bluez/Linux 上从 GATT 服务器获取断开连接事件

    环境 Bluez 5 14 Linux 3 1 USB 可插拔 BLE 无线电 TI BLE 密钥卡 CC2541 开发套件 Linux 设备 USB BLE 无线电 我们使用 gatttool 启用 TI 密钥卡上的按键事件并开始监听事件
  • 在内核模块中执行shell命令

    是否可以在内核模块中执行shell命令 我知道我们可以在用户空间 C 代码中使用system子程序 我正在调试一个存在内存泄漏问题的内核模块 在无限循环中执行 insmod 和 rmmod module ko 后 8G RAM 的系统在几分
  • dmesg 和 /var/log/kern.log 之间的区别

    我正在修改kvm模块 并在内核代码中添加了printk语句 运行虚拟机后 printk为我提供了错误地址和有关客户操作系统的其他信息 我需要根据此信息生成统计信息 当我使用 dmesg 时 我只能看到错误地址 在内核空间中 即它们的地址高于
  • 为什么 i2c_smbus 函数不可用? (I2C——嵌入式Linux)

    有很多参考使用i2c smbus 开发嵌入式 Linux 软件时在 I2C 总线上进行通信的函数 什么时候i2c smbus函数如i2c smbus read word data在软件项目中引用了 ARM8 处理器错误 例如 i2c smb
  • u-boot:搬迁

    这是一个与u boot相关的基本问题 为什么 u boot 代码会自行重新定位 好吧 如果 u boot 是从 NOR flash 或启动 ROM 空间执行 那么这是有道理的 但如果它已经从 SDRAM 运行 为什么它必须再次重新定位自己呢

随机推荐

  • Delphi XE - RawByteString 与 AnsiString

    我在这里有一个类似的问题 Delphi XE 我应该使用 String 还是 AnsiString 在决定在我的 大型 库中使用 ANSI 字符串是正确的之后 我意识到我实际上可以使用 RawByteString 而不是 ANSI 因为我将
  • 创建可下载的自定义主题并在运行时应用它

    我正在制作一个 Android 应用程序 需要允许客户端维护来自服务器的资源 其中包括字符串 可绘制对象等 我已经创建了一种机制来下载包含所有这些文件的 zip 文件 并且它们能够非常轻松地更改字符串 我还创建了一种允许客户端更改 UI 控
  • Java抽象类和接口[重复]

    这个问题在这里已经有答案了 在面试中我被问到以下问题 我试图回答这个问题 但我想要问题的确切答案 如果我可以将抽象类模拟为接口 为什么java还要提供接口呢 这意味着如果在抽象类中我可以将所有方法标记为抽象 然后抽象类将充当接口 那么为什么
  • 将包含字典列表的列转换为 pandas 数据框中的多列

    我有一个 Pandas 数据框 如下所示 pd DataFrame a 1 2 b c 1 d 5 c 3 d 7 c 10 d 50 Out 2 a b 0 1 u c 1 u d 5 u c 3 u d 7 1 2 u c 10 u d
  • Mongoid:如何仅加载通过引用延迟加载的对象的某些字段?

    出于性能原因 我尽可能经常使用only 编写 mongoid 查询时使用关键字来指定我想要加载的字段 通常的嫌疑是 例如 当我希望所有管理员的用户电子邮件仅用于显示目的时 我会写 User where groups gt admins on
  • Linq to Entity 从 DateTime 获取日期

    var islemList 来自Entity Islemler中的isl 其中 isl KayitTarihi 日期 gt dbas isl KayitTarihi Value Date 它给出错误 LINQ to Entities 不支持
  • 如何获取包含图像的 contenteditable div 的插入符位置

    我有这个 contenteditable div div minubyv img src class emojiText iubyvt div Here is an image description of the code output
  • android 自定义对话框背景

    我需要在我的 Android 应用程序中显示自定义对话框 标准AlertDialog设计是不可接受的 Android 文档说 提示 如果您想要自定义对话框 您可以显示一个 Activity 作为对话框而不是使用对话框 API 只需创建一个
  • 有没有办法在匹配 url 之前更改 request.path?

    当我收到包含 self 一词的路径请求时 我想在将其与 URL 匹配之前将其替换为用户 ID 我尝试使用这样的中间件 def process request self request if self in request path requ
  • 在Linux中,如何使用外部jar文件执行Java jar文件?

    在Linux中 如何使用外部jar文件执行Java jar文件 要么使用 cp flag java cp path to somefolder jar path to otherfolder jar com YourMainClass 或者
  • 通过 https 从 C# 使用 POST 进行发布

    浪费了两天时间后这个问题 并试图让它发挥作用 我决定退后一步 问一个更基本的问题 因为显然有些东西我不知道或者我做错了 要求很简单 我需要通过 https 进行 HTTP post 传递一些值 来自 C 该网站 如果给定了适当的值 将返回一
  • 浏览器会解析/预渲染/绘制显示:无HTML吗?

    我想阻止浏览器执行解析和预渲染或绘制一些 隐藏 HTML 的工作 直到我准备好显示它 以便我可以快速显示一组最小的内容 让浏览器只执行以下操作渲染可见的部分 我正在寻找初始页面加载的最大渲染 绘制速度 我当前的 HTML div div c
  • pygame 错误:“ImportError:没有名为 'pygame' 的模块”

    这是我的情况 我尝试导入pygame在 python 3 4 2 和 python 3 6 3 中都使用pip and pip3分别 在 python 3 4 2 shell 中 回溯 最近一次调用最后一次 是 文件 第 1 行 位于导入p
  • 评估 100 * 2.55 值时得到错误结果

    我使用以下方法得到错误的结果 public double evaluate final double leftOperand final double rightOperand Double rtnValue new Double left
  • Service Fabric 微服务与 Azure 云服务/Web 应用程序集合的优势

    我有一个可以分解为多个通信服务的应用程序 我当前的实现是整体的 我想重新组织它 以便可以独立地部署 迭代和扩展各个组件 我发现使用 Azure 有两种方法可以实现此目的 Service Fabric 服务由一组通信微服务 无状态 Web A
  • 应用 ElementStyle 时 DataGridCheckBoxColumn 丢失 IsReadOnly 状态

    我需要垂直居中DataGridCheckBoxColumn 因为我没有找到里面的房产DataGridCheckBoxColumn 我应用了ElementStyle 然而 当应用这种风格时 我的CheckBox再次变为可检查 尽管它被设置为R
  • 如何在Eclipse平台上自动启动/热启动OSGi服务

    我开发了一个 Eclipse RCP 应用程序 该应用程序大量使用 OSGi 捆绑包 这些捆绑包提供服务以供以后使用 该用例要求捆绑包注册其服务 例如导入过滤器 以便稍后在不同情况下使用 OSGi 捆绑包是使用 maven bundle p
  • 如何在片段中使用 XML onClick 处理按钮点击

    在 Honeycomb 之前 Android 3 每个 Activity 均注册为通过以下方式处理按钮点击 onClick布局 XML 中的标记 android onClick myClickMethod 在该方法中您可以使用view ge
  • heroku db:拉不起作用?

    我收到以下错误消息 heroku db pull debug postgres USERNAME PASSWORD localhost test Loaded Taps v0 3 23 Warning Data in the databas
  • 如何将文件操作附加到平台驱动程序中的 sysfs 属性?

    我为我们开发的外围设备编写了一个平台驱动程序 并希望向 sysfs 公开一些配置选项 我已设法使用属性结构创建适当的文件 见下文 并且sysfs create file在探针函数中 但我不知道如何将显示 存储函数附加到平台驱动程序中的结构