2017年7月31日月曜日

Maker Faire Tokyo 2017用のビラ

MFTまであと1週間を切っていて、修羅場に突入しつつあります。
先日注文していたビラが届いたのでデータを張ります。会場で配布予定です。

2017年7月9日日曜日

Cで非カノニカル、非ブロッキングなシリアル通信プログラム

シリアル通信では2種類の設定項目があります。

カノニカルor非カノニカル

  • カノニカル(デフォルト)
    通信の単位は「行」、つまり\nの文字が来たらデータを送信する。つまりwrite(fd,"hello",5);では送信を行わなく、write(fd,"hell\n",6);で初めて送信をする。また\nを受信したらそこまでのデータを1行だとして受信処理をする。
  • 非カノニカル
    通信の単位は「Byte」つまりwrite(fd,"hello",5);でも送信をするし、受信も\nが来ていなくてもreadでデータを読み出せる。

 ブロッキングorノンブロッキング

  • ブロッキング(デフォルト)
    read関数を使ったときに、データを受信するまで、そこでウェイトをする。カノニカルモードなら\nが来るまで待つし、非カノニカルモードなら1byteでもデータが来るまで待つ。
  • ノンブロッキング
    read関数を使ったときに何もデータが来ていなくてもウェイトは発生せず、何も受信しなかったという結果を返す。read関数の返り値が受信バイト数。
普通のPCのプログラミングだとカノニカルかつブロッキングが通信をすることが普通です。組み込み的なプログラムは非カノニカルかつノンブロッキングに書くのが普通でしょう。この設定を書く資料が微妙に見つけにくいのでメモ的に書いておきます。
ノンブロッキングモードはopenで_NONBLOCKINGをつけるだけで良いとありましたがUbuntu14.4ではそれではダメなようです。

########モード#########

#include <stdio.h>

#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

int main()
{   
    int fd1=open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);
    fcntl(fd1, F_SETFL,0);
    //load configuration
    struct termios conf_tio;
    tcgetattr(fd1,&conf_tio);
    //set baudrate
    speed_t BAUDRATE = B1000000;
    cfsetispeed(&conf_tio, BAUDRATE);
    cfsetospeed(&conf_tio, BAUDRATE);
    //non canonical, non echo back
    conf_tio.c_lflag &= ~(ECHO | ICANON);
    //non blocking
    conf_tio.c_cc[VMIN]=0;
    conf_tio.c_cc[VTIME]=0;
    //store configuration
    tcsetattr(fd1,TCSANOW,&conf_tio);

    write(fd1,"#;",2);
    printf("Bytes sent\n");
   
    sleep(1);
   
    char buff[100]="=======================";
    int rd=read(fd1,buff,sizeof(buff));
    printf("Bytes sent are %s\n",buff);
    printf("rd:%d\n",rd);
    close(fd1);
    return 0;
}