Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Usb设备id表理解_C_Linux_Usb_Drivers - Fatal编程技术网

C Usb设备id表理解

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

我试图理解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
    {} /* 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)
  • 这是如何终止的
C标准规定:

初始化应按初始化器列表顺序进行,每个 为覆盖任何子对象的特定子对象提供的初始值设定项 以前列出的同一子对象的初始值设定项;所有子对象 未显式初始化的应隐式初始化 与具有静态存储持续时间的对象相同

以及:

如果未初始化具有自动存储持续时间的对象 显然,它的值是不确定的。如果对象具有静态 未明确初始化存储持续时间,则:

  • 如果有指针类型,则初始化为空指针
  • 如果它具有算术类型,则初始化为(正数或正数) (无符号)零
  • 如果是聚合,则初始化每个成员(递归) 根据这些规则
  • 如果是联合,则初始化第一个命名成员 (递归地)根据这些规则
有鉴于此,
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);}