ENGLISH 简体中文 日本語 한국어  



   
 
キーワードまたは型番を入力    




アプリケーションノート 3931

旧式コンピュータ周辺機器のネットワーク対応化

要約:インターネットを通じて旧式コンピュータ機器にアクセスすることができるようにすると、旧式コンピュータ機器を再生することができます。このアプリケーションノートでは、TINI®を使ってパラレルポート接続のみを備える旧式のドットマトリックスプリンタをネットワーク対応させる方法を紹介します。ここに示す同じプロトコル変換手法を使って、多数のデバイスをインターネットに接続することができます。

はじめに

妻が、2つの穴が開いただけの靴下と、草で小さな染みが付いたシャツを捨てていた時のことです。もったいないという気持ちを何とか抑えていられましたが、旧式のドットプリンタにまで来た時、その気持ちは抑えられなくなりました。「あなたは何年もこのプリンタを使っていないじゃないの。家のどのコンピュータも、このプリンタと通信することさえできない」と、彼女は軽蔑して言いました。他の技術オタクと同様に、私は旧式のコンピュータ機器を破棄するなどと考えるのは耐えられないことでした。私の任務は明らかでした。そのプリンタを再び使えるようにするか、またはそれを永遠になくしてしまうかです。そこで、私は、ネットワークを通じてそのプリンタにアクセスすることができるようにしようと決心しました。幸いにも、私にはそれを可能にするTINI (Tiny INternet Interface)がありました。

ネットワークとの接続

TINIは、マキシムのDS80C390、DS80C400、DS80C410、およびDS80C411マイクロコントローラで動作するマキシムの組込みネットワーキングプラットフォームです。これらのマイクロコントローラはすべて、24ビットアドレス、ハードウェアネットワークコントローラ、複数データポインタ、専用ハードウェアスタック、および高速動作を備える拡張8051マイクロコントローラです。

TINIプラットフォームは、TCP/IPネットワークスタック(IPv4およびIPv6)、メモリマネージャ、プロセススケジューラ、およびI²C、SPI、CANなどの多数の通信プロトコルをサポートしています。TINIは、8051のアセンブリ言語、C言語、またはおなじみのプログラミングインターフェースを備えるJavaでプログラミングすることができます。Cランタイムはバークリースタイルのソケットインタフェースを備え、JavaランタイムはJava 1.1.8 APIのコアをサポートしています。

多数のIOサポート、簡易なネットワークインタフェース、およびそのインタフェースをプログラミングする数多くの方法によって、TINIは優れたプロトコルコンバータになります。これは、旧式プリンタを救うためにまさに私に必要なものです。TINIはネットワークインタフェースを提供するため、TINIでプリンタと通信させる方式にします。

ハードウェア構成

システムのブレーン用に、TINI評価(EV)キットを使用します。DS80C400マイクロコントローラを基盤として、このEVキットは、1MBのフラッシュ、1MBのRAM、RS-232およびEthernet通信用のコネクタを搭載しています。Cやアセンブリでもプログラミングすることもできますが、そのメモリ構成はTINI Javaランタイムに対応しています。このため、プリンタインタフェースのプロトタイプ作成とアプリケーション完成のための選択肢が数多く提供されます。

問題のプリンタは、Epson LX-800です。カーボンの年代と厚く積もったほこりは、このプリンタを真空管とフラフープの時代に近づけてくれます。LX-800は9ピンプリンタです。9ピンは、プリンタを駆動するのに必要な並列信号の数ではなく、印刷ヘッドのピンの点数を示しています。実際には、プリンタを駆動するのに17の信号を必要とします(グランドを除く)。図1は、PCプリンタのパラレルインタフェース内に標準で存在する信号と、25ピンプリンタコネクタにおける信号の配置を示しています。

Figure 1. A 25-pin signal definition for the parallel printer interface.
図1. 25ピンパラレルプリンタインタフェースの信号定義

