[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[WitchTech 00869] 割り込み中の RTC アクセス競合にご注意。



不定期でハングする問題を解決するために用意したスタックダンプで追うと、

FD90:0E35 E4CA          IN	AL,CA
FD90:0E37 A880          TEST	AL,80
FD90:0E39 74FA          JZ	0E35
FD90:0E3B C3            RET

で I/O 0xCAhが変わるのをずっと待っているようです。
BIOSエリア、ハードウェアがらみとなるとこれ以上の解析は規約違反になりそう
なので、ハードウェアアクセスするところだろうという見当でソースを当ってい
くとどうやらRTCが怪しいようです。
#BIOSエリアだとわかった段階でQuteに解析依頼が正しいのかも知れませんが
#本当にそこが原因か分からないので確信が持てるところまでちょっとだけ追い
#ました。

そこで、
mainでRTC読み出し、割り込みで書き込みというテストルーチンを走らせてみたの
ですが一晩かけても凍らなかったので悩んでいました。

ところがOzeki君からストールしているようだというメールがあり、確かに似た
ような頻度でrtc_get_datetime_struct()から最大 55 V_BLANK、0.73秒という
CPUにとっては無限にも等しい時間、帰ってきません。
(割り込みルーチンは最大でも1 V_BLANKで抜けているので確実にここです。念の
ため^-^;)。
セマフォを張ったりRTC読み出し中は割り込み禁止にしたりすると起こらないよ
うなので

RTC読み出し中
 割り込み RTC書き込み
RTC読み出し再開

でなにかが起こっているという推測は当たっていたようです。
RTCはアドレス節約のためにレジスタが少なく、ステートを持っているのが普通
なので理解できる動きですね。このテストルーチンそのものはハングしないの
ですがさらに「なにか」が起こってハングしてしまうのでしょう。実際、この
ために0.1msで終了する割り込みルーチンをタイマで1/8秒間隔と間延びした間隔
で呼び出しているのに再入してしまうという問題が発生していて、これもセマフォ
でブロックするとストールはするもののとりあえずハングしないようです。

なんでこういう構成になっているのか疑問だ、割り込み中では極力、素性のわか
らない(失礼!)ルーチンを呼ばないのが基本でしょうという人に。
受信したデータでRTCを設定しなおす..遅れては意味がないので割り込み内。
読み出しは時間を知りたいときなので割り込み内でやっては意味がない。
というのでこういう構成になっていました。
割り込みで使って良い関数と悪い関数、できれば実行時間も知りたいところです
ね。

セマフォを張って確実に保護し、それだけではセマフォにブロックされて割り込
みが無駄になってしまうのでRTCの読み書きの頻度を落として無駄なブロックを
減らすことで対処しました。

 今回は書き込みでしたが割り込みで読み出しする場合も同様の現象がでると
思います。ご注意あれ。


ML Archives