0

I am trying access a USB device using libFtd2xx (Version : libftd2xx.so.1.3.6)driver.

Driver Link : http://www.ftdichip.com/Drivers/D2XX/Linux/ReadMe-linux.txt ... To test device functionality used Simple from example directory and mentioned below are the output during execution.

Under ROOT

venkat:/opt# ./simple-dynamic
Device 0 Serial Number - 12Z9UXGV
Device 1 Serial Number -
Opened device 12Z9UXGV

Under NON_Privilaged User

venkat@venkat:/opt$ ./simple-dynamic
Error: FT_ListDevices(2)

Under ROOT User : Device accessing worked as expected. However, when tried executing it under normal user the device was not accessible.

I believe it is somewhere related to some permission . But not able to get through this.

Strace Diff

ROOT

  open("/dev/bus/usb/001/005", O_RDWR)    = 10

Normal user

  open("/dev/bus/usb/001/005", O_RDWR)    = -1 EACCES (Permission denied)

Thing I made sure before running this application:

    1. rmmod ftdi_sio (as super user)
    2. chmod 0755 /usr/local/lib/libftd2xx.so.1.3.6
    3. ln -sf /usr/local/lib/libftd2xx.so.1.3.6 /usr/local/lib/libftd2xx.so

Tried adding permission to UDEV too:

ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", MODE="0755"

Request some guidance in addressing this issue.

Source Sample:

/* Simple example to open a maximum of 4 devices - write some data then read it back. Shows one method of using list devices also. Assumes the devices have a loopback connector on them and they also have a serial number*/