従来型の25ピンセントロニクスプリンタケーブルを使って、TINIからプリンタに接続するときに、図1に示された接続部を一致させる必要があります。ただし、TINIボードのIOは広いパラレルバスとして使用するのに不便であるという問題が1つあります。必要とするおよそ半分の8または9つの汎用IO (GPIO)信号しかありません。また、これらのGPIO信号は、複数の異なるレジスタに分割されます。8個の出力ビットを設定するには複数のレジスタ書込みが必要であるため、GPIO信号の制限によって、プリンタの8ビットデータバスに簡単な書込みを行うことが不便になります。幸いにも、TINIソケットボードは、CPLD (Complex Programmable Logic Device)を追加するためのパッドとトレースを備えています。このCPLDによって、TINIのIO機能を大幅に拡張することができます。CPLDを搭載すると、(JTAGインタフェースを通じて) CPLDをプログラミングするためのヘッダとTINI端子の一部へのアクセスを可能にするヘッダが必要になります。

CPLDのプログラミング

CPLDを変更可能なハードウェアと見なしてください。CPLDは極めて柔軟な内部構造を備え、この構造によって幅広い論理機能と状態マシンを実装することができます。TINIのソケットボード設計は、100ピンVQFPパッケージにXILINX® CoolRunner®-II XC2C64 CPLD用のスペースを用意し、他のCoolRunner-IIがこれと同じパッケージとピン配置の場合は、そのCoolRunner-IIを使用することができます。このプロジェクト用に、ピン配置が同じで、キャパシティを拡大したデバイスのXC2C128を使用しました。

CPLDは、DS80C400マイクロコントローラの外部メモリバスを通じてTINIシステムに接続されます。CPLDにアクセスするには、マイクロコントローラは以下のように専用アドレスとの間で読取りまたは書込みを行う必要があります。

read_from_cpld:
mov dptr, #0C00000h ; CPLD address
movx a, @dptr ; read from the device
CPLDには、より複雑なタスクがあります。一方では、CPLDはTINIの外部メモリバス信号に適切に応答する必要があります。すなわち、TINIがCPLDに書き込むとバスから値を読み取り、TINIが読取りを要求すると値をバスに供給します。プリンタ側では、CPLDは、プリンタが実行していることを示すステータス信号(BSYなど)を読み取り、プリンタを制御する出力信号(8ビットデータバスおよび印字ストローブSTRなど)を駆動する必要があります。図2は、CPLDが実装するブロック図を示しています。

Figure 2. The CPLD must implement an interface between its own IO pins and the microcontroller's address bus.
図2. CPLDは、そのIO端子とマイクロコントローラのアドレスバス間のインタフェースを実装する必要があります。

CPLDは、CPLDの32個のI/O端子に対応する4個の8ビットレジスタを実装しています。0に設定されたレジスタビットは対応する出力端子をローに駆動し、また1に設定されたレジスタビットはハイにフロートします。したがって、I/O端子から読み取るには、それに対応するレジスタビットは1である必要があるため、CPLDは端子を駆動しません。

図2の入力信号はすべて、TINIの外部メモリバスから供給されます。TINIがCPLDに書き込むときは、データバスは、TINIが書き込もうとしている8ビット値を保持しています。TINIが読取りを実行するときは、CPLDは検出された入力値でデータバスを駆動する必要があります。ただし、TINIが読取りを要求するとき常に(すなわち、nPSENがアクティブであるとき常に)、CPLDはデータバスを単純に駆動することはできません。その理由は、バスを共用している他のデバイスがおそらく存在するためです。CPLDがデータバスを駆動しても、TINIは不適切な命令やデータをフェッチするため、予測不可能なシステム動作が発生するでしょう(すなわち、「悪いことが発生」)。同様に、TINIが書込みを実行するときは常に(すなわち、nWrがアクティブであるときは常に)、すべての書込みがCPLD用とは限らないため、CPLDは対応する必要はありません。このため、図2の読取りおよび書込み信号は、アドレスラインによって限定されます。

選択したチップイネーブルがアクティブのとき(この例では、チップイネーブル6を使用)、およびAH0とAH1 (TINIの第16および第17アドレスライン)が0のときは常に、CPLDは作動します。TINIは2MB毎のチップイネーブルに設定されているため、CPLDにアクセスするためのベースアドレスは0xC00000です(2,097,152 x 6 = 12,582,912 = 0xC00000)。なお、選択した構成では、TINIのアドレスラインの大部分は、TINIとCPLD間のインタフェースで指定されていません。たとえば、TINIのアドレスラインA2~A15はどの値も受入れ可能で、CPLDを作動させることもできます。ただし、簡単にするために、ソースコードはアドレス0xC00000~0xC00003を常時使用し、4個の8ビットレジスタにアクセスします。

