리눅스 C언어 시리얼 통신 질문이요...
글쓴이: 러닝@Naver / 작성시간: 월, 2018/06/04 - 10:55오후
시리얼 통신으로 데이터를 읽는데 터미널 프로그램들은 손실없이 잘 읽어들이는데,,,
제가 짠 프로그램은 데이터가 잘려서 들어오는 군요...
예를 들면
*abcdefg 이런 데이터가 있다면 터미널 프로그램에서는
[*abcdefg*abcdefg*abcdefg*abcdefg*abcdefg*abcdefg] 이렇게 연속적으로 잘들어옵니다.
그런데 제가 짠 프로그램에서는
[*abcdefg*abcegbc*abcdefg*abcdefgdefg*abcdebcdefg*abcdefg*abcdefg] 잘 들어오는 것과 손실된것이 섞여 있습니다.
원인이 무엇일까요... ㅠㅠ
보내는 쪽은 1초에 10번 보내고 있습니다.(*abcdefg)
struct termios fire_ter; memset(&fire_ter, 0, sizeof(fire_ter)); fire_ter.c_cflag = B9600 | CS8 | CLOCAL | CREAD; fire_ter.c_iflag = IGNPAR; fire_ter.c_oflag = 0; fire_ter.c_lflag = 0; fire_ter.c_cc[VTIME] = 0; fire_ter.c_cc[VMIN] = 1; tcflush(fd_serial, TCIFLUSH); tcsetattr(fd_serial, TCSANOW, &fire_ter); 설정부분 --------------------------------------------------- void* read_serial_send_sock(void *arg){ int sec = 1000000; char stx = '*', *buf = malloc(sizeof(char) * buf_size); pth_param* pp = (pth_param*)arg; int fd_serial = pp->fd1; int sock = pp->fd2; int len = 0; while(1){ int serial_read_len = read(fd_serial, buf, buf_size); printf("serial_read_len: %d \n", serial_read_len); if(serial_read_len > 0){ if(buf[0] == stx){ printf("if : %s \n", buf); } } usleep(sec/10); } 읽어 들이는 쪽
Forums:
buf[0]에 항상 '*'이 들어올꺼라는 생각은
buf[0]에 항상 '*'이 들어올꺼라는 생각은 하시면 안됩니다.
추가적으로 궁금한게 논블럭이 아니라면 아래 코드를
추가적으로 궁금한게 논블럭이 아니라면 아래 코드를
이렇게 바꾸는건 문제 될게 있나요?
음... *은 깨진 데이터는 무시하려고 넣었습니다.
음... *은 깨진 데이터는 무시하려고 넣었습니다.
바꾸는것도 문제는 없는데 *abcdefg 요거를 받아야되는데
cdefg 이렇게나 *abcd 이렇게 데이터가 깨지니까 못쓰겠더군요...
그래서 아에 버려버릴려고 *부터 받는걸로 했었습니다.
시리얼 설정이 잘못된건지... 버퍼를 건드려야되는지...
보내는 쪽과 받는쪽의 동기가 잘 맞다가 안맞다가 요러는거 같아요...
찾아보니 이런 내용이 있네요
찾아보니 이런 내용이 있네요
https://kldp.org/node/58340
동기화는 아닙니다. 시리얼 통신 자체가
동기화는 아닙니다. 시리얼 통신 자체가 asynchronous 통신이기 때문이죠.
데이터가 빠지는 것은 시리얼로 받은 데이터를 임시 보관하는 버퍼가 다른 데이터를 받기 전에 받아야 하는데 그러지 않아서 다른 데이터로 덮어지기 때문입니다.
하려고 하는 시리얼 방식을 잘 이해하지 못하겠지만 (제공 자료가 부족하고 직접 연관된 부분이 없는 것으로 보입니다) 언뜻 봐서는 초당 20회 정도로 read()를 실행해 보면 되지 않나 싶습니다.
하지만 커널 드라이버가 아닌 일반 어플리케이션에서 바로 read()를 읽어서 쓰는 것은 일반적인 접근은 아닙니다. 어디까지나 커널 드라이버에서 read()를 호출 해 유저 데이터 버퍼에 넘겨주고, 유저 어플리케이션에서는 유저 데이터 버퍼에 들어있는 것을 사용하는 것이 좋습니다.
댓글 달기