2014-01-15 46 views
2

我正在寫一個程序,不斷髮出「你好」到CAN總線和通過SocketCAN總線讀取數據。我希望這兩個步驟是獨立的。這意味着即使公交車上沒有數據,程序仍會發送「Hello」。但是通常的CAN讀取是不可能的,因爲這個函數會停止程序運行並等待數據。SocketCAN連續讀取和寫入

有沒有辦法如何使它非阻塞或等待數據只有幾毫秒?

回答

2

您可以使用下面的星座(這是不完整的解決方案,而只是算法):

while(1) { 
    FD_ZERO(&rdfs); 
    FD_SET(s, &rdfs); 

    tv.tv_sec = 0; 
    tv.tv_usec = 10000; // microseconds 

    rc = select(s + 1, &rdfs, NULL, NULL, &tv); 

    // rc == 0 - timeout 
    if (!rc) { 
     // write your CAN frame 
    } 

    if (FD_ISSET(s, &rdfs)) { 
     // read CAN frames 
    } 
} 

man select瞭解更多信息,以及如何處理返回值。

+3

您不必使用'select'爲SocketCAN(雖然這不是一個問題,如果你這樣做的話);你也可以使用'setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,&t​​v,sizeof(tv))',其中'tv'是接收超時的'timeval'。然後,如果超時到期,'read'將會失敗並返回'EAGAIN'。 –

+0

@Jason C:我喜歡你的建議,但它並沒有爲我工作:我試圖如上,並與「setsockopt的(SKT,SOL_CAN_RAW,SO_RCVTIMEO,......」因爲這似乎更容易,但在這兩種情況下, 「讀」呼叫永遠阻塞,直到幀到達(無超時) – Jeremy

+0

哎呀,我的錯......從「窩」在Linux手冊:「如果超時設置爲零(默認值),則操作永遠不會超時。「如果沒有幀要讀取,我正在使用超時0來希望立即返回。 – Jeremy

3

另一種方式,我發現 - 線程。只需使線程中的CAN讀取工作,並且不會停止主循環。對於Linux系統,它看起來像這樣:

#include <pthread.h> 

    void *thread(int cansock) { 
     struct can_frame rxmsg;  
     while (1) { 
      read(cansock, &rxmsg, sizeof(rxmsg)); 
      printf("message received\n");      
     } 
    } 

    int main(){ 
// initialize CAN socket and message to send 
    pthread_t pth; 
    pthread_create(&pth, NULL, thread, cansock); 
    while(1){ 
     write(cansock, &txmsg, sizeof(txmsg)); 
     printf("message sent\n"); 
     } 
    return 0; 
    } 
+3

順便說一句,您可以使用'setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,&t​​v,sizeof(tv))'其中'tv'是一個'timeval'來設置讀取超時時間,如果超時過期,'read'將會失敗並返回'EAGAIN',您也可以使用['CAN_RAW_FILTER'](https://www.kernel.org/ doc/Documentation/networking/can.txt)來減少處理開銷並僅過濾感興趣的幀。 –

0

謹慎使用此解決方案:

void *thread(int cansock) { 
     struct can_frame rxmsg;  
     while (1) { 
      read(cansock, &rxmsg, sizeof(rxmsg)); 
      printf("message received\n");      
     } 
    } 

,因爲如果閱讀()開始無阻擋返回一個錯誤,這是在現場和有沒有人看看printf()的結果,你將進入一個繁忙的循環。

+0

這可能會損壞d作爲對另一個答案的評論更好;而不是本身的答案。我知道你還不能發表評論 - 請參閱[這篇文章](http://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-c​​an-i -do-instead/214174#214174)瞭解你可以在此期間做什麼的一些細節。 –