하드웨어
$ echo "500000" > /sys/class/net/can0/can_bittiming/bitrate $ ifconfig can0 up |
$ echo "500000" > /sys/class/net/can1/can_bittiming/bitrate $ ifconfig can1 up |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <linux/can.h> #include <linux/can/raw.h> int main( int argc, char *argv[]) { int fd_can; struct sockaddr_can addr; struct can_frame frame; int nbytes; struct ifreq ifr; int ifindex; if ( 2 > argc){ printf( "인수가 모자릅니다. 시리얼 포트를 입력하여 주시오\n"); printf( "실행방법: ]$ ./app_can_sender can0\n"); exit( 0); } if ( 0 > ( fd_can = socket(PF_CAN, SOCK_RAW, CAN_RAW)) ) { perror("socket"); return 1; } strcpy(ifr.ifr_name, argv[1]); ioctl( fd_can, SIOCGIFINDEX, &ifr); ifindex = ifr.ifr_ifindex; addr.can_family = AF_CAN; addr.can_ifindex = 0; /* bind to all interfaces */ if ( 0 > bind( fd_can, (struct sockaddr *)&addr, sizeof(addr)) ) { perror("bind"); return 1; } /* fill CAN frame */ frame.can_id = 0x32; frame.can_dlc = 8; frame.data[0] = 0x46; // 'F' frame.data[1] = 0x41; // 'A' frame.data[2] = 0x4C; // 'L' frame.data[3] = 0x69; // 'i' frame.data[4] = 0x6E; // 'n' frame.data[5] = 0x75; // 'u' frame.data[6] = 0x78; // 'x' frame.data[7] = 0x21; // '!' addr.can_family = AF_CAN; addr.can_ifindex = ifindex; /* send via this interface */ nbytes = sendto( fd_can, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr, sizeof(addr)); close( fd_can); return 0; } |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <linux/can.h> #include <linux/can/raw.h> int main( int argc, char *argv[]) { int sock; struct sockaddr_can addr; struct can_filter rfilter[4]; struct can_frame frame; int ndx; struct ifreq ifr; int ifindex; if ( 2 > argc){ printf( "인수가 모자릅니다. 시리얼 포트를 입력하여 주시오\n"); printf( "실행방법: ]$ ./app_can_receiver can0\n"); exit( 0); } // can 포트를 open if ( 0 > (sock = socket(PF_CAN, SOCK_RAW, CAN_RAW))) { perror("socket"); return 1; } rfilter[0].can_id = 0x32; rfilter[0].can_mask = CAN_SFF_MASK; rfilter[1].can_id = 0x200; rfilter[1].can_mask = 0x700; rfilter[2].can_id = 0x80123456; rfilter[2].can_mask = 0x1FFFF000; rfilter[3].can_id = 0x80333333; rfilter[3].can_mask = CAN_EFF_MASK; setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); strcpy( ifr.ifr_name, argv[1]); // 사용할 CAN 번호 ioctl(sock, SIOCGIFINDEX, &ifr); ifindex = ifr.ifr_ifindex; addr.can_family = AF_CAN; addr.can_ifindex = ifindex; if (bind( sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; } while ( 1 ) { int rd_size; rd_size = read( sock, &frame, sizeof(struct can_frame)); if ( 0 > rd_size) { fprintf(stderr, "read error"); } else if ( rd_size < sizeof( struct can_frame)) { fprintf(stderr, "read: incomplete CAN frame\n"); return 1; } else { if (frame.can_id & CAN_EFF_FLAG) printf("%8X ", frame.can_id & CAN_EFF_MASK); else printf("%3X ", frame.can_id & CAN_SFF_MASK); printf("[%d] ", frame.can_dlc); for ( ndx = 0; ndx < frame.can_dlc; ndx++) { printf("%02X ", frame.data[ndx]); } if (frame.can_id & CAN_RTR_FLAG) printf("remote request"); printf("\n"); fflush(stdout); } } close( sock); return 0; } |
위의 프로그램을 작성하였다면 C221-S3C6410 보드에서 테스트하는 방법을 아래와 같습니다.
$ ./app_can_sender can0 & |
CAN1 포트로 데이타를 수신합니다.
$ ./app_can_receiver can1 |
위의 소스 및 실행 프로그램은 C221-S3C6410 보드를 구매하시면 제공되는 소스들입니다.
다음 강좌에서는 C221-S3C6410 보드에 있는 WLAN 설정 방법을 소개하도록 하겠습니다.
좋은 내용 감사합니다!!
receiver 프로그램에서 질문이 있습니다.
filter가 왜 4개인지, 다른 사이트를 찾아봐도 filter의 갯수는 다 다르던데...
filter의 적용 규칙이 어떻게 되는건가요? 찾기가 참 힘드네요.
오래된 글이라 답변이 달릴지 모르겠군요ㅠㅠ