/*To build use the following gcc statement 
(assuming you have the d2xx library in the /usr/local/lib directory).
gcc -o simple main.c -L. -lftd2xx -Wl,-rpath /usr/local/lib
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../ftd2xx.h"

#define BUF_SIZE 0x10

#define MAX_DEVICES     5



static void dumpBuffer(unsigned char *buffer, int elements)
{
    int j;

    printf(" [");
    for (j = 0; j < elements; j++)
    {
        if (j > 0)
            printf(", ");
        printf("0x%02X", (unsigned int)buffer[j]);
    }
    printf("]\n");
}



int main()
{
    unsigned char   cBufWrite[BUF_SIZE];
    unsigned char * pcBufRead = NULL;
    char *  pcBufLD[MAX_DEVICES + 1];
    char    cBufLD[MAX_DEVICES][64];
    DWORD   dwRxSize = 0;
    DWORD   dwBytesWritten, dwBytesRead;
    FT_STATUS   ftStatus;
    FT_HANDLE   ftHandle[MAX_DEVICES];
    int iNumDevs = 0;
    int i, j;
    int iDevicesOpen;   

    for(i = 0; i < MAX_DEVICES; i++) {
        pcBufLD[i] = cBufLD[i];
    }
    pcBufLD[MAX_DEVICES] = NULL;

    ftStatus = FT_ListDevices(pcBufLD, &iNumDevs, FT_LIST_ALL | FT_OPEN_BY_SERIAL_NUMBER);

    if(ftStatus != FT_OK) {
        printf("Error: FT_ListDevices(%d)\n", (int)ftStatus);
        return 1;
    }

    for(i = 0; ( (i <MAX_DEVICES) && (i < iNumDevs) ); i++) {
        printf("Device %d Serial Number - %s\n", i, cBufLD[i]);
    }

    for(j = 0; j < BUF_SIZE; j++) {
        cBufWrite[j] = j;
    }

    for(i = 0; ( (i <MAX_DEVICES) && (i < iNumDevs) ) ; i++) {
        /* Setup */
        if((ftStatus = FT_OpenEx(cBufLD[i], FT_OPEN_BY_SERIAL_NUMBER, &ftHandle[i])) != FT_OK){
            /* 
                This can fail if the ftdi_sio driver is loaded
                use lsmod to check this and rmmod ftdi_sio to remove
                also rmmod usbserial
            */
            printf("Error FT_OpenEx(%d), device %d\n", (int)ftStatus, i);
            printf("Use lsmod to check if ftdi_sio (and usbserial) are present.\n");
            printf("If so, unload them using rmmod, as they conflict with ftd2xx.\n");
            return 1;
        }

        printf("Opened device %s\n", cBufLD[i]);

        iDevicesOpen++;
        if((ftStatus = FT_SetBaudRate(ftHandle[i], 9600)) != FT_OK) {
            printf("Error FT_SetBaudRate(%d), cBufLD[i] = %s\n", (int)ftStatus, cBufLD[i]);
            break;
        }

        printf("Calling FT_Write with this write-buffer:\n");
        dumpBuffer(cBufWrite, BUF_SIZE);

        /* Write */
        ftStatus = FT_Write(ftHandle[i], cBufWrite, BUF_SIZE, &dwBytesWritten);
        if (ftStatus != FT_OK) {
            printf("Error FT_Write(%d)\n", (int)ftStatus);
            break;
        }
        if (dwBytesWritten != (DWORD)BUF_SIZE) {
            printf("FT_Write only wrote %d (of %d) bytes\n", 
                   (int)dwBytesWritten, 
                   BUF_SIZE);
            break;
        }
        sleep(1);

        /* Read */
        dwRxSize = 0;           
        while ((dwRxSize < BUF_SIZE) && (ftStatus == FT_OK)) {
            ftStatus = FT_GetQueueStatus(ftHandle[i], &dwRxSize);
        }
        if(ftStatus == FT_OK) {
            pcBufRead = realloc(pcBufRead, dwRxSize);
            memset(pcBufRead, 0xFF, dwRxSize);
            printf("Calling FT_Read with this read-buffer:\n");
            dumpBuffer(pcBufRead, dwRxSize);
            ftStatus = FT_Read(ftHandle[i], pcBufRead, dwRxSize, &dwBytesRead);
            if (ftStatus != FT_OK) {
                printf("Error FT_Read(%d)\n", (int)ftStatus);
                break;
            }
            if (dwBytesRead != dwRxSize) {
                printf("FT_Read only read %d (of %d) bytes\n",
                       (int)dwBytesRead,
                       (int)dwRxSize);
                break;
            }
            printf("FT_Read read %d bytes.  Read-buffer is now:\n",
                   (int)dwBytesRead);
            dumpBuffer(pcBufRead, (int)dwBytesRead);
            if (0 != memcmp(cBufWrite, pcBufRead, BUF_SIZE)) {
                printf("Error: read-buffer does not match write-buffer.\n");
                break;
            }
            printf("%s test passed.\n", cBufLD[i]);
        }
        else {
            printf("Error FT_GetQueueStatus(%d)\n", (int)ftStatus); 
        }

    }

    iDevicesOpen = i;
    /* Cleanup */
    for(i = 0; i < iDevicesOpen; i++) {
        FT_Close(ftHandle[i]);
        printf("Closed device %s\n", cBufLD[i]);
    }

    if(pcBufRead)
        free(pcBufRead);
    return 0;
}
  • You're kind of missing some information! (though it's nice to have code). What are the permissions (ls -l) actually achieved on the device node? If you're not sure what the device node is called, run your code under strace -e open. Also note udev rules are not re-applied automatically, udevadm trigger might work though the most robust approach would just be to reboot. – sourcejedi Aug 23 '16 at 8:04
  • @sourcejedi added strace info :: Seems /dev/bus/usb/001/005 permission issue . request your views – Ragav Aug 23 '16 at 9:17
  • The question I asked was What are the permissions (ls -l) actually achieved on the device node? – sourcejedi Aug 23 '16 at 9:27
  • @sourcejedi : (0644 ) crw-rw-r-- 1 root root 189, 5 Sep 9 14:51 /dev/bus/usb/001/006 – Ragav Aug 23 '16 at 9:31
  • ok so the rule you added sadly hasn't changed the mode here - (you will also need to change the ownership (user root group root) for your user to gain access) - can you confirm whether the rule has had a chance to be applied, as described in my first comment? Actually, if you can unplug+replug the device, that would do it too... you don't need any other restart/reload of udev because it watches the rule files using inotify, all it needs is a prod to get it to run the rule. – sourcejedi Aug 23 '16 at 9:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.