ちなみに、実装は 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 件のコメント:
コメントを投稿