(この節は Serial-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 はい くつかの決められたフローレート(速度)の組を持っていて、これをシリアルポー トインタフェースで使うことができます。
[ 訳注 : JF プロジェクトによる日本語訳 Serial-HOWTO ]
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 がソケット形 式ならば、(置き換えるチップさえあれば)アップグレードは簡単でしょう。新 しいチップと古いチップのピン配置は互換です。新しいシリアルボードをイン ターネットで購入することもできるかもしれません(現在はシリアルボードを 扱っている小売店はほとんどありません)。