[ C++で開発 ]

シリアル通信プログラム(POSIX編)

UNIX系OSでは、POSIX規格によりおおよそシリアル通信のシステムコール等が標準化されています。(POSIX.1-2001らしい)

シリアル通信の設定に関するメモ

シリアル通信(RS-232C)での設定について、最低限前提となる知識を整理します。

調歩同期式(無手順)

スタートビッド、ストップビット

キャラクタ(1文字)の前後に、文字を識別できるように必ず付けるのがスタートビットおよびストップビットです。スタートビットは1ビットですが、ストップビットは1ビット・1.5ビット・2ビットがあります。

パリティビット

EVEN(偶数)、ODD(奇数)、なし、の3つから選択します。EVENまたはODDのときは、データビットとパリティビットの中でビットが1となる数をEVENまたはODDになるよう調整します。

ビットレート

RTS

Request To Sendの略で端末からモデムへ出力する制御信号の1つ。フロー制御の方式でハードウェアフロー制御を用いる場合に使われる。

シリアル通信プログラミング

ポートのオープン

シリアルポートのデバイスファイル名を指定してシステムコールopenを呼び出します。デバイスファイル名は、OSによって異なります。

OS デバイスファイル名 内容 備考
Solaris 2.x
/dev/ttya
ポートA(1)
/dev/ttyb
ポートB(2)
#include <unistd.h>
#include <errno.h>

int main(int argc, char* argv[])
{
    int fd = open("/dev/ttya", O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd == -1) {
        perror("Unable to open /dev/ttya - ");
        return -1;
    }
    :

O_RDWRは、ポートを読み書き両方でオープンする指定
O_NOCTTYは、tty制御をしない指定
O_NDELAYは、***

ポートの設定

シリアルポートの属性の取得と設定は、tcgetattrおよびtcsetattrシステムコールを呼び出します。

属性には、ボーレート、データビット数、パリティ、ストップビット、フロー制御等があります。これらを通信の両者で合わせる必要があります。

既存の設定の保存

アプリケーションが使用後は元の設定に戻しておくのが良識でしょう。

struct termios old_options, new_options;
int ret;

ret = tcgetattr(fd, &old_options);
  : // 通信処理
ret = tcsetattr(fd, TCSANOW, &old_options); // 既存の設定を復帰
close(fd);

termios構造体の設定

termios構造体は以下のように定義されています。

struct termios {
        tcflag_t        c_iflag;        /* input modes */
        tcflag_t        c_oflag;        /* output modes */
        tcflag_t        c_cflag;        /* control modes */
        tcflag_t        c_lflag;        /* line discipline modes */
        cc_t            c_cc[NCCS];     /* control chars */
};

tcflag_tは、unsigned intのtypedefです。cc_tは、unsigned charのtypedefです。

c_iflag

すべてのビットを0にするのがよい(らしい)。ソフトウェアフロー制御を有効にするときだけ0以外の値を設定。

c_oflag

すべてのビットを0にするのがよい(らしい)。遅い端末へ何とか出力するための制御なので昨今では不要というのが理由。

c_cflag
options.c_cflag &= ~CSIZE; // キャラクタ・サイズ数のビット部分だけ0にセット
options.c_cflag |= CS8;    // データビット数を8にする
c_cflagに設定する属性(抜粋)
属性定義シンボル 内容 ビットマスク
CLOCAL ローカルライン(モデム制御なし) 0x00000800
CREAD 受信を有効にする 0x00000080
CRTSCTS ハードウェアフロー制御を有効にする 0x80000000
CSTOPB ストップビットを2に設定する 0x00000040
CSIZE データビット数を指定するためのビットマスク 0x00000030
CS5〜CS8 データビット数、5〜8ビットまで指定可能 0x00000000
0x00000010
0x00000020
0x00000030
PARENB パリティビットを有効 0x00000100
PARODD パリティビットは奇数とする 0x00000200

CLOCALとCREADを指定しているサンプルコードが多いようです。これは必須なのかもしれません。

CREADを0( options.c_cflag &= CREAD )してみたところ、受信できなくなりました。

c_lflag
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
c_lflagに設定する属性(抜粋)
属性定義シンボル 内容
ECHO 入力文字の表示
ECHOCTL 制御文字を^charとしてエコーする
ECHOE
ECHOK
ECHONL NLをエコーする
ICANON
c_cc
options.c_cc[VTIME] = 0; // タイマを使わない
options.c_cc[VMIN] = 1;   // 1文字来るまでreadをブロック

参考文献

Web上