3

シリアル接続でファイルを送信するには、助けが必要です。RS232 から USB へのケーブルが 2 本あり、1 本をデータの送信に使用し、もう 1 本をデータの受信に使用してコードをテストしています。両方を物理的に接続しています。

そのため、いくつかのソースから適合させたコードをいくつか書きましたが、一連の文字を正常に転送できます。1 つのプログラムがデータを受信し、もう 1 つのプログラムがデータを送信します。これら2つを2つの別々のターミナルで開いています。以下の 2 つのコード ブロックを見つけます。

serialout.c

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

int main()
    {
            //writing
            int writeport = open_port("/dev/ttyUSB0");

            char str[] = "hello how are you?";
            int n = write(writeport, str, strlen(str));
            if (n < 0)
                    fputs("write() of bytes failed!\n", stderr);

            //closing ports
            close(writeport);
    }

    int open_port(char str[])
{
    int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); // ?? NDELAY or NONBLOCK?

  if (fd == -1)
  {
                    perror("open_port: Unable to open /dev/ttyS0 - ");
  }
  else
                    fcntl(fd, F_SETFL, 0);

      struct termios options;
      tcgetattr(fd, &options); //this gets the current options set for the port

      // setting the options

      cfsetispeed(&options, B9600); //input baudrate
      cfsetospeed(&options, B9600); // output baudrate
      options.c_cflag |= (CLOCAL | CREAD); // ?? enable receicer and set local mode
      //options.c_cflag &= ~CSIZE; /* mask the character size bits */
      options.c_cflag |= CS8;    /* select 8 data bits */
      options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // choosing raw input
      options.c_iflag &= ~INPCK; // disable parity check
      options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable software flow control
      options.c_oflag |= OPOST; // ?? choosing processed output
      options.c_cc[VMIN] = 0; // Wait until x bytes read (blocks!)
      options.c_cc[VTIME] = 0; // Wait x * 0.1s for input (unblocks!)

      // settings for no parity bit
      options.c_cflag &= ~PARENB;
      options.c_cflag &= ~CSTOPB;
      options.c_cflag &= ~CSIZE;
      options.c_cflag |= CS8;

      tcsetattr(fd, TCSANOW, &options); //set the new options ... TCSANOW specifies all option changes to occur immediately

  return (fd);
}

serialin.c

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

int main()
{
    //reading   
    int readport = open_port("/dev/ttyUSB1");

    //trying to read one character at a time
    char buff;
    int n = 1;

   while (n > 0)
   {
    n = read(readport, &buff, 1);
    printf("%c", buff, buff);
   }

    printf("\n");

    //closing ports
    close(readport);
}

int open_port(char str[])
{
    int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); // ?? NDELAY or NONBLOCK?

  if (fd == -1)
  {
        perror("open_port: Unable to open /dev/ttyS0 - ");
  }
  else
        fcntl(fd, F_SETFL, 0);

  struct termios options;
  tcgetattr(fd, &options); //this gets the current options set for the port

  // setting the options

  cfsetispeed(&options, B9600); //input baudrate
  cfsetospeed(&options, B9600); // output baudrate
  options.c_cflag |= (CLOCAL | CREAD); // ?? enable receicer and set local mode
  //options.c_cflag &= ~CSIZE; /* mask the character size bits */
  options.c_cflag |= CS8;    /* select 8 data bits */
  options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // choosing raw input
  options.c_iflag &= ~INPCK; // disable parity check
  options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable software flow control
  options.c_oflag |= OPOST; // ?? choosing processed output
  options.c_cc[VMIN] = 0; // Wait until x bytes read (blocks!)
  options.c_cc[VTIME] = 0; // Wait x * 0.1s for input (unblocks!)

  // settings for no parity bit
  options.c_cflag &= ~PARENB;
  options.c_cflag &= ~CSTOPB;
  options.c_cflag &= ~CSIZE;
  options.c_cflag |= CS8;

  tcsetattr(fd, TCSANOW, &options); //set the new options ... TCSANOW specifies all option changes to occur immediately

  return (fd);
}

だから私がやりたいのは、ファイルを送ることです。たとえば、jpeg ファイル。それをバイトコードに変換して jpeg として再アセンブルする方法はありますか? あちこち検索しましたが、残念ながら関連する情報はほとんど見つかりませんでした。おそらく、間違った用語を検索しているのでしょう。

ファイルを圧縮してから送信することをお勧めします。最終的に、gzip を使用して jpeg ファイルを圧縮し、シリアル接続で送信しています。みんな、ありがとう!

4

2 に答える 2

5

ファイルを転送する場合は、ファイルをチャンクに分割し、各チャンクでチェックサムを使用する必要があります。次に、反対側でチャンクを再結合するときにチェックサムを確認します。

これは新しい問題ではありません。他の人があなたのためにそれを解決しました。既存の信頼できるファイル転送プログラムを入手して、シリアル リンクを介して実行する必要があります。

一番の選択肢は rsync です。これは GPL であるため、プロプライエタリな作業を行っている場合、ライセンスによって使用できない場合があります。

もう 1 つの適切な選択肢は、XMODEM (または YMODEM または ZMODEM) です。XMODEM の C 実装を BSD ライセンスで見つけたので、これを確実に使用できます。これも rsync よりも小さくて単純です。

http://www.menie.org/georges/embedded/#xmodem

http://en.wikipedia.org/wiki/XMODEM

于 2012-07-23T20:21:20.330 に答える
4

また、ファイル転送には Z-Modem または X-Modem を提案するつもりでした。しかし、あなたが理解しなければならないのは、ファイルには特別なことは何もないということです。転送元のコンピュータと受信端末に関する限り、送信されるファイルは、JPEG 画像、圧縮ファイル、テキスト ファイルのいずれであっても、単なるバイナリ データのストリームです。

受信ストリームをファイルに書き込み、適切に処理できるように適切な拡張子が付けられていることを確認するだけです。

上記の転送プロトコルは、ファイル全体が送信され、破損していないことを確認するためにレイヤーを追加するだけですが、最初のインスタンスでそれらを無視して、概念を理解することができます.

于 2012-07-23T21:36:06.180 に答える