Android USB实现通信

3,105

USB开发相关内容 UsbManager UsbDevice UsbInterface UsbEndPoint UsbDeviceConnection

1、 USB免驱设备。(驱动部分已在Android底层或Linux层实现) USB指定驱动设备。(硬件厂家驱动、通用通讯协议

2 获取连接的USB设备,可以筛选出想要的设备

在USB连接过程中需要知道USB设备的vendorId(设备厂商Id)和productId(设备产品Id),在UsbDevice类中的属性,可以获取,并且可以筛选需要的USB设备, 在操作的Activity或service中添加meta-data

这里的usb_xml文件为res文件夹下的xml文件夹中的设备过滤文件,每一个usb-device都是一个USB设备

3 找到USB指定设备进行连接

/** * 找到自定设备 */

  public void findUSB(int VENDORID, int PRODUCTID) {
      //1)创建usbManager
      usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
      //2)获取到所有设备 选择出满足的设备
      HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
      Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
      while (deviceIterator.hasNext()) {
          UsbDevice device = deviceIterator.next();
          Log.i(TAG, "vendorID--" + device.getVendorId() + "ProductId--" + device.getProductId());
          if (device.getVendorId() == VENDORID && device.getProductId() == PRODUCTID) {
              usbDevice = device; // 获取USBDevice
          }
      }
  }
  

4 查找设备接口

通过UsbDevice获取,一个设备可能有多个设备接口,数量通过UsbDevice的interfaceCount获取数量,通过UsbDevice.getInterface(int position)获取对应的 设备接口 UsbInterface usbInterface = UsbDevice.getInterface(int position)

5 获取usb设备的通信通道

blog.csdn.net/zqixiao_09/…

USB通信通道即和USB设备间接收和发送的通道,通过获取通道中对应的断点发送或接收数据实现控制,UsbEndPoint,断点 端点位于USB外设内部,所有通信数据的来源或者目的都基于这些端点,是一个可寻址的FIFO。 每个USB 外设有一个唯一的地址,可能包含最多十六个端点。主机通过发出器件地址和每次数据传输的端点号,向一个具体端点(FIFO)发送数据。 每个端点的地址为0 到15,一个端点地址对应一个方向。所以,端点2-IN 与端点2-OUT 完全不同。 每个器件有一个默认的双向控制端点0,因此不存在端点0-IN 和端点0-OUT。

在一个USB设备中会有很多endpoint,最多有16个。而我用的S5PV210处理器中有 16个,分别为EP0 – EP15。一个EP本质上讲是FIFO,也就是一段缓冲区,我们可以这样理解一个USB OTG设备就是有很多个缓冲区的集合。

虽然有16个端点,但是我们通常只会用到3个。比较常用的做法是EP0用做传输配置和控制信息,EP1做IN_EP,EP2做OUT_EP。

IN_EP的作用是用于把数据从Host传到Device中。而OUT_EP的作用是用于把数据从Device传送到Host中。即他们分别用做发送和接收

传输模式四种,通过枚举获取类型usbEndpoint.type 控制传输、批量传输、中断传输、同步传输

USB 有上述四种传输类型。枚举期间外设告诉主机每个端点支持哪种传输类型。

USB设备驱动向USB控制器驱动请求的每次传输被称为一个事务(Transaction)

事务有四种类型:Bulk Transaction、Control Transaction、Interrupt Transaction和Isochronous Transaction。

6 打开USB设备连接

在打开USB设备的时候是需要申请USB连接权限的,而且申请权限的次数是根据连接的设备来确定。 也就是说需要给每个usb设备单独授权(这个也好理解,只是很多时候系统USB权限弹窗都一样,多个设备时体验不好,如果要修改我认为只能从系统层面解决)。

  if (usbManager.hasPermission(usbDevice)) {
        //有权限打开
          conn = usbManager.openDevice(usbDevice);
      } else {
          usbManager.requestPermission(usbDevice, intent);
          if (usbManager.hasPermission(usbDevice)) { //权限获取成功
              conn = usbManager.openDevice(usbDevice);
          } else {
              Log.e(TAG, "没有权限");
          }
      }
      if(usbDeviceConnect.claimInterface(usbInterface,true)){
                  if(usbDeviceConnect != null){
                      logger("open设备成功")
                  }
                  var name = usbDeviceConnect.serial
                  logger("设备serial number:$name")
              }else{
                  logger("无法打开连接通道")
                  usbDeviceConnect.close()
              }

7 发送数据、读取数据

  private fun sendData(buffer:ByteArray){
      if(usbDeviceConnect  == null || outPoint == null)
          return
      if(usbDeviceConnect.bulkTransfer(outPoint,buffer,buffer.size,0) >= 0){
          logger("发送成功")
      }else{
          logger("发送失败")
      }
  }

  //读取数据
  var isReading = true
  private fun readData(){
      var qr = StringBuffer()
      Thread(Runnable {
          while (isReading){
              var bytes = byteArrayOf()
              if(usbDeviceConnect.bulkTransfer(inPoint,bytes,inPoint.maxPacketSize,100)>=0){
                  var stringBuffer = StringBuffer(inPoint.maxPacketSize)
              }
          }
      }).start()
  }