使用宏时,c-char驱动程序设备问题



上下文

我被要求为一个特定的硬件包制作一个字符驱动程序。此驱动程序需要有两个设备位于同一类下。目前,我并没有真正关心整个file_operations结构,因为我主要在sysfs和属性定义方面有问题。我正在开发一个VMware,驱动程序必须能够在linux v.10.X.上运行。

已经做了什么

到目前为止,我已经将我的驱动程序(在任何功能之外(初始化为:

static struct class * dev_class; 
static struct device * some_dev_1;
static struct device * some_dev_2; 
static struct cdev some_cdev_1;
static struct cdev some_cdev_2;
static dev_t dev_num_1 = MKDEV(MAJOR_NUMBER_1, 0); /* Major is 235 */
static dev_t dev_num_2 = MKDEV(MAJOR_NUMBER_2, 0); /* Major is 240 */

因此,我有两个设备(用于sysfs(和它们的cdev(用于用户界面(。在device_bringup函数(见下文(中,我想用结构文档中的show/store方法填充attribute_group ** groups结构。我试着遵循本教程和本教程,得到了以下代码:

int device_bringup(char * device_1_name, char * device_2_name){
int return_value = SUCCESS;
some_dev_1 = device_create(dev_class, NULL, dev_num_1, NULL, device_1_name); /* Create/Registers it on sysfs */
some_dev_2 = device_create(dev_class, NULL, dev_num_2, NULL, device_2_name);
if(some_dev_1 == NULL){
printk(KERN_ALERT KBUILD_MODNAME " Cannot create the Device #1 !n");
return_value = init_error_manager(1);
}
printk(KERN_ALERT KBUILD_MODNAME " Device #1 was created !n");
if(some_dev_2 == NULL){
printk(KERN_ALERT KBUILD_MODNAME " Cannot create the Device #2 !n");
return_value = init_error_manager(2);
}
printk(KERN_ALERT KBUILD_MODNAME " Device #2 was created !n");

DEVICE_ATTR(first, 0664, sysfs_show, sysfs_store); /* Name should be dev_attr_first */
DEVICE_ATTR(second, 0664, sysfs_show, sysfs_store); /* Name should be dev_attr_second */
struct attribute * some_dev_1_attrs[] = { /* see https://docs.kernel.org/driver-api/driver-model/device.html for info */
&dev_attr_first.attr, 
&dev_attr_second.attr, 
NULL
};
struct attribute * some_dev_2_attrs[] = { 
&dev_attr_first.attr, 
&dev_attr_second.attr, 
NULL
};
ATTRIBUTE_GROUPS(some_dev_1); /* Create the some_dev_1_groups */
ATTRIBUTE_GROUPS(some_dev_2); /* Create the some_dev_2_groups */

some_dev_1->groups = some_dev_1_groups;
some_dev_2->groups = some_dev_2_groups;
return return_value;
}

问题

在完成了这两个教程之后,我的内核无法构建,我收到了以下错误:

error: initializer element is not constant ATTRIBUTE_GROUPS(some_dev_1);
error: initializer element is not constant ATTRIBUTE_GROUPS(some_dev_2);

然后我阅读了这个问题,它似乎源于some_dev_1some_dev_2设备指针没有初始化的事实。然而,在阅读了一些stackoverflow线程后,我尝试了以下操作:

static struct device * some_dev_1 = kmalloc(sizeof(some_dev_1));

然后

static struct device * some_dev_1 = &(struct device){.name = "test"};

甚至

static struct device * some_dev_1 = NULL;

然而,这些都没有解决这个问题。我确信这个问题很容易解决,但我似乎只能绕着它转

解决方案

事实证明,问题源于宏ATTRIBUTE_GROUPS(some_dev_1)并没有真正使用范围外定义的some_dev_1。它只是将其用作组名称的字符串。

使用device_create_with_groups而不将属性组直接分配给设备,这使它对我有效。我还必须使DEVICE_ATTR和属性数组为静态,以便它们在范围之外可用。这是最后的工作代码:

int device_bringup(char * device_1_name, char * device_2_name){
int return_value = SUCCESS;
static DEVICE_ATTR(first, 0664, sysfs_show, sysfs_store); /* Name should be dev_attr_tape_deck_first */
static DEVICE_ATTR(second, 0664, sysfs_show, sysfs_store); /* Name should be dev_attr_tape_deck_second */
static struct attribute * some_dev_1_attrs[] = {
&dev_attr_first.attr, 
&dev_attr_second.attr, 
NULL
};
static struct attribute * some_dev_2_attrs[] = { 
&dev_attr_first.attr, 
&dev_attr_second.attr, 
NULL
};
ATTRIBUTE_GROUPS(some_dev_1); 
ATTRIBUTE_GROUPS(some_dev_2); 
some_dev_1 = device_create_with_groups(dev_class, NULL, dev_num_1, NULL, some_dev_1_groups, device_1_name);
some_dev_2 = device_create_with_groups(dev_class, NULL, dev_num_2, NULL, some_dev_2_groups, device_2_name);
if(IS_ERR_OR_NULL(some_dev_1)){ 
printk(KERN_ALERT KBUILD_MODNAME " Cannot create the Device #1 !n");
return_value = PTR_ERR(some_dev_1);
}
printk(KERN_ALERT KBUILD_MODNAME " Device #1 was created !n");
if(IS_ERR_OR_NULL(some_dev_2)){
printk(KERN_ALERT KBUILD_MODNAME " Cannot create the Device #2 !n");
return_value = PTR_ERR(some_dev_2);
}
printk(KERN_ALERT KBUILD_MODNAME " Device #2 was created !n");
return return_value;
}

这不是它的最终版本,因为我必须使函数更加原子化,并且不要在同一个函数中创建两个设备,而是每次调用只创建一个设备。然而,上面的代码解决了我的问题。我希望它能帮助任何遇到这种问题的人。

最新更新