linux sysfs open,使用Linux sysfs_notify调用

我正在尝试在内核驱动程序和用户空间程序之间进行异步通信(我知道这里有很多问题需要类似的信息,但是找不到与sysfs_notify相关的信息)。

我将在这里留下Vilhelm的编辑,但是将源代码添加到一个使用sysfs的简单驱动程序中,并在一个用户空间程序中对其进行轮询。驱动程序工作正常(我从网络上获得了大部分钱;它缺少功劳,但是我回去添加功劳时找不到它们)。不幸的是,轮询程序无法正常工作。它总是立即返回成功。有趣的是,如果我在轮询之前不执行两次读取,则revents成员将设置为POLLERR

| 在程序输出中看到的是POLLIN,而不仅仅是POLLIN。

程序输出:

root @ ubuntu:/ home / wmulcahy / demo#./readhello已

触发

属性文件值:74(t)[0]

清除[0]:00000001

清除[1]:00000001

这是驱动程序:hello.c(您可以看到我从哪里开始…)

#include

#include

#include

#include

#include

struct my_attr {

struct attribute attr;

int value;

};

static struct my_attr notify = {

.attr.name="notify",

.attr.mode = 0644,

.value = 0,

};

static struct my_attr trigger = {

.attr.name="trigger",

.attr.mode = 0644,

.value = 0,

};

static struct attribute * myattr[] = {

&notify.attr,

&trigger.attr,

NULL

};

static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)

{

struct my_attr *a = container_of(attr, struct my_attr, attr);

printk( "hello: show called (%s)\n", a->attr.name );

return scnprintf(buf, PAGE_SIZE, "%s: %d\n", a->attr.name, a->value);

}

static struct kobject *mykobj;

static ssize_t store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t len)

{

struct my_attr *a = container_of(attr, struct my_attr, attr);

sscanf(buf, "%d", &a->value);

notify.value = a->value;

printk("sysfs_notify store %s = %d\n", a->attr.name, a->value);

sysfs_notify(mykobj, NULL, "notify");

return sizeof(int);

}

static struct sysfs_ops myops = {

.show = show,

.store = store,

};

static struct kobj_type mytype = {

.sysfs_ops = &myops,

.default_attrs = myattr,

};

static struct kobject *mykobj;

static int __init hello_module_init(void)

{

int err = -1;

printk("Hello: init\n");

mykobj = kzalloc(sizeof(*mykobj), GFP_KERNEL);

if (mykobj) {

kobject_init(mykobj, &mytype);

if (kobject_add(mykobj, NULL, "%s", "hello")) {

err = -1;

printk("Hello: kobject_add() failed\n");

kobject_put(mykobj);

mykobj = NULL;

}

err = 0;

}

return err;

}

static void __exit hello_module_exit(void)

{

if (mykobj) {

kobject_put(mykobj);

kfree(mykobj);

}

printk("Hello: exit\n");

}

module_init(hello_module_init);

module_exit(hello_module_exit);

MODULE_LICENSE("GPL");

这是轮询程序:readhello.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define TEST_SYSFS_TRIGGER "/sys/hello/trigger"

#define TEST_SYSFS_NOTIFY "/sys/hello/notify"

int main(int argc, char **argv)

{

int cnt, notifyFd, triggerFd, rv;

char attrData[100];

struct pollfd ufds[2];

// Open a connection to the attribute file.

if ((notifyFd = open(TEST_SYSFS_NOTIFY, O_RDWR)) < 0)

{

perror("Unable to open notify");

exit(1);

}

// Open a connection to the attribute file.

if ((triggerFd = open(TEST_SYSFS_TRIGGER, O_RDWR)) < 0)

{

perror("Unable to open trigger");

exit(1);

}

ufds[0].fd = notifyFd;

ufds[0].events = POLLIN;

ufds[1].fd = triggerFd;

ufds[1].events = POLLIN;

// Someone suggested dummy reads before the poll() call

cnt = read( notifyFd, attrData, 100 );

cnt = read( triggerFd, attrData, 100 );

ufds[0].revents = 0;

ufds[1].revents = 0;

if (( rv = poll( ufds, 2, 10000)) < 0 )

{

perror("poll error");

}

else if (rv == 0)

{

printf("Timeout occurred!\n");

}

else if (ufds[0].revents & POLLIN)

{

printf("triggered\n");

cnt = read( notifyFd, attrData, 1 );

printf( "Attribute file value: %02X (%c) [%d]\n", attrData[0], attrData[0], cnt );

}

printf( "revents[0]: %08X\n", ufds[0].revents );

printf( "revents[1]: %08X\n", ufds[1].revents );

close( triggerFd );

close( notifyFd );

}

