FTDI2XXドライバーを使用して権限のないユーザーとしてUSBデバイスにアクセスする

FTDI2XXドライバーを使用して権限のないユーザーとしてUSBデバイスにアクセスする

libFtd2xx(バージョン:libftd2xx.so.1.3.6)ドライバを使用してUSBデバイスにアクセスしようとしています。

ドライバリンク:http://www.ftdichip.com/Drivers/D2XX/Linux/ReadMe-linux.txt...使用されているデバイスの機能をテストします。シンプルサンプルディレクトリの内容と以下の内容は実行中に出力されます。

ルートの下

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

NON_権限を持つユーザー

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

ROOTユーザーから:デバイスへのアクセスが期待どおりに機能します。ただし、通常のユーザーとして実行しようとすると、そのデバイスにアクセスできなくなります。

私はこれがいくつかの権限に関連していると思います。しかし、これを通過することはできません。

ストレス差

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

一般ユーザー

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

このアプリケーションを実行する前に確認した事項は次のとおりです。

    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

また、UDEVに権限を追加してみてください。

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

この問題を解決するために指示を求めます。

ソース例:

/*最大4つのデバイスを開く簡単な例 - いくつかのデータを書き込んで再読み込みします。また、リストデバイスの使用方法も表示されます。デバイスにループバックコネクタがあり、シリアル番号もあると仮定*/

/*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;
}

関連情報