2015-08-21 81 views
1

GPIO閱讀的linux的sysfs我寫一個簡單的程序使用Linux的sysfs沒有輪詢閱讀GPIO,但似乎當我想讀低於三個字符龜etc並與fgets不能正常工作,我不知道這是否只是一個錯誤,或者如果我在我的代碼中犯錯誤。與龜etc

FILE* fd = fopen("/sys/class/gpio/gpio12/value", "rw+"); 
if(!fd) { 
    cerr << "could not open the file." << endl; 
} 
setbuf(fd, NULL); 

while(true) { 
    if(fseek(fd, 0L, SEEK_SET)) { 
     cerr << "could not reposition the indicator" << endl; 
    } 

    char val = fgetc(fd); 
    cout << val << '\r'; 

    cout.flush(); 
}; 

上面的代碼總是返回「0」,甚至當我申請一個高電位給GPIO#12,但是當我更換龜etc和它下面的行與這些

char str[3] = {0}; 
    fgets(str, 3, fd); 
    cout << str[0] << 'r'; 

線方案作品正確。另一方面,值文件只包含一個字符'1'或'0',並且可以考慮使用具有2或1個字符的fgets。在那種情況下它也不起作用。有人可以解釋一下那裏發生了什麼嗎?上面的代碼有什麼問題。 我使用g ++編譯代碼,我的gcc版本是4.6.3-14 armhf

回答

0

您可以使用/ bin/cat來顯示/ sys/class/gpio/gpioXX/value文件的內容。該文件的內容將是ASCII字符'0'或ASCII字符'1',後跟換行符'\ n'。

我覺得你可以簡單地去獲取文件中的零字節,看看它是否是一個ASCII「0」(的0x30)的字符或者ASCII「1」字符(0X31)。在這種情況下,緩衝I/O無效。

int fd; 
char val; 
int ret; 

if ((ret = open("/sys/class/gpio/gpio12/value", O_RDONLY)) < 0) { 
    // Fail. 
    return; 
} 

fd = ret; 

for (;;) { 
    if ((ret = lseek(fd, 0, SEEK_SET)) < 0) { 
     // Fail. 
     break; 
    } 
    if ((ret = read(fd, &val, 1)) < 0) { 
     // Fail. 
     break; 
    } 

    if ((val != 0x30) && (val != 0x31)) { 
     // Whiskey tango foxtrot. 
    } 

    val = val - 0x30; 

    fprintf(stdout, "val=%d\n", val); 
    fflush(stdout); 
}; 
+0

謝謝你的回覆,當然如果你提到'setbuf(fd,NULL)',我已經使用了非緩衝流;''是的,在這種情況下正確的閱讀工作,但爲什麼iso c fgetc不起作用。那是因爲復位操作不適用於fgetc或這樣的事情。 – AMCoded

+0

@AMCoded:你說你的fgetc例子不起作用,但是我在嵌入式EV500 PPC linux上試過了,它是A-OK。同樣,我不認爲你應該擔心,因爲它有大小兩個字節的sysfs虛擬文件操作時緩衝I/O的語義,只是使用open(2),lseek的(2),並讀取(2 ),也許你會把注意力集中在更有用的東西上。 – ewd

+0

好的,謝謝,因爲它在你的嵌入式系統中工作,我不會花更多的時間在它上面。我已經在raspbian上測試了上述代碼,用於覆盆子pi板。並沒有工作,所以我會把它標記爲raspbian gcc的bug。 – AMCoded