在Ubuntu Linux下输入和输出的Libusb错误-USB的C编程

时间:2019-02-28 21:17:47

标签: c usb libusb usbserial

我制作了一个可以使用USB的C程序。但是我有一个错误-1,表示我有一些输入/输出错误。

我的C代码在下面。我将解释它是如何工作的。函数getDevices()打印出vendor IDproduct ID以及device name。运行函数getDevices()时,请记住那些。

然后,您必须选择要连接的设备。选择设备后,请在此处vendor IDproduct ID中写入。

#define USB_VENDOR_ID   1155
#define USB_PRODUCT_ID  14415 /* USB product ID used by the device */

在那之后,您需要运行功能connectUSB()。它只需连接到您已写入USB_VENDOR_IDUSB_PRODUCT_ID的USB设备上即可。

我在阅读传入消息时遇到问题。尝试阅读时出现错误LIBUSB_ERROR_IO = -1

那么,当我尝试阅读时为什么会出现-1错误?我尝试过:

  • 以完全管理权限(例如root)运行C代码
  • 拔出计算机内部的USB设备,而不将其拔出
  • 在我使用此C程序的同时测试是否已打开USB阅读器软件

如果要尝试使用我的代码,则必须安装LibUSB。在Deb,Ubuntu,Raspberry等基于Deb的系统中,可以通过在终端中编写此命令来完成此操作。

sudo apt-get install libusb-1.0.0-dev libusb-1.0-0

下面的我的C代码。

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

libusb_context *CONTEXT; //a libusb session
libusb_device_handle *DEVICEHANDLE; //a device handle
libusb_device * DEVICE_POINTER; // a pointer to a device
libusb_device **ARRAY_OF_POINTERS_TO_DEVICE; // an array of pointers to devices
ssize_t NUMBER_OF_USB_DEVICES; // Initial zero devices

static uint8_t receiveBuf[64];
uint8_t transferBuf[64];

uint16_t counter = 0;
#define USB_ENDPOINT_IN     0x80   /* endpoint address */
#define USB_ENDPOINT_OUT    0x01  /* endpoint address */
#define USB_TIMEOUT 3000 /* Connection timeout (in ms) */
#define USB_VENDOR_ID   1155
#define USB_PRODUCT_ID  14415 /* USB product ID used by the device */

/*
 * Here we are going to read the USB
 */
int readUSB() {
    int nread, r, counter = 0;
    nread = 4;
    int transfered;
    unsigned char data[4];

    r = libusb_bulk_transfer(DEVICEHANDLE, USB_ENDPOINT_IN, data, nread, &transfered, USB_TIMEOUT);
    if (LIBUSB_ERROR_TIMEOUT == r) {
        printf("LIBUSB_ERROR_TIMEOUT = %d\n", r);
        return -1;
    }else if(LIBUSB_ERROR_PIPE == r){
        printf("LIBUSB_ERROR_PIPE = %d\n", r);
        return -1;
    }else if(LIBUSB_ERROR_OVERFLOW == r){
        printf("LIBUSB_ERROR_OVERFLOW = %d\n", r);
        return -1;
    }else if(LIBUSB_ERROR_NO_DEVICE == r){
        printf("LIBUSB_ERROR_NO_DEVICE = %d\n", r);
        return -1;
    }else if(LIBUSB_ERROR_IO == r){
        printf("LIBUSB_ERROR_IO = %d\n", r);
        return -1;
    } else {
        printf("r = %d, %d receive %d bytes from device: %s\n", r, ++counter, nread, data);
        return 0;
    }


    return 0;
}

/*
 * Here are we going to write to the USB
 */
int writeUSB() {
    int n, ret;
    uint16_t count = 0;
    //count up
    n = sprintf(transferBuf, "%d\0", count++);
    //write transfer
    //probably unsafe to use n twice...
    ret = libusb_bulk_transfer(DEVICEHANDLE, USB_ENDPOINT_OUT, transferBuf, n,
            &n, USB_TIMEOUT);
    //Error handling
    switch (ret) {
    case 0:
        printf("send %d bytes to device\n", n);
        return 0;
    case LIBUSB_ERROR_TIMEOUT:
        printf("ERROR in bulk write: %d Timeout\n", ret);
        break;
    case LIBUSB_ERROR_PIPE:
        printf("ERROR in bulk write: %d Pipe\n", ret);
        break;
    case LIBUSB_ERROR_OVERFLOW:
        printf("ERROR in bulk write: %d Overflow\n", ret);
        break;
    case LIBUSB_ERROR_NO_DEVICE:
        printf("ERROR in bulk write: %d No Device\n", ret);
        break;
    default:
        printf("ERROR in bulk write: %d\n", ret);
        break;

    }
    return -1;
    return 0;
}

/*
 * This will connect to our USB device
 */
