2013-02-08 90 views
5

我想用libusb1.0.9實現用戶空間的USB驅動程序。我有我的lpc2148藍板(ARM7)。此板由Bertrik Sikken先生加載開源USB堆棧/固件。現在我的用戶空間驅動程序正在嘗試用電路板讀寫。我正在獲取垃圾數據。 我想知道散裝物流的流程。 對於任何傳輸/事務是否有內核設備驅動程序? 我們是否需要usb gadget設備驅動程序? 我無法理解數據被複制的位置。 重要的是,當我讀/寫中斷得到生成,我可以看到LCD上的正確數據。我是否需要讀取/寫入USBRxData/USBTxData? 請做好必要的準備。libusb批量傳輸

我試過讀寫批量傳輸下面的代碼..

int usb_read(struct libusb_device *dev,struct libusb_device_handle *hDevice) 
{ 
    char *data,*data1; 
    struct libusb_endpoint_descriptor *ep;  
    struct libusb_interface_descriptor *id; 
    int len=64,r,ret_alt,ret_clm,ret_rst,i; 
    struct libusb_device **list; 

    data = (char *)malloc(512); //allocation of buffers 
    data1 = (char *)malloc(512); 
    memset(data,'\0',512); 
    memset(data1,'\0',512); 

    if(hDevice==NULL) 
    { 
     printf("\nNO device found\n"); 
     return 0; 
    } 
    int ret_open = libusb_open(dev,&hDevice); 
    if(ret_open!=0) 
    { 
     printf("Error in libusb_open\n"); 
     libusb_free_device_list(list,1); 
     return -1; 
    }  
    char str_tx[512]="G"; //data to send to device 
    char str_rx[512];  //receive string 
    data = str_tx; 

    printf("data::%s\t,str::%s\n",data,str_tx); 
    //printf("%c\n",data); 
    ep = active_config(dev,hDevice); 
    printf("after ep\n"); 
    //printf("alt_interface = %d\n",alt_interface); 
    ret_rst = libusb_reset_device(hDevice); 
    if(ret_rst < 0) 
    { 
     printf("Error in reset :: %d",ret_rst); 
     return -1; 
    } 
    printf("original data1 : %s\n",data1); 
    r = libusb_bulk_transfer(hDevice,0x08,str_tx,512,&len,0); 
    //write to device buffer from data 

    printf("Error number :: %d\n",r); 
    int le = ep->bEndpointAddress; 
    int ty = ep->bDescriptorType; 
    int y = ep->bmAttributes; 

    printf("y::%d\tatt:: %d\n",y,ep->bmAttributes); 
    if(r==-1) 
     printf("Error in io\n"); 
    if(r==0) 
    { 
     printf("data returned :: %s\n",data); 
     printf("len= %d\n",len); 
     printf("Device Button Pressed!!!!\n"); 
    } 
    else 
    { 
     printf("Error in bulk transfer\n"); 
     return -1; 
    } 

    r = libusb_bulk_transfer(hDevice,0x82,data1,512,&len,0); 
    //read from device buffer to data1 
    //str_rx = data1; 
    //printf("End point address::%d\n",le); 
    //printf("End point desc.type::%d\n",ty); 
    if(r==-1) 
     printf("Error in io\n"); 
    if(r==0) 
    { 
     printf("data1 returned::%s\n",data1); //received string in data1 
     printf("len= %d\n",len); 
     printf("Device Button Pressed!!!!\n"); 
    } 
    else 
    { 
     printf("Error in bulk transfer\n"); 
     return -1; 
    } 


    return 0; 
} 
+2

你沒有說你使用的是什麼操作系統! –

回答

7

嘗試下面給出的代碼,它應該在LPC2148工作。 我已經測試了這一點,配置了一個lpc2148,用於在寫入(來自用戶空間)並且RTC開始運行後接收來自USB的中斷。

回答你的問題是否涉及內核驅動程序的讀寫問題,據我研究,你必須拆分內核驅動程序並使用libusb API聲明接口。雖然我不確定是否可以不拆卸它。

#include <stdio.h>  
#include <stdlib.h>  
#include <sys/types.h>  
#include <string.h>  
#include </usr/local/include/libusb-1.0/libusb.h>  


#define BULK_EP_OUT  0x82  
#define BULK_EP_IN  0x08  

int interface_ref = 0;  
int alt_interface,interface_number;  

int print_configuration(struct libusb_device_handle *hDevice,struct libusb_config_descriptor *config)  
{  
    char *data;  
    int index;  

    data = (char *)malloc(512);  
    memset(data,0,512);  

    index = config->iConfiguration;  

    libusb_get_string_descriptor_ascii(hDevice,index,data,512);  

    printf("\nInterface Descriptors: ");  
    printf("\n\tNumber of Interfaces : %d",config->bNumInterfaces);  
    printf("\n\tLength : %d",config->bLength);  
    printf("\n\tDesc_Type : %d",config->bDescriptorType);  
    printf("\n\tConfig_index : %d",config->iConfiguration);  
    printf("\n\tTotal length : %lu",config->wTotalLength);  
    printf("\n\tConfiguration Value : %d",config->bConfigurationValue);  
    printf("\n\tConfiguration Attributes : %d",config->bmAttributes);  
    printf("\n\tMaxPower(mA) : %d\n",config->MaxPower);  

    free(data);  
    data = NULL;  
    return 0;  
}  

