小明哥学linux驱动之USB-OTG(基于gadget框架)

一、简介

OTG是On-The-Go的缩写。其设计的初衷是为了两个“外设”在没有PC(Host)的情况下,也可以通过USB进行数据传输。可以理解为,拥有OTG功能的USB设备(OTG设备)既可以做host,也可以做peripheral。

二、OTG基本结构

2.1 OTG硬件结构

一个完整的OTG连接由A-device和B-device组成。A设备(Micro-A)默认作为Host并供电,B设备(Micro-B)默认作为peripheral,B设备可以通过HNP协议进行协商,使自己成为Host。

OTG比普通USB接口多了一条USB_OTG_ID连线。Micro-A插座的USB_OTG_ID接地,而Micro-B插座的USB_OTG_ID悬空。如图所示。

2.2 OTG连接方式

2.2.1 OTG设备和host连接

在这种情况下,OTG设备和PC或嵌入式主机连接。此时,OTG设备满足标准USB外设的所有要求。当OTG设备连接到PC或嵌入式主机时,主机枚举OTG设备并将其视为外围设备。

2.2.2 OTG设备和peripheral连接

在这种情况下, OTG设备作host(A-Device),外接一个peripheral设备(B-Device)。当OTG设备检测到设备已连接时,OTG设备枚举peripheral设备.

2.2.3 OTG设备和OTG设备连接

在这种情况下,默认host(A-Device)首先枚举peripheral(B-Device)。然后user可以控制选择A-Device或B-Device哪个作host。比如,连接carplay时,iphone为B-Device作host;而A-Device需将状态切花挪威peripheral。

2.3 OTG支持协议

OTG支持HNP协议,SRP协议。

2.3.1 HNP协议

HNP(即主机协商协议),实现在不调换Micro-A和Micro-B插座的情况下,Host和Peripheral两种角色在A-Device和B-Device上相互切换;

无论A-device扮演host还是peripheral角色,均由A-device向USB接口供电;

系统初始化,应将A-device默认设置为host。当B设备写入b_bus_req,向A设备发起HNP请求。待A设备响应之后,A设备发送a_set_b_hnp_en,B设备响应之后即进入主机状态,同时发送请求使用A设备set_device,这样A、B设备完成主从交换。

2.3.2 SRP协议

A-device在总线空闲时关闭总线。当一个B-device想要工作时,可向A-device请求开启总线。

A-Device时序图如下

B-Device时序图如下

三、OTG状态机

3.1 OTG状态机状态简介

OTG-A-device状态迁移图如图所示。

OTG-B-device状态迁移图如图所示。

以A-Device为例,主要otg_machine_status如下表所示。

a_idle

A-device starting state

a_wait_vrise

Wait for VBUS to go into regulation

a_wait_bcon

Wait for B-device to signal connection

a_host

Acting as a host

a_suspend

Bus suspend

a_peripheral

Acting as a peripheral

a_wait_vfall

Wait for VBUS to drop to VOTG_VBUS_LKG

a_vbus_err

Wait for recovery from over-current condition

状态机主要输入状态

★id :A-Device为0,否则是B-Device为1。

The identification (id) input is FALSE when a Micro-A plug is inserted in the device’s Micro-AB receptacle. Otherwise, this input is TRUE.

★a_bus_drop :A-Device放弃总线时为1,此时a_bus_req必须为0。

The “A-device bus drop” (a_bus_drop) input is TRUE when the Application running on the A-device wants to power down the bus, and is FALSE otherwise. When this input is TRUE, then the a_bus_req input shall be FALSE.

★a_bus_req   :A-Device申请总线时为1。

The “A-device bus request” (a_bus_req) input is TRUE during the time that the Application running on the A-device wants to use the bus, and is FALSE when the Application no longer wants to use the bus. a_bus_req can also be set to TRUE in response to remote wakeup signaling from the B-device should the A-device decide to resume the bus.

……