CPLDのプログラミングは、HDL (ハードウェア記述言語)で指定されます。開発用にXilinx WebPACK™を使用し、Verilog™でハードウェア記述を書き、モジュール定義は図2に従います。すなわち、8ビットレジスタ、マルチプレクサ、およびデコーダ用の独立したモジュールがあります。ブロックおよびアドレスデコーディングは、最上位ブロックで実行されます。

CPLDの実装およびプログラミングを行った後、プリンタに接続する前に、私は信号のどれがどれかを実際に認識しているか確認するためにチェックをしたいと思いました。そこで、図3にあるような、4個の論理レジスタ(IO7:0、IO15:8、IO23:16、およびIO31:24)に接続された4個のLEDバンクを備える小さなボードを作成しました。C言語で書かれた簡易なプログラムは、途中で休止を伴って、4個のLEDバンクに対して増加する値を書込み、これによって、プログラムの動作を視認することができました。CPLDのプログラミングと接続の理解が正しいことを確信して、写真にあるプリンタを接続しました。図3は、TINIボードから25ピンプリンタコネクタに接続するフライングワイヤコネクタを示しています。

Figure 3. TINIs400 socket board connected to the Epson printer.
図3. Epsonプリンタに接続されたTINIs400ソケットボード

プリンタとの通信

私の最終目標は、特別なドライバやクライアントアプリケーションを用いずにプリンタを使用することでした。すなわち簡単に言うと、内蔵の印刷ドライバとWindows®の印刷ダイアログを使って、旧式プリンタでなにかを実現させたかったのです。アプリケーションの最終試験は、MS Wordからなにかを印刷することです。不適切なことがある場合は、Wordによってそれが明かされると思いました。同時に、MS Wordが最終目標でしたが、もっと小さなステップを実行してから、その最終目標に達したいと思いました。

最初のステップは、ネットワークを接続せずに、いくつかのASCII文字をプリンタに送出する小さなアプリケーションを書くことでした。このアプローチによって、一度にデバッグするのは1つだけになります。理論的には、私がコマンドコードやその他の非ASCII文字を避けている限り、プリンタは私が送出した各文字のみを印刷すべきです。あらゆる優れた技術プロジェクトと同様に、私はこのプロジェクトが順調かつ迅速に進行することを期待し、すぐにネットワークインタフェースの決定に移ることができました。当然、私は完全に間違っていました。

私は、Keil Software® µVision®2ツールスイートを使って、C言語で最初のプリンタアプリケーションを書きました。「The Indispensable PC Hardware Book」の参照を通じて、必要なことはプリンタを初期化し、印字を開始することだけと思われました。¹文字の書込みは、以下のような簡単なアルゴリズムでした。
  1. BSYが非アクティブになるのを待機
  2. データバス上で出力値を設定
  3. ライトストローブ STRをアクティブに設定
  4. ACK信号が受信データを肯定応答するのを待機
  5. ライトストローブ STRを非アクティブに設定
  6. 初期化、要求によって反復


最初の試験では、ステータス信号のいずれか1つが不適切な場合(極性の間違い、端子の間違いなど)、印刷されたものを確認するために、多くの遅延をこのアルゴリズムに挿入しました。このため、最初のプログラムは、1秒当り約1文字を印字します。以下のような、増分カウンタを印字することに決めました。

012345678901234567890123456789...

プログラムをTINIにロードし、プログラムを実行しました。オフラインやオンラインになると印刷ヘッドが移動するのが聞こえたため、すぐにプリンタ初期化ルーチンが実行されたことがわかりました。ただし、数秒後には、なにも印刷されませんでした。私はプログラムをリセットし、接続の二重、三重のチェックをし始めました。残念ながら、プリンタから送出されるステータス信号を監視するスコープがありません。すべて問題がないように見えたため、信頼できるPCハードウェアガイドブックを読み返してみました。再読すると、信号の一部の極性に関して少し誤解していたのがわかりました。たとえば、ハードウェアレベルではBSYは実際アクティブハイですが、従来型のPCインタフェースでは、BSYは値が0でアクティブであると示します。各信号を様々に反転したCプログラムを数回繰り返した後も、プリンタは初期化後に沈黙したままでした。プリンタが動作するはずと思われる方法にロジックレベルを合わせて、プログラムを通じてさらにもう1回試しました。プログラムを実行しましたが、再度なにも起こりませんでした。

