C Usb设备id表理解
我试图理解linux内核初始化结构的不同方式。在这个查询中,我编写了一个示例usb驱动程序,但我不理解其中的一些要点,如前面的注释C Usb设备id表理解,c,linux,usb,drivers,C,Linux,Usb,Drivers,我试图理解linux内核初始化结构的不同方式。在这个查询中,我编写了一个示例usb驱动程序,但我不理解其中的一些要点,如前面的注释 static struct usb_device_id pen_table[] = //?? why pen_table is an array { { USB_DEVICE(0xaaaa , 0x8816) }, //??what type of array initialization is this {} /* Terminati
static struct usb_device_id pen_table[] = //?? why pen_table is an array
{
{ USB_DEVICE(0xaaaa , 0x8816) }, //??what type of array initialization is this
{} /* Terminating entry */ //??how this terminates
};
我试图以这种方式初始化设备id表,但在接近初始化时出现错误
static struct usb_device_id pen_table = {
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor=0xaaaa,
.idProduct = 0x8816,
};
要真正理解这一点,您应该手头有
Linux
内核源代码
- 为什么
是数组pen\u table
模块设备表
(请参阅)和定义usb驱动程序的实例
结构中,请参阅
- 这是什么类型的数组初始化
USB\U设备
是在include/linux/USB.h中定义的宏:
#define USB_DEVICE(vend, prod) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
.idVendor = (vend), \
.idProduct = (prod)
- 这是如何终止的
- 如果有指针类型,则初始化为空指针李>
- 如果它具有算术类型,则初始化为(正数或正数) (无符号)零李>
- 如果是聚合,则初始化每个成员(递归) 根据这些规则李>
- 如果是联合,则初始化第一个命名成员 (递归地)根据这些规则
id\u表
被定义为指针,而不是usb\u驱动程序中的数组
:
const struct usb_device_id *id_table;
使用id\u table
的函数将递增指向id\u table
的指针,直到其中一个元素为NULL,而不是单独传递数组大小。请参见此表示此技术的简短示例:
#include <stdio.h>
#include <stdlib.h>
struct small
{
int a;
int b;
};
struct big
{
struct small *s;
};
struct small table[] =
{
{1, 1},
{2, 2},
{3, 3},
{}
};
int main(void)
{
struct big b = {
.s = table
};
const struct small *s;
/* traverse through table using pointer arithmetic */
for (s = b.s; s->a; s++)
{
printf("%d\n", s->a);
printf("%d\n", s->b);
}
exit(0);
}
#包括
#包括
结构小型
{
INTA;
int b;
};
结构大
{
结构小*s;
};
结构小表[]=
{
{1, 1},
{2, 2},
{3, 3},
{}
};
内部主(空)
{
结构大b={
.s=表格
};
const struct small*s;
/*使用指针算法遍历表*/
对于(s=b.s;s->a;s++)
{
printf(“%d\n”,s->a);
printf(“%d\n”,s->b);
}
出口(0);
}
- 我试图以这种方式初始化设备id表,但我得到了 接近初始化时出错
我不知道,你确定你没有试图重新定义
pen\u table
?什么是错误消息?这是一个数组,因为它是如何定义和使用数据结构的
您有n个条目,然后是一个终止条目(在本例中为全零)
无论在初始化中使用哪个数组,它都将从表符号开始并使用条目,直到到达终止符,然后停止。这样,您也不需要传达条目的数量
此模式有助于配置数据与库的后期绑定,并允许更多的编译时配置,而不是运行时配置,并且还需要更少的同步内容才能正确运行(因此出错的可能性更小)
您的第二个结构没有终止符,因此解析表的东西一直在进行,直到它崩溃或出错。您的示例很好,但您不应该在不同上下文中的三个位置使用“s”。唯一可以使用不同标识符的位置是在
const struct small*s
中,例如,它可以是const struct small*sp代码>和for
循环可以是for(sp=b.s;sp->a;sp++){printf(“%d\n”,sp->a);printf(“%d\n”,sp->b);}