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

관련 정보