struct libusb_endpoint_descriptor* active_config(struct libusb_device *dev,struct libusb_device_handle *handle)  
{  
    struct libusb_device_handle *hDevice_req;  
    struct libusb_config_descriptor *config;  
    struct libusb_endpoint_descriptor *endpoint;  
    int altsetting_index,interface_index=0,ret_active;  
    int i,ret_print;  

    hDevice_req = handle;  

    ret_active = libusb_get_active_config_descriptor(dev,&config);  
    ret_print = print_configuration(hDevice_req,config);  

    for(interface_index=0;interface_index<config->bNumInterfaces;interface_index++)  
    {  
     const struct libusb_interface *iface = &config->interface[interface_index];  
     for(altsetting_index=0;altsetting_index<iface->num_altsetting;altsetting_index++)  
     {  
      const struct libusb_interface_descriptor *altsetting = &iface->altsetting[altsetting_index];  

      int endpoint_index;  
      for(endpoint_index=0;endpoint_index<altsetting->bNumEndpoints;endpoint_index++)  
      {  
       const struct libusb_endpoint_desriptor *ep = &altsetting->endpoint[endpoint_index];  
       endpoint = ep;  
       alt_interface = altsetting->bAlternateSetting;  
       interface_number = altsetting->bInterfaceNumber;  
      }  

      printf("\nEndPoint Descriptors: ");  
      printf("\n\tSize of EndPoint Descriptor : %d",endpoint->bLength);  
      printf("\n\tType of Descriptor : %d",endpoint->bDescriptorType);  
      printf("\n\tEndpoint Address : 0x0%x",endpoint->bEndpointAddress);  
      printf("\n\tMaximum Packet Size: %x",endpoint->wMaxPacketSize);  
      printf("\n\tAttributes applied to Endpoint: %d",endpoint->bmAttributes);  
      printf("\n\tInterval for Polling for data Tranfer : %d\n",endpoint->bInterval);  
     }  
    }  
    libusb_free_config_descriptor(NULL);  
    return endpoint;  
}  