在内部,补丁程序向系统上的每个kobject添加了一个等待队列头。将该队列插入到轮询表中,以响应poll()调用。sysfs代码无法知道,但是,任何给定sysfs属性的值何时更改,因此实现可轮询属性的子系统必须对以下内容进行显式调用:

void sysfs_notify(struct kobject *kobj, char *dir, char *attr);

谢谢李

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux sysfsLinux内核提供的一种虚拟文件系统,用于向用户空间提供内核信息和控制接口。它提供了一种统一的方式来访问内核数据结构,包括设备、驱动程序、文件系统和其他内核组件。通过sysfs,用户可以查看和修改内核状态,例如设备属性、驱动程序参数和系统配置。sysfs还提供了一些特殊的文件和目录,用于管理和监控系统资源,例如CPU、内存和网络接口。 ### 回答2: Linux sysfs 是一种用于管理 Linux 操作系统的虚拟文件系统。它为用户提供了一种简单、一致和易于理解的方式来管理系统设备、内核模块和进程的系统信息。 Linux sysfs 基于文件系统的概念,它不是用于存储文件的常规文件系统,而是用于存储和显示有关系统设备、内核模块和进程的信息。在 sysfs 中,几乎一切都被表示为文件或目录,并且可以通过文件系统的操作进行读写操作。 Linux sysfs 中的设备表示为一个目录结构,包括每个设备的名称和属性。这些属性包括该设备的状态、参数和配置。可以通过 sysfs 修改设备属性,从而在运行时对系统进行配置。 sysfs 还提供了一种管理内核模块的机制。内核模块将自己的信息写入 sysfs 中的相应目录,用户可以通过 sysfs 查看和修改内核模块的状态和参数,包括加载、移除、卸载和重载内核模块。 除了管理设备和内核模块之外,sysfs 还将进程信息以文件和目录的形式公开。每个进程都被表示为一个目录,包含进程的状态、配置和其他信息。sysfs 使用户可以查看和操作进程的信息,启用或禁用进程、发送信号和进程间通信等。 总之,Linux sysfs 是一个非常强大且重要的系统机制,它为用户提供了一种易于理解、一致、可靠且灵活的方式来管理系统设备、内核模块和进程的信息。无论您是管理 Linux 系统还是进行开发,了解 sysfs 都将是一个非常重要的领域。 ### 回答3: Linux sysfs是一个虚拟文件系统,用于向用户提供内核和设备驱动程序的信息。它提供了一个层次结构的文件系统,其中每个组件都被表示为文件夹和文件。这些文件夹和文件中包含有关系统状态和设备信息的数据。sysfsLinux内核的一个重要组成部分,它提供了很多调试和诊断功能,同时也可以帮助开发者编写更好的设备驱动程序。 sysfs的主要作用是提供一种简单的方式来访问内核信息,通过读取或写入sysfs中的数据,用户可以获取有关设备、内核参数、驱动程序信息等很多数据。通过sysfs中的节点,用户可以查看内核的许多设置,例如IRQ映射、内存布局和中断控制器等。这些信息对于系统管理、硬件和软件故障排除以及性能调整至关重要。 sysfs还提供了另一个强大的功能,即让用户可以修改某些内核参数和配置。例如,通过sysfs,用户可以更改CPU调度策略、设置内核调试等级,或禁用某个硬件设备。这种灵活性使得开发者和系统管理员可以轻松地调整系统性能、解决问题并添加新的功能。 总之,Linux sysfs是一个非常有用的工具,提供了一种轻松访问内核和设备信息的方式。通过它,用户可以查看和修改内核参数和配置,有助于诊断和解决系统问题。在Linux的开发、管理和维护过程中扮演着非常重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值