ドットマトリックスプリンタがテキスト行を打ち出し、その激しい、かき乱すような音を聞いたときに、私は離れた所にいました。私は戻って、美しい印刷文字の行を確認しましたが、プリンタは再び完全停止していました。その後、ある見解が心に浮かびました。すなわち、プリンタが80字の制限に達したか、または行末シーケンスがデータストリームに挿入されたかに関係なく、プリンタはバッファアップすることです。わずかな時間の作業で、その見解が検証されました。これによって、私は簡単なテキスト文字列を印刷しました。

LPDデーモンの実装

その翌日、ネットワークをプリンタインタフェースに接続することにしました。その簡単な答えは、データをネットワークから受信し、そのデータをプリンタに出力するカスタムアプリケーションを作成することでした。この方式には、プリンタにMS Wordで動作させるという問題があります。Windowsプリンタドライバを書く必要もあります。このプリンタドライバを私はおそらく理解可能ですが、あまり面白いとは思えません。このため、無駄な作業をせずに、できればプリンタドライバの全詳細を学ばなくてもいい選択肢を検討するようになりました。

私にとって理想的な設計は仮想パラレルポートでした。このアイデアとは、仮想パラレルポートが標準パラレルポートと同じインタフェースを提供するというものですが、ドライバレベルではネットワークを通じてTINIとの間で実際にはデータを送受信します。このような仮想ポートとプロトコルはTINIで一般的なアプリケーションであり、同様のアイデアを用いる仮想シリアルポートの実装経験が私には少しありました。多くのアプリケーションはPCのパラレルポートのレジスタに直接書き込むと思われるため、この実装方法の決定に苦労しました。次の選択肢は、既存のプロトコルに注目することでした。同僚のアドバイスに従って、私はラインプリンタのデーモン(LPD)プロトコルのRFC 1179を調べてみました。²

LPDは、まさに私に必要なものでした。これはUNIX界で広くサポートされているネットワークプロトコルであり、わずかの簡単な設定ステップによってWindowsで使用することができます。ドライバをインストールするには、コンピュータに接続された新規ローカルプリンタをインストールするようにWindowsに指示しますが、使用する既存のポートを指示する代わりに新たな「LPRポート」を作成します。ここでLPDサーバを稼動するマシンの名称(私の場合は、TINIのIPアドレス)を設定し、Windowsに印刷待ち行列の名称を指示することができます(私は、自分のプリンタにふさわしいと思い、ある印刷待ち行列を「crusty (気難し屋)」と名称設定しました)。最後に、Windowsにプリンタの種類(私の場合は、Epson LX-800)を指示します。

この設定の優れた点は、Windowsプリンタドライバが全データを自動的にフォーマッティングし、プリンタEpson ESC/Pの自然言語で印刷することです。ESC/Pの言語に関してなにも学ぶ必要はなく、またPCからTINIに届いたどのデータも解析する必要はありません。さらに、ベーシックなLPDサーバの実装はごく簡単で、私はメモリマッピングされたCPLDにアクセスするための固有の方式を少し用いてJavaで実装しました。その結果、実コードは約400行で、TINIに対応する際のJavaクラスファイルはわずか約4kBです。なお、LPDプロトコルを全部実装したのではなく、一度に1ファイルを印刷するのに必要な部分のみを実装しました。

印刷

プロジェクトの完了を宣言するには、以下の3項目を実行する必要があると思っていました。すなわち、Notepadからの印刷、MS Wordからの印刷、およびすごくやる気がある場合は、小さなGIFまたはJPGファイルの印刷です。LPDサーバを少しデバッグした後に、運よくNotepadからファイルを印刷しました。2行のテキストファイルが約5000バイトを印刷のためにTINIに送信しているのが、私には奇妙に思われました。その理由は、単にASCII文字を送信するのではなく、ビットマップ画像を印刷するためにWindowsドライバがファイル全体をESC/P命令に変換していたことでした。それでも、Notepadからの印刷が成功したため、私はMS Wordに取りかかりました。

