리눅스 C언어 시리얼 통신 질문이요...

러닝@Naver의 이미지

시리얼 통신으로 데이터를 읽는데 터미널 프로그램들은 손실없이 잘 읽어들이는데,,,
제가 짠 프로그램은 데이터가 잘려서 들어오는 군요...

예를 들면

*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);
}
읽어 들이는 쪽
익명 사용자의 이미지

buf[0]에 항상 '*'이 들어올꺼라는 생각은 하시면 안됩니다.

익명 사용자의 이미지

추가적으로 궁금한게 논블럭이 아니라면 아래 코드를

        if(serial_read_len > 0){
            if(buf[0] == stx){
             printf("if : %s \n", buf);
        }

이렇게 바꾸는건 문제 될게 있나요?

        if(serial_read_len > 0)
        {
            printf("if : %s \n", buf);
        }
        bzero(buf,sizeof(buf));

러닝@Naver의 이미지

음... *은 깨진 데이터는 무시하려고 넣었습니다.
바꾸는것도 문제는 없는데 *abcdefg 요거를 받아야되는데
cdefg 이렇게나 *abcd 이렇게 데이터가 깨지니까 못쓰겠더군요...
그래서 아에 버려버릴려고 *부터 받는걸로 했었습니다.
시리얼 설정이 잘못된건지... 버퍼를 건드려야되는지...
보내는 쪽과 받는쪽의 동기가 잘 맞다가 안맞다가 요러는거 같아요...

익명 사용자의 이미지

찾아보니 이런 내용이 있네요

https://kldp.org/node/58340

라스코니의 이미지

동기화는 아닙니다. 시리얼 통신 자체가 asynchronous 통신이기 때문이죠.
데이터가 빠지는 것은 시리얼로 받은 데이터를 임시 보관하는 버퍼가 다른 데이터를 받기 전에 받아야 하는데 그러지 않아서 다른 데이터로 덮어지기 때문입니다.

하려고 하는 시리얼 방식을 잘 이해하지 못하겠지만 (제공 자료가 부족하고 직접 연관된 부분이 없는 것으로 보입니다) 언뜻 봐서는 초당 20회 정도로 read()를 실행해 보면 되지 않나 싶습니다.

하지만 커널 드라이버가 아닌 일반 어플리케이션에서 바로 read()를 읽어서 쓰는 것은 일반적인 접근은 아닙니다. 어디까지나 커널 드라이버에서 read()를 호출 해 유저 데이터 버퍼에 넘겨주고, 유저 어플리케이션에서는 유저 데이터 버퍼에 들어있는 것을 사용하는 것이 좋습니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.