在驱动开发中,USB驱动是比较难以理解的部分,也是令驱动开发者比较头疼的,不仅是因为USB包括host端和设备端;USB的协议类型也非常多:数据传输的协议,控制协议,主控制器协议,设备相关的协议,硬件接口的协议。

还要注意的是,设备端还包括多种设备,主要分为五大类:显示器、通信设备(串口一类)、人机输入(键鼠)、音频设备、海量储存(U盘)。

每一种设备的通信协议都不一样,比如海量存储设备,它的通信协议有四个规范:CBI传输、Bulk-Only传输、ATA命令块、UFI命令规范。

而USB的所有系统实现中,UBoot的实现是最为简单易懂的,这点我相信进行过驱动开发的同学都能体会。不仅是因为UBoot的设备树管理简单,而且实现方式基本都是polling,不会用到中断,理解起来方便很多。这里用BBB板子作为示例

首先是初始化,BBB的USB初始化并不包含在board.c文件中,也就是说并不是上电后就自动初始化USB。这点和UBoot的其他很多板子都不一样。而是要利用usb的shell命令进行初始化:在uboot命令行下输入usb回车;如下图所示:

可以看到利用usb start命令可以实现usb的初始化,看下usb start源码实现:

在common/cmd_usb.c中:

static void do_usb_start(void)
{bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");if (usb_init() < 0)return;/* Driver model will probe the devices as they are found */
#ifndef CONFIG_DM_USB
#ifdef CONFIG_USB_STORAGE/* try to recognize storage devices immediately */usb_stor_curr_dev = usb_stor_scan(1);
#endif
#endif
#ifdef CONFIG_USB_HOST_ETHER
# ifdef CONFIG_DM_ETH
#  ifndef CONFIG_DM_USB
#   error "You must use CONFIG_DM_USB if you want to use CONFIG_USB_HOST_ETHER with CONFIG_DM_ETH"
#  endif
# else/* try to recognize ethernet devices immediately */usb_ether_curr_dev = usb_host_eth_scan(1);
# endif
#endif
#ifdef CONFIG_USB_KEYBOARDdrv_usb_kbd_init();
#endif
}

进入该函数首先调用usb_init函数,该函数在common/usb.c中:

int usb_init(void)
{void *ctrl;struct usb_device *dev;int i, start_index = 0;int controllers_initialized = 0;int ret;dev_index = 0;asynch_allowed = 1;usb_hub_reset();/* first make all devices unknown */for (i = 0; i < USB_MAX_DEVICE; i++) {memset(&usb_dev[i], 0, sizeof(struct usb_device));usb_dev[i].devnum = -1;}/* init low_level USB */for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {/* init low_level USB */printf("USB%d:   ", i);ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl);if (ret == -ENODEV) {   /* No such device. */puts("Port not available.\n");controllers_initialized++;continue;}if (ret) {       /* Other error. */puts("lowlevel init failed\n");continue;}/** lowlevel init is OK, now scan the bus for devices* i.e. search HUBs and configure them*/controllers_initialized++;start_index = dev_index;printf("scanning bus %d for devices... ", i);ret = usb_alloc_new_device(ctrl, &dev);if (ret)break;/** device 0 is always present* (root hub, so let it analyze)*/ret = usb_new_device(dev);if (ret)usb_free_device(dev->controller);if (start_index == dev_index) {puts("No USB Device found\n");continue;} else {printf("%d USB Device(s) found\n",dev_index - start_index);}usb_started = 1;}debug("scan end\n");/* if we were not able to find at least one working bus, bail out */if (controllers_initialized == 0)puts("USB error: all controllers failed lowlevel init\n");return usb_started ? 0 : -ENODEV;
}

在usb_init函数中会调用usb_lowlevel_init函数,该函数实现了的是ehci的初始化,也就是调用了ehci_hcd_init函数,该函数的具体实现在每个班子的board.c中,这里不做过多分析。

返回到do_usb_start函数中,调用完usb_init函数后,会进行各种设备的检测:

#ifdef CONFIG_USB_STORAGE

如果定义了CONFIG_USB_STORAGE宏定义,那么会调用usb_stor_scan函数对usb海量数据存储设备进行检测,也就是对u盘进行检测:

看看该函数的实现:

在common/usb_storage.c中:

int usb_stor_scan(int mode)
{unsigned char i;if (mode == 1)printf("       scanning usb for storage devices... ");usb_disable_asynch(1); /* asynch transfer not allowed */usb_stor_reset();for (i = 0; i < USB_MAX_DEVICE; i++) {struct usb_device *dev;dev = usb_get_dev_index(i); /* get device */debug("i=%d\n", i);if (usb_stor_probe_device(dev))break;} /* for */usb_disable_asynch(0); /* asynch transfer allowed */printf("%d Storage Device(s) found\n", usb_max_devs);if (usb_max_devs > 0)return 0;return -1;
}

该函数中首先调用usb_disable_asynch函数禁用异步传输,然后reset stor设备,然后就是最重要的usb_stor_probe_device函数,也就是探测storage设备:

该函数也在同一个文件中:

