시리얼통신에서 데이터를 놓침니다..

cdcmp의 이미지

안녕하세요...

시리얼 통신으로 센서 입력을 받고 있는데요...

입력 받은 데이터를 확인 하면 계속 데이터를 잃어버립니다...

코드는 다음과 같습니다...

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>


#define  SERIALDEVICE "/dev/ttyMP1"
#define  BAUDRATE B9600

#define FALSE 0
#define TRUE 1

volatile int READ_LOOP = TRUE;
volatile int WRITE_LOOP = TRUE; 


unsigned char tx_buf[8];
unsigned char rx_buf[10000];

FILE *fp;

main()
{
	tx_buf[0] = 0x02;
    	tx_buf[1] = 0x00;
    	tx_buf[2] = 0x02;
    	tx_buf[3] = 0x00;
    	tx_buf[4] = 0x20;
    	tx_buf[5] = 0x24;
    	tx_buf[6] = 0x34;
    	tx_buf[7] = 0x08;

	int fd;
	int i,res;
	struct termios oldtio, newtio;
	
	fd = open(SERIALDEVICE,O_RDWR|O_NOCTTY);
	if(fd<0)
	{
		printf("file open error\n");
		perror(SERIALDEVICE);
		exit(-1); 
	}
			
	tcgetattr(fd,&oldtio);
	bzero(&newtio, sizeof(newtio));
	newtio.c_cflag= (CS8+BAUDRATE+CREAD+CLOCAL+HUPCL);
	newtio.c_lflag &= ~ICANON;
	newtio.c_iflag = IGNPAR | ICRNL;
	newtio.c_oflag = 0;
	
	tcflush(fd, TCIFLUSH);
	tcsetattr(fd,TCSANOW,&newtio);
		
	while(WRITE_LOOP == TRUE)
	{
		for(i=0;i<8;i++)
		{		
			write(fd,&tx_buf[i],8);
		}

		WRITE_LOOP = FALSE;
		i = 0;
	}
	
	while(READ_LOOP == TRUE)
	{
		fp = fopen("/home/eunsu/serial/laser1/can/data.txt","a+");		
			
		read(fd,&rx_buf[i],sizeof(rx_buf));
		fprintf(fp,"%x \n",rx_buf[i]);
		printf("%x \n",rx_buf[i]);
		i++ ;
		fclose(fp);
	}
	tcsetattr(fd,TCSANOW,&oldtio);
}

pc에서 8개의 데이터를 센서로 보내면 센서에서는 측정한 데이터를 pc로

계속 보내게 되는 겁니다..

센서는 거리측정용 레이져 센서입니다..

그런데 입력 받은 데이터를 확인 하면 잃어버린 데이터가 많습니다..

read해서 버퍼에 저장된 데이터를 루프가 한번 돌때마다 한번씩 프린트 하게

했습니다..

그 이유 때문인지는 모르겠지만....

버퍼에 입력된 데이터를 저장한후 몇 바이트 단위로 한꺼번에 출력을 해야

하는지...

지금은 한번 저장된 데이터를 바로 출력 하게 했거든요...

이거 실험하다가 비싼 센서도 고장나 버리고.....

바로바로 되는게 너무 없는거 같습니다...ㅜㅜ

hb_kim의 이미지

데이터를 안잃어버리려면 하드웨어건 소프트웨어건 flow control 을 해야 합니다. 즉 상대방이 데이터를 받을 준비가 되어 있지 않을때는 이쪽에서 보낼 데이터가 있어도 전송하지 않고 기다려야 합니다. 보통 실제 시스템에서는 시리얼 포트가 절대적으로 중요한 기능에 사용되지 않는 경우에 flow control 을 끄도록 세팅된 경우가 많습니다. flow control 을 사용하면 상대방의 시스템이 죽으면 이쪽의 시스템도 정지되어야 하니까요. 센서의 스펙을 한번 보세요, flow control 이 있는지. 있다면 이쪽 시리얼 포트도 같은 방법의 flow control을 쓰도록 설정해줘야 됩니다.

flow control 이 없는 상태에서 데이터를 잃어버리는 것을 '최소화' 하려면 (완전히 없애지는 못합니다) 데이터를 될수 있으면 빨리, 효율적으로 받으면 됩니다. 시스템을 빠른것으로 쓰고, FIFO 크기가 큰 UART 칩을 쓰고, 소프트웨어 버퍼도 늘리고, 드라이버에서 ZIO 처리도 하고 애플리케이션은 불필요한 동작을 줄이고 등등.

그래도 잃어버리는 데이터가 있을수 있으니까, 데이터를 패킷화해서 CRC 도 붙이고 재전송 처리도 하고... 제대로 하려면 꽤 복잡해지죠?

mach의 이미지

read()하기 전에 select()를 사용해서 데이터가 왔는지를 대기하도록
프로그램을 수정하시고, 터미널의 버퍼크기를 조절하세요.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.