2012/07/16

[os]シリアルドライバのセマフォID

まずはUARTを動かしたかったので、簡単なソースを書いた。

   1: serial_opn_por(1);    //ch4
   2: serial_wri_dat(1, "1234", 4);

 

   1: INCLUDE("target_timer.cfg");
   2: //INCLUDE("syssvc/syslog.cfg");
   3: INCLUDE("syssvc/banner.cfg");
   4: INCLUDE("syssvc/serial.cfg");
   5: //INCLUDE("syssvc/logtask.cfg");
   6:  
   7: #include "xxx.h"
   8:  
   9: CRE_TSK(LED_TASK, { TA_ACT, 0, main_task, 7, 128, NULL });

 

システムログを使うとUART資源が減ってしまうので、切った。
私はFM3のch4を使いたかっただけなので、target_config.hのSIO_PORTIDを1以外にしてしまうという方法もあったのだけど、なんかね。
MakefileにTOPPERS_OMIT_SYSLOGを定義し、それでも呼ばれそうだったのでlogtaskの中をifdefで切るようにした。

このあたりがすぐにわかったのも、OpenOCDでデバッグできたからだ。
よかったよかった。


これでポートオープンはできるようになったのだが、送信ができない。
serial_wri_dat()の中でエラーを起こしているようだ。

よくよく追ってみると、送信するときにセマフォでリソースを確保しようとしているのだが、セマフォIDがおかしいということでエラーにされているみたい(えらく大きい値だった)。

セマフォIDは、syssvc/serial.cの内部に持っている値で、どうも外から設定している気配がない。。。
と思ったら、こんなconst値だった。

   1: static const SPINIB spinib_table[TNUM_PORT] = {
   2:     { SERIAL_RCV_SEM1, SERIAL_SND_SEM1,
   3:       SERIAL_RCV_BUFSZ1, rcv_buffer1,
   4:       SERIAL_SND_BUFSZ1, snd_buffer1 },
   5: ・・・

 

このSERIAL_RCV_SEMxとSERIAL_SND_SEMxがセマフォIDのようだ。
ってことは、固定値なのか。

送信なのでSERIAL_SND_SEM1だったのだが、検索しても芳しくない。
target/cq_frk_fm3_armcc/uvision/kernel_cfg.hか、あとはそれぞれのcfg1_out.cとkernel_cfg.h。
それぞれのcfg1_out.cは、

#define SERIAL_SND_SEM1    (<>)

となっていた。
???
エラーにならんのかい?
いや、そもそもこれはCソースだ。includeして使うタイプなのだろうか。

それに、kernel_cfg.hに定義してあるのにその値になってなかったということは、読み込まれてないということなのだろうか?
いやいや、serial.cには"kernel_cfg.h"をインクルードしている。
うーん、別のkernel_cfg.hを読んでるのか?


途中を省いて結果だけいうと、UARTの割込を有効にしておかないとFM3のUARTオープン途中で設定が終わってしまい、セマフォIDなどが未設定になってしまう、というような感じになっているみたいだ。
target_serial.cのsio_opn_por()の最後にやってる割込マスク解除あたりで何か起こっているみたい。

とりあえず空実装でcfgに追加すると、シリアル出力することがロジアナで確認できた。

   1: INCLUDE("target_timer.cfg");
   2: //INCLUDE("syssvc/syslog.cfg");
   3: INCLUDE("syssvc/banner.cfg");
   4: INCLUDE("syssvc/serial.cfg");
   5: //INCLUDE("syssvc/logtask.cfg");
   6:  
   7: #include "snep_target.h"
   8:  
   9: CRE_TSK(LED_TASK, { TA_ACT, 0, main_task, 7, 128, NULL });
  10:  
  11: CFG_INT(IRQ_VECTOR_MFS4RX, { TA_NULL, INTPRI_SIO });
  12: ATT_ISR( { TA_NULL, INTATR_SIO, IRQ_VECTOR_MFS4RX, NULL, 1} );
  13: CFG_INT(IRQ_VECTOR_MFS4TX, { TA_NULL, INTPRI_SIO });
  14: ATT_ISR( { TA_NULL, INTATR_SIO, IRQ_VECTOR_MFS4TX, NULL, 1} );

 

デバッガとの接続とか、UARTの動作とか、そんな初歩っぽいところでつまると、かなりがっくりしますわ。
昔の私は、もうちょっと応用性があったんじゃないか、とか、そんながっくり感。

 

まあ、歳のせいばかりにしてられないので、ふんばろう。
次はRC-S620/Sに送信して、ACKをもらうところだな。


調べて、やってみてうまくいったものの、UARTと割込の件はあまり納得していない。
FM3に移植したTOPPERS/ASPを使ったサンプルで、そういう記述がないからだ。
システムログをまったく止めたことで悪影響が出ているのか、なんか考え違いをしているのか…。

   1: /*
   2:  *  シリアルI/O割込みのマスクを解除する.
   3:  */
   4: if (!opnflg) {
   5:     ercd = ena_int(p_siopinib->intno_rx);
   6:     assert(ercd == E_OK);
   7:     ercd = ena_int(p_siopinib->intno_tx);
   8:     assert(ercd == E_OK);
   9: }

 

この部分。
ここでassert()を通っていたのだ、割込を有効にしていなかったら。

_kernel_bitpat_cfgint[]を見て、割込が有効じゃなかったらエラーを返すような感触だった。
でも、assert()を通ったからといって死ぬわけでもなく、進んだようだった。
これはコンパイルオプションとかの関係かもしれん。

このあとはreturnで値を返すだけで、assert()するだけで死ななかったら、他に影響を及ぼすような感じもしない。
しないのだけど、spcb_table[].p_spinibの値が変わってたのよねぇ。

デバッガでアドレス指定の書き込みブレークなんかも設定できるんかいな。
できるなら、そのタイミングを見ればいいんだけど。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。