2014年3月7日金曜日

Linuxのシリアルポート

Raspberry PiでFT232を使えれば便利だと思ったので、試しています

とりあえず
      1 #include <sys/types.h>
      2 #include <sys/stat.h>
      3 #include <fcntl.h>
      4 #include <termios.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <unistd.h>
      9
     10 #define BAUDRATE (115200)
     11 #define MODEMDEVICE "/dev/ttyUSB0"
     12
     13 int main(void) {
     14     int fd;
     15     struct termios oldtio, newtio;
     16     char buf[255];
     17
     18     sprintf(buf, "stty -F %s speed %d\n", MODEMDEVICE, BAUDRATE);
     19     system(buf);
     20
     21     fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY);
     22     if (fd < 0) { perror(MODEMDEVICE); return(-1); }
     23
     24     tcgetattr(fd, &oldtio);
     25
     26     bzero(&newtio, sizeof(newtio));
     27     newtio.c_cflag = CRTSCTS | CS8 | CLOCAL | CREAD;
     28     newtio.c_iflag = IGNPAR;
     29     newtio.c_oflag = 0;
     30     newtio.c_lflag = 0;
     31     newtio.c_cc[VTIME] = 0;
     32     newtio.c_cc[VMIN]  = 0;
     33
     34     tcflush(fd, TCIOFLUSH);
     35     tcsetattr(fd, TCSANOW, &newtio);
     36
     37
     38     strcpy(buf, "hello world " __DATE__ " " __TIME__ " " __FILE__ "\n");
     39     write(fd, buf, strlen(buf));
     40
     41     int size = 0;
     42     int ret;
     43     memset(buf, 0, sizeof(buf));
     44
     45     while (size < 10) {
     46         ret = read(fd, buf + size, 10 - size);
     47         if (ret < 0) { break; }
     48         size += ret;
     49     }
     50
     51     printf("%d:%s\n", size, buf);
     52
     53     tcflush(fd, TCIOFLUSH);
     54     tcsetattr(fd, TCSANOW, &oldtio);
     55     close(fd);
     56
     57     return(0);
     58 }
という感じのコードになっています

tcsetattrでビットレートの設定ができなかったため、system関数でstty関数を叩いて変更しています

そしてwriteで出力後、readで10文字を入力して終了
という感じの動作となるはずです

しかし実際には
1)起動
2)入力待ち
3)10文字入力する
4)入力された文字列を表示
5)送信先に文字列が表示される
6)終了
という感じで、文字列の送信がうまく出来ていません

動作としてはバッファリングされている感じですが、そもそもopenはじめwriteなどの低レベル処理ではバッファリングはされていないはずで、結局どこが原因かわかっていません
とりあえずwriteした直後にmemsetでバッファを0埋めしているので、少なくともwrite関数から出た時点でどこかのバッファなりに転送しているはずです
なので問題が有るとすればwrite関数の中か、writeよりも低レベルな場所ということになります

「送信したいのに送信されてない」という問題さえなんとかなれば、いろいろ使い道が出てくるのですが。。

27行目、c_cflagに設定しているCTRSCTSを消したら希望通りの動作をするようになりました
やっぱ説明はちゃんとしたのを読む必要がありますね!!!

ということで、ファイルディスクリプタを引数にしたUARTアクセス用のライブラリを作れば結構便利に扱えそうです

例えば秋月のXBeeアダプタはFT232を使っているので、簡単にRasPiからXBee経由で他のマイコンと通信ができるようになります


まとめ

情報はちゃんと調べよう

0 件のコメント:

コメントを投稿