上节中看到usb目录中有一个core目录,凡是认识这个core单词的人都会想要先看看它是什么,对不?用LDD3中一幅图,来表述usb core所处地位。

usb core负责实现一些核心的功能,为别的设备驱动程序提供服务,提供一个用于访问和控制USB硬件的接口,而不用去考虑系统当前存在哪种host controller。

上述就是core的作用和地位,下面就分析core目录下的代码。首先用ls命令看一下它包含哪些文件,顺便用wc –l命令统计一下多少文件和代码。是不是吓了一跳?几万行的代码,core不愧是core,为大家默默的做这么多事。当然不用紧张,我们还是拿着地图(还记得地图是什么?)去慢慢探索。

先看Kconfig文件,主要包括:USB_DEBUG、USB_DEVICEFS、USB_SUSPEND等,不过这个好像和我们要进行分析的代码没有多大关系,还是等用到再说吧。下面去看Makefile,这个文件就显得简单多了。但是内容却一点也不轻松。

usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \

config.o file.o buffer.o sysfs.o endpoint.o \

devio.o notify.o generic.o quirks.o

USB core从USB子系统的初始化开始,我们也需要从那里开始,它们在文件drivers/usb/core/usb.c。

首先,subsys_initcall(usb_init);module_exit(usb_exit);两个函数分别是usb core子系统的入口和出口点。先看入口

/*
* Init
*/
static int __init usb_init(void)
{
int retval;
if (nousb) {
pr_info("%s: USB support disabled\n", usbcore_name);
return 0;
} retval = ksuspend_usb_init();
if (retval)
goto out;
retval = bus_register(&usb_bus_type);
if (retval)
goto bus_register_failed;
retval = usb_host_init();
if (retval)
goto host_init_failed;
retval = usb_major_init();
if (retval)
goto major_init_failed;
retval = usb_register(&usbfs_driver);
if (retval)
goto driver_register_failed;
retval = usb_devio_init();
if (retval)
goto usb_devio_init_failed;
retval = usbfs_init();
if (retval)
goto fs_init_failed;
retval = usb_hub_init();
if (retval)
goto hub_init_failed;
retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE);
if (!retval)
goto out; usb_hub_cleanup();
hub_init_failed:
usbfs_cleanup();
fs_init_failed:
usb_devio_cleanup();
usb_devio_init_failed:
usb_deregister(&usbfs_driver);
driver_register_failed:
usb_major_cleanup();
major_init_failed:
usb_host_cleanup();
host_init_failed:
bus_unregister(&usb_bus_type);
bus_register_failed:
ksuspend_usb_cleanup();
out:
return retval;
}

先看一下上面定义里的__init标记,写过驱动的应该不会陌生,它对内核来说就是一种暗示,表明这个函数仅在初始化期间使用,在模块被装载之后,它占用的资源就会释放掉用作它处。

另外,nousb是一个标志,这里的nousb是用来让我们在启动内核的时候通过内核参数去掉USB子系统的,一般来说是不会去指定nousb为真,否则输出“USB support disabled”,然后退出usb_init。

最后,上述的代码一气呵成,排比强烈。总结一下其中各个函数的作用。

ksuspend_usb_init() 和电源管理相关,如果在编译内核时没有打开电源管理,也就是说没有定义CONFIG_PM,它就什么也不做。

bus_register(&usb_bus_type)注册USB总线,只有成功的将USB总线子系统注册到系统中,我们才可以向这个总线添加USB设备。

usb_host_init()执行host controller相关的初始化。

usb_major_init()一个实际的总线也是一个设备,必须单独注册,因为USB是通过快速串行通信来读写数据,这里把它当作了字符设备来注册。

usb_register(&usbfs_driver)、usb_devio_init()、usbfs_init()都是usbfs相关的初始化。usbfs为咱们提供了在用户空间直接访问usb硬件设备的接口,但它需要内核的大力支持,usbfs_driver就是用来完成这个光荣任务的。

usb_hub_init() 和hub相关的初始化。

usb_register_device_driver(&usb_generic_driver,THIS_MODULE)睁大大眼睛看清楚是USB device driver而不是USB driver,前面说过,一个设备可以有多个接口,每个接口对应不同的驱动程序,这里所谓的device driver对应的是整个设备,而不是某个接口。内核里结构到处有,只是USB这儿格外多。