static int usb_stor_probe_device(struct usb_device *dev)
{if (dev == NULL)return -ENOENT; /* no more devices available */debug("\n\nProbing for storage\n");if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) {/* OK, it's a storage device.  Iterate over its LUNs* and populate `usb_dev_desc'.*/int lun, max_lun, start = usb_max_devs;max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);for (lun = 0;lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;lun++) {struct block_dev_desc *blkdev;blkdev = &usb_dev_desc[usb_max_devs];memset(blkdev, '\0', sizeof(block_dev_desc_t));blkdev->if_type = IF_TYPE_USB;blkdev->dev = usb_max_devs;blkdev->part_type = PART_TYPE_UNKNOWN;blkdev->target = 0xff;blkdev->type = DEV_TYPE_UNKNOWN;blkdev->block_read = usb_stor_read;blkdev->block_write = usb_stor_write;blkdev->lun = lun;blkdev->priv = dev;if (usb_stor_get_info(dev, &usb_stor[start],&usb_dev_desc[usb_max_devs]) ==1) {usb_max_devs++;debug("%s: Found device %p\n", __func__, dev);}}}/* if storage device */if (usb_max_devs == USB_MAX_STOR_DEV) {printf("max USB Storage Device reached: %d stopping\n",usb_max_devs);return -ENOSPC;}return 0;
}

这样就实现了usb中大容量设备的检测;然后回到do_usb_start函数,如果定义了CONFIG_USB_HOST_ETHER,那么会调用usb_host_eth_scan函数对usb 网卡设备进行检测,同理如果定义了CONFIG_USB_KEYBOARD,会调用drv_usb_kbd_init函数对人体标准输入设备进行初始化。

全部检测完成后会在shell输出检测结果:

同样,调用usb的其他命令也会执行相应函数,都在cmd_usb.c文件中。不做展开。

Uboot Beaglebone Black Usb驱动分析相关推荐

  1. RTEMS-libbsd 实现beaglebone black USB驱动

    libbsd是移植Freebsd的代码库,因此包含了USB的协议栈部分,因此我们要做的就是移植USB底层驱动程序. Beaglebone black 的AM335x处理器采用的是musb otg的设备 ...

  2. uboot源码——mmc驱动分析

    以下内容源于朱有鹏<物联网大讲坛>课程的学习,以及博客http://www.cnblogs.com/biaohc/p/6409197.html的学习整理,如有侵权,请告知删除. 一.ubo ...

  3. Omap4470 USB驱动分析之注册过程

    平台:OMAP4470,linix3.4,Android4.2平台. 问题: 1. usb host/otg模式切换的时候容易导致系统卡顿,甚至死机. 2. omap4470的usb接了一个usb-E ...

  4. USB驱动分析(三)

    分类: LINUX 需要注意的是,这些调试信息得是我们打开了编译选项CONFIG_USB_STORAGE_DEBUG才有意义的,这里也看出来了,如果这个选项为0,那么这几个宏就什么也不干,因为它们被赋 ...

  5. USB驱动分析(一)

    原文:http://blog.chinaunix.net/space.php?uid=12051988&do=blog&id=2963109 这个故事中使用的是2.6.10的内核代码. ...

  6. linux dwc3 usb驱动分析

    基于linux 4.9内核 源码: drivers/usb/dw3/core.c 主要完成DesignWare USB3.0 Controller phy初始化,以及模式选择. static stru ...

  7. Linux USB驱动分析(一)----USB2.0协议分析

    原文地址:http://blog.chinaunix.net/uid-25445243-id-4040449.html 一.USB硬件介绍 1.1.概述 一条USB传输线分别由地线.电源线.D+和D- ...

  8. 【linux驱动】USB子系统分析

    本文针对Linux内核下USB子系统进行分析,主要会涉及一下几个方面: USB基础知识:介绍USB设备相关的基础知识 Linux USB子系统分析:分析USB系统框架,USB HCD/ROOT HUB ...

  9. USB驱动及其源码分析

    一.USB理论部分 1.USB概述 USB1.0版本速度1.5Mbps(低速USB). USB1.1版本速度12Mbps(全速USB). USB2.0版本速度480Mbps(高速USB).USB3.0 ...

最新文章

  1. flowlayout java_【简答题】通过使用flowlayout设计出来 java程序如下图所示
  2. bugzilla部署
  3. 【复盘】升级打怪第一关,冲啊!
  4. pip 查看安装路径
  5. windows系统下实现Redis的配置与连接操作
  6. Android牟利之道(一)--界面嵌入有米广告
  7. 【重磅】ArcGIS 10.8手把手经典图文安装教程(附安装包全套装下载,亲测可用)
  8. 3 运行时间太长_10大污水处理预处理系统动态图及运行管理、故障处理
  9. 2022年青年科学基金项目预算经费下降!
  10. 如何改变标题栏的宽度
  11. 怎么讲d 盘里的软件弄到桌面_GNOME 2 粉丝喜欢 Mate Linux 桌面的什么?
  12. 销售服务器 以次充好 判刑,销售假冒产品怎么判刑处罚,法律怎么规定的?
  13. anaconda python更换清华源
  14. RHCE 7.0 考试命令整理
  15. apktool下载及“安装”(windows系统)
  16. python爬虫技术如何挣钱?教你爬虫月入三万
  17. ios共享账号公众号_forest 专注森林 ios下载账号分享 公众号 iphone ipad
  18. 安全狗技术分享|Web应用防火墙之攻击防护
  19. 苹果5壁纸_元气壁纸软件-元气壁纸安卓版下载v1.0.2
  20. 2023健康展/山东睡眠健康展/养生保健展/产后恢复与健康展

热门文章

  1. matlab光谱数据,matlab生成光谱仿真数据
  2. 联合证券|日元疯狂跳水30000点!神秘无人机现身韩国萨德基地!
  3. 正日计算机在线考试系统,正日考试系统对电脑是否有要求
  4. 自从用了speedpdf,PDF转JPG再也不用愁了
  5. 加量不加价 — MateBook 13 2020 评测
  6. EasyDSS启动后443端口未被占用,访问不了https网页是什么原因?
  7. 苹果cms v10 采集视频资源图片不显示加载慢修复方法
  8. mysql指定collation_MySql:charset和collation的设置
  9. Shader编程(一):水波浪
  10. jetson nano写入镜像系统