技术标签: LINUX篇
usb采用树形拓扑结构,可分为主机侧与设备侧,每一条USB总线上只有一个主机控制器,负责协调主机与设备之间的通讯,设备不能主动的向主机发送任何消息,如下图所示
如上图所示,从主机侧视角去看,在linux驱动中,usb驱动处于最上层,主要表现为usb主机侧的功能具体实现(比如U盘,鼠标,usb camer等),其下为usb核心层,主要完成usb驱动管理以及协议处理,再下为usb主机控制器,主要提供usb控制器的API,维护整个usb系统,完成设备的热插拔,总线传输控制等,最下为具体的USB硬件实现。
从从机侧看,linux的usb分为3个层次,udc,gadget api与gadget驱动,udc为直接访问硬件,控制usb与主机之间的底层通讯,上下层提供硬件相关的操作接口,gadget api主要完成对udc层的一些封装,适配于上层的gadget 驱动层的需求,最上层为gadget驱动层,主要完成设备的运用表现(网络打印,usb mass storage)等特性,gadget的存在主要是为了gadget将运用于底层的硬件操作进行隔离,是的gadget驱动层不需要关系udc层的具体实现。
还是口头叙述吧,懒得画图了,挺麻烦的 ~~ 哈哈哈 ~~~~~~
当主机检测到usb设备插入后,
上庙的设备描述符中,我们主要关心vid,pid,配置数目这三个参数,vid与pid在usb的driver中会进行table的对比,当匹配当table中有相对应的VID与PID参数后,才会执行driver->probe进行参数的相关处理。
这里主要关心接口的个数,在同一个配置下,可能存在很多的接口设备,所有这里的配置根据其下的接口描述符的个数进行修改。
这里主要关心端点数,接口类型,一个接口下可能会有多个端点,不同的断电对应不同的类型(短点0主要用于usb控制,所以我们的功能定制需要从短点1开始,比如端点1用于hid设备的out端口,端点2用于hid的in端口,端点3用于mass storage的out 端点,断点4用于mass storage的in端点,。。。),
自此,usb的枚举以及完成,主机会将usb的信息存储到driver->private数据接口,获取到的数据都存储到struct usb_interface中,在probe函数中将相关的信息提出出来,进行usb的core相关即可完成usb的枚举过程。
usb主控制器有三种规格,OHCI(open host controller interface),UHCI(universal host controller interface)和EHCI(enhanced host controller interface)。
嵌入式中常用的是OHCI,在主机侧,用hub_hcd来描述主机相关的相关信息,
usb_hcd主要描述了主机控制器的相关信息,同时usb_driver为控制usb主机的钩子函数(回调函数)。
usb从机可大概分为如下几个设备类、
1、音频设备类
2、通讯设备类
3、HID设备类
4、mass storage类
5、集线器设备类
usb的从机侧使用usb_Driver来描述一个从机usb设备驱动,数据结构如下、
在编写usb从机侧驱动时候,主要完成probe与diconnect函数,
probe函数的被调用如上枚举所言,只要当枚举到的VID与PID与我们驱动中的id_table成员中的相同,才会被执行,usb设备拔出后disconnect函数在设备被拔出时才会被执行。
urb(usb request block)为usb输出传输的载体,用于描述usb传输数据包的基本信息,结构体如下、
transfer_flags表示当前usb的状态,只有当该状态处于idle时,数据才能被submit到usb的ENDPOINT的queue中。
使用struct urb *usb_alloc_urb(int iso_pockets,int men_flags)来动态的分配一个urb资源。
iso_pockets表示分配的urb个数,为0则表示分配的urb是非实时性的,
usb_free_urb(struct urb *urb) 表示将分配的资源进行释放。
使用void usb_fill_int_urb(struct urb *urb,struct usb_device *dev,unsigned int pipe,void *transfer_buf,int buffer_length,usb_complete complete,void *context,int interval)来初始化中断urb,
urb表示需要初始化的urb的指针,dev表示需要发送这个urb的usb设备,pipe表示urb需要发送到的usb指定的端口(一般情况下使用usb_sndintpipe()或者usb_rcvintpipe()创建),transfer_buf是指向发送数据或者接受数据的缓冲区,buffer_len表示数据长度,complete表示传输完成之后需要执行的处理回调函数,xontext字面上是上下文(咱不理解),interval表示这个urb被调度的间隔。
使用int usb_submit_urb(struct urb *urb,int mem_flag)将urb的数据提交到usb的core层,注意,在complete没有没调用之前,不要再次submit urb
建议:关于usb的相关,内核中已经提供了一个很好的usb框架文件在drivers/usb/usb-skeleton.c
举个栗子:见下一篇 usb emulate camera device。
**~~~~~~~~~~~~~~~~~~~~~废话太多了,再见 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
文章浏览阅读7.2k次,点赞28次,收藏57次。背景Ambari是一个强大的大数据集群管理平台。在实际使用中,我们使用的大数据组件不会局限于官网提供的那些。如何在Ambari中集成进去其他组件呢?一、Ambari基本架构Ambari Server 会读取 Stack 和 Service 的配置文件。当用 Ambari 创建服务的时候,Ambari Server 传送 Stack 和 Service 的配置文件以及 Service 生命周期的控制脚本到 Ambari Agent。Agent 拿到配置文件后,会下载安装公共源里软件包(R._如何重写 ambari abstracttimelinemetricssink
文章浏览阅读402次。Write By Monkeyfly以下内容均为原创,如需转载请注明出处。该博客写于:2018年01月04日 11:46:52前提:今天在复习for循环的过程中,碰到这样一个问题——就是这个可恶的字符串的拼接问题,一直都看不懂,不知道到底是怎么实现的。中途看过好几次,每次都思考半天,最后还是没有看懂。话不多说,直接上代码:原始的p标签长这样:<p st..._javascript 字符串拼接异常
文章浏览阅读2.3k次,点赞3次,收藏2次。import java.math.*;import java.util.*;public class Main { public static void main(String[] args) { // TODO Auto-generated method stub char[] C = {'0','1','2','3','4'}; String A = new Str..._byte[]实例化
文章浏览阅读2.6k次。GRADLE_USER_HOME用法指南_gradle_user_home
文章浏览阅读2.7k次,点赞3次,收藏4次。最近,很多网友问我,怎么才能成为优秀的软件工程师,而不是优秀的码农?这个问题应该是最近这几年程序员的诉求了,估计每个程序员的理想都是做一个高大上的工程师,而不是只会Ctrl+C和Ctrl+V的码农。从我们踏入这个行业开始,我相信大多数人都是差不多的,都是学习编程基础,学习算法基础,学习各个大牛的骚操作,学习优秀框架或者项目中的各种写法等等。这个时候我们都是码农,是一个处于入门状态的程序员。当..._希望成为一名优秀的软件工程师?还是成为一名优秀的程序员?
文章浏览阅读4.4k次,点赞2次,收藏28次。目前,世界各主要军事大国的军事装备信息化的步伐明显加快。而在信息复杂多样且多变的现代战争背景下,不仅军用仿真技术作为未来战争至关重要的一环节,信息更成为了胜负的决定因素,战场信息融合技术至关重要。只有依靠完备的信息融合有效感知战场态势,才能及时准确地判断战场动态、威胁估计以及作战效能等关键信息,最大程度支撑有效决策。_万象视景
文章浏览阅读2.9w次,点赞25次,收藏55次。[EndNote]关于导入CAJ文献 EndNote在导入一些PDF格式的文献时,有时会发生不能自动填充信息的情况。这种情况产生的原因是EndNote在这篇PDF格式文献当中,不能查询到DOI。 对于中国知网上面的学位论文,先不必说EndNote导入中文文献时对文献信息的识别能力不足,单就学位论文的CAJ格式,就能给导入工作带来一些头疼的问题。注意:以下过程是在校_endnote为啥导入不了caj
文章浏览阅读1.5w次,点赞16次,收藏120次。小程序是运行在微信环境中,而网页是运行在浏览器环境中。由于运行环境不同,所以小程序中,无法调用DOM和BOM的API。但是,小程序中可以调用微信环境提供的各种API,例如地理定位,扫码,支付。网页的开发模式:浏览器+代码编辑器。而小程序有自己的一套标准开发模式:登录网址https://mp.weixin.qq.com/,注册一个个人的账号,填写好相关的信息,我们的账号就注册好了。获取小程序的APPID。在上边的网址完成注册以后,我们在页面中可以找到我们的小程序的APPID展示在如图所示的位置。微信_小程序别人把我加入开发者模式
文章浏览阅读5.4k次,点赞2次,收藏10次。 内容主要来自官方手册pg252-vcu。 vcu的逻辑电路还是还是很好理解,以下只记录觉得重要的部分。 1.添加Zynq UltraScale+ VCU IP以及Zynq UltraScale+ MPSoC到block design。 2.选择PL1 clock频率为333MHz,使能中断以及4个PS-PL从接口AXI HP。 3.剩下的连接如下图值得注意的是pll..._vcu 参考时钟
文章浏览阅读1.2w次,点赞4次,收藏13次。1.引入unity的 classes.jar包 本人安装unity-5.6.1版本,目录为D:\Program Files\unity-561\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar 若直接将classes.jar导入AndroidSt..._com/unity3d/player/unityplayer
文章浏览阅读5.3k次。动画控件 Windows 95支持一种动画控件(Animate control),动画控件可以播放AVI格式的动画片(AVI Clip),动画片可以来自一个AVI文件,也可以来自资源中。合理地使用动画控件,可以使程序的界面更加形象生动。11.5.1 动画控件的使用MFC的CAnimateCtrl类封装了动画控件,该类的Create成员函数负责创建动画控件,其声明为:BOO_mfcanimation control
文章浏览阅读1.1k次。在 Linux 中运行后台进程运行有很多方法,例如 nohup,screen 等。但如果想要可靠地在后台运行一个服务程序,就需要把它做成 daemon,最好还能监控进程状态,在意外结束时能自动重启。supervisor 就是用 Python 开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。一、安装以 CentOS 为例。先安装 easy-installyum install python-setuptools然后用 easy-i_unix:///usr/local/supervisor/tmp/supervisor.sock refused connection