3.2 OTG状态机切换流程(A-Device

★启动时,状态机的正确切换流程如下:

(START)->(a_idle)->(a_wait_vrise)->(a_wait_bcon)

 

★连接仅peripheral的B-Device,状态机的正确切换流程如下:

(a_wait_bcon)->(a_host)

拔出仅peripheral的B-Device,状态机的正确切换流程如下:

(a_host)->(a_wait_bcon)

 

★插入OTG B-Device,状态机的正确切换流程如下(A-Device为peripheral):

(a_wait_bcon)->(a_host)->(a_suspend)->(a_peripheral)

拔出OTG B-Device,状态机的正确切换流程如下:

(a_peripheral)->(a_wait_bcon)

四、代码分析

OTG代码主要分为硬件层,驱动层和功能层。

硬件层主要source文件:udc.c, host.c

驱动层主要source文件:core.c

功能层主要source文件:otg.c, otg_fsm.c, usb-otg-fsm.c

OTG注册流程图如下

OTG中断处理流程图如下

SRP协议流程图如下

HNP协议流程图如下

附录

SRP

In order to conserve power, an A-device is allowed to leave VBUS turned off when the bus is not being used. The Session Request Protocol (SRP) allows a B-device to request the A-device to turn on the power supply to the USB interface (VBUS) and start a session. A session is defined as the period of time that VBUS is powered. The session ends when VBUS is no longer powered.

 

HNP

The Host Negotiation Protocol (HNP) allows the host function to be transferred between two directly connected OTG devices and eliminates the need for a user to switch the cable connections in order to allow a change in control of communications between the devices. HNP will typically be initiated in response to input from the user or an Application on the OTG B-device. HNP may only be implemented through the Micro-AB receptacle on a device. The A-device is always responsible for powering the USB interface regardless of whether it is acting in host or peripheral role3.

At the start of a session, the A-device defaults to having the role of host. During a session, the role of host can be transferred back and forth between the A-device and the B-device any number of times, using HNP.

### 回答1: Linux USB gadget驱动编写有如下几个步骤: 1. 确定USB gadget功能:首先需要确定所需实现的USB gadget功能,例如以USB设备的形式提供存储、网络、音频等服务。这样可以决定需要实现的USB gadget驱动类型和功能。 2. 编写USB驱动框架:基于Linux内核框架,编写USB gadget驱动的基本框架。这包括注册USB gadget驱动和常用的函数接口等。 3. 实现USB gadget子系统:根据所需的功能,实现USB gadget子系统的模块,如存储、网络或音频子系统等。这些子系统需要封装底层的USB通信协议和数据传输,供应用程序调用。 4. 配置USB gadget驱动:根据具体需求,在系统配置文件中进行必要的配置,以启用和配置USB gadget驱动。这包括配置端点、描述符和功能等。 5. 移植和编译:将驱动程序编译成内核模块,然后将其移植到目标设备上。对于嵌入式设备,可能需要修改硬件相关的代码,以适应硬件平台。 6. 测试和调试:编写测试用例,对USB gadget驱动进行测试和调试,确保其正常工作。这包括对设备和主机之间的数据传输进行验证,以及处理异常情况和错误处理。 总之,编写Linux USB gadget驱动需要明确所需实现的功能、基于内核框架编写驱动框架、实现USB gadget子系统、配置以及移植和编译。最后进行测试和调试,确保驱动程序的正常运行。通过以上步骤,可以实现各种USB设备功能的驱动。 ### 回答2: Linux USB gadget驱动是用于实现USB设备的功能的驱动程序。它使得Linux设备可以作为一个USB设备与其他主机进行通信。在编写Linux USB gadget驱动时,需要完成以下几个步骤。 首先,需要确定设备的功能和属性。USB设备可以有多种功能,如储存设备、键盘、鼠标等。根据设备的类型和规格,确定设备的操作和数据传输方式。 其次,在驱动程序中定义设备的USB描述符。USB描述符包括设备描述符、接口描述符和端点描述符等,它们是USB协议的一部分,用于描述设备的属性和功能。 然后,在驱动程序中实现设备的相关功能。根据设备的类型和规格,编写相应的功能代码。例如,如果设备是一个键盘,就需要实现按键事件的处理逻辑;如果设备是一个储存设备,就需要实现读写数据的逻辑。 最后,编译和加载驱动程序。使用Linux内核提供的工具链,将驱动程序编译为可执行文件,并将其加载到Linux内核中运行。加载驱动程序后,系统即可识别设备,并根据驱动程序中定义的功能和属性来处理设备的操作和数据传输。 总之,编写Linux USB gadget驱动需要确定设备的功能和属性、定义USB描述符、实现设备的相关功能,最后编译和加载驱动程序。通过这些步骤,我们可以在Linux系统中实现USB设备的功能。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值