USB 设备 id table 理解
Usb device id table understanding
我试图了解 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 table,但在接近初始化时出现错误
static struct usb_device_id pen_table = {
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor=0xaaaa,
.idProduct = 0x8816,
};
您应该手头有 Linux
内核源代码才能真正理解这一点。
- 为什么
pen_table
是数组?
MODULE_DEVICE_TABLE
中有必要(参见 Hard time in understanding MODULE_DEVICE_TABLE(usb, id_table) usage) and in defining instance of usb_driver
struct, see http://opensourceforu.efytimes.com/2011/11/usb-drivers-in-linux-2/。
- 这是什么类型的数组初始化?
USB_DEVICE
是在include/linux/usb.h:
中定义的宏
#define USB_DEVICE(vend, prod) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
.idVendor = (vend), \
.idProduct = (prod)
- 这是如何终止的?
C 标准说:
The initialization shall occur in initializer list order, each
initializer provided for a particular subobject overriding any
previously listed initializer for the same subobject; all subobjects
that are not initialized explicitly shall be initialized implicitly
the same as objects that have static storage duration.
和:
If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate. If an object that has static
storage duration is not initialized explicitly, then:
- if it has pointer type, it is initialized to a null pointer;
- if it has arithmetic type, it is initialized to (positive or
unsigned) zero;
- if it is an aggregate, every member is initialized (recursively)
according to these rules;
- if it is a union, the first named member is initialized
(recursively) according to these rules.
因此,id_table
被定义为指针而不是 usb_driver
中的数组:
const struct usb_device_id *id_table;
使用 id_table
的函数将递增指向 id_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);
}
- 我尝试以这种方式初始化设备 ID table,但是我得到了
接近初始化的错误
我不知道,你确定你不是要重新定义 pen_table
?什么是错误消息?
它是一个数组,因为它是数据结构的定义和使用方式。
您有 n 个条目,然后是终止条目(在本例中为全零)。
无论在什么地方使用此数组进行初始化,它都会从 table 符号开始并消耗条目,直到它到达终止符,然后停止。这样您也不需要传达条目数。
此模式有助于将配置数据与库进行后期绑定,并允许更多的编译时配置,而不是 运行 时间配置,并且还需要更少的同步才能正确运行(因此机会更少错误)。
你的第二个结构没有终止符,所以解析 table 的东西会一直继续下去,直到它崩溃或出错。
我试图了解 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 table,但在接近初始化时出现错误
static struct usb_device_id pen_table = {
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor=0xaaaa,
.idProduct = 0x8816,
};
您应该手头有 Linux
内核源代码才能真正理解这一点。
- 为什么
pen_table
是数组?
MODULE_DEVICE_TABLE
中有必要(参见 Hard time in understanding MODULE_DEVICE_TABLE(usb, id_table) usage) and in defining instance of usb_driver
struct, see http://opensourceforu.efytimes.com/2011/11/usb-drivers-in-linux-2/。
- 这是什么类型的数组初始化?
USB_DEVICE
是在include/linux/usb.h:
#define USB_DEVICE(vend, prod) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
.idVendor = (vend), \
.idProduct = (prod)
- 这是如何终止的?
C 标准说:
The initialization shall occur in initializer list order, each initializer provided for a particular subobject overriding any previously listed initializer for the same subobject; all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.
和:
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
- if it has pointer type, it is initialized to a null pointer;
- if it has arithmetic type, it is initialized to (positive or unsigned) zero;
- if it is an aggregate, every member is initialized (recursively) according to these rules;
- if it is a union, the first named member is initialized (recursively) according to these rules.
因此,id_table
被定义为指针而不是 usb_driver
中的数组:
const struct usb_device_id *id_table;
使用 id_table
的函数将递增指向 id_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);
}
- 我尝试以这种方式初始化设备 ID table,但是我得到了 接近初始化的错误
我不知道,你确定你不是要重新定义 pen_table
?什么是错误消息?
它是一个数组,因为它是数据结构的定义和使用方式。
您有 n 个条目,然后是终止条目(在本例中为全零)。
无论在什么地方使用此数组进行初始化,它都会从 table 符号开始并消耗条目,直到它到达终止符,然后停止。这样您也不需要传达条目数。
此模式有助于将配置数据与库进行后期绑定,并允许更多的编译时配置,而不是 运行 时间配置,并且还需要更少的同步才能正确运行(因此机会更少错误)。
你的第二个结构没有终止符,所以解析 table 的东西会一直继续下去,直到它崩溃或出错。