2012-06-12 3 views
1

아래의 코드는 마우스와 같은 USB 장치에서 4 비트의 데이터를 가져옵니다. 코드를 실행할 때와 끝내면 마우스가 작동을 멈추는 것을 제외하고는 모든 것이 잘 작동합니다. 코드를 다시 실행하면 오류가 발생하거나 예기치 않은 결과가 발생합니다. 장치를 뽑고 코드를 다시 실행해야만 예상 한 ans를 얻을 수 있습니다.UBS 입력 처리 하드웨어를 분리했다가 다시 연결하지 않는 한 UBS 입력은 한 번만 작동합니다.

이 문제의 원인은 무엇이며 어떻게 해결할 수 있습니까?

#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 
//========================================== 
+1

완료되면'libusb_attach_kernel_driver'가 필요하지 않습니까? –

+0

libusb_attach_kernel_driver (devHandle, 0)가 추가되었습니다. –

답변

3

장치의 현재 드라이버를 분리합니다.

libusb_detach_kernel_driver(devHandle, 0) 

그러나에 실패하여 (libusb_release_interface 당신을 위해이 작업을 수행하지 않습니다) 완료되면 다시 연결합니다. 복원을 완료하면 libusb_attach_kernel_driver()으로 전화해야합니다.