2013-04-11 74 views
3

我有一個仿真鍵盤的USB RFID讀卡器。 所以當我把一張卡片放到它上面時,我在終端窗口上看到字符串-i.e. "0684a24bc1"從/ dev/input讀取

但我想在我的C程序中閱讀它。 當我使用沒有問題:scanf("%s",buff);

但是,當我使用下面的代碼,我得到了很多(約500字節)未識別的數據。 爲什麼? 我想有非阻塞閱讀。

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <termios.h> 

int main(int argc, char ** argv) { 
    int fd; 
    char buf[256]; 

    fd = open("/dev/input/event3", O_RDWR | O_NOCTTY | O_NDELAY); 
    if (fd == -1) { 
    perror("open_port: Unable to open /dev/ttyAMA0 - "); 
    return(-1); 
    } 

    // Turn off blocking for reads, use (fd, F_SETFL, FNDELAY) if you want that 
    fcntl(fd, F_SETFL, 0); 


    } 

while(1){ 
    n = read(fd, (void*)buf, 255); 
    if (n < 0) { 
    perror("Read failed - "); 
    return -1; 
    } else if (n == 0) printf("No data on port\n"); 
    else { 
    buf[n] = '\0'; 
    printf("%i bytes read : %s", n, buf); 
    } 
sleep(1); 
printf("i'm still doing something"); 

} 
    close(fd); 
    return 0; 
} 
+0

你不應該設置'O_NONBLOCK'標誌使描述符無阻塞嗎? – 2013-04-11 12:50:15

+0

此外,直接從設備讀取數據時,您會讀取_raw_數據,然後將其轉換爲可以像終端一樣讀取的字符。 – 2013-04-11 12:52:51

+0

我只想補充一點,這是一個糟糕的RF-ID驅動程序實現。它應該作爲一個字符設備來實現。 – stdcall 2013-04-11 13:31:21

回答

8

按照Linux input documentation,部分5,在/ dev /輸入/ eventX設備返回數據如下:

可以使用阻塞和非阻塞讀取,還選擇()在 /dev/input/eventX設備,並且您將在讀取過程中始終獲得整數的輸入事件數 。它們的佈局是:

struct input_event { 
     struct timeval time; 
     unsigned short type; 
     unsigned short code; 
     unsigned int value; }; 

「時間」是時間戳,它返回該事件發生 的時間。類型例如是相對時刻的EV_REL,用於 按鍵或釋放的EV_KEY。 include/linux/input.h中定義了更多類型。

'code'是事件代碼,例如REL_X或KEY_BACKSPACE,同樣是一個 完整列表位於include/linux/input.h中。

「值」是事件攜帶的值。對於發佈版本,對於 EV_REL,EV_ABS(操縱桿...)的絕對新值,或對EV_KEY 爲0的相對改變,對於按鍵2和對於自動重複2的相對改變。

0

您的代碼在打開/dev/input/下的事件設備時顯然是錯誤的。即使你的錯誤信息矛盾的選擇:

perror("open_port: Unable to open /dev/ttyAMA0 - "); 

讀取/dev/input/eventN文件返回與事件描述(如指針移動或按下按鈕),而不是文本的二進制數據。您可能想要打開某種串行仿真設備。

+1

根據標題判斷,他確實想讀取'/ dev/input'下的內容,而不是'/ dev/ttyAMA0'。錯誤消息不正確。 – Hasturkun 2013-04-11 13:26:35