하드웨어
C221-S3C6410 보드에 있는 RS232 로 들어오는 데이터를 CAN 통신으로 보내는 프로그램은 다음과 같습니다.
#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 <linux/can.h> #include <linux/can/raw.h> #include <termios.h> #include <fcntl.h> #define BUFF_SIZE 1024 int main(int argc, char *argv[]) { char can_port[BUFF_SIZE]; char rs_port[BUFF_SIZE]; if (3 > argc) { printf("인수가 모자릅니다. 시리얼 포트를 입력하여 주시오\n"); printf("실행방법: ]$ ./app_rs232_to_can /dev/ttySAC3 can0\n"); exit(0); } sprintf(rs_port, argv[1]); // 사용할 시리얼 포트 디바이스 이름을 구한다. sprintf(can_port, argv[2]); // can 포트 디바이스 이름을 구한다. // can 포트 open int fd_can; struct sockaddr_can addr; struct can_frame frame; struct ifreq ifr; int ifindex; // can 포트를 open if (0 > (fd_can = socket(PF_CAN, SOCK_RAW, CAN_RAW))) { perror("socket"); return 1; } strcpy(ifr.ifr_name, can_port); // 사용할 CAN 번호 ioctl(fd_can, SIOCGIFINDEX, &ifr); ifindex = ifr.ifr_ifindex; addr.can_family = AF_CAN; addr.can_ifindex = 0; if (0 > bind(fd_can, (struct sockaddr *) &addr, sizeof(addr))) { perror("bind"); return 1; } // rs232 통신 포트 초기화 int fd_rs232; struct termios newtio; fd_rs232 = open(rs_port, O_RDWR | O_NOCTTY | O_NONBLOCK); memset(&newtio, 0, sizeof(newtio)); newtio.c_cflag = B115200; // 통신 속도 115200 newtio.c_cflag |= CS8; // 데이터 비트가 8bit newtio.c_cflag |= CLOCAL; // 외부 모뎀을 사용하지 않고 내부 통신 포트 사용 newtio.c_cflag |= CREAD; // 쓰기는 기본, 읽기도 가능하게 newtio.c_iflag = 0; // parity 비트는 없음 newtio.c_oflag = 0; newtio.c_lflag = 0; newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 1; tcflush(fd_rs232, TCIFLUSH); tcsetattr(fd_rs232, TCSANOW, &newtio); // 포트에 대한 통신 환경을 설정합니다. // poll 초기화 및 등록 struct pollfd poll_events; // 체크할 event 정보를 갖는 struct int poll_state; poll_events.fd = fd_rs232; 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 가 자료 수신? { char rx_buff[BUFF_SIZE + 1]; int rd_size; rd_size = read(fd_rs232, rx_buff, BUFF_SIZE); if (8 < rd_size) // CAN으로 전송할 수 있는 최대 바이트 수는 8 { printf("resize to 8"); rd_size = 8; } /* fill CAN frame */ frame.can_id = 0x32; frame.can_dlc = rd_size; memcpy(frame.data, rx_buff, rd_size); addr.can_family = AF_CAN; addr.can_ifindex = ifindex; /* send via this interface */ sendto(fd_can, &frame, sizeof(struct can_frame), 0, (struct sockaddr*) &addr, sizeof(addr)); } if (poll_events.revents & POLLERR) // event 가 에러? { printf("통신 라인에 에러가 발생, 프로그램 종료"); break; } } } close(fd_can); close(fd_rs232); return 0; } |
다음 강좌에서는 can to tcp 프로그램을 설명하도록 하겠습니다.