OTG中的ID脚风波释疑

原文:http://my.oschina.net/u/130864/blog/15322    Weike的博客

 

1. 概要
OTG设备使用插头中的ID引脚来区分A/B Device,ID接地被称作为A-Device,充当USB Host,A-Device始终为总线  提供电力,ID悬空被称作为B-Device,充当USB Device,设备的USB Host/USB Device角色可以通过HNP(主机交换  协议)切换。OTG设备连接时不能跨越USB Hub,如果跨越USB Hub则失去HNP功能。A-Device/B-Device与USB  Host/Device没有必然的关系,主机切换完毕后A-Device变成USB从设备,但是仍然为总线供电。

2.USB-OTG插槽类型

As Host Only :提供标准的A插座,普通的USB Host并带有TPL(支持设备列表)

As Device Only:仅能作为外设的B-Device(分为插头一体和插头线缆分离的)

OTG Dual      :使用Micro AB插座,可以在运行时切换Host/Device。

OTG Dual  在插头插入后会先打开VBus,如果没有设备连接则关闭VBus,并开启ADP侦测,而EAs Host Only 则  不会再次关闭VBus
3.协议
SRP(Session Request Protocol)对话请求协议: 
SRP协议允许Adevice在总线为使用时通过切断VBUS来节省电源消耗,任何一类Adevice都应该能够响应SRP请求,任何Bdevice也应该能够发起SRP请求,
ADP(Attach Detection Protocol): 
提供是否有对端设备插入的检测,支持任何OTG设备
HNP(Host Negotiation Protocol)主机交换协议: 
OTG设备通过HNP来切换Host/Device角色,Adevice通过查询Bdevice的OTG性能描述符来判断是否支持HNP协议,以判断Bdevice是否为两用的OTG设备,如果Bdevice支持HNP协议,Bdevice将会返回有效的OTG性能描述符,随后Adevice产生一个SetFeature命令告知Bdevice:你可以在总线挂起时以主机的方式工作,Adevice发送了这个SetFeature命令后挂起总线,  本次Session结束后Host回到Adevice手里。
4.设备框架
OTG描述符
在设备枚举时,A-Device通过GetDeor向B设备请求OTG描述符。OTG描述符也应当作为GetConfiguration()的一部分返回。其中的bmAttributes标示B-Device是否支持ADP/HNP/SRP
标准设备特性,通过SetFeature()设置。
b_hnp_enable 
设置此特性,显示B-Device被允许进行HNP,A设备必须在T(HOST_REQ_SUSP)时间内挂起总线,此特性在session结束时清除。
a_hnp_support
早期OTG版本的兼容特性,设置这个特性指示B-Device对端的A-Device支持HNP。
a_alt_hnp_support 
该标志已被废弃
5.连接方式(Host -> Device)
As Host Only 与 仅作为外设的B-device(带A插头型)
Host端检测到A插头插入,停止ADP,打开VBus,因为B-Device的A插头与设备作为一体,此时B-Device必定与A插头连接,Host检测到外设连接,开始枚举。 
As Host Only 与 仅作为外设的B-device(A插头为线缆连接)
Host段检测到A插头插入,停止ADP,打开VBus,如果B-Device是线缆连接完毕在将A插头插入则整个连接过程与上面无异,因为此 时B-Device可能还没有插入插头,则设备连接超时,VBus再次关闭,等待下一次ADP的改变(线缆连接完毕),再次打开VBus,此时开始正常总 线枚举。
OTG Device 与 OTG Device
Host端检测到插头插入,则打开VBus,如果没有外设检测到,则关闭VBus,打开ADP Probing,Device端检测到插头插入,则打开SRP,如果线缆没有插入,则SRP超时,Device端开始进行ADP Probing,当线缆连接完毕,Device端侦测到ADP变化,发送SRP请求Host打开VBus,Host回应SRP并且打开VBus,完成设备连接。
6.案例分析:
有客户反馈他们的样机OTG mrio AB插座不能识别U盘,最后查出的原因是客户样机的USB的ID脚没有接地,
样机没有切换到USB HOST模式。

 

