0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

从数据传输的角度理解Gadge框架

麦辣鸡腿堡 来源:嵌入式Linux系统开发 作者:嵌入式Linux系统开 2023-07-13 11:41 次阅读

5.1 使用流程

USB 协议中,永远是 Host 主动发起传输。作为一个 Gadget 驱动程序,它永远都是这样:

  • 想接收数据:
    • 先构造好 usb_request:分配 buffer、设置回调函数
    • 把 usb_request 放入队列
    • UDC 和 Host 完成 USB 传输,在 usb_request 中填充数据,并触发中断调用 usb_request 的回调函数
  • 想发送数据:
    • 先构造好 usb_request:分配 buffer、在 buffer 里填充数据、设置回调函数
    • 把 usb_request 放入队列
    • UDC 和 Host 完成 USB 传输,把 usb_request 的数据发给 Host,并触发中断调用 usb_request 的回调函数

5.2 endpoint 是核心

USB 传输的对象是 endpoint,使用流程如下:

  • 功能驱动里,通过 endpoint 描述符表明需要怎样的 endpoint,比如(注意:bEndpointAddress 是表明方向,里面还没有地址,driversusbgadgetfunctionf_loopback.c):

图片

  • 功能驱动里,它的 bind 函数根据 endpoint 描述符向底层申请分配 endpoint,比如:

图片

  • 功能驱动里,使能 endpoint,比如:

图片

  • 功能驱动里,给 endpoint 分配 buffer、设置 usb_request、提交 usb_request,比如:

图片

5.3 回调函数

功能驱动里构造的 usb_request,可以是接收 Host 发来的数据,也可以是向 Host 发送数据。当传输完成,usb_request 的回调函数被调用。

在回调函数里,可以再次提交 usb_request。

怎么调用到回调函数?源头是 UDC 的中断函数。

5.3.1 IMX6ULL

调用关系如下:

// Linux-4.9.88driversusbchipideacore.c
ci_irq
 /* Handle device/host interrupt */
 if (ci- >role != CI_ROLE_END)
  ret = ci_role(ci)- >irq(ci);  // udc_irq
   udc_irq
                if (USBi_UI  & intr)
                    isr_tr_complete_handler(ci);
                     err = isr_tr_complete_low(hwep);
                        usb_gadget_giveback_request(&hweptemp- >ep, &hwreq- >req);
                         req- >complete(ep, req);

5.3.2 STM32MP157

调用关系如下:

// Linux-5.4driversusbdwc2gadget.c
dwc2_hsotg_irq
  // 处理endpoint中断
  for (ep = 0; ep < hsotg- >num_of_eps && daint_out;
      ep++, daint_out > >= 1) {
   if (daint_out & 1)
    dwc2_hsotg_epint(hsotg, ep, 0);
     dwc2_hsotg_handle_outdone(hsotg, idx);
      dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result);
       usb_gadget_giveback_request(&hs_ep- >ep, &hs_req- >req);
        req- >complete(ep, req);
  }

  for (ep = 0; ep < hsotg- >num_of_eps  && daint_in;
      ep++, daint_in > >= 1) {
   if (daint_in & 1)
    dwc2_hsotg_epint(hsotg, ep, 1);
     dwc2_hsotg_complete_in(hsotg, hs_ep);
      dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
       usb_gadget_giveback_request(&hs_ep- >ep, &hs_req- >req);
        req- >complete(ep, req);
  }

5.4 f_loopback分析

loopback 就是回环,Host 发数据给 Gadget,然后再读 Gadget 就可以得到原样的数据。

5.4.1 Gadget接收数据

Host 选择某个配置时,默认会选择这个配置下那些接口的第 0 个设置(altsetting);

当 Host 发来 USB_REQ_SET_INTERFACE 请求时,可以选择指定的设置。

所以,我们从 f_loopback.c 的函数loopback_set_alt开始分析。

调用关系为:

loopback_set_alt
 enable_loopback
  result = enable_endpoint(cdev, loop, loop- >in_ep);
  
  result = enable_endpoint(cdev, loop, loop- >out_ep);
  
  result = alloc_requests(cdev, loop);

图片

如上图所示,先提交的是 out_req,它在等待 Host 发来数据。

假设断点 loop->out_ep 的 out_req 获得了数据,它的回调函数loopback_complete被调用,如下:

图片

5.4.2 Gadget 回环数据

图片

5.5 f_sourcesink 分析

前面的 f_loopback 也实现了两个方向的数据传输:Host 到 Gadget、Gadget 到 Host,但是它们之间是有依赖关系的,Host 必须先发送数据再读数据。

f_sourcesink.c 也实现了两个方向的数据传输:Host 到 Gadget、Gadget 到 Host,它们是独立的。

  • Host 读 Gadget:驱动程序里构造好数据,Host 可以读到,Gadget 作为源(source)
  • Host 写 Gadget:驱动程序里得到 Host 发来的数据,Gadget 作为目的(sink)

5.5.1 Host 写 Gadget

Host 选择某个配置时,默认会选择这个配置下那些接口的第 0 个设置(altsetting);

当 Host 发来 USB_REQ_SET_INTERFACE 请求时,可以选择指定的设置。

