[英]char driver device issue when using macros
我被要求為特定的硬件 package 制作一個字符驅動程序。 此驅動程序需要有兩個設備位於同一 class 下。 現在,我並不真正介意整個 file_operations 結構,因為我主要遇到 sysfs 和屬性定義的問題。 我正在使用 VMware,驅動程序必須能夠在 linux v5.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
function(見下文)內部,我想用我的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;
}
在按照上面的兩個教程進行操作后,我的 kernel 無法構建,並且收到以下錯誤:
error: initializer element is not constant ATTRIBUTE_GROUPS(some_dev_1);
error: initializer element is not constant ATTRIBUTE_GROUPS(some_dev_2);
然后我閱讀了這個問題,這似乎源於some_dev_1
和some_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
之外定義的 some_dev_1。 它僅將其用作組名稱的字符串。
使用device_create_with_groups
而不將屬性組直接分配給設備是它對我有用的原因。 我還必須制作屬性 static 的DEVICE_ATTR
和 arrays,以便它們在 scope 之外可用。 這是最終的工作代碼:
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;
}
這不是它的最終版本,因為我必須使 function 更具原子性,並且不在同一個 function 中創建兩個設備,但每次調用只創建一個。 但是,上面的代碼解決了我的問題。 我希望它能幫助遇到此類問題的任何人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.