uboot usb设备驱动
文章目录
- DTS中定义
- usb driver
- bind
- fastboot
- fastboot命令处理
- fastboot触发
介绍usb device设备驱动
uboot在init_dm中会扫描dtb和代码中driver进行匹配,匹配成功就调用driver驱动进行bind
以dwc3为例进行介绍
DTS中定义
usb0: usb0@ff9d0000 {#address-cells = <2>;#size-cells = <2>;status = "disabled";compatible = "xlnx,zynqmp-dwc3"; //匹配的compatible reg = <0x0 0xff9d0000 0x0 0x100>;clock-names = "bus_clk", "ref_clk";power-domains = <&pd_usb0>;ranges;nvmem-cells = <&soc_revision>;nvmem-cell-names = "soc_revision";dwc3_0: dwc3@fe200000 {compatible = "snps,dwc3";status = "disabled";reg = <0x0 0xfe200000 0x0 0x40000>;interrupt-parent = <&gic>;interrupts = <0 65 4>, <0 69 4>;#stream-id-cells = <1>;iommus = <&smmu 0x860>;snps,quirk-frame-length-adjustment = <0x20>;snps,refclk_fladj;snps,enable_guctl1_resume_quirk;snps,enable_guctl1_ipd_quirk;snps,xhci-stream-quirk;/* dma-coherent; */};
};usb1: usb1@ff9e0000 {#address-cells = <2>;#size-cells = <2>;status = "disabled";compatible = "xlnx,zynqmp-dwc3";reg = <0x0 0xff9e0000 0x0 0x100>;clock-names = "bus_clk", "ref_clk";power-domains = <&pd_usb1>;ranges;nvmem-cells = <&soc_revision>;nvmem-cell-names = "soc_revision";dwc3_1: dwc3@fe300000 {compatible = "snps,dwc3";status = "disabled";reg = <0x0 0xfe300000 0x0 0x40000>;interrupt-parent = <&gic>;interrupts = <0 70 4>, <0 74 4>;#stream-id-cells = <1>;iommus = <&smmu 0x861>;snps,quirk-frame-length-adjustment = <0x20>;snps,refclk_fladj;snps,enable_guctl1_resume_quirk;snps,enable_guctl1_ipd_quirk;snps,xhci-stream-quirk;/* dma-coherent; */};
};
usb driver
drivers\usb\dwc3\dwc3-generic.c
用于match的compatible
static const struct udevice_id dwc3_generic_ids[] = {{ .compatible = "xlnx,zynqmp-dwc3" },{ }
};定义了driver
U_BOOT_DRIVER(dwc3_generic_wrapper) = {.name = "dwc3-generic-wrapper",.id = UCLASS_MISC,.of_match = dwc3_generic_ids,.bind = dwc3_generic_bind,
};
bind
compatible = “xlnx,zynqmp-dwc3” ,dts和driver匹配成功,定义driver->bind,即dwc3_generic_bind
static int dwc3_generic_bind(struct udevice *parent)
{const void *fdt = gd->fdt_blob;int node;int ret;遍历dts中usb device,一个soc可能包含多个usb控制器for (node = fdt_first_subnode(fdt, parent->of_offset); node > 0;node = fdt_next_subnode(fdt, node)) {const char *name = fdt_get_name(fdt, node, NULL);enum usb_dr_mode dr_mode;struct udevice *dev;debug("%s: subnode name: %s\n", __func__, name);if (strncmp(name, "dwc3@", 4))continue;dr_mode = usb_get_dr_mode(node);//usb 控制器模式,device模式或主机模式switch (dr_mode) {case USB_DR_MODE_PERIPHERAL://device模式case USB_DR_MODE_OTG://otg模式//进一步进行device和driver匹配,驱动name为 "dwc3-generic-peripheral",ret = device_bind_driver_to_node(parent,"dwc3-generic-peripheral",name, node, &dev);break;case USB_DR_MODE_HOST:debug("%s: dr_mode: HOST\n", __func__);ret = device_bind_driver_to_node(parent,"dwc3-generic-host",name, node, &dev);break;default:break;};}return 0;
}
device_bind_driver_to_node–》device_bind–》device_bind_common:匹配了device和驱动,调用uclass-bind和driver bind。
"dwc3-generic-peripheral"驱动
U_BOOT_DRIVER(dwc3_generic_peripheral) = {.name = "dwc3-generic-peripheral",.id = UCLASS_USB_DEV_GENERIC,.ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata,.probe = dwc3_generic_peripheral_probe,.remove = dwc3_generic_peripheral_remove,.bind = dwc3_generic_peripheral_bind,.platdata_auto_alloc_size = sizeof(struct usb_platdata),.priv_auto_alloc_size = sizeof(struct dwc3),.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
dwc3_generic_peripheral_bind–》device_probe–》dev->drv->probe》dwc3_generic_peripheral_probe
调用了dwc3_generic_peripheral_probe–》dwc3_init进行dwc3初始化
–》dwc3_core_init_mode–》dwc3_gadget_init–》usb_add_gadget_udc
初始了gadget功能,并向udc core注册。
具体初始化过程不再描述。
完成了底层usb device和驱动初始化,上层抽象功能在进行初始化,比如,网络,鼠标等等。
fastboot
以fastboot为例,分析function驱动初始注册。
f_fastboot.c
DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add);
声明定义了g_dnl_bind_callback 结构的fastboot function功能。
/** @usb_fname: unescaped USB function name* @callback_ptr: bind callback, one per function name*/
#define DECLARE_GADGET_BIND_CALLBACK(usb_fname, callback_ptr) \ll_entry_declare(struct g_dnl_bind_callback, \__usb_function_name_##usb_fname, \g_dnl_bind_callbacks) = { \.usb_function_name = #usb_fname, \.fptr = callback_ptr \}typedef int (*g_dnl_bind_callback_f)(struct usb_configuration *);/* used in Gadget downloader callback linker list */
struct g_dnl_bind_callback {const char *usb_function_name;g_dnl_bind_callback_f fptr;
};
do_fastboot中调用注册了fastboot驱动,
do_fastboot--》g_dnl_register("usb_dnl_fastboot");--》
g_dnl_driver.name = name;
usb_composite_register(&g_dnl_driver);--》
composite = driver;
usb_gadget_register_driver(&composite_driver);
--》usb_gadget_probe_driver
找到一个udc,前面usb初始化已经向usb core注册了udc
list_for_each_entry(udc, &udc_list, list) {/* For now we take the first one */if (!udc->driver)goto found;}ret = udc_bind_to_driver(udc, driver);---》driver->bind(udc->gadget); 回调g_dnl_bindusb_gadget_udc_start(udc); 开启usb func功能,触发usb device和usb host交互usb_gadget_connect(udc->gadget);
g_dnl_bind–》g_dnl_config_register
一些usb 设备的configconfig->label = name;config->bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER;config->bConfigurationValue = CONFIGURATION_NUMBER;config->iConfiguration = STRING_USBDOWN;config->bind = g_dnl_do_config;
usb_add_config--》config->bind(config);--》 g_dnl_do_config
static int g_dnl_do_config(struct usb_configuration *c)
{const char *s = c->cdev->driver->name;struct g_dnl_bind_callback *callback = g_dnl_bind_callback_first();for (; callback != g_dnl_bind_callback_end(); callback++)if (!strcmp(s, callback->usb_function_name))return callback->fptr(c); //回调所有dnl类型的function功能return -ENODEV;
}
--》fastboot_add进行functiong功能注册
以上过程就是function对应设备接口,配置和端点注册过程
static inline int usb_gadget_udc_start(struct usb_udc *udc)
{return udc->gadget->ops->udc_start(udc->gadget, udc->driver);
}
fastboot_add功能添加
static int fastboot_add(struct usb_configuration *c)
{struct f_fastboot *f_fb = fastboot_func;int status;debug("%s: cdev: 0x%p\n", __func__, c->cdev);if (!f_fb) {f_fb = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_fb));if (!f_fb)return -ENOMEM;fastboot_func = f_fb;memset(f_fb, 0, sizeof(*f_fb));}f_fb->usb_function.name = "f_fastboot";f_fb->usb_function.bind = fastboot_bind;f_fb->usb_function.unbind = fastboot_unbind;f_fb->usb_function.set_alt = fastboot_set_alt;f_fb->usb_function.disable = fastboot_disable;f_fb->usb_function.strings = fastboot_strings;status = usb_add_function(c, &f_fb->usb_function);return status;
}
在接口配置设置时回调f_fb->usb_function.set_alt = fastboot_set_alt;
fastboot_set_alt中配置了端点回调函数,并且使能了端点。
f_fb->out_req->complete = rx_handler_command; 从host接收到usb包,回调函数
f_fb->in_req->complete = fastboot_complete; 发送一个usb包,回调函数
fastboot命令处理
rx_handler_command中解析接收到usb数据,并匹配是否含有定义的fastboot协议命令
static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
{char *cmdbuf = req->buf;void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL;int i;匹配命令for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) {if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) {func_cb = cmd_dispatch_info[i].cb;break;}}if (req->actual < req->length) {u8 *buf = (u8 *)req->buf;buf[req->actual] = 0;func_cb(ep, req); //处理命令}*cmdbuf = '\0';req->actual = 0;usb_ep_queue(ep, req, 0);
}
static const struct cmd_dispatch_info cmd_dispatch_info[] = {{.cmd = "reboot",.cb = cb_reboot,}, {.cmd = "getvar:",.cb = cb_getvar,}, {.cmd = "download:",.cb = cb_download,}, {.cmd = "boot",.cb = cb_boot,}, {.cmd = "continue",.cb = cb_continue,},
#ifdef CONFIG_FASTBOOT_FLASH{.cmd = "flash",.cb = cb_flash,}, {.cmd = "erase",.cb = cb_erase,},
#endif{.cmd = "oem",.cb = cb_oem,},
};
fastboot触发
上一节分析了fastboot功能的注册。
命令fastboot触发fastboot功能进行初始化注册,并继续后续处理。
U_BOOT_CMD(fastboot, 2, 1, do_fastboot,"use USB Fastboot protocol","<USB_controller>\n"" - run as a fastboot usb device"
);
static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{int controller_index;char *usb_controller;int ret;if (argc < 2)return CMD_RET_USAGE;usb_controller = argv[1];controller_index = simple_strtoul(usb_controller, NULL, 0);ret = board_usb_init(controller_index, USB_INIT_DEVICE);if (ret) {error("USB init failed: %d", ret);return CMD_RET_FAILURE;}g_dnl_clear_detach();ret = g_dnl_register("usb_dnl_fastboot");if (ret)return ret;if (!g_dnl_board_usb_cable_connected()) {puts("\rUSB cable not detected.\n" \"Command exit.\n");ret = CMD_RET_FAILURE;goto exit;}前面注册usb fastboot驱动下面是和host交互命令处理while (1) {if (g_dnl_detach())break;if (ctrlc())break;usb_gadget_handle_interrupts(controller_index); 中断处理,处理event buf,回调上面的out_req->complete和in_req->complete}ret = CMD_RET_SUCCESS;return ret;
}
uboot usb设备驱动相关推荐
- Linux USB设备驱动程序设计 和 USB下载线驱动设计
Linux USB设备驱动程序设计 和 USB下载线驱动设计 USB设备驱动模型 USB设备包括配置(configuration).接口(interface)和端点(endpoint),一个USB设备 ...
- usb linux 内核,Linux内核USB驱动架构:USB设备驱动架构.pdf
USB 设备驱动架构 LK 版本:2.6.35.3 2013 年1 月14 日 任务目标: 分析整理插入一个USB 设备的处理过程. USB 设备.配置.接口.设置以及端点的五者关系图: 一个 ...
- usb设备驱动之uvc设备
usb设备驱动之uvc设备 声明:涉及相关内容包括v4l2框架/drivers/media/v4l2-core/,usb设备控制器驱动/drivers/usb/dwc3/,usb composite驱 ...
- 浅谈Linux USB设备驱动
1.USB基础介绍 1-1.USB硬件接口介绍 USB接口在硬件上总共有四根线组成VCC.D+.D-.GND,通过计算D+和D-的差值来确定数据.USB设备在传输速率上可以分为低速(1.5Mbps). ...
- WDF开发USB设备驱动教程(2)
PDF全文下载:http://bbs.driverdevelop.com/read.php?tid-120461.html 3.2 获取描述符 上一小节认识了USB 的描述符后,这一节就来讲如何从 U ...
- WDF开发USB设备驱动教程(1)
PDF下载地址(1.2版):链接地址 CY001开发板讨论帖:链接地址 注:本文档新版本已出,请在博客中查找,或下载PDF全文文档. 链接地址WDF开发USB设备驱动教程 by 张佩 文档说明 作者写 ...
- Linux设备驱动之usb设备驱动详解
原文地址:http://blog.csdn.net/chenjin_zhong/article/details/6329316 1.Linux usb设备驱动框架 USB是通用串行总线的总称,Linu ...
- 第八章 USB 设备驱动移植
8.1 USB协议 USB协议系统主要组成,总线拓扑结构,内部层次关系,数据流模式,USB调度等等 8.1.1 主要组成部分 USB的连接部分,USB的 ...
- windows 7 出现MTP usb设备驱动安装问题解决方法
连接电脑提示MTP USB设备驱动失败,网上搜到了解决方案: http://11643599.blog.hexun.com/61703464_d.html 这个设备是用来同步媒体的,windows m ...
最新文章
- ​rsync应用拓展多模块同步13
- 软件分享:将应用一键打包成dmg文件
- boost::mp11::mp_fill相关用法的测试程序
- RUNOOB python练习题 35 python print各色字体及背景
- Oracle基础语句
- TFS Training for Kunlun bank (http://www.klb.cn/) 微软研发流程(ALM)管理培训会议(昆仑银行) 2016.09.21...
- 用c语言写三个人打鱼问题,用c语言解决三天打鱼,两天晒网的问题要用到什么函数...
- 【es】使用ElasticSearch的44条建议 性能优化
- flask 上传excel 前端_flask 笔记
- 微软VC/MFC FAQ(转)
- 何时该开始写测试代码
- Kconfig中select与depends on原理
- 什么是通配符 计算机网络,通配符
- 会计做什么副业好?分享几个适合会计的副业
- 【日记本砸】21.06.11-20 复杂的式子和角标只是一个符号一个标记而已
- 《程序员修炼之道:从小工到专家》读书笔记
- C3D:视频动作分类demo实现
- 我的世界服务器物品栏变小了,我的世界如何改变物品大小 | 手游网游页游攻略大全...
- 二代测序linux软件,二代测序数据分析软件包大全
- DELPHI学习笔记1