usb驱动开发3之先看core的更多相关文章

  1. HarmonyOS USB DDK助你轻松实现USB驱动开发

    HDF(Hardware Driver Foundation)驱动框架是HarmonyOS硬件生态开放的基础,为开发者提供了驱动加载.驱动服务管理和驱动消息机制等驱动能力,让开发者能精准且高效地开发驱 ...

  2. 转: 嵌入式linux下usb驱动开发方法--看完少走弯路【转】

    转自:http://blog.csdn.net/jimmy_1986/article/details/5838297 嵌入式linux下的usb属于所有驱动中相当复杂的一个子系统,要想将她彻底征服,至 ...

  3. usb驱动开发1之学习准备

    此系列是http://blog.csdn.net/fudan_abc/博文的整理,同时加入了自己的理解.很敬佩fudan_abc的文章,仔细学习和分析受益很多.注:fundan_abc所分析linux ...

  4. usb驱动开发24之接口驱动

    从第一节我们已经知道,usb_generic_driver在自己的生命线里,以一己之力将设备的各个接口送给了linux的设备模型,让usb总线的match函数,也就是usb_device_match, ...

  5. usb驱动开发15之设备生命线

    总算是进入了HCD的片儿区,既然来到一个片区,怎么都要去拜会一下山头几个大哥吧.,先回忆一些我们怎么到这里的?给你列举一个调用函数过程usb_control_msg->usb_internal_ ...

  6. usb驱动开发14之设备生命线

    直接看代码吧. /*-------------------------------------------------------------------*/ /** * usb_submit_urb ...

  7. usb驱动开发12之设备生命线

    函数usb_control_msg完成一些初始化后调用了usb_internal_control_msg之后就free urb.剩下的活,全部留给usb_internal_control_msg去做了 ...

  8. usb驱动开发10之usb_device_match

    在第五节我们说过会专门分析函数usb_device_match,以体现模型的重要性.同时,我们还是要守信用的. 再贴一遍代码,看代码就要不厌其烦. static int usb_device_matc ...

  9. usb驱动开发5之总线设备与接口

    Linux设备模型中的总线落实在USB子系统里就是usb_bus_type,它在usb_init的函数bus_register(&usb_bus_type)里注册.usb_bus_type定义 ...

随机推荐

  1. onWindowFocusChanged

    这个onWindowFocusChanged指的是这个Activity得到或者失去焦点的时候 就会call. 也就是说 如果你想要做一个Activity一加载完毕,就触发什么的话 完全可以用这个!!! ...

  2. tableview直接滚动至最后一行的问题

    tableview直接滚动至最后一行 类似聊天界面,tableview应该直接显示在最后一行,并且不应该有滚动的出现. 在网上查了很久,直接滚动至最后一行很容易实现,有两种方法比较好. 1. 调用sc ...

  3. 【读书笔记】iOS-UIFont-如何知道字体的PostScript名称

    一,名词解释 PostScript字体: 按 PostScript 页面描述语言 (PDL) 规则定义的字体,并且只能在 PostScript 兼容的打印机上打印. 二,打开Launchpad---- ...

  4. iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合

    1.地图坐标转换那些事 (1)投影坐标系与地理坐标系 地理坐标系使用三维球面来定义地球上的位置,单位即经纬度.但经纬度无法精确测量距离戒面积,也难以在平面地图戒计算机屏幕上显示数据.通过投影的方式可以 ...

  5. ios 删除系统从相册压缩的视频

    iOS的沙盒机制,应用只能访问自己应用目录下的文件.iOS不像android,没有SD卡概念,不能直接访问图像.视频等内容.iOS应用产生的内容,如图像.文件.缓存内容等都必须存储在自己的沙盒内.默认 ...

  6. iOS label根据显示内容自适应大小

    - (void)setupLabel { //准备工作 UILabel *textLabel = [[UILabel alloc] init]; textLabel.font = [UIFont sy ...

  7. LeetCode 6 ZigZag Conversion(规律)

    题目来源:https://leetcode.com/problems/zigzag-conversion/ The string "PAYPALISHIRING" is writt ...

  8. chrome和搜狗浏览器的js问题

    1.在chrome中如果是js添加颜色必须用"#00CC00",必须加#号...不然会出问题,但是在搜狗浏览器中可以没有#号也能正确识别...

  9. Effective Java 63 Include failure-capture information in detail message

    Principle To capture the failure, the detail message of an exception should contain the values of al ...

  10. 更改ubuntu下mysql的密码

    1.首先,进入环境中去,即 mysql  -u  root  -p   ,然后输入原始密码 2.此时会出现 mysql > 3.开始修改密码: mysql >   use  mysql ; ...