Linux kernel 轮询sysfs和内核模块
我已经阅读了很多关于这个主题的文章,但我无法找出内核模块中的sysfs实现到底出了什么问题。我试图在轮询上创建一个用户空间程序块,直到sysfs文件中的值发生更改。大多数人似乎没有受到阻碍,我似乎无法摆脱阻碍。以下是相关代码: 内核模块:Linux kernel 轮询sysfs和内核模块,linux-kernel,linux-device-driver,sysfs,Linux Kernel,Linux Device Driver,Sysfs,我已经阅读了很多关于这个主题的文章,但我无法找出内核模块中的sysfs实现到底出了什么问题。我试图在轮询上创建一个用户空间程序块,直到sysfs文件中的值发生更改。大多数人似乎没有受到阻碍,我似乎无法摆脱阻碍。以下是相关代码: 内核模块: static int sysfs_test = 88; static ssize_t test_interrupts_show(struct device* dev, struct device_attribute* attr, const cha
static int sysfs_test = 88;
static ssize_t test_interrupts_show(struct device* dev, struct device_attribute* attr, const char* buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", sysfs_test);
}
static ssize_t test_interrupts_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count)
{
kstrtol(buf, 10, &sysfs_test);
return count;
}
static DEVICE_ATTR(interrupts, S_IWUSR | S_IRUGO, test_interrupts_show, test_interrupts_store);
static int __init test_init(void)
{
int result;
if(dev_major)
{
dev = MKDEV(dev_major, dev_minor);
result = register_chrdev_region(dev, NUM_DEVICES, name);
} else {
result = alloc_chrdev_region(&dev, dev_minor, NUM_DEVICES, name);
dev_major = MAJOR(dev);
dev_minor = MINOR(dev);
}
if(result < 0) {
printk(KERN_WARNING "%s: can't get major %d\n", name, dev_major);
return -1;
}
printk(KERN_NOTICE "%s: Major = %d, Minor = %d\n", name, dev_major, dev_minor);
// Register as character device
test_cdev = cdev_alloc();
cdev_init(cajun_cdev, &test_fops); // Initialize cdev structure
test_cdev->owner = THIS_MODULE; // Add owner
result = cdev_add(test_cdev, dev,1); // Tell kernel about our device
if(result)
{
printk(KERN_NOTICE "Error %d adding cdev\n", result);
goto OUT2;
}
// This stuff relates to sysfs:
ctest_class = class_create(THIS_MODULE, NAME);
if(IS_ERR(test_class))
{
printk(KERN_ALERT "Failed to register device class\n");
goto OUT2;
}
test_device = device_create(test_class, NULL, dev, NULL, NAME);
if(IS_ERR(test_device))
{
printk(KERN_ALERT "Failed to create device\n");
goto OUT3;
}
result = device_create_file(test_device, &dev_attr_interrupts);
if (result < 0)
{
printk(KERN_ALERT "failed\n");
}
OUT3:
class_unregister(test_class);
class_destroy(test_class);
OUT2:
cdev_del(test_cdev);
OUT1:
unregister_chrdev_region(dev, NUM_DEVICES);
return -1;
我在后台运行我的用户空间代码。/test&然后我将一个新值回显到sysfs文件中以进行中断。我正在跳转,等待我的用户空间程序解除阻止,并在值更改时返回。我做错了什么
编辑:
你不应该指望这会奏效。请考虑NETLink套接字。您的文件操作结构TestTyfOPS?罢工-使用SysfsIn通知。另请参见:为什么此人不需要sysfs\u notify?该问题中的代码不起作用。问题撰写者最终解决了轮询不阻塞的问题,但没有描述可能需要进行哪些其他更改才能使整个工作正常进行,例如添加sysfs\u notify。
char interrupts_path[] = "/sys/class/test_module/test_module/interrupts";
int main()
{
struct pollfd fds;
fds.fd = open(interrupts_path, O_RDWR | O_SYNC);
char dummy_buff[1];
read(fds.fd, dummy_buff, 1);
lseek(fds.fd, 0, SEEK_SET);
fds.events = POLLPRI;
printf("Polling for interrupt\n");
poll(&fds,1,-1);
printf("Interrupt occured\n");
return 0;
}
struct file_operations test_fops = {
.owner = THIS_MODULE,
.llseek = test_llseek,
.read = test_read,
.write = test_write,
.unlocked_ioctl = test_ioctl,
.open = test_open,
.release = test_release
};