MS Wordからの印刷は、少し問題がありました。試験ファイルを面白くするために、2番目または3番目の各単語を異なるフォントにして、この機会を利用して、いままで見たことがないフォントを確認しようとしました。印刷すると、プリンタが複数行スキップ、奇妙なASCIIグラフィックス文字(0x80~0xFFの範囲の文字)の印刷、何回ものビープ音といった多数の不良事項が出現しました。結局、正しいテキストの一部は表示されましたが、一方、不良事項もさらに出現しました。TINIに送信されるESC/P命令を通じて数回のデバッグと追跡を行った後に、拡張文字に遅延を追加することを試すことにしました。これによって、プログラムは正常に印刷するようになりましたが、超低速でした。さらに少し実験した後に、行末文字に遭遇した場合に限り、遅延が必要であることに気付きました。このことはめったに発生しないため、実際に遅延に気が付かなかったのです。

MS Wordでの印刷がやや困難であったため、GIFファイルの印刷は不可能に近いと私は判断しましたが、結局はそうではないことが判明しました。1つだけ問題に直面しました。すなわち、ESC/P命令に変換されたGIFファイルが64kを上回りました。この64kは使用したTINIのバージョンでサポートされる最大ダイナミックバッファサイズです。ただし、TINIはこうした制限値がないファイルシステムをサポートしています。このため、ダイナミックメモリバッファでなく、ファイル内に受信データを保存しました。その変更を行うと、TINIのRAMサイズでのみ制限され、グラフィックスファイルを問題なく印刷することができました。

その他の(旧式?)機器の救助

ドットマトリックスプリンタの寿命は延長されました。TINIが窮地から救いました。プログラミングが容易なスタックによって、TINIは1台のレガシ機器をネットワーク対応させるのに適した選択になりました。TINIの有効性は、ネットワークへのパラレルポートデバイスの接続にとどまりません。CAN、SPI、I²C、RS-232、1-Wire、およびその他の多数の通信バスのサポートによって、TINIはネットワークをあらゆる種類のレガシ機器にブリッジするのに最適な選択です。DHCP、HTTP、FTP、Telnet、DNSなどのようなネットワークプロトコルに対するソフトウェアサポートによって、旧式機器への使い慣れたアクセス手段(ウェブページなど)を提供するスケーラブルな方法が多数あります。TINIは、高コストの旧式機器にアクセシビリティの向上が求められる場合に適した選択です(新しいドットマトリックスプリンタは、現在約400ドルのコストがかかります!)。このため、旧式機器を捨てないでください。TINIを通じて旧式機器を救ってください。

¹ Messmer, Hans-Peter, The Indispensable PC Hardware Book (Addison Wesley, 1994).
² RFC 1179: LPD Protocol www.faqs.org/rfcs/rfc1179.html

同様の記事が、Circuit Cellar誌192 (2006年7月)号にオンライン掲載されています。


関連製品  APP 3931: Nov 13, 2006
DS80C400 ネットワークマイクロコントローラ フルデータシート
(PDF, 1.8MB)
無料
サンプル

自動アップデート
お客様が関心のある分野でアプリケーションノートが新規に掲載された際に自動通知Eメールの受信を希望する場合は、EE-Mail™にご登録ください。


We Want Your Feedback!



フィードバックをお寄せください。
内容に満足されましたか、あるいは満足されていませんか?もっと良いページにできると思いますか?あるいは、単なるコメントでも結構です。フィードバックをお待ちしています。—マキシムはお客様からいただく訂正、提案を元に改善していきます。 このページを評価し、フィードバックを送信する。

 

ダウンロード、PDFフォーマットダウンロード、PDFフォーマット(76kB)
 AN3931, AN 3931, APP3931, Appnote3931, Appnote 3931

        •         •         •     プライバシーポリシー     •     法的お知らせ

    Copyright © 2009 by Maxim Integrated Products