シリアル通信(だけじゃないと思うけど)において、
入力待ちをしない、いわゆるノンブロッキングにする方法について。
カノニカルモードにすることは知っていると思うけど、
ほかにせっていするところがある。
まとめると、2つの方法があるらしい
【方法1】
1.termiosの
c_lflag &= ~(ICANON);
で、カノニカルモード無効化(非カノニカルモード)
2.termiosの
c_cc[VMIN] = 0;
c_cc[VTIME]= 0;
にする。このVMINとVTIMEの関係は、以下を参照
termios.c_cc の VMIN VTIME について(メモ)
http://oasynnoum.hatenablog.com/entry/2012/10/31/184038
【方法2】
上記さいとにある、O_NDELAY指定。つまり、openでO_NONBLOCK または O_NDELAYを指定する。
詳しくは、以下のサイト
open - システムコールの説明 - Linux コマンド集 一覧表
http://kazmax.zpp.jp/cmd/o/open.2.html
ちなみに、以前の記事
LinuxのCで、キー入力されたらすぐ表示するけど、入力しないとき待たないようにしたい
http://blog.goo.ne.jp/xmldtp/e/067f5e0ff4efeca546e4458f4d36a619
では(これはコンソール端末=標準入力なので、fd=0で説明している)、
方法1で、VMIN=0,VTIME=1にしている
以下、raspberry piのシリアル通信における方法1の雰囲気(確認していないので、バグがあるかも・・・)
入力待ちをしない、いわゆるノンブロッキングにする方法について。
カノニカルモードにすることは知っていると思うけど、
ほかにせっていするところがある。
まとめると、2つの方法があるらしい
【方法1】
1.termiosの
c_lflag &= ~(ICANON);
で、カノニカルモード無効化(非カノニカルモード)
2.termiosの
c_cc[VMIN] = 0;
c_cc[VTIME]= 0;
にする。このVMINとVTIMEの関係は、以下を参照
termios.c_cc の VMIN VTIME について(メモ)
http://oasynnoum.hatenablog.com/entry/2012/10/31/184038
【方法2】
上記さいとにある、O_NDELAY指定。つまり、openでO_NONBLOCK または O_NDELAYを指定する。
詳しくは、以下のサイト
open - システムコールの説明 - Linux コマンド集 一覧表
http://kazmax.zpp.jp/cmd/o/open.2.html
ちなみに、以前の記事
LinuxのCで、キー入力されたらすぐ表示するけど、入力しないとき待たないようにしたい
http://blog.goo.ne.jp/xmldtp/e/067f5e0ff4efeca546e4458f4d36a619
では(これはコンソール端末=標準入力なので、fd=0で説明している)、
方法1で、VMIN=0,VTIME=1にしている
以下、raspberry piのシリアル通信における方法1の雰囲気(確認していないので、バグがあるかも・・・)
/* * ノンブロッキングテスト * 内容 電文の送受信を1電文繰り返す * 参考: http://www.rt-shop.jp/blog/archives/4145 (シリアル通信) * http://oasynnoum.hatenablog.com/entry/2012/10/31/184038 (ノンブロッキング) * http://simd.jugem.jp/?eid=145 (時間部分) */ #include<stdio.h> #include<stdlib.h> #include<strings.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <termios.h> #include <unistd.h> #include <time.h> #include <sys/time.h> #define SERIAL_PORT "/dev/ttyAMA0" #define BAUDRATE B9600 int main(int argc, char *argv[]) { int fd; char com[16]; // とりあえず16バイト以上来ないものとする char buf[2]; // 一時的に入れておく struct termios newtio, oldtio; // コントロールの構造体 int len; // 文字列の長さ clock_t nowtime,oldtime; double keika; // 経過時間 //==============================// // オープンと設定 // //==============================// if(!(fd = open(SERIAL_PORT, O_RDWR))) { printf("data error \n"); return -1; } // 現在のシリアルポートの設定を待避 ioctl(fd, TCGETS, &oldtio); // ポートのコントロール初期化 bzero(&newtio, sizeof(newtio)); newtio = oldtio; // ポートの設定をコピー=基本的には同じにする // ボーレートなど設定 newtio.c_cflag = (BAUDRATE | CS8 | CLOCAL | CREAD); newtio.c_iflag = (IGNPAR); // エラー処理:無視 newtio.c_oflag = 0; // 非カノニカルモード newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); newtio.c_cc[VMIN] = 0; // ノンブロッキング newtio.c_cc[VTIME]= 0; ioctl(fd, TCSETS, &newtio); // 初期設定 //==============================// // データ処理 // //==============================// bzero(com, sizeof(com)); len = 0; // 文字の長さ=次に文字が入るところ oldtime = clock(); while(len < 15) { if ( read(fd,buf,1) <= 0 ) // 1バイトだけ読む { // 読めないとき nowtime = clock(); keika = ((double)(nowtime - oldtime)) / (double)CLOCKS_PER_SEC; if (keika > 0.5) // 0.5秒たっても読めない { printf("no data \n"); oldtime = nowtime; continue; } } else { com[len] = buf[0]; len++; oldtime = nowtime; nowtime = clock(); } } com[len] = 0; printf("data:%s\n",com); //==============================// // 終了 // //==============================// newtio = oldtio; // ポートの設定を戻す ioctl(fd, TCSETS, &newtio); // 前に戻す close(fd); printf("end\n"); } |
昨日(10月20日)NIIの市民講座
情報学最前線
「正しいプログラムを簡単に書くには?プログラムの型とそのデバッグ手法」
を聞いてきた!ので、その内容をメモメモ
・正しいプログラムは何で必要か
いろんなところでプログラムが使われている
→正しいプログラムを書こうという努力
・プログラムとはどんなものか?
速く書けるときもあるが・・・
・プログラムとは何か
コンピューターへの指令・指示書
例:1~10までたしてください→あいまい
・プログラム:明確な手順を指定した指令
・プログラムはどう実行されるか
1+10+2*3
字句解析(じくかいせき):トークンの列
構文解析:トークンの列→(どことどこがくっついているのか)→抽象構文木
各種変換・最適化・コード生成:抽象構文木→いろいろ→機械語
機械語を実行する=17
※字句解析、構文解析はツール(lex,yacc)。
構文解析器は古くからあるが、今も研究
「LR構文解析の原理」大堀淳
・正しいプログラムとは何か
・コンピューターが解釈できる
→実行は出来る
・人が思ったとおりに動作する
→意図どおりに書くのは難しい
・プログラムの正しさを、どう高めるか?
・データの種類に注目して、書けるプログラムに制限を設ける
・データの種類:型
→型を使って制限する
:動作を予期しないプログラムをのぞくことが出来る
いつ型を検査するか
1.静的型付け:実行前検査
2.動的型付け:実行時検査
※値の性質まで入った型: LiquidHaskell
・型の難しさ
修正→型エラーのデバッグ手法
本質的な難しさ
どれが正しいかは自動的には決められない
型エラーのデバッグ手法
エラーに関係している:型エラースライス
対話的に:対話的型エラーデバッガ
可能性の高い:原因箇所推定
・研究の話(宣伝)
機能を再利用
・型以外の手法
テスト
性質の検証
・テスト
研究:テスト例自動生成
→自動生成をどうするか:ランダム、小さいものから全通り
・性質の検証
性質が満たされるか証明する
→自動定理証明:ここ10年ほどホットトピック
・本講座で話したこと
プログラム:明確な指令
プログラムの正しさ
正しさを高める「型」
型以外:テスト・証明
・プログラムを書くには?
プログラミングの学びかた:コースとかあふれている
Gacco はじめてのP
競技プログラミング、プログラミングコンテスト
ICFP プログラミングコンテスト
Q&A
・静的と動的の型付け、どっちがいい
→大規模は静的、ネットでの処理・外部との受け渡しは動的
1回実行すればいいのも動的で
・なんで似たような言語が出てくるの?
言語を作るのが好きだから
・ツールはどんなの?
emacs
・生産効率的な点からコメント
型を使う:型がひとつのドキュメント→あがっている
ソフトウェア工学で研究しているので、そちらのほうを見て
情報学最前線
「正しいプログラムを簡単に書くには?プログラムの型とそのデバッグ手法」
を聞いてきた!ので、その内容をメモメモ
・正しいプログラムは何で必要か
いろんなところでプログラムが使われている
→正しいプログラムを書こうという努力
・プログラムとはどんなものか?
速く書けるときもあるが・・・
・プログラムとは何か
コンピューターへの指令・指示書
例:1~10までたしてください→あいまい
・プログラム:明確な手順を指定した指令
・プログラムはどう実行されるか
1+10+2*3
字句解析(じくかいせき):トークンの列
構文解析:トークンの列→(どことどこがくっついているのか)→抽象構文木
各種変換・最適化・コード生成:抽象構文木→いろいろ→機械語
機械語を実行する=17
※字句解析、構文解析はツール(lex,yacc)。
構文解析器は古くからあるが、今も研究
「LR構文解析の原理」大堀淳
・正しいプログラムとは何か
・コンピューターが解釈できる
→実行は出来る
・人が思ったとおりに動作する
→意図どおりに書くのは難しい
・プログラムの正しさを、どう高めるか?
・データの種類に注目して、書けるプログラムに制限を設ける
・データの種類:型
→型を使って制限する
:動作を予期しないプログラムをのぞくことが出来る
いつ型を検査するか
1.静的型付け:実行前検査
2.動的型付け:実行時検査
※値の性質まで入った型: LiquidHaskell
・型の難しさ
修正→型エラーのデバッグ手法
本質的な難しさ
どれが正しいかは自動的には決められない
型エラーのデバッグ手法
エラーに関係している:型エラースライス
対話的に:対話的型エラーデバッガ
可能性の高い:原因箇所推定
・研究の話(宣伝)
機能を再利用
・型以外の手法
テスト
性質の検証
・テスト
研究:テスト例自動生成
→自動生成をどうするか:ランダム、小さいものから全通り
・性質の検証
性質が満たされるか証明する
→自動定理証明:ここ10年ほどホットトピック
・本講座で話したこと
プログラム:明確な指令
プログラムの正しさ
正しさを高める「型」
型以外:テスト・証明
・プログラムを書くには?
プログラミングの学びかた:コースとかあふれている
Gacco はじめてのP
競技プログラミング、プログラミングコンテスト
ICFP プログラミングコンテスト
Q&A
・静的と動的の型付け、どっちがいい
→大規模は静的、ネットでの処理・外部との受け渡しは動的
1回実行すればいいのも動的で
・なんで似たような言語が出てくるの?
言語を作るのが好きだから
・ツールはどんなの?
emacs
・生産効率的な点からコメント
型を使う:型がひとつのドキュメント→あがっている
ソフトウェア工学で研究しているので、そちらのほうを見て