<think>我们正在解决一个安卓9设备上开启ADB调试后导致OTG无法识别U盘的问题。根据用户提供的信息和之前的引用,我们可以从几个方面进行排查: 引用[2]和引用[4]中提到,USB控制器的工作模式(dr_mode)配置可能影响设备识别。在引用[2]中,RK3568设备将dr_mode从"otg"改为"host"后解决了U盘识别问题。引用[4]则提到当设备作为设备模式时,VBUS和ID的电压异常导致无法识别U盘,并修改了dts中usb的供电。 另外,引用[1]提到adb设备识别问题可能与usb id有关,但当前问题不是adb设备无法识别,而是开启ADB后OTG功能失效(不识别U盘),所以重点应放在USB工作模式和供电上。 因此,我们推测问题可能出在: 1. USB控制器的模式设置(dr_mode)不正确,导致开启ADB后设备进入设备模式(作为adb设备连接电脑)而无法作为主机识别U盘。 2. USB供电异常,导致连接U盘时无法提供足够的电压。 解决方案步骤(需要root权限和内核源码支持,因为可能涉及修改设备树): 步骤1:检查当前USB控制器的工作模式 在Android设备上,通过adb shell(或终端)执行以下命令查看当前USB控制器的工作模式(需要root): ```bash su cat /sys/kernel/debug/usb/*/dr_mode ``` 或者查看dmesg日志: ```bash dmesg | grep dr_mode ``` 注意:路径可能因设备而异,需要根据实际情况调整。 步骤2:修改设备树(dts)中的USB控制器配置 如果发现dr_mode被设置为"otg"或"peripheral",而我们需要作为主机使用(连接U盘),则应改为"host"。但注意,开启ADB调试时,设备通常需要作为设备(peripheral)模式连接电脑,所以这里可能存在冲突。 引用[2]的解决方案是直接修改dts文件,将dr_mode从"otg"改为"host"。但这样修改后,设备将无法作为从设备连接电脑(即无法使用有线ADB)。因此,如果用户需要同时使用ADB调试(无线ADB)和OTG功能,我们可以考虑以下方案: 方案A:使用无线ADB,并将USB控制器永久设置为host模式(这样OTG可以正常工作,而有线ADB将不可用,符合用户之前的要求:保留无线ADB,关闭有线ADB)。 方案B:动态切换模式(需要内核支持),当连接U盘时切换到host模式,当连接电脑时切换到peripheral模式。但动态切换在安卓系统中可能比较复杂,且需要特定的硬件支持(如ID检测)。 步骤3:检查USB供电 引用[4]中提到VBUS电压异常,修改了dts中usb的供电。我们可以检查dts中关于USB供电的配置,确保当USB作为主机时,VBUS能够正常输出5V电压。 在设备树中,通常会有USB节点的供电相关属性,例如: ```dts &usb0 { vbus-supply = <&vcc5v0_usb>; dr_mode = "host"; status = "okay"; }; ``` 确保供电的调节器(如vcc5v0_usb)在主机模式下能够使能。 步骤4:重新编译内核并刷机 修改dts后,需要重新编译内核(或整个系统),并将新内核刷入设备。 步骤5:测试验证 刷机后,测试OTG功能(连接U盘)和无线ADB功能。 由于用户设备是安卓9,且之前已经要求保留无线ADB关闭有线ADB,我们可以采用方案A(永久设置USB为host模式)并确保无线ADB可用。 具体操作: 1. 获取设备的内核源码,找到对应设备的dts文件(如rk3399-evb.dtsi或类似)。 2. 在dts文件中,将目标USB控制器的dr_mode改为"host"。 3. 检查并确保USB供电配置正确(如vbus-supply指向正确的供电节点,且该节点在主机模式下能正常使能)。 4. 编译内核,生成boot.img,刷入设备。 注意:此操作需要一定的嵌入式开发经验,并且需要设备解锁bootloader。 如果用户无法进行内核编译,可以尝试以下临时解决方案(需要root): 1. 在系统启动后,通过sysfs动态切换模式(如果内核支持): ```bash su echo host > /sys/kernel/debug/usb/*/dr_mode # 然后重新加载USB驱动或重启USB控制器 ``` 但这种方法可能不持久,且不是所有设备都支持。 2. 使用USB切换工具(如USB Host Controller)来强制启用主机模式。 考虑到问题的复杂性,如果用户不具备内核编译条件,建议联系设备制造商获取支持。 总结:根本解决方法是修改设备树,将USB控制器的dr_mode设置为host,并确保供电正常,然后重新编译内核刷机。这样设备将永久处于主机模式,可以识别U盘,同时通过无线ADB进行调试。 注意:修改后,设备将无法通过USB线连接电脑进行ADB调试(因为USB处于主机模式,而不是设备模式),所以必须确保无线ADB已经配置好。 引用[1]中关于adb_usb.ini的解决方案是针对电脑识别设备的问题,与当前问题无关。 根据引用[2][^2]和引用[4][^4]的经验,我们重点调整了工作模式和供电。 相关问题: 1. 如何获取安卓设备的设备树(dts)文件? 2. 如何编译安卓内核并刷入设备? 3. 如何通过软件方式动态切换USB主机/设备模式?</think>### 安卓9开启ADB后OTG无法识别U盘问题排查与解决方案 #### 问题原因分析(基于引用[2][3][4]) 1. **USB工作模式冲突** ADB调试要求USB处于**设备模式**(`peripheral`),而OTG识别U盘需要**主机模式**(`host`)。当设备树(dts)中`dr_mode`设置为`otg`(自动切换)时,系统可能因ADB占用而无法切换到主机模式[^2]。 2. **供电异常** 开启ADB后VBUS电压可能异常(实测应为5V,但实际为0V),导致U盘无法获得足够电力[^4]。 3. **驱动冲突** ADB服务(`adbd`)可能独占USB控制器资源,阻止OTG功能正常加载[^3]。 --- ### 解决方案(需root权限) #### 1. 修改USB工作模式(关键步骤) ```bash su # 查找USB控制器节点(通常为/sys/devices/platform/*.dwc3*/) usb_path=$(find /sys/devices/platform -name "*.dwc3*" -type d | head -1) # 强制切换为host模式(永久生效需修改dts) echo host > $usb_path/dr_mode # 重启USB控制器 echo $usb_path > /sys/bus/platform/drivers/dwc3/unbind echo $usb_path > /sys/bus/platform/drivers/dwc3/bind ``` > 📌 **验证**:`cat $usb_path/dr_mode` 应返回 `host`[^2] #### 2. 修复供电问题 ```bash # 检查VBUS电压(正常应≥4V) cat /sys/class/power_supply/usb/voltage_now # 若电压异常,启用外部供电(需硬件支持) echo 1 > /sys/class/power_supply/usb/otg_switch ``` > ⚠️ 如电压仍异常,需修改设备树供电配置[^4]: > ```dts > &usbdrd_dwc3 { > vbus-supply = <&vcc5v0_usb>; // 添加供电节点 > dr_mode = "host"; // 固定主机模式 > }; > ``` #### 3. 优化ADB与OTG共存 ```bash # 限制ADB仅使用WiFi(避免占用USB) setprop persist.adb.tcp.port 5555 stop adbd && start adbd # 释放USB资源给OTG echo 0 > /sys/class/android_usb/android0/enable ``` > 💡 此时可通过 `adb connect <设备IP>` 无线调试 --- ### 验证流程 1. 插入U盘后执行: ```bash ls /storage # 应显示U盘挂载点 dmesg | grep "USB Mass Storage" # 检查内核识别日志 ``` 2. 同时确认无线ADB可用: ```bash adb devices # 应显示无线连接设备 ``` --- ### 补充说明 1. **内核兼容性** 部分设备需修改内核配置: ```makefile CONFIG_USB_CONFIGFS_F_FS=y CONFIG_USB_CONFIGFS_MASS_STORAGE=y ``` 2. **系统级修复** 若问题持续,需重新编译内核并修改设备树: ```dts &usb0 { dr_mode = "host"; // 强制主机模式 extcon = <&usb2phy0>; // 确保PHY配置正确 vbus-supply = <&vcc5v0_usb>; // 明确供电源 }; ``` > ⚠️ **操作风险**:修改dts需专业开发能力,错误操作可能导致USB功能完全失效
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值