Android Usb的研究

1 篇文章 0 订阅
1 篇文章 0 订阅

USB为什么复杂,因为USB标准内容太多了.

Android上的USB外围设备.指纹,鼠标,触摸屏,U盘.大部分人用USB充充电.USB的介绍网上已经很多了,我以移植一个USB触摸屏来说明我的理解.

Android上USB的API android.hardware.usb.UsbManager,涉及到权限和协议.

权限:

先解决应用层的问题,这和android权限机制有关系.

第一步:

在AndroidManifest.xml加入

 

 <uses-permission android:name="android.hardware.usb.host" />
 <uses-permission android:name="android.hardware.usb.accessory" />

第二步:

 

怎么找到我的设备呢?

 

mManager = (UsbManager) c.getSystemService(Context.USB_SERVICE);		
HashMap<String, UsbDevice> list = mManager.getDeviceList();
for (UsbDevice usb : list.values()) {
    int pid = usb.getProductId();
    int vid = usb.getVendorId();
}

遍历list,打印出pid和vid号,看和你实际对应pid,vid号是不是一样呢?

如果你没看到usb设备呢?我想大部分人会遇到,有人会说你没把vid,pid号加入usbfilter.xml文件里.不要被误导,usbfilter.xml列举热插拔设备。getDeviceList会获取所有usb设备.

参考这篇文章基本能解决,因为android很多版本都不完善.

 

http://blog.csdn.net/trbbadboy/article/details/8929673

第三步:

 

打开设备:

 

mDeviceIntf = mDevice.getInterface(0);
mDeviceConnect = mManager.openDevice(mDevice);
mDeviceConnect.claimInterface(mDeviceIntf, true);

初步完成.

第四步(可选):

google这点做的不厚道,什么东西都要求权限,上个厕所都得申请,虽然可以记住用户选择,可别忘了usb是热插拔设备,你拔完之后,从新插入又是一个新设备,又得申请权限。

答案在这里,修改所有的申请都为通过.

 

frameworks/base/services/java/com/android/server/usb/UsbSettingsManager.java

这是得修改系统源码.
 

 

协议

参考usb协议。

一个命令格式:bmRequestType + bRequest + wValue + wIndex + wLength ,总共8个字节

当然命令+=数据

可以这么简单理解.

bmRequest代表方向,主机->从设备或者从设备到主机

bRequest 命令,参考表2

wValue 参数1,得仔细看协议标准,太多了

wIndex 参数2,得仔细看协议标准,太多了

wLength:接收或者发送数据的大小,不包括命令本身(8字节)

data;数据,根据实际情况

命令格式表9-2

命令表9-4

 

 

例子:

我拿一帧数据举个例子,我用BusHound抓取获取描述符的命令,IN是接收到的数据

 

命令格式:81 06 02 03 09 04 02 02

bmRequestType = 0x80; 从设备到主机

bRequest = 0x06; 参考表9-4,GET_DESCRIPTOR

wValue = 0x0302;参数1,高位代表类型(String类型),低位代表索引值

wIndex = 0x0409;参数2

wLength = 0x0202;接收长度0x0202字节

参考手册GET_DESCRIPTOR的解释。

那在android上怎么用呢?这是UsbDeviceConnection的一个标准函数,这里面的参数就是上面所说的参数.

 

* <p>
     * This method transfers data starting from index 0 in the buffer.
     * To specify a different offset, use
     * {@link #controlTransfer(int, int, int, int, byte[], int, int, int)}.
     * </p>
     *
     * @param requestType request type for this transaction
     * @param request request ID for this transaction
     * @param value value field for this transaction
     * @param index index field for this transaction
     * @param buffer buffer for data portion of transaction,
     * or null if no data needs to be sent or received
     * @param length the length of the data to send or receive
     * @param timeout in milliseconds
     * @return length of data transferred (or zero) for success,
     * or negative value for failure
     */
    public int controlTransfer(int requestType, int request, int value,
            int index, byte[] buffer, int length, int timeout) {
        return controlTransfer(requestType, request, value, index, buffer, 0, length, timeout);
    }

我们试着发送一下上面抓取的数据

 

 

void test() 
{
    byte [] rcv = new byte[0x0202];
    int r = mDeviceConnect.controlTransfer(
    0x80,
    0x06,
    0x3 << 8 | 0x2,
    0x4 << 8 | 0x9,
    rcv,
    0x0202,
    1000);

    ComFunc.log("is test log", rcv, 64);
}

得到结果:

 

 

/Timeline(  762): Timeline: Activity_windows_visible id: ActivityRecord{419df0c8 u0 com.ou.usbtp/com.ou.ui.DemoActivity
 t24} time:16355386
I/MLog    ( 4562): is test log{
I/MLog    ( 4562): 2c,03,49,00,6e,00,66,00,72,00,61,00,72,00,65,00,
I/MLog    ( 4562): 64,00,20,00,54,00,6f,00,75,00,63,00,68,00,20,00,
I/MLog    ( 4562): 53,00,63,00,72,00,65,00,65,00,6e,00,00,00,00,00,
I/MLog    ( 4562): 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,};
V/RenderScript( 4562): Application requested CPU execution

和bushound抓取结果一样.
当然我们不会只做获取描述符简单的问题,我们还需要设计到配置信息和读取信息的功能.

和上面类似,只是换了命令类型,
这是我配置USB触摸屏使用到的配置信息片段,大家可以参考.

Device  Length    Phase  Data                                                Description       Cmd.Phase.Ofs(rep)  Time        
------  --------  -----  --------------------------------------------------  ----------------  ------------------  ------------
  37.0            CTL    21 09 05 03  02 00 40 00                            SET REPORT               1.1.0        10:08:02.852  
  37.0        64  OUT    05 03 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................         1.2.0        10:08:02.852  
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................         1.2.16                     
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................         1.2.32                     
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................         1.2.48                     
  37.0            CTL    a1 01 06 03  02 00 40 00                            GET REPORT               2.1.0        10:08:02.872  
  37.0        64  IN     06 03 00 00  fc 00 00 80  00 00 00 00  00 00 00 00  ................         2.2.0        10:08:02.872  
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................         2.2.16                     
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................         2.2.32                     
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................         2.2.48                    

另外一些相关涉及的方面

android usb-touchscreen驱动:

 

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/input/touchscreen/usbtouchscreen.c?h=v4.12-rc4

usb 2.0协议标准(英文):

 

 

http://www.usb.org/developers/docs/usb20_docs/

有兴趣一起讨论.
 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值