termio(블루투스)로 이미지 전송 시 속도 문제

hozeronoh의 이미지

임베디드 보드에 UART 라인에 RS232와 블루투스 칩을 달아두었습니다.
결국 한 라인을 스위칭해서 쓰는 구조인데요..

256 사이즈로 버퍼를 하나 할당해서
파일을 읽어다가 아래처럼 이미지를 전송해보앗습니다.

// termios 세팅부분
    struct termios newtioRS232;
    bzero(&newtioRS232, sizeof(newtioRS232));
 
    newtioRS232.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
    newtioRS232.c_iflag = IGNPAR;
    newtioRS232.c_oflag = 0;
    newtioRS232.c_lflag = 0;
    newtioRS232.c_cc[VMIN] = 1;
    newtioRS232.c_cc[VTIME] = 0;
 
    tcflush(mIntFd, TCIFLUSH);
    tcsetattr(mIntFd,TCSANOW, &newtioRS232);
 
// 데이터 전송 부분
#define BT_BUFF_SIZE 256
 
FILE *fp;
 
fp = fopen("/MEDIZS/window.bmp", "rb");
int readCnt, total = 0;
while(1){
   readCnt = fread((void*)buff, 1, BT_BUFF_SIZE, fp);
   total+=readCnt;
 
 
   if(readCnt < BT_BUFF_SIZE){
      write(mIntFd, &buff, readCnt);
      break;
    }
    write(mIntFd, &buff, BT_BUFF_SIZE);
 
}

RS232 케이블을 연결해서 PC로 이미지를 날려보면
위 코드처럼 한 버퍼를 보낼때마다 usleep 없이도
데이텉 손실없이 좍좍 날아가서 이미지가 전송되는데요..

블루투스 칩으로 전송해보면
손실이 있고.. 손실없이 보내려면
적어도 write 할대마다 270ms 정도 usleep을 주면 손실 없이 가긴 갑니다..

블루투스 칩의 문제인걸까요..? 아니면 세팅을 좀 바꿔서 하면 좀 더 나은 결과를 얻을수 있으려나요?

익명 사용자의 이미지

어떤 임베디드 보드를 사용 중이고 블루투스 칩셋은 어떤 걸 사용 중인가요?

hozeronoh의 이미지

보드는 i.mx6 dual 이고요 블루투스는 amped rf bt53이란 녀석입니다.

익명 사용자의 이미지

위의 상황은 통신 관련 경험이 부족한 사람들이 흔히 하는 실수 중에 하나입니다.
serial이나 BT 같이 전송 속도 제한이 있을 경우 POSIX write 함수는 크기보다 적게
전송할 수 있습니다. write의 결과 값을 확인하여 적게 전송한 경우 전송되지 않은
부분을 재전송하는 코드를 작성해 줘야 합니다.

hozeronoh의 이미지

송신쪽에서 256 Byte를 전송한다면,
전송이 이후 수신측에서 수신이 완료된 이후 자신이 몇바이트를 수신했는지
송신쪽에다가 다시 보내주어 송신쪽에서 보낸 길이와 수신에서 몇바이트를 받았는지
체크하는.. handshake 방식을 사용하라는 말씀이신가요..?

익명 사용자의 이미지

뭐 그런 셈이죠. 지금 코드를 보니 단순히 "나는 몇 바이트 받았다"는 것만 송신측에 알려 주고 있네요. 그래서 그 정보를 좀 유용하게 써야 한다는 거죠.

익명 사용자의 이미지

write 함수의 manual page를 읽어보시면 제가 쓴 글이 무슨 뜻인지 알 수 있습니다.
지금 글을 읽어보니 write 함수가 리턴 값을 반환하는 함수인 것을 전혀 모르고 있는 것 같습니다.
기본 과정이 잘못된 거라 따로 handshake나 복잡한 과정 없이도 해결되는 문제입니다.

bushi의 이미지

송신측 커널 버퍼에 복사된 바이트 갯수는 수신측이 수신한 바이트 갯수, 그러니까 rx fifo overflow 가 얼마나 일어났는지와는 무관합니다.
이런 걸 방지하려고 있는게 rs232 flow control 이죠.

그런데, (무선 환경 처럼) 항상 flow control 이 가능할 수가 없으니https://elixir.bootlin.com/linux/latest/source/drivers/tty/n_hdlc.c 같은게 나왔습니다.
link 수준에서 뭔가 보장이 되야 handshake 프토코콜을 그 위에 얹죠.
송수신측 모두가 linux 라면, tty open 후에 TIOCSETD ioctl 를 이용하면, N_TTY 대신 N_HDLC 를 사용할 수 있습니다.

쉽게 말하면, handshake 같은 간단한 방법으로는 해결을 할 수 없는 복잡한 문제입니다.

덧.

예제 링크를 잘 못 단 것 같습니다.
기억이 오래되서 어떤 소스인지 가물가물한데, 차라리 HDLC 에 대한 RFC 를 보거나 PPP 프로그램에서 frame 단위로 어떻게 송수신(인코딩/디코딩) 하는지 보시는게 좋을 것 같습니다.
몇 년전인지조차도 가물거리는데...
어느 고객께서 자신들의 PPP 서버는 HDLC 기반으로 되어 있으니 알아서 잘 붙으라는 얘기를 전해듣고 PPP 와 HDLC 를 접붙여야 테스트가 될 것 같아 코드로 고민을 좀 했는데,
알고보니 비표준 PPP 서버를 만들어 놓고는 뻥을 친 것이더군요.
표준 PPP 서버는 초기 접속 때 서버와 클라이언트가 교섭을 해서 escape sequence 를 적용해야 할 문자와 그렇지 않은 문자를 정하는데,
이놈의 서버는 STX,ETX 쯤에 해당하는 문자 빼고는 처음부터 죄다 escape sequence 를 적용하지 않는 것으로 가정하고 돌고 있었습니다.
리눅스 ppp 옵션만 조정하니 그냥 붙더군요.

익명 사용자의 이미지

그리고 위의 경우 대기 시간을 주면 제대로 전송이 된다고 하는 것으로 보아 write의 결과 값을
확인하라는 답변을 쓴 것입니다. 무선 통신 오류에 의한 손실일 경우 대기 시간을 준다고 오류율이
크게 바뀌지 않습니다. CRC 확인이나 재전송은 블루투스에서도 구현하고 있으므로 굳이 PPP나
HDLC까지 등장할 이유는 없어 보입니다.

익명 사용자의 이미지

CTS/RTS 핀이 연결된 경우라도 소스 코드에서 CTS/RTS를 사용하게 해 줘야 합니다.
지금 보이는 소스 코드에서는 CTS/RTS를 사용하고 있지 않으므로 UART 구간에서 데이터
손실이 발생할 수 있습니다.

댓글 달기

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