2014-01-15 11 views
2

"Hello"를 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

SocketCAN에'select'를 사용할 필요는 없습니다 (그렇게해도 문제는 아닙니다). 당신은'setsockopt (SOL_SOCKET, SO_RCVTIMEO, & tv, sizeof (tv))'를 사용할 수있다.'tv'는 수신 타임 아웃을위한'timeval'이다. 타임 아웃이 만료되면'read '는'EAGAIN'과 함께 실패합니다. –

+0

@ Jason C : 나는 당신의 제안을 좋아하지만, 저에게는 효과가 없습니다. 위와 같이 시도했는데 "setsockopt (skt, SOL_CAN_RAW, SO_RCVTIMEO, ...)"로 시도했습니다. "read"호출이 프레임이 도착할 때까지 영원히 차단됨 (시간 초과 없음) – Jeremy

+0

"소켓"에 대한 리눅스 매뉴얼에서 실수로 ... "시간 초과가 0으로 설정된 경우 (기본값) 작업이 절대로 시간 초과되지 않습니다 "프레임을 읽을 필요가 없다면 즉각적으로 반환 할 수 있도록 타임 아웃을 0으로 사용하고 있습니다. – Jeremy

3

내가 찾은 또 다른 방법은 - 스레드입니다. 스레드에서 CAN 읽기 작업을 수행하면 주주기가 중지되지 않습니다. 리눅스 시스템의 경우는 다음과 같습니다

#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 (SOL_SOCKET, SO_RCVTIMEO, & tv, 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

This woul 다른 대답에 대한 의견으로는 더 낫다. 그 자체가 대답이 아닙니다. 아직 댓글을 달 수 없다는 것을 알고 있습니다. [이 게시물] (http://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i)를 참조하십시오. -do- 대신/214174 # 214174)를 사용하십시오. –