1

以下のコードは、マウスなどの USB デバイスから 4 ビットのデータを取得します。コードを実行すると、コードが終了するとマウスが機能しなくなることを除いて、すべて正常に動作します。コードを再度実行すると、エラー、望ましくない、または予期しない結果が発生します。デバイスのプラグを抜いて、コードを再度実行する必要があります。そうして初めて、予想される ans が得られます。

何が原因で、どうすれば解決できますか?

 #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 に答える