serial-howto에서 출력(write)가 안되네요...좀 봐주세요..
linux와 win과의 serial 통신을 하려구 합니다.
linux에서의 read는 잘 되는데.
반대로 linux에서 write를 통해 win으로 출력을 하려고 하면..
값이 이상한 값으로 출력이 됩니다..('-', ??)
문자열등..여러가지 테스트를 해봤는데 마찬가지이구요...
(며칠째 고생임다..)
아마도..출력시 termios의 설정이 달라서 그런것 같지만,
출력시 구체적으로 어떤 Flag를 사용해야 되는지 모르겠네요...
혹시 이부분에 대해 알고 계시면..부탁드립니다...
정말..이 부분만 끝나면..끝나는데..휴....
같은 linux박스에서 read write 테스트도 해봤는데 제대로 된 출력이 안되
는 건 마찬가지이구요....
write에서 문제가 있다는 건 확실한 것 같은데...도저히 잘 모르겠습니다.
관련 문서에두..이부분에 대한 내용이 없어서...ㅠ.ㅎ
write관련 소스 코드입니다..
#include
#include
#include
#include
#include
#include
#define BAUDRATE B19200
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
void signal_handler_IO (int status);
int wait_flag=TRUE;
char buf[255];
main()
{
int fd,c, res;
struct termios oldtio,newtio;
struct sigaction saio;
int n,i;
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd <0) {perror(MODEMDEVICE); exit(-1); }
saio.sa_handler = signal_handler_IO;
saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
fcntl(fd, F_SETOWN, getpid());
fcntl(fd, F_SETFL, FASYNC);
tcgetattr(fd,&oldtio);
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR | ICRNL;
newtio.c_oflag = OPOST;
newtio.c_lflag = 0;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
// printf("input data A");
buf[0]='A';
n=write(fd,buf,255);
if (n < 0)
{
fputs("wirte() of 4bytes failed!\n",stderr);
}
tcsetattr(fd,TCSANOW,&oldtio);
}
void signal_handler_IO (int status)
{
printf("received SIGIO signal.\n");
wait_flag = FALSE;
}
Re: serial-howto에서 출력(write)가 안되네요...좀 봐주세요..
코드를 자세하게 보기는 그렇고 해서 그냥 옛날에
비슷한 경험이 있어서 토를 답니다.
newtio.c_oflag = OPOST;
요놈 주석처리해서 함 해보세요...
되면 좋고, 아님 다시 고민상태로 ...
함 소스 테스트 해 봤으면 좋겠지만 널 케이블이 지금은 없어서리
그럼...
Re^2: 주석처리해도 마찬가지네요...ㅠ.ㅠ..그리고..
일단 답변해 주셔서 감사합니다.
그런데..
주석처리해도 마찬가지입니다...ㅠ.ㅠ
이 소스를 비슷하게(??) 해가지고 저번에 실제 제대로 출력을 받았었거든
요...
그런데 다시..몇가지 수정하다가..보니...안되더라구요...
뭐가 문제진...아무리..다시 뒤져보고, 찾아봐도..그대로 입니다...
휴....
이제는 아예...넋놓고 있네요..다른 방법으로 해결해야하는지..참네..
Re^3: 주석처리해도 마찬가지네요...ㅠ.ㅠ..그리고..
옛날에 제가 작성했던 장난감입니다.
참조하세요...
cr+lf의 유닉스와 윈도우 모드 자동전환을 안하시려면 raw output이라고
주석되어 있는 부분을 좀 고치면 될겁니다.
/*
* non-canonical mode(한 문자단위 입력 모드) serial programming
* nocan.c를 수정 본 것. */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if 0
#include "gfxdev.h"
#endif
enum comport_number { COM1, COM2, COM3, COM4 };
#define BAUDRATE B38400 //baudrate setting
#define _POSIX_SOURCE 1 // POSIX compliant source
struct termios oldtio, newtio; // for terminal attribute save &
setting
int serial_fd; // serial port file descriptor
int serial_open(int which_port)
{
char *port_str;
switch(which_port)
{
case COM1
port_str = "/dev/ttyS0";
break;
case COM2
port_str = "/dev/ttyS1";
break;
case COM3
port_str = "/dev/ttyS2";
break;
case COM4
port_str = "/dev/ttyS3";
break;
default
printf("input serial port error\n");
exit(EXIT_FAILURE);
}
serial_fd = open(port_str, O_RDWR | O_NOCTTY );
if( serial_fd < 0 )
{
printf("serial_port open error %s\n", port_str);
exit(-1);
}
tcgetattr(serial_fd,&oldtio); // 현재 설정을 oldtio에 저장
bzero(&newtio, sizeof(newtio));
//newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; // 흐름제어 없음
newtio.c_iflag = IGNPAR;
#if 0 // raw output
newtio.c_oflag &= ~OPOST;
#endif
// preprocessing output 즉 output하기 전에 어떤 처리를 해서 ouput
을 한다.
newtio.c_oflag |= OPOST; // post processing enable
newtio.c_oflag |= ONLCR; // 유닉스 용의 newline(NL'\n')을 dos용
의 newline인
// CR-NL('\r'\'n')으로 자동 전환 옵션
// set input mode (non-canonical, no echo,...)
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0; // 문자 사이의 timer를 disable
newtio.c_cc[VMIN] = 1; // 최소 5 문자 받을 때까진 blocking
tcflush(serial_fd, TCIFLUSH);
tcsetattr(serial_fd,TCSANOW,&newtio);
return 0;
}
void serial_close(void)
{
// 원래의 attribute로 돌려 놓는다.
tcsetattr(serial_fd, TCSANOW, &oldtio);
close(serial_fd);
}
void gprintf(char *fmt,...)
{
char buf[512];
int ret;
va_list ap;
va_start(ap,fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
ret = write(serial_fd, (void *)buf, strlen(buf));
if( ret < 0 )
{
printf("serial write error %s\n", strerror(errno));
}
}
int getch(void)
{
int read_bytes;
unsigned char buf;
read_bytes = read(serial_fd, &buf, 1); // 1 문자를 받으면 리턴
if( read_bytes > 0 )
return (int)buf;
if( (read_bytes < 0) && (errno != EINTR) && (errno != EAGAIN) )
return -1;
}
int main(void)
{
int i = 10, ch;
serial_open(COM2);
while(i--)
{
gprintf("serial_print %d\n", i);
}
ch = getch();
printf("ch = %d\n", ch);
gprintf("ch = %d\n", ch);
serial_close();
}
댓글 달기