シリアル・インターフェース

シリアル・インターフェース・ドライバはTOPPERS/JSPのカーネルの機能ではありませんが、調歩同期式シリアル・ポート(いわるゆるCOMポート)を操作する際に便利な補助機能です。以下ではTOPPERS/JSPのシリアル・インターフェース・ドライバの概略と、Blackfin実装にあたって工夫した部分を説明します。実装は、TOPPERS/JSP 1.4.2のpdic/simple_sio/st16c2550.*に手を入れて行いました。

なお、シリアル・インターフェース・ドライバに関しては、TOPPERS/JSPのdoc/config.txtおよび、トロン協会が公開している組み込みシステムにおけるPDIC機能ガイドラインを一読することをお勧めします。前者に関しては、インデックス付けしてPDF化した文書をsourceforgeにおいています

構造

図1にTOPPERS/JSPのシリアル・インターフェース・ドライバの構造を示します。

図1 TOPPERS/JSPのシリアル・インターフェースの構造

SERIAL.*

最上位のserial.*はTOPPERS/JSPが提供するファイルで、関数、タスク、コールバックからなります。

関数はAPIとして機能する部分で、ser_opn_por()などといったポート操作関数の集合となっています。データの送受信もser_wri_dat()、ser_rea_dat()関数越しに行います。

コールバックは下位の層のためのサービスで、受信割込みや送信割込みを受けて必要なバッファ操作を行う関数群です。コールバックが用意されているため、下位の割込みハンドラは単にこのコールバックを適切に呼ぶのが仕事になります。

タスクは関数とコールバックの間の調停を行うためのものです。

serial.*はタスクを持っており、アプリケーション・タスクとの間で関数を使ったデータの受け渡しを行います。そのため、排他的制御のためのセマフォが必要になります。このセマフォの宣言や、タスクの登録のための静的インターフェースがserial.cfgとして用意されており、UNIX環境ではアプリケーションのコンフィギュレーション・ファイルからインクルードして使うことができます。

HW_SERIAL.*

hw_serial.*はシステム依存部がserial.*に対するサービスとして公開する関数群です。この関数群はPDICとして動作し、以下の関数を実装するようdoc/config.txtに指示されています。

m68kをはじめとする実装では、hw_serial.hにはマクロが定義が並んでおり、実際の関数、たとえばuart_cls_porをsio_cls_porに置き換えているだけです。これは、サンプルとなる実装では単一種のシリアル・デバイスしか用いていないためです。小規模なシステムの場合、単に内蔵シリアル・ペリフェラルを使うだけでしょうから、これでもかまいません。

大規模な実装となると、チップ外部にシリアル・デバイスをつなぐこともあり、そういった場合には単一種のドライバだけではカバーしきれないかもしれません。そこで、下位のPDIC実装群を束ね、serial.*から渡されるポート番号によって適切なPDICを呼び出すインターフェースをhw_serial.*に構築します。

このように、本来複数種のデバイスを抽象化するための層がhw_serial.*ですが、大抵のサンプル実装では一種しか通信デバイスが無いため、hw_serial.hのマクロで用が済んでいるのです。

UART.*

今回、st16c2550.*を修正して作ったのがuart.*です。st16c2550はNS16550A互換のUARTが2つ入ったチップであり、そのPDICであるst16c2550.*はFIFOを殺して使っています。つまり、16450と同じチップとして扱っています。ですので、16450互換であるADSP-BF533のUARTにはぴったりです。

改造にあたっては、ADSP-BF533のUART専用にするのではなく、8250/16450/16550系のUARTに汎用的に使えるものを目標としました。具体的には次のような点に気を使っています。

レジスタ名はBlackfinのUARTではなく16550にあわせました。NS16550のデータシートは入手できませんでしたが、可能なかぎりの本やページにあたってレジスタ名を決めています。

レジスタ・オフセットの配置に関しては、オリジナルの8250は当然1バイト境界であるものの、その後のCPUアーキテクチャの制約で異なるという事情があります。たとえば、BlackfinのMMRは32ビット境界ですので、レジスタは不可避的に4バイトごとに並びます。

送受の割り込みは本来のUARTでは1系統になっています。しかし、SOC化した場合などでは割り込みが別になっているかもしれません。ポーリングしてもかまわないのですが、せっかく別系統になっている割り込みをまとめてポーリングしなおすのもばかばかしいので、送受別々の割込みに対応できるようにしました。1系統のものにも対応できます。

未チェックながら、3系統のUARTに対応できるようにしています。3系統あれば大抵の用途には使えると思いますし、4系統目を追加するのも楽でしょう。

