f

    科技2022-07-11  97

    前言

    之所以选择f_fs.c作为这系列的开始,因为usb在/driver/usb下面的内容实在太多太多,如果讲各种各样点会太分散了。所以决定切入点以实际使用为主,就是f_fs了,目前我了解这是做bulk裸传输使用的,具体的通信协议自己确定。

    初始化部分

    开始点从这个路径下说起,

    /drivers/usb/gadget/function/f_fs.c

    然后f_fs.c第一个使用的是include/composite.h中的宏定义function

    #define DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc) \ static struct usb_function_driver _name ## usb_func = { \ .name = __stringify(_name), \ .mod = THIS_MODULE, \ .alloc_inst = _inst_alloc, \ .alloc_func = _func_alloc, \ }; \ MODULE_ALIAS("usbfunc:"__stringify(_name)); #define DECLARE_USB_FUNCTION_INIT(_name, _inst_alloc, _func_alloc) \ DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc) \ static int __init _name ## mod_init(void) \ { \ return usb_function_register(&_name ## usb_func); \ } \ static void __exit _name ## mod_exit(void) \ { \ usb_function_unregister(&_name ## usb_func); \ } \ module_init(_name ## mod_init); \ module_exit(_name ## mod_exit) DECLARE_USB_FUNCTION_INIT(ffs, ffs_alloc_inst, ffs_alloc);

    以上大家其实可以看得到,Linux中宏定义的形式比较有特色。如果两个宏有父子关系,比如上面代码段这种,就会将子宏放在前面,然后后面再定义父宏(Linux应该没有父子宏这种说法,我自己编的)。最后我们f_fs.c中就调用了这么一个宏。我们解析一下这个宏调用后都生成了什么:

    static struct usb_function_driver ffsusb_func = { .name = ffs, .mod = THIS_MODULE, .alloc_inst = ffs_alloc_inst, .alloc_func = ffs_alloc, }; static int __init ffsmod_init(void) { return usb_function_register(&ffsusb_func); } static void __exit ffsmod_exit(void) { usb_function_unregister(&ffsusb_func); }

    系统刚启动时候,会执行module_init函数,然后依次执行ffsmod_init->usb_function_register->ffsusb_func挂入全局func_list当中,就算是完成了任务了,初始化结束。以上其实也就说明了,一个usb_function_driver只能被挂载一次,usb_function_register这个函数内部会进行对比,也就只要挂载一次就够了。一个driver和多个设备绑定,也就是多个同样的设备是可以使用同一个driver进行驱动的(大家应该都知道)。

    Processed: 0.025, SQL: 8