所为,我们从 f_sourcesink.c 的函数sourcesink_set_alt开始分析。

sourcesink_set_alt
 enable_source_sink(cdev, ss, alt);

图片

作为"source",函数source_sink_start_ep会构造数据、提交 usb_request:

图片

当 Host 读取到数据后,usb_request 的回调函数被调用,它只是再次提交 USB 请求,给 Host 继续提供跟上次一样的数据:

图片

5.5.2 Host 读 Gadget

仍然从 f_sourcesink.c 的函数sourcesink_set_alt开始分析。

sourcesink_set_alt
 enable_source_sink(cdev, ss, alt);

图片

作为"sink",函数source_sink_start_ep会故意把数据设置为 0x55(这是为了调试,当读到数据时可以看到 0x55 被覆盖)、提交 usb_request:

图片

当 Host 发来数据,usb_request 的回调函数被调用,它检查收到的数据,再次提交 usb_request:

图片

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5045

    文章

    18813

    浏览量

    298429
  • Linux
    +关注

    关注

    87

    文章

    11123

    浏览量

    207889
  • 框架
    +关注

    关注

    0

    文章

    396

    浏览量

    17263
收藏 人收藏

    评论

    相关推荐

    无线数据传输模块的实际应用

    随着无线数据传输技术的发展,无线传输模块的稳定可靠、安装简便、灵活性高等优势获得了广泛的应用,特别是在无线抄表、环境监测等方向,无线数据传输模块发挥着重要的传输
    发表于 06-18 04:21

    USART数据传输模型怎么理解

    亲爱的所有人,正如我所能检查到的,有三种不同的数据传输方式:a)使用逐字节模型-这用于一次传输一个字节;b)使用文件I/O类型读/写传输模型-应用程序调用USART驱动程序读/写例程通过USART
    发表于 04-23 13:56

    DMA进行数据传输和CPU进行数据传输的疑问

    求大佬解答,本人正在学习STM32单片机中DMA直接数据存储部分的内容 看了DMA简介后,也上手过实例代码,但是没有实际的项目经验,所以有以下疑问: DMA外设在进行数据传输的操作,是否也是需要经过
    发表于 05-25 17:18

    数据传输

    通信工程丛书--数据传输 这资料还是不错的,可供参考学习哦!
    发表于 03-25 00:53 29次下载

    数据传输介质

    2.5  数据传输介质      传输介质是通信网络中连接计算机的具体物理设备和数据传输物理通路。传输介质的特性包括物理描述
    发表于 06-27 21:47 0次下载

    什么是内部数据传输

    什么是内部数据传输率       数据传输率的单位一般采用MB/s或Mbit/s,尤其在内部数据传输率上官方数据中更多的采
    发表于 06-17 07:39 1601次阅读

    IDE数据传输模式

    IDE数据传输模式 随着技术的发展,产品对数据传输速度要求的提高,IDE接口硬盘的数
    发表于 12-25 14:58 397次阅读

    Modem数据传输标准

     Modem数据传输标准 数据传输标准是指MODEM的
    发表于 12-28 13:29 983次阅读

    RAID卡的数据传输速度

    RAID卡的数据传输速度              数据传输速度是指硬盘接口的传输速度。比如ATA100接口硬盘的
    发表于 01-09 10:47 2007次阅读

    数据传输,数据传输的工作方式有哪些?

    数据传输,数据传输的工作方式有哪些? 将数据从一个地方传输到另一个地方的方法多得令人难以置信。 数
    发表于 03-18 14:41 6002次阅读

    数据传输速率是什么意思

    数据传输速率是什么意思 数据传输速率是通过信道每秒可传输的数字信息量的量度。数据传输速率也称为吞吐率。数据传输速率由很
    发表于 03-18 14:45 4974次阅读

    tcp_ip 协议讲座:介绍数据传输

    介绍了tcp协议:数据传输的问题(交互式数据传输,批量数据传输,流量控制,拥塞避免)
    的头像 发表于 07-03 11:05 3341次阅读
    tcp_ip 协议讲座:介绍<b class='flag-5'>数据传输</b>

    多维度阐述数据传输方式分类

    数据传输方式是数据在信道上传送所采取的方式。若按数据传输的顺序可以分为并行传输和串行传输;若按数据传输
    的头像 发表于 03-24 11:04 1728次阅读

    硬件软件角度理解Gadget框架

    2. 硬件软件角度理解 Gadget 框架 USB 传输的核心是 endpoint,使用 endpoint 可以收发
    的头像 发表于 07-13 11:32 815次阅读
    <b class='flag-5'>从</b>硬件软件<b class='flag-5'>角度</b><b class='flag-5'>理解</b>Gadget<b class='flag-5'>框架</b>

    SPI数据传输有哪些方式

    SPI 数据传输可以有两种方式:同步方式和异步方式。 同步方式:数据传输的发起者必须等待本次传输的结束,期间不能做其它事情,用代码来解释就是,调用传输的函数后,直到
    的头像 发表于 07-25 10:54 4524次阅读
    SPI<b class='flag-5'>数据传输</b>有哪些方式