int connectUSB() {
    int r;
    r = libusb_init(&CONTEXT);
    if(r > 0){
        printf("Libusb_init error %d\n", r);
        return -1;
    }
    //libusb_set_debug(CONTEXT, 0);

    //Open Device with VendorID and ProductID
    DEVICEHANDLE = libusb_open_device_with_vid_pid(CONTEXT, USB_VENDOR_ID, USB_PRODUCT_ID);
    if (DEVICEHANDLE == NULL) {
        perror("DEVICEHANDLE == NULL");
        return -1;
    }

    //Claim Interface 0 from the device
    r = libusb_claim_interface(DEVICEHANDLE, 0);
    if (r == LIBUSB_ERROR_NOT_FOUND) {
        fprintf(stderr, "LIBUSB_ERROR_NOT_FOUND = %d\n", r);
        return -1;
    }else if(r == LIBUSB_ERROR_BUSY){
        fprintf(stderr, "LIBUSB_ERROR_BUSY = %d\n", r);
        return -1;
    }else if(r == LIBUSB_ERROR_NO_DEVICE){
        fprintf(stderr, "LIBUSB_ERROR_NO_DEVICE = %d\n", r);
        return -1;
    }

    printf("Interface claimed\n");
    return 0;
}

/*
 * This will show all the devices for USB and send it thru sockets
 */
int getDevices() {

    /*
     * Special local device handle for only get the name of the USB device
     */
    libusb_device_handle *DEVICEHANDLE_NULL; //a device handle

    /*
     * Compute the number of USB
     */
    int returnValue = libusb_init(NULL);
    NUMBER_OF_USB_DEVICES = libusb_get_device_list(NULL,
            &ARRAY_OF_POINTERS_TO_DEVICE);

    /*
     * Create our list of Vendor, Product and device
     * Vendor and product are important for connect the USB and device is important for the user to see which USB to connect
     */
    uint16_t vendor[NUMBER_OF_USB_DEVICES];
    uint16_t product[NUMBER_OF_USB_DEVICES];
    char device[NUMBER_OF_USB_DEVICES][256 * 2];

    /*
     * Loop thru all USB devices
     */
    ssize_t deviceIndex = 0;
    while (deviceIndex < NUMBER_OF_USB_DEVICES) {

        /*
         * Get the description of the USB device
         */
        DEVICE_POINTER = ARRAY_OF_POINTERS_TO_DEVICE[deviceIndex];
        struct libusb_device_descriptor deviceDescriptor;
        returnValue = libusb_get_device_descriptor(DEVICE_POINTER,
                &deviceDescriptor);
        if (returnValue != LIBUSB_SUCCESS)
            break;

        /*
         * Open the USB device with NULL. It's only because we want the name of the USB device
         */
        DEVICEHANDLE_NULL = NULL;
        returnValue = libusb_open(DEVICE_POINTER, &DEVICEHANDLE_NULL);
        if (returnValue != LIBUSB_SUCCESS) {
            /*
             * There was an error. Not success.
             */

            if (DEVICEHANDLE_NULL != NULL) {
                libusb_close(DEVICEHANDLE_NULL);
                DEVICEHANDLE_NULL = NULL;
            }

            /*
             * Write as there was no info at all to display
             */
            product[deviceIndex] = 0;
            vendor[deviceIndex] = 0;
            memcpy(device[deviceIndex], "-", 256 * 2 * sizeof(char));
            deviceIndex++;
            continue;

        }

        /*
         * Get the string associated with iManufacturer index.
         */
        const int STRING_LENGTH = 256;
        unsigned char stringManufacturer[STRING_LENGTH];
        unsigned char stringProduct[STRING_LENGTH];
        char stringDeviceName[STRING_LENGTH * 2];
        if (DEVICEHANDLE_NULL != NULL && deviceDescriptor.iManufacturer > 0) {
            returnValue = libusb_get_string_descriptor_ascii(DEVICEHANDLE_NULL,
                    deviceDescriptor.iManufacturer, stringManufacturer,
                    STRING_LENGTH);
            if (returnValue < 0)
                break;
        }

        /*
         * Get string associated with iProduct index.
         */
        if (DEVICEHANDLE_NULL != NULL && deviceDescriptor.iProduct > 0) {
            returnValue = libusb_get_string_descriptor_ascii(DEVICEHANDLE_NULL,
                    deviceDescriptor.iProduct, stringProduct, STRING_LENGTH);
            if (returnValue < 0)
                break;
        }

        /*
         * Combine manufacturer and product
         */
        strcpy(stringDeviceName, (char*) stringManufacturer);
        strcat(stringDeviceName, " "); // a space only
        strcat(stringDeviceName, (char*) stringProduct);
        //printf("%s\n", stringDeviceName);

        /*
         * Save them all into arrays
         */
        product[deviceIndex] = deviceDescriptor.idProduct;
        vendor[deviceIndex] = deviceDescriptor.idVendor;
        memcpy(device[deviceIndex], stringDeviceName, 256 * 2 * sizeof(char));

        /*
         * Close and try next one.
         */
        if (DEVICEHANDLE_NULL != NULL) {
            libusb_close(DEVICEHANDLE_NULL);
            DEVICEHANDLE_NULL = NULL;
        }

        /*
         * Next USB device
         */
        deviceIndex++;
    }

    /*
     * Print our result what we found and send them to socket
     */
    for (int i = 0; i < 11; i++) {
        printf("Name: %s\n", device[i]);
        printf("Vendor: %u\n", vendor[i]);
        printf("Product: %u\n\n", product[i]);
    }

    libusb_exit(NULL);

    return 0;
}

0 个答案:

没有答案