하드웨어
C221-S3C6410 보드에 있는 CAN 으로 들어오는 데이터를 UDP 통신으로 보내는 프로그램은 다음과 같습니다.
#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 <sys/poll.h> #include <net/if.h> #include <arpa/inet.h> #include <sys/socket.h> #include <linux/can.h> #include <linux/can/raw.h> #define BUFF_SIZE 1024 int main( int argc, char *argv[]) { char can_port[BUFF_SIZE]; char server_ip[BUFF_SIZE]; if ( 3 > argc){ printf( "인수가 모자릅니다. 포트의 서버 IP를 입력하여 주십시오.\n"); printf( "실행방법: ]$ ./app_can_to_485 can0 127.0.0.1\n"); exit( 0); } sprintf( can_port , argv[1]); sprintf( server_ip , argv[2]); // can 포트 open //////////////////////////////////////////////////////////// int fd_sock; struct sockaddr_can addr; struct can_filter rfilter[4]; struct ifreq ifr; int ifindex; // can 포트를 open if ( 0 > ( fd_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( fd_sock, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); strcpy( ifr.ifr_name, can_port); // 사용할 CAN 번호 ioctl( fd_sock, SIOCGIFINDEX, &ifr); ifindex = ifr.ifr_ifindex; addr.can_family = AF_CAN; addr.can_ifindex = ifindex; if ( bind( fd_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; } // poll 초기화 및 등록 //////////////////////////////////////////////////// struct pollfd poll_events; // 체크할 event 정보를 갖는 struct int poll_state; poll_events.fd = fd_sock; poll_events.events = POLLIN | POLLERR; // 수신된 자료가 있는지, 에러가 있는지 poll_events.revents = 0; // 자료 송수신 //////////////////////////////////////////////////////////// while ( 1) { poll_state = poll( // poll()을 호출하여 event 발생 여부 확인 (struct pollfd*)&poll_events, // event 등록 변수 1, // 체크할 pollfd 개수 1000 // time out 시간 ); if ( 0 < poll_state) // 발생한 event 가 있음 { if ( poll_events.revents & POLLIN) // event 가 자료 수신? { struct can_frame frame; int rd_size; rd_size = read( fd_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 { int sock_client; struct sockaddr_in server_addr; char tx_buff[BUFF_SIZE+1]; int ndx; if (frame.can_id & CAN_EFF_FLAG) printf("%8X ", frame.can_id & CAN_EFF_MASK); else printf("%3X ", frame.can_id & CAN_SFF_MASK); if (frame.can_id & CAN_RTR_FLAG) printf("remote request"); printf(" [%d] ", frame.can_dlc); for ( ndx = 0; ndx < frame.can_dlc; ndx++) { printf("%02X ", frame.data[ndx]); tx_buff[ndx] = frame.data[ndx]; } printf("\n"); tx_buff[ndx++] = '\0'; sock_client = socket( PF_INET, SOCK_DGRAM, 0); if( -1 == sock_client) { printf( "socket 생성 실패n"); } memset( &server_addr, 0, sizeof( server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons( 4000); server_addr.sin_addr.s_addr= inet_addr( server_ip); sendto( sock_client, tx_buff, ndx, 0, // +1: NULL까지 포함해서 전송 ( struct sockaddr*)&server_addr, sizeof( server_addr)); close( sock_client); } } if ( poll_events.revents & POLLERR) // event 가 에러? { printf( "통신 라인에 에러가 발생, 프로그램 종료"); break; } } } close( fd_sock ); return 0; } |
===========
다음 강좌에서는 tcp to can 프로그램을 설명하도록 하겠습니다