siar

Snowy Institute

Linux のシリアル通信において termios 構造体で設定可能なパラメータをまとめる (C/C++)

termios の中身を読んでみました.

termios について

概要

termios はターミナルI/O用の Unix API です. サポートされる主な機能は次のとおりです.

  • シリアルポートの開閉
  • 通信のパラメータの設定
  • シリアル通信による読み書き

コマンドライン上での操作ができるほか,プログラミング言語での操作も可能になっています.

旧バージョンの API として termio があります. 現在こちらも利用可能な環境があるようですが,POSIX.1-1990 からは上位バージョンである termios が標準となっています.

大幅な変更は,対応する制御文字の追加(8個から19個)となっています.

参考: termio(7) - Linux manual page

Unix のカノニカル/ノンカノニカルモードに対してそれぞれ挙動が異なります.

使用方法

C/C++ の場合,

#include <termios.h>

とすれば使用可能になります.

ファイルの所在

環境によって異なると思います.

例えば,

OS Ubuntu 16.04
CPU X86_64
Kernel 4.4.0-141-generic

上記の環境においては

/usr/src/linux-headers-4.4.0-141-generic/include/uapi/asm-generic/ 

以下に存在が確認されました.

なお,termios 構造体の定義はtermios.hではなく termbits.hに記述されていることに注意が必要です.

どちらも同じ場所にあり,termios.htermbits.hをincludeしている関係にあります.

中身

termbits.hにある termios 構造体の中身は次の通りです.

typedef unsigned char   cc_t;
typedef unsigned int    tcflag_t;
#define NCCS 19
struct termios {
    tcflag_t c_iflag;       /* input mode flags */
    tcflag_t c_oflag;       /* output mode flags */
    tcflag_t c_cflag;       /* control mode flags */
    tcflag_t c_lflag;       /* local mode flags */
    cc_t c_line;            /* line discipline */
    cc_t c_cc[NCCS];        /* control characters */
};

下にメンバの一覧を示します.

メンバ名 ビット数 役割
c_iflag 16 読み取り時の設定
c_oflag 16 書き込み時の設定
c_cflag 16 通信方法の設定
c_lflag 16 処理全般の設定
c_line 8 ライン制御用ビット (カーネルが管理のため使用)
c_cc 8 * 19 特殊文字への処理の設定

ここでいうビット数は,C言語の規格により保証されているビット数を指します.

パラメータについて

ほぼ全てのパラメータの説明が下記参照先で記述されています.

Man page of TERMIOS

一部POSIX標準ではなくLinuxでのローカルルールがあることに注意してください.

下では,補足と追記を行います.

c_oflag

補足

NLDLY,CRDLY,TABDLY,BSDLY,VTDLY,FFDLY の遅延設定は全て「あり(各最大値)」がデフォルトとなっている.

c_cflag

補足

CSIZE のデフォルト設定は CS8

追記

パラメータとしてサポートされている通信速度は以下の通りです.

通信速度 [bps]
0
50
75
110
134
150
200
300
600
1200
1800
2400
4800
9600
19200
38400
57600
115200
230400
460800
500000
576000
921600
1000000
1152000
1500000
2000000
2500000
3000000
3500000
4000000

指定する通信速度の前にBを付ければ良いです.

設定方法

*flagという名前のメンバは全てレジスタを操作するための値となっていますから,全ての設定パラメータの論理和 (OR) を代入すれば良いです.

例えば,通信方式の設定において,

  1. 115200 bps
  2. 読み取りを許可
  3. 文字サイズはCS8

としたい場合は,

struct termios termios_new;

のように構造体を宣言したうえで,

termios_new.c_cflag = B115200 | CREAD | CS8;

とすれば良いです.

その後,tcsetattr()関数を利用することで設定が適用できます.

参考文献

termios(3) - Linux manual page

関連記事

ssr-yuki.hatenablog.com