libusb: Asynchrones Lesen

Beim Austesten der libusb (bzw. libusb-win32) wollte ich eine bestimmte Anzahl von Bytes aus dem USB-Gerät (genauer meiner Diplomarbeit) abholen. Ein usb_bulk_read() wartet aber so lange, bis sein Puffer voll ist. Ausserdem ist das ständige warten in einer while-Schleife nicht gerade performant. In der neuen Version der libusb gibt es bereits asynchrone Funktionen, die beim Datenempfang eine andere Funktion, die man sich selber definiert, abarbeitet. Das ist aber in der aktuelle libusb-win32 nicht möglich, da sie auf einer älteren Version beruht.

Deshalb habe ich mich entschieden, drei nicht oder nur sehr spärlich dokumentierte Funktionen zu verwenden:

– usb_bulk_setup_async(fd, &context, EP);
– usb_submit_async(context, buf, sizeof(buf));
– usb_reap_async(context, timeout);

So lassen sich in einem Thread die Daten abholen und dann an einen anderen Thread bzw.  eine andere Funktion weitersenden.

Hier ein noch nicht funktionierender Beispielcode.

// copyright benjamin schroedl
// benjamin@dev-tec.de
#include "allmyincludes_usb.h"

struct usb_bus *bus;
struct usb_device *dev;

// find my USB-Devices with MY_VID and MY_PID
function open()
 {
  for(bus = usb_get_busses(); bus; bus = bus->next)
   {
    for(dev = bus->devices; dev; dev = dev->next)
     {
      printf("USB device found [%s][%ld]: %s %d\r\n", bus->dirname, bus->location, dev->filename, dev->devnum);
   }

  printf("Enumeration of Devices done\r\n");

  for(bus = usb_get_busses(); bus; bus = bus->next)
   {
    for(dev = bus->devices; dev; dev = dev->next)
     {
      if(dev->descriptor.idVendor == MY_VID && dev->descriptor.idProduct == MY_PID)
       {
        printf("\r\nDevice found\r\n");
      return usb_open(dev);
       }
     }
   }
  return NULL;
}

int main()
 {
  usb_init(); 		/* initialize the library */
  usb_find_busses(); 	/* find all busses */
  usb_find_devices(); /* find all connected devices */

  if(!(fd_dev = open()))
   {
    printf("Error: device not found!\r\n");
    return(false);
   }

  if(usb_set_configuration(fd_dev, 1) < 0)
   {
    printf("Error: setting config 0 failed\n");
    printf("Error: %s\r\n", usb_strerror());
    usb_close(this->fd_dev);
    return(false);
   }

  if(usb_claim_interface(fd_dev, 0) < 0)
   {
    printf("Error: claimin interface failed\n");
    printf("Error: %s\r\n", usb_strerror());
    usb_close(this->fd_dev);
  }
}

// MY_Thread
thread
 {
  threadsetup();
  while(isrunning)
   {
   usb_bulk_setup_async(fd_dev, &context0, EP_IN);
   usb_submit_async(context0, this->buf, sizeof(buf));
   bytesread = 0;

   bytesread = usb_reap_async(context0, 500);

   if(bytesread < 0)
    {
     if(bytesread != -116) // nothing read
     {
      printf("code: %d error:%s\n", bytesread, usb_strerror());
     }
    }
   else
    {
     printf("%d bytes read\n\r", bytesread);
    }
  }
}

Leave a comment

Your comment