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 프로그램을 설명하도록 하겠습니다.