int main(void)  
{  
    int r = 1;  
    struct libusb_device **devs;  
    struct libusb_device_handle *handle = NULL, *hDevice_expected = NULL;  
    struct libusb_device *dev,*dev_expected;  

    struct libusb_device_descriptor desc;  
    struct libusb_endpoint_descriptor *epdesc;  
    struct libusb_interface_descriptor *intdesc;  

    ssize_t cnt;  
    int e = 0,config2;  
    int i = 0,index;  
    char str1[64], str2[64];  
    char found = 0;  

// Init libusb  
    r = libusb_init(NULL);  
    if(r < 0)  
    {  
     printf("\nfailed to initialise libusb\n");  
     return 1;  
    }  
    else  
     printf("\nInit Successful!\n");  

// Get a list os USB devices  
    cnt = libusb_get_device_list(NULL, &devs);  
    if (cnt < 0)  
    {  
     printf("\nThere are no USB devices on bus\n");  
     return -1;  
    }  
    printf("\nDevice Count : %d\n-------------------------------\n",cnt);  

    while ((dev = devs[i++]) != NULL)  
    {  
     r = libusb_get_device_descriptor(dev, &desc);  
     if (r < 0)  
      {  
      printf("failed to get device descriptor\n");  
      libusb_free_device_list(devs,1);  
      libusb_close(handle);  
      break;  
     }  

     e = libusb_open(dev,&handle);  
     if (e < 0)  
     {  
      printf("error opening device\n");  
      libusb_free_device_list(devs,1);  
      libusb_close(handle);  
      break;  
     }  

     printf("\nDevice Descriptors: ");  
     printf("\n\tVendor ID : %x",desc.idVendor);  
     printf("\n\tProduct ID : %x",desc.idProduct);  
     printf("\n\tSerial Number : %x",desc.iSerialNumber);  
     printf("\n\tSize of Device Descriptor : %d",desc.bLength);  
     printf("\n\tType of Descriptor : %d",desc.bDescriptorType);  
     printf("\n\tUSB Specification Release Number : %d",desc.bcdUSB);  
     printf("\n\tDevice Release Number : %d",desc.bcdDevice);  
     printf("\n\tDevice Class : %d",desc.bDeviceClass);  
     printf("\n\tDevice Sub-Class : %d",desc.bDeviceSubClass);  
     printf("\n\tDevice Protocol : %d",desc.bDeviceProtocol);  
     printf("\n\tMax. Packet Size : %d",desc.bMaxPacketSize0);  
     printf("\n\tNo. of Configuraions : %d\n",desc.bNumConfigurations);  

     e = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, (unsigned char*) str1, sizeof(str1));  
     if (e < 0)  
     {  
     libusb_free_device_list(devs,1);  
      libusb_close(handle);  
      break;  
     }  
     printf("\nManufactured : %s",str1);  

     e = libusb_get_string_descriptor_ascii(handle, desc.iProduct, (unsigned char*) str2, sizeof(str2));  
     if(e < 0)  
     {  
     libusb_free_device_list(devs,1);  
      libusb_close(handle);  
      break;  
     }  
     printf("\nProduct : %s",str2);  
     printf("\n----------------------------------------");  

     if(desc.idVendor == 0xffff && desc.idProduct == 0x4)  
     {  
     found = 1;  
     break;  
     }  
    }//end of while  
    if(found == 0)  
    {  
     printf("\nDevice NOT found\n");  
     libusb_free_device_list(devs,1);  
     libusb_close(handle);  
     return 1;  
    }  
    else  
    {  
     printf("\nDevice found");  
     dev_expected = dev;  
     hDevice_expected = handle;  
    }  

    e = libusb_get_configuration(handle,&config2);  
    if(e!=0)  
    {  
     printf("\n***Error in libusb_get_configuration\n");  
     libusb_free_device_list(devs,1);  
     libusb_close(handle);  
     return -1;  
    }  
    printf("\nConfigured value : %d",config2);  

    if(config2 != 1)  
    {  
     libusb_set_configuration(handle, 1);  
     if(e!=0)  
     {  
      printf("Error in libusb_set_configuration\n");  
      libusb_free_device_list(devs,1);  
      libusb_close(handle);  
      return -1;  
     }  
     else  
      printf("\nDevice is in configured state!");  
    }  

    libusb_free_device_list(devs, 1);  

    if(libusb_kernel_driver_active(handle, 0) == 1)  
    {  
     printf("\nKernel Driver Active");  
     if(libusb_detach_kernel_driver(handle, 0) == 0)  
      printf("\nKernel Driver Detached!");  
     else  
     {  
      printf("\nCouldn't detach kernel driver!\n");  
      libusb_free_device_list(devs,1);  
      libusb_close(handle);  
      return -1;  
     }  
    }  

    e = libusb_claim_interface(handle, 0);  
    if(e < 0)  
    {  
     printf("\nCannot Claim Interface");  
     libusb_free_device_list(devs,1);  
     libusb_close(handle);  
     return -1;  
    }  
    else  
     printf("\nClaimed Interface\n");  

    active_config(dev_expected,hDevice_expected);  

    // Communicate  

    char *my_string, *my_string1;  
    int transferred = 0;  
    int received = 0;  
    int length = 0;  

    my_string = (char *)malloc(nbytes + 1);  
    my_string1 = (char *)malloc(nbytes + 1);  

    memset(my_string,'\0',64);  
    memset(my_string1,'\0',64);  

    strcpy(my_string,"prasad divesd");  
    length = strlen(my_string);  

    printf("\nTo be sent : %s",my_string);  

    e = libusb_bulk_transfer(handle,BULK_EP_IN,my_string,length,&transferred,0);  
    if(e == 0 && transferred == length)  
    {  
     printf("\nWrite successful!");  
     printf("\nSent %d bytes with string: %s\n", transferred, my_string);  
    }  
    else  
     printf("\nError in write! e = %d and transferred = %d\n",e,transferred);  

    sleep(3);  
    i = 0;  

    for(i = 0; i < length; i++)  
    {  
     e = libusb_bulk_transfer(handle,BULK_EP_OUT,my_string1,64,&received,0); //64 : Max Packet Lenght  
     if(e == 0)  
     {  
      printf("\nReceived: ");  
      printf("%c",my_string1[i]); //will read a string from lcp2148 
      sleep(1);  
     }  
     else  
     {  
      printf("\nError in read! e = %d and received = %d\n",e,received);  
      return -1;  
     }  
    }  


    e = libusb_release_interface(handle, 0);  

    libusb_close(handle);  
    libusb_exit(NULL);  

    printf("\n");  
    return 0;  
}  
+1

而且,我無法足夠回答關於轉移後數據駐留的位置。爲此,我已確保將lpc2148固件配置爲將其存入緩衝區並將其打印在LCD上。所以對成功轉移的雙重確認。在讀取過程中,固件被配置爲發送一個字符串來表示RTC正在運行。雖然我無法通過讀取在控制檯上打印RTC時間戳。對於我迄今爲止所做的小型工作發表評論將是非常令人愉快的。改進指南是最受期待和歡迎的。 – 2013-02-10 14:35:11

0

處理內核分離。

if(libusb_kernel_driver_active(dev_handle, 0) == 1)   //find out if kernel driver is attached 
{ 
    cout << "Kernel Driver Active" << endl; 

    if(libusb_detach_kernel_driver(dev_handle, 0) == 0)  //detach it 
    { 
     cout << "Kernel Driver Detached!" << endl; 
    } 
}