1

我下面的代码从 USB 设备(例如鼠标)获取 4 位数据。一切正常,除了当我运行代码和结束时我的鼠标停止工作。如果我再次运行我的代码,那么它会给出错误或不希望的或意外的结果。我必须拔下设备并再次运行我的代码,然后才能得到预期的答案。

什么可能导致这种情况,我该如何解决?

 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <libusb-1.0/libusb.h>

//=========================================================================
// This program detects usb and print out their details and reads data
//=========================================================================

int main (int argc, char *argv)
{
libusb_device                    **devList = NULL;
libusb_device                    *devPtr = NULL;
libusb_device_handle             *devHandle = NULL;
libusb_context                   *ctx = NULL;            //a libusb session
struct libusb_device_descriptor  devDesc;
struct libusb_config_descriptor *configDesc ;
unsigned char              strDesc[256];
ssize_t                    numUsbDevs = 0;      // pre-initialized scalars
ssize_t                    idx = 0;
int                        retVal = 0;

//========================================================================
// test out the libusb functions
//========================================================================

 printf ("*************************\n USB Detection    Program:\n*************************\n");
retVal = libusb_init (&ctx);

if(retVal < 0) {
    printf ("%d",retVal," Init Error "); //there was an error
        return 1;
          }

//========================================================================
// Get the list of USB devices visible to the system.
//========================================================================

numUsbDevs = libusb_get_device_list (ctx, &devList);  //Return no.of USB Devices

//========================================================================
// Loop through the list, looking for the device 
//========================================================================

while (idx < numUsbDevs)
{
  printf ("\n\n[%d]\n", idx+1);

  //=====================================================================
  // Get next device pointer out of the list, use it to open the device.
  //=====================================================================

  devPtr = devList[idx];

  retVal = libusb_open (devPtr, &devHandle);
  if (retVal != LIBUSB_SUCCESS)
     break;

  //=====================================================================
  // Get the device descriptor for this device.
  //=====================================================================

  retVal = libusb_get_device_descriptor (devPtr, &devDesc);
  if (retVal != LIBUSB_SUCCESS)
     break;

  //=====================================================================
  // Get the string associated with iManufacturer index.
  //=====================================================================

 printf ("iManufacturer = %d", devDesc.iManufacturer);
  if (devDesc.iManufacturer > 0)
  {
     retVal = libusb_get_string_descriptor_ascii
              (devHandle, devDesc.iManufacturer, strDesc, 256);
     if (retVal < 0)
        break;

     printf ("     string = %s",  strDesc);
  }

  //========================================================================
  // Get string associated with iProduct index.
  //========================================================================

  printf ("  \niProduct      = %d", devDesc.iProduct);
  if (devDesc.iProduct > 0)
  {
     retVal = libusb_get_string_descriptor_ascii
              (devHandle, devDesc.iProduct, strDesc, 256);
     if (retVal < 0)
        break;

     printf ("     string = %s", strDesc);
  }

  //==================================================================
  // Get string associated with iSerialNumber index.
  //==================================================================

  printf ("  \niSerialNumber = %d", devDesc.iSerialNumber);
  if (devDesc.iSerialNumber > 0)
  {
     retVal = libusb_get_string_descriptor_ascii
              (devHandle, devDesc.iSerialNumber, strDesc, 256);
     if (retVal < 0)
        break;

     printf ("     string = %s", strDesc);
  }

  //==================================================================
  // Print product id and Vendor id and 
  //==================================================================

    printf ("  \nProductid     = %d", devDesc.idProduct);
    printf ("  \nVendorid      = %d", devDesc.idVendor);

  //========================================================================
  // Close and try next one.
  //========================================================================

  libusb_close (devHandle);
  devHandle = NULL;
  idx++;

  //========================================================================
  // Selection of device by user
  //========================================================================

     if(idx==numUsbDevs) 
            { printf("\n\nselect the device :  ");
              scanf("%d",&idx);
         if(idx > numUsbDevs)
             {printf("Invalid input, Quitting.............");
              break; }    

       devPtr = devList[idx-1];

       retVal = libusb_open (devPtr, &devHandle);
           if (retVal != LIBUSB_SUCCESS)
           break;

      retVal = libusb_get_device_descriptor (devPtr, &devDesc);
           if (retVal != LIBUSB_SUCCESS)
           break;
               printf ("  \nProductid     = %d", devDesc.idProduct);
               printf ("  \nVendorid      = %d", devDesc.idVendor);

      retVal = libusb_get_config_descriptor(devPtr, 0, &configDesc);

      printf( "\nNumber of Interfaces:%d", (int)configDesc->bNumInterfaces);

      const struct libusb_interface *inter;
      const struct libusb_interface_descriptor *interdesc;
      const struct libusb_endpoint_descriptor *epdesc;

      int i,j,k ;
      for ( i = 0; i < (int)configDesc->bNumInterfaces; i++) {

      inter = &configDesc->interface[i];

      printf( "\nNumber of alt settings: %d " , inter->num_altsetting);

      for ( j = 0; j < inter->num_altsetting; j++) {

       interdesc = &inter->altsetting[j];

       printf( "\nInterface number: %d" ,(int)interdesc->bInterfaceNumber);

       printf( "\nNumber of endpoints: %d" , (int)interdesc->bNumEndpoints);

       for ( k = 0; k < (int)interdesc->bNumEndpoints; k++) {

       epdesc = &interdesc->endpoint[k];

       printf("\n\nDescriptor type:%d " ,(int)epdesc->bDescriptorType);

       printf("\nEP Address     : %d" ,(int)epdesc->bEndpointAddress);

      }  

     }

    }


   //========================================================================
   // Reading Data
   //========================================================================

     unsigned char data[4]; //data to read

        // data[0]='a';data[1]='b';data[2]='c';data[3]='d'; //some dummy values


    if(libusb_kernel_driver_active(devHandle, 0) == 1) { //find out if kernel driver is attached

         printf("\nKernel Driver Active\n");

    if(libusb_detach_kernel_driver(devHandle, 0) == 0) //detach it

        printf("Kernel Driver Detached!");
     }

         int r; //for return values 
          r = libusb_claim_interface(devHandle, 0); //claim interface of device

      if(r < 0) {

    printf("\nCannot Claim Interface %d",r);

    return 1;
                }

    printf("\nClaimed Interface\n");

   int actual_length; //used to find out how many bytes were written


   r = libusb_bulk_transfer(devHandle,129, data, sizeof(data), &actual_length, 0);
     printf("r is %d\n",r);



FILE *fp;
fp=fopen("test.txt","w");
      if (r == 0 && actual_length == sizeof(data)) {

            for(i=0; i<sizeof(data);i++)
        {
                    fprintf(fp,"%u\t",data[i]);
            printf("%u\t",data[i]);
        }
      // results of the transaction can now be found in the data buffer
             // parse them here and report button press
          } 
      else {
             error();
           } 


   r = libusb_release_interface(devHandle, 0); //release the claimed interface

   if(r!=0) {

            printf("\nCannot Release Interface");

            return 1;
           }

            printf("\nReleased Interface");


            idx=numUsbDevs +2; //to exit if statement
            }

   }  // end of while loop

  if (devHandle != NULL)
 {
  //========================================================================
  // Close device if left open due to break out of loop on error.
  //========================================================================

  libusb_close (devHandle);
 }   


 libusb_exit (ctx); //close the session

 printf ("\n*************************\n        Done\n*************************\n");
 return 0;
 }

//==========================================
// EOF
//==========================================
4

1 回答 1

3

您分离设备的当前驱动程序;

libusb_detach_kernel_driver(devHandle, 0)

但是当您完成后无法重新连接(libusb_release_interface不会为您执行此操作)。您需要libusb_attach_kernel_driver()在完成后致电以恢复内容。

于 2012-06-18T14:35:29.977 回答