2008年11月27日木曜日

TOPPERS/JSP for秋月電子H8 3069 LANボード (5)

さてさて、H8向けのTOPPERS/JSPには、シリアルインタフェースドライバ内にシリアル受信割込ハンドラとシリアル受信エラー割込ハンドラの2つが定義可能です。しかし、後者は #ifdef の条件分岐によってコメントアウトされており、前者内でエラーの割込も処理するようになっています。

ちなみに、実装は jsp/config/h8/hw_serial.c 内の SCI_in_handler です。

さて、SCI_in_handler の実装を見てみましょう。

void SCI_in_handler(ID sioid)
{
SIOPCB *pcb;
UB status;

pcb = get_siopcb(sioid);
status = sil_reb_mem((VP)(pcb->inib->base + H8SSR));

if (status & (H8SSR_ORER | H8SSR_FER | H8SSR_PER)) {

/* エラー処理 */

/* エラーフラグをクリア */
sil_wrb_mem((VP)(pcb->inib->base + H8SSR), status & ~(H8SSR_ORER | H8SSR_FER | H8SSR_PER));
}

if (status & H8SSR_RDRF) {
if (pcb->openflag) {
/* 受信可能コールバックルーチンを呼出す。*/
SCI_ierdy_rcv(pcb->exinf);
} else {
sil_wrb_mem((VP)(pcb->inib->base + H8SSR), status & ~H8SSR_RDRF);
}
}
}

ううむ・・・真ん中当たりに「エラー処理」と書かれて放置されている(っぽい)辺りが怪しい。ここに書けば良いのかな。

とりあえず、フレーミングエラーの場合はシリアルチャネルのRxDを調べて、ブレーク信号かどうかを判断すれば良いそうです。こんな処理を入れちゃいましょう。

/* フレーミングエラー発生時 */
if (status & H8SSR_FER){
/* RDR (Receive Data Register) がブレーク信号受信状態 (全ビットがLOW = 0x00) であるかどうかをチェック */
if (sil_reb_mem((VP)(pcb->inib->base + H8RDR)) == 0x00){
/* ブレーク信号受信時には SCR (Serial Control Register) の RE (Receive Enable) フラグを落とす */
sil_wrb_mem((VP)(pcb->inib->base + H8SCR),
sil_reb_mem((VP)(pcb->inib->base + H8SCR)) & ~H8SCR_RE);
}
}

RxDを調べるとブレーク信号かどうか分かるって言うんですが、それってRDR (Receive Data Register) の値を調べれば良いって事と等価ですよね?RSR (Receive Shift Register) は直接CPUから読み書きできませんので、これで合ってると思うんですが。

そして、このコード修正をカーネルに反映してアプリを再コンパイルします。カーネルをアプリとは別にコンパイルしている場合は、

% cd jsp/(kernel_build_dir)
% make realclean
% make depend
% make libkernel.a

とかやっときましょう。たぶん最後の行の「make libkernel.a」だけで良い筈ですが、チキンな私は「make realclean」からやっときました(^^;)

さて、アプリをコンパイルしてH8に転送し、実行します。そして、シリアルコンソールのminicomから「Ctrl-a f」でブレーク信号を送信しますが・・・あ、シリアルコンソールからのデバッグ出力が止まった。カーネルがハングしたっぽい。

何でやねん!!

今入れたコードは何だったんだ・・・orz

(苦悩は続く・・・)

0 件のコメント: