最近工作突然有了很大的变动,导致工作比较繁忙。接手新业务,从零开始研究USB。简单分享一下,一些不成熟的看法。

1. 背景

由于公司新的芯片内核进行了大版本升级,需要将原有的uvc驱动(设备端驱动,包括uvc、uac、hid、adb)适配新版本的内核之上,并在新的芯片上跑通。

需求:从3.14 内核,适配到4.4.94内核。打通整个uvc驱动通路,host 端能成功枚举设备,并正常出视频和放音。

问题:0 USB 经验(或者说少量经验)、对uvc、uac、hid协议一窍不通。

那么我是如何在一周内,在毫无usb经验情况下,打通uvc设备端通信的?

2. 我是如何做的?

2.1 分析优缺点

优点:有旧有驱动示例,至少协议这块的配置无需多虑,只需要关注框架和流程的差异;有内核源码借鉴;有其他懂 usb 的同事。

缺点:不懂usb、或者说研究的不深;4.x的内核相比3.x的内核在 usb gadget 驱动结构上有些许差异,不能完全照搬。

2.2 虚心请教

接手这个任务的第一件事情,就是咨询公司懂 usb 的同事,让其推荐 usb 相关的资料。然后花了一天时间学习usb的基础知识,包括uvc协议简单了解。对 usb 先有一个浅显的认识。

2.3 检索

紧接着,又花了1~2天,去国内外查询 uvc 相关知识,包括但不限于知乎、B站、微信公众号、博客、github、StackOverflow等。梳理USB 驱动框架,包括hdc、udc、gadget 和 compsite等。

2.4 阅读源码

Linus 有一句治理名言,RTFSC(Read The Fucking Source Code),读那该死的代码。

事实上内核代码都给出了具体的答案,只不过有些时候,默认驱动可能比较简单。比如内核g_webcam模块,就是一个简单的uvc设备,只不过不带uac以及其他复合功能。

当然内核里面也有hid、adb、uvc等驱动。我们只需要读懂了,并稍加修改即可完工。

故而又花了一天时间研究新旧内核usb gadget 驱动框架的流程,以及差异。只有搞懂了流程,才能修改。

2.5 写代码

其实真正写代码的时间反而不多。搞懂了新版内核 gadget 驱动差异后,改起来就方便了。花了一天时间写代码,把 uvc 功能跑通 。跑通一个后面,再加adb、hid、uac就容易多了。

3. 总结

本文主要分析自己接触新东西调试过程的经验分享,给大家提供一些思路,仅供参考。

此方法只适用于快速上手,如果想要深入,后续得继续把USB整个体系的知识逐渐架起来。 这里需要注意几点:


  • 【先整体,后局部】。先抓整体框架脉络,忽略细节。具体到工作中,先快速跑通,然后再工作中边做,边深入。如果一开始就陷入usb协议中,会使整个周期拉长;
  • 重视前人经验。虚心请教,可以少走不少弯路。
  • 善于归纳总结。能够从海量的资源中,吸收对自己有用的东西。
  • 【阅读源码】。接触一个新的东西,最好的学习方式就是直接阅读其源码,从源码中学习。


我是如何快速上手新任务的?_知乎