沼津高専 電子制御工学科
MIRS0602 シリアル通信(RS-232C)調査報告書
MIRSATLM-REGU-1404
改訂記録
版数 作成日 作成者 承認 改訂内容
A01 2006.7.9 吉田 尾崎 初版
A02 2006.9.5 吉田 尾崎 中間報告を追加

1.本ドキュメントについて

C言語によるシリアル通信(RS-232C)の方法について述べる。ただし、プログラムの実行環境はVine Linux(MIRSと同じ)とする。

2.RS-232Cとは

RS-232(Recommended Standard 232)は、パソコンと音響カプラ、モデムなどを接続するシリアル方式のインターフェースの一つである。インターフェースはポートとも呼ばれるため、シリアルポートと一般に呼ばれることもある。
MIRS0602では、音声再生モジュールとCPUボードの通信にこのRS-232Cを用いる。シリアルポートはCPUボードに標準装備されているので、導入の際にハードウェアの改造が不要といった利点がある。

3.Linuxにおけるシリアル通信の方法(C言語)

Linuxではハードウェアをある種のファイルとして扱うため、C言語を用いてシリアル通信を行うためには該当するデバイスファイルをオープンし、それに対して書き込み、読み込みを行えばよい。
デバイスファイルの場所は、/dev/ttyS*(COM1なら/dev/ttyS0)である。
また、通信方式や通信速度の設定にはtermios構造体を用いる。termios構造体はtermios.hで定義されているため、termios.hをインクルードした後にstructで構造体を宣言する必要がある。ただし、デフォルトの設定を使う場合はこれらの操作は必要ない。

4.プログラム開発の中間報告

7月24〜28日の間に行われた電子機械設計演習の授業でシリアル通信のプログラム開発を行ったので、それにより新しくわかったことを報告する。
プログラム開発の詳細はMIRS06sp-num0003a 音声出力のためのソフトウェア開発参照。

今回作成したプログラム「term.c」は、非同期通信で通信速度9600bps に設定されているが、これは通信相手である音声再生モジュール(以下モジュール)の初期設定に合わせた結果である。(通信速度は変更可能)
以下、プログラムの順を追って追いながら説明する。

  1. 必要なファイルをインクルードする。stdio.h とstring.h 以外はすべてシリアル通信で必要なようである。string.h はユーザーからの「end」入力判定と、モジュールからのエラーコード判定を行うために読み込んでいる。


  2. 通信速度とデバイス名が定義されている。MIRSに搭載されているポートは1つ(COM1)なので、デバイス名は"/dev/ttyS0"


  3. シグナルハンドラとなる関数を定義する。非同期通信を行う場合は相手からの信号がいつ来るかわからないので、シグナルハンドラに処理を任せることによってどのタイミングで信号が来ても対応できるようになる。


  4. termios構造体は通信の設定を格納するためのもので、sigaction構造体はシグナルハンドラの設定を格納するためのもの。


  5. デバイスを非ブロッキングモードで開くと、そのデバイスに対してread関数による読み出しを行った場合、データがなければすぐに復帰するようになる(データ待ちの状態にならない)。


  6. シグナルハンドラの設定を構造体に格納した後にsigaction関数を使って設定を行う。saio.sa_mask = 0;ではエラーが出たので変わりにsigemptyset(&saio.sa_mask);を使っている。


  7. fcntl関数によってデバイスを非同期モードにする。


  8. デバイスの設定を構造体に格納した後にtcsetattr関数を使って設定を行う。非カノニカルモード:改行コードがなくてもデータを受信、.c_cc[VTIME]:通信が終了(中断)されてから受信を終了するまでの時間、.c_cc[VMIN]:受信するデータの最大量


  9. あとは、ユーザーからの入力を受け取ったらそれを送信(「end」なら終了)して応答を待ち、応答がきたらまたユーザーからの入力を待つことになる。モジュールはWindows機と通信することを前提に作られたようで、送信データの最後にWindowsの改行コード"\r\n"(Linux系は"\n"のみ)を付加しないとうまく動作しなかった。


  10. モジュールがエラーコードを返すことがあるので、それに対応したメッセージを出力するようにしてある。ただし、MIRSには日本語フォントが入っていないので、MIRSに搭載するなら全て半角英数にしなくてはならない。


  11. プログラムが終了する前にポートの設定を元に戻してポートを閉じる。



関連文書