(この節は Modem-HOWTO にもあります。) UART (Universal Asynchronous Receiver Transmitter) とは、PC のマザーボード(あるいは内蔵モデムカード)に載っているシリアル 用チップのことです。UART の機能は、他の用途のチップが兼用で実現してい ることもあります。多くの 486 マシンのような古いコンピュータでは、この チップはディスク I/O コントローラカードに載っていました。比較的古いコ ンピュータの中には、まだ専用のシリアルボードを載せているものもあります。
UART の目的は、PC のパラレルバスからやってくるバイトデータをシリアルの ビットストリームに変換することです。シリアルポートから出ているケーブル はデータをシリアルに送るようになっており、データが流れる方向それぞれ について 1 つしか線がありません。シリアルポートは一度に 1 ビットずつ ビットストリームを送ります。逆に、外付けケーブルを経由してシリアルポート に入ってきたビットストリームは、コンピュータが処理できるパラレルなバイト データに変換されます。UART はデータをバイト単位で扱います。この単位は 都合がいいことに ASCII 文字の大きさでもあります。
PC にぶら下がっている端末があるものとします。ユーザが文字を入力すると、 端末はその文字をトランスミッタに(UART にも)送ります。トランスミッタは そのバイトデータをシリアル回線に送り、送信は 1 バイトずつ、特定の速度 で行われます。PC 側では、受信を行う UART がビット列を全て受け取り、(パ ラレルの)バイトデータに復元し、これをバッファに入れます。
シリアルとパラレルの変換に加えて、UART は主な処理の副産物(副作用)とし て他の処理もいくつか行います。ビット列を表すために使う電圧も変換(変更) されます。バイトデータが送信される前にそれぞれのバイトに対して追加のビッ ト(いわゆるスタートビットとストップビット)が加えられます。詳しくは Serial-HOWTO の 電圧の波形の節を見てくださ い。また、コンピュータ内部のパラレルバス上のフローレート(バイト/秒)は 非常に高いですが、シリアルポート側の UART から出るフローレートはこれよ りもずっと遅いです。UART はいくつかの決められたフローレート(速度)の組 を持っていて、これをシリアルポートインタフェースで使うことができます。
UART の基本的な種類は 2 つ(ダム UART と FIFO UART)あります。ダム UART は 8250, 16450, 初期型 16550, 初期型 16650 です。これらは時代遅れ のものですが、これらの動作の仕組みがわかれば、FIFO UART(最近の 16550, 16550A, 16c552, 最近の 16650, 16750, 16950)の動作を理解するのも容易で す。
16550 については紛らわしい点がいくつかあります。初期モデルにはバグがあ り、(FIFO を持たない)16450 としてしか正しく動作しません。バグが修正さ れた最近のモデルに は 16550A という名前が付いていますが、多くのメーカーは名前を変更してお らず、16550 と呼び続けています。現在使われている 16550 の大部分は 16550 のようです。ハードウェアのマニュアルに 16550 であると書かれてい ても(あるいはラベルにそのように刻印されていても)、Linux は 16550A であ ると認識してくれます。同様の事情が 16650 にもあります(こちらの方が深刻です。というのも、聞いた話ではメー カーがバグを認めなかったからです)。Linux は最近の 16650 を 16650V2 と して認識します。16650 と認識された場合には残念ながら、1 バイトのバッファ しか持っていないように動作します。
ダムと FIFO(キューの動作がファーストイン・ファーストアウト(First In, First Out)である)の違いを説明するために、まずは UART が 1 バイトのデータを送 受信した場合のことを調べてみましょう。UART 本体は自分を通るデータに関 しては何も行わず、単にデータを送受信するだけです。元々のダム UART の場 合は、バイトデータが送受信される度に CPU がシリアルデバイスから割り込 みを受け取ります。CPU はこれを受けて、受信したバイトデータを UART のバッ ファから取り出してメモリ上のどこかに置くか、送信すべき次のバイトデータ を UART に渡すかのどちらか動作を行います。8250 と 16450 UART には 1 バ イトしかバッファがありません。つまり、1 バイトのデータを送受信する度に CPU に割り込みがかかります。転送速度が低ければこれでも大丈夫です。しか し転送速度が高速である場合には、UART の処理の負荷が CPU にかかりすぎる ため、他の処理をうまく行えるだけの時間がなくなってしまいます。場合によっ ては、CPU の割り込み処理が間に合わなくなってしまい、バイトデータが上書 きされてしまいます。なぜなら、データが入ってくるのが速過ぎるからです。 これは「オーバーラン(overrun)」あるいは「オーバーフロー(overflow)」と 呼ばれます。
これが FIFO UART が役立つ理由です。16550A(あるいは 16550)の FIFO チッ プには 16 バイトの FIFO バッファが付いています。つまり、CPU に割り込み がかかるまでに 16 バイトまでを受け取る(送る)ことができるのです。たくさ んのバイトデータを待つことができるだけではなく、CPU は 14 バイト(また はそれ以上)のバイトデータを同時に転送できます。これは、バッファを 1 バ イトしか持っていない他の UART に対して特に優れている点です。CPU が受け る割り込みも少なく他の処理に回せますし、データがなくなることもなく皆幸 せになれます。FIFO バッファの割り込みの閾値(トリガレベル)には 14 以下 の値が設定できる点に注意してください。この他には 1, 4, 8 が選べます。
大抵の PC には 16 バイトのバッファを持つ 16550 しか付いていませんが、 高級な UART にはもっと大きなバッファがあります。割り込みはバッファがいっ ぱいになる直前(16 バイトのバッファでは 14 バイトのいわゆる「トリガレベ ル」の時点)に発行される点に注意してください。こうすることにより、割り 込みサービスが実行される間にも何バイトかのデータを受け取れる余裕が残り ます。このトリガレベルには、カーネルのソフトウェアが許可した色々な値を 設定することができます。トリガレベルを 1 にすると、ダム UART とほぼ同 じになります(ただし、割り込みを発行した後にもさらに 15 バイトを受け取 る空きが残っている点が異なります)。
BBS に入っている時に何か文字を入力した場合、入力した文字はシリアルポー ト経由で送り出されます。入力した文字が画面に表示されるのは、その文字が 電話回線・モデム・シリアルポート経由で画面にエコーバックされているから です。シリアルポートに 16 バイトのバッファが付いている場合(これは 14 バイト集まるまで文字を送ってくれません)、入力した文字が表示されるまで には文字をたくさん入力しなければならないでしょう。 とても紛らわしいのですが、これを防ぐための「タイムアウト」があります。 したがって、普通は文字を入力すると、その文字はすぐに画面に表示されます。
UART の受信バッファの場合、この「タイムアウト」は 以下のように動作しま す: 文字が次々とやってきても、割り込みは発行されるのは、バッファに例え ば 14 個文字がたまった時だけです。しかし、ある文字が届いた後にしばらく 次の文字が届かなくても割り込みが発行されます。この割り込みはたとえバッ ファに 14 個文字が入っていなくても発行されます(1 文字でも入っていれば 発行されます)。したがって、このバッファを通して文字を入力すると、バッ ファの大きさが実際には 16 バイトであっても(あなたが文字を打ち込む速さ が普通の 100 倍でなければ) 1 バイトのバッファのように動作します。同様 の「タイムアウト」が送信バッファにもあります。
以下の UART の一覧を示します。TL はトリガレベル(Trigger Level) です。
時代遅れの UART がうまく動作するのは 14.4k より遅いモデム(DTE 速度は 38400 bps まで)の場合だけです。最近のモデムでは、少なくとも 16550 (初期型 16550 は含みません)が必要です。V.90 規格の 56k モデムの場合に は、16650 を使うと数パーセント速くなることがあります(特に圧縮されてい ないファイルをダウンロードする時)。16650 を使う主な利点はバッファのサ イズが大きいことであり、モデムの圧縮比が高くなければ必要以上の速度が必 要ない点です。一部の 56k 内蔵モデムには 16650 が載っていないものがあり ます(筆者は確かめていません)。
UART でなくインテリジェントなマルチポートボードでは、DSP チップを使っ てさらなるバッファリングと制御を行っています。したがって、CPU の負荷は さらに軽くなっています。例えば、Cyclades 製の Cyclom や Stallion 製の EasyIO ボードは Cirrus Logic CD1400 RISC UART を使って、これ以外の多く のボードは 80186 CPU や特殊な RISC CPU さえ使ってシリアル I/O を処理し ます。
最近の PC のほとんど(486, Pentium 以降のマシン)には 16550A (普通は単に 16550 と呼ばれます)が載っています。実は古いチップが載っていたという場 合には、既存の 16450 チップを外して、新しく買った 16550A チップと置き 換えることにより、アップグレードすることができます。他のタイプのチップ が載っていた場合は、残念ながらあきらめてください。UART がソケット形式 ならば、(置き換えるチップさえあれば)アップグレードは簡単でしょう。新し いチップと古いチップのピン配置は互換です。新しいシリアルボードをインター ネットで購入することもできるかもしれません(現在はシリアルボードを扱っ ている小売店はほとんどありません)。