COM포트로 들어오는 데이터를 파일에 쓰기...
글쓴이: leolo / 작성시간: 목, 2003/07/10 - 8:52오후
리눅스에서 COM포트로 들어오는 데이터를
파일로 쓰고 싶습니다.
COM포트에는 데이터를 받기위한 장비가 설치되어있습니다.
이 경우 open하고 select하면 될꺼 같은데.
보낸 데이터와 받은 데이터가 다릅니다.
com = open("/dev/ttyS1", O_RDONLY);
while(1){
FD_ZERO(&rfd);
FD_SET(com, &rfd);
select(maxfd+1, &rfd, NULL, NULL, (struct timeval*)0);
if(FD_ISSET(com, &rfd)){
file write....
}
}
대충 이렇게 하니까.. 보낸 데이터와 파일에 써지는 데이터가 다릅니다.
써지는 데이터가 순서가 다르게 라이트 되네요...
원인이 무엇인지 알고 싶습니다.
[/code]
Forums:


소스 올립니다.baud는 매크로로 이미 정의되어 있는게 있습니다.
소스 올립니다.
baud는
매크로로 이미 정의되어 있는게 있습니다.
/usr/include/termios.h 에
B9600, B19200 같은식으로 헤더에 있습니다.
더 많은 정보가 termios.h에 친절하게도 잘 되어 있네요.
주석 없어도 한눈에 보이니까 걱정 마시고 한번 보시면 좋을듯 합니다.
이건 제가 쓰는 용도가 고정되어 이렇게 쓰는것뿐이고
더 많은 기능을 알아보세요.
/* Copyright (c) 2002 Information Equipment co.,LTD. All Right Reserved. Code by JaeHyuk Cho <minzkn@infoeq.co.kr> */ #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> #include <sys/time.h> int MZ_OpenSerial(void *s_DeviceName, int s_Baud); int MZ_CloseSerial(int s_Handle); int MZ_RecvSerial(int s_Handle, void *s_Buffer, int s_Length, int s_Timeout_Sec, int s_Timeout_uSec); int MZ_SendSerial(int s_Handle, void *s_Buffer, int s_Length, int s_Timeout_Sec, int s_Timeout_uSec); int MZ_OpenSerial(void *s_DeviceName, int s_Baud) { int s_Return = (-1); if(s_DeviceName == (void *)0)s_DeviceName = "/dev/ttyS0"; s_Return = open((char *)s_DeviceName, O_RDWR | O_NOCTTY | O_NONBLOCK, 0644); if(s_Return >= 0) { struct termios s_Termios; int s_Count; if(tcgetattr(s_Return, &s_Termios) == 0) { s_Termios.c_iflag = IGNBRK | IGNPAR; s_Termios.c_oflag = 0; s_Termios.c_cflag = CS8 | CLOCAL; s_Termios.c_lflag = 0; for(s_Count = 0;s_Count < NCCS;s_Count++)s_Termios.c_cc[s_Count] = 0; s_Termios.c_cc[VMIN] = 1; s_Termios.c_cc[VTIME] = 0; if((cfsetispeed(&s_Termios, s_Baud) < 0) || (cfsetispeed(&s_Termios, s_Baud) < 0)) { close(s_Return); s_Return = (-1); fprintf(stderr, "%s: %s - [ERROR] Can not set speed !!!\n", __FILE__, __FUNCTION__); } else { if(tcsetattr(s_Return, TCSANOW, &s_Termios) < 0) { close(s_Return); s_Return = (-1); fprintf(stderr, "%s: %s - [ERROR] Can not set attr !!!\n", __FILE__, __FUNCTION__); } else { if(tcflush(s_Return, TCIOFLUSH) < 0) { close(s_Return); s_Return = (-1); fprintf(stderr, "%s: %s - [ERROR] Can not flush tcio !!!\n", __FILE__, __FUNCTION__); } } } } else { close(s_Return); s_Return = (-1); fprintf(stderr, "%s: %s - [ERROR] Can not get termios structure !!!\n", __FILE__, __FUNCTION__); } } else fprintf(stderr, "%s: %s - [ERROR] Can not open serial device \"%s\" !!!\n", __FILE__, __FUNCTION__, (char *)s_DeviceName); return(s_Return); } int MZ_CloseSerial(int s_Handle) { if(s_Handle >= 0)close(s_Handle); s_Handle = (-1); return(s_Handle); } int MZ_RecvSerial(int s_Handle, void *s_Buffer, int s_Length, int s_Timeout_Sec, int s_Timeout_uSec) { int s_Return = (-1); struct timeval s_TimeVal; fd_set s_fdread; int s_IsSelect, s_IsFDRead, s_RecvSize; if(s_Handle >= 0) { if(s_Buffer) { if(s_Length > 0) { do { FD_ZERO(&s_fdread); FD_SET(s_Handle, &s_fdread); s_TimeVal.tv_sec = (s_Timeout_Sec >= 0 ? s_Timeout_Sec : 1); s_TimeVal.tv_usec = (s_Timeout_uSec >= 0 ? s_Timeout_uSec : 1); s_IsSelect = select(s_Handle + 1, &s_fdread, (fd_set *)0, (fd_set *)0, &s_TimeVal); s_IsFDRead = FD_ISSET(s_Handle, &s_fdread); if(s_IsSelect > 0 && s_IsFDRead != 0) { if(s_Return < 0)s_Return = 0; s_RecvSize = read(s_Handle, (void *)(((char *)s_Buffer) + s_Return), s_Length); if(s_RecvSize > 0) { s_Return += s_RecvSize; s_Length -= s_RecvSize; } else { if(s_RecvSize < 0)fprintf(stderr, "%s: %s - [ERROR] Serial error !!!\n", __FILE__, __FUNCTION__); break; } } else break; }while(s_Length > 0); } else fprintf(stderr, "%s: %s - [ERROR] s_Length <= 0 !!!\n", __FILE__, __FUNCTION__); } else fprintf(stderr, "%s: %s - [ERROR] s_Buffer is null !!!\n", __FILE__, __FUNCTION__); } else fprintf(stderr, "%s: %s - [ERROR] s_Handle < 0 !!!\n", __FILE__, __FUNCTION__); return(s_Return); } int MZ_SendSerial(int s_Handle, void *s_Buffer, int s_Length, int s_Timeout_Sec, int s_Timeout_uSec) { int s_Return = (-1); int s_SendSize; (void)s_Timeout_Sec, (void)s_Timeout_uSec; if(s_Handle >= 0) { if(s_Buffer) { if(s_Length > 0) { do { if(s_Return < 0)s_Return = 0; s_SendSize = write(s_Handle, (void *)(((char *)s_Buffer) + s_Return), s_Length); if(s_SendSize > 0) { s_Return += s_SendSize; s_Length -= s_SendSize; } else { if(s_SendSize < 0)fprintf(stderr, "%s: %s - [ERROR] Serial error !!!\n", __FILE__, __FUNCTION__); break; } }while(s_Length > 0); } else fprintf(stderr, "%s: %s - [ERROR] s_Length <= 0 !!!\n", __FILE__, __FUNCTION__); } else fprintf(stderr, "%s: %s - [ERROR] s_Buffer is null !!!\n", __FILE__, __FUNCTION__); } else fprintf(stderr, "%s: %s - [ERROR] s_Handle < 0 !!!\n", __FILE__, __FUNCTION__); return(s_Return); } /* End of source */Re: COM포트로 들어오는 데이터를 파일에 쓰기...
com 포트, 유닉스 개념상 파일이지요. 파일일지라도 com포트는 단지 open하고 select해서는 안됩니다. 원격지와 통신(IO)하기위해 특별한 조작을 해주어야합니다. 조작은 통신속도, 패리티등인데요. 이 파라메터가 원격지와 일치해야 원하는 값을 가지고 통신할 수 있습니다.
조작하는 방법은 ioctl()을 사용하며, ioctl()에 넣어주는 파라메터는 운영체제별로 다 틀립니다.
이때 파라메터를 맞추는 방법은, 리눅스쪽에서 통신하는 장비쪽으로 스펙 맞추는것이 일반적인 방법입니다. 장비의 능력에 맞춘다고나 할까요?
그리고, 세팅하는 방법의 실질적인 한가지 사례는 minzkn님의 예가 있군요 8)
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
제가 참 어리석었군요..
제가 참 어리석었군요..
ㅎㅎ
그럼 한가지 더 질문 드릴께요..
c_cflag 세팅을 해야하는데요..
이 경우 어떻게 하죠..
9600bps, 8 data-bits, Non parity, 1 stop-bit, H/W flow control을
세팅하고 싶은데 어떻게 하죠..
이렇게 하면 되나요..
#define BAUDRATE B9600
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
이렇게 하면 되나요..
또, 9600bps, 8 data-bits, Non parity, 1 stop-bit, NO flow control을
세팅하고 싶은데 어떻게 하죠..
이렇게 하면 되나요..
#define BAUDRATE B9600
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
newtio.c_cflag &= ~CRTSCTS
이렇게 하면 되나요..
실력이 있으면 삶이 편하다... 영차 영차...
댓글 달기