最後に、内部のuartレジスタ・アクセスは、SILを使っています。SILはIOをアクセスするに当たって、IO空間を使うかメモリ空間を使うか選ぶことが出来ます。これはアーキテクチャに依存する話ですので、マクロ宣言によって選べるようにしています。

一方で、以下のような点についてはあきらめています。

エラー割込みを使う場合にはコードを書き換える必要があります。最低でもポートの初期化でIERに書き込む値を変えてエラー割り込みを許す必要があります。

また、レジスタ配置境界は全体で1つだけ選べるようにしています。すべてのポートに独立したアドレス境界を与えてもいいのですが、コードが肥大する割にはそのような場合はほとんど無いように思えます。このような問題は内蔵UARTのほかに外付けUARTを使う場合に起きる可能性があります。

SILによるレジスタ・アクセスのiop/mem選択は全体でひとつだけ選べます。ポートごとにするとあまりにも負荷が大きいように思えるからです。

使い方

uart.*を使うには、構成用のマクロを用意します。マクロはsys_config.hで宣言します。以下の説明でUARTx_のxとは0から始まる整数です。この数字はPDIC内部の管理番号であって、内蔵UARTの番号とは無関係です。管理番号はユーザーが勝手に決めてかまいません。しかし0から始まる連続した数でなければなりません。現在の実装では許されるのは0,1,2のみです。

TNUM_PORT_UART
UARTのうち、幾つのポートをPDICとして使用するか宣言します。ADSP-BF533の内蔵UARTだけを使う場合は0あるいは1を指定します。
UART_BOUNDARY
UARTのレジスタが何バイト境界に配置されているかを指定します。指定できる値は1,2,4のいずれかです。
UART_IOP_ACCESS
UARTレジスタへのアクセスをsil_xxb_iop()使う場合にはこのマクロを宣言します。値は不要です。宣言しない場合、sil_xxb_mem()によってアクセスします。Blackfin実装ではiopアクセスを使用します。BlackfinはIOメモリ空間を持ちませんが、外付けIOに関してはアクセス時に割込み禁止が必要な場合があるので、iopアクセスを行います。
UARTx_ADDRESS
UARTのベース・アドレスを指定します。ベースアドレスとはTHRのアドレスのことです。
UARTx_DIVISOR
UART内部の分周回路の設定値を指定します。16ビットの値です。uart.c内部で上位と下位に分割してDLM/DLLレジスタに設定されます。
UARTx_BLACKFIN_UCEN
ADSP-BF533内蔵のUARTはUART_GCTLレジスタのUCENビットを1にしなければ動作しません。そこで、その設定が必要なポートに関してはこのマクロを宣言します。値は不要です。

以上で構成は完了です。使い方の例はBlackfin実装のconfig/blackfin-vdsp/bf533/sys_config.hおよびconfig/blackfin-vdsp/bf533/board_config.hを参照してください。

次に割込みハンドラの登録を行うコンフィギュレーションファイルhw_serial.cfgを用意します。このファイルでは以下のハンドラを割込みに割り当てます。

uartx_isr()
xは数字です。送受の割込みが共有されている一般的なUARTの場合は、このハンドラだけを登録してください。必要な作業はこれだけです。
uartx_tx_isr()
xは数字です。送受の割り込みが分離しているUARTの場合は、送信用にこのハンドラを登録してください。
uartx_rx_isr()
xは数字です。送受の割り込みが分離しているUARTの場合は、受信用にこのハンドラを登録してください。

hw_serial.hに関しては特に説明しません。上記のように単一種類のUARTを使うだけならマクロ定義だけで終わるはずです。

サンプル

TOPPERS/JSP 1.4.2上でのサンプルプログラムを用意しましたので、ダウンロードしてください。TOPPERS/JSP 1.4.2のsampleフォルダのものとは違います。なお、zipの中のディレクトリはBlackfinとは無関係のファイルなどを消しています。正式なTOPPERS/JSP 1.4.2はTOPPERSプロジェクトからダウンロードしてください。

サンプルを使うには、EZ-KIT BF533とPCのCOMポートをストレート・ケーブルで接続してHyperTerminalのような端末ソフトを立ち上げ、9600bps, 8btit, 1 stopbit,パリティ無しに設定します。次にVisualDSP++のFile⇒Open⇒Project Group...からusr/ezkit_bf533/19_serial_loopback/19_serial_loopback.dpgを開いてください。ビルドしてEZ-KIT BF533にダウンロードします。実行すると端末上にオープニング・メッセージが表示されます。キーボードから適当な文字をたたくとエコーバックが見えるはずです。

ダウンロード : 702KB

Blackfin空挺団 | プログラム | EZ-KIT | コア&ペリフェラル | TOPPERS/JSP | こぼれ話 | DSP掲示板