クリティカルなIO制御 | 組込みとともに

クリティカルなIO制御

IO制御でクリティカルな処理についてのメモです。

μITRON等を使える場合はセマフォやミューテックス等で排他制御を行うが、OSなしの場合は独自実装を行う必要があります。

割り込み処理で変数やIOを扱うときは特に排他制御を意識しないとタイミング系のバグとなりテストではなかなか発見出来なかったりバグを見つけても不具合箇所の特定が困難であったりします。


こう言った不具合への対応策は設計レベルでフォローするのが一般的ではないかと思います。


では設計時に置いて何をしたら良いでしょうか?


割り込み処理内で書き込みを行うグローバル変数、IO の洗い出し。同様にメイン処理側も。

ここでそれぞれを表にしてそれぞれで書き込みを行っている変数・IOを見つけましょう。
この変数・IOは後述のクリティカル処理が必要です。

ここからが重要なポイントです。
ここまではハード系の知識があまりなくとも感覚でわかるかもしれませんが、次のことは回路図を見ないと判断出来ないので、多少の電子回路図を読む力が必要になります。
丁寧なハードウェア仕様書を作っている会社の場合はそれを確認してください。


ある特定のIOポートへ信号を送った場合でもCPUの処理はポート単位となる場合があります。CPUがビット制御対応でアセンブラレベルで一回でポートのデータレジスタへ値が渡せる場合は気にしなくてよいですが、CPUの命令で対応してなかったりC言語でアセンブラレベルの動作が不透明な場合は、タイミングによっては次の動作となり不具合となります。

メイン側
処理:ビット1をH
1、レジスタAへIOの状態をリード
2、レジスタAに01hで論理和
3、レジスタAをIOへ反映

割り込み処理
処理:ビット2をH
4、レジスタAへIOの状態をリード
5、レジスタAに02hで論理和
6、レジスタAをIOへ反映

※ここで割り込み処理はメイン処理のいかなるタイミングでも呼ばれる可能性があるとします。

メイン処理の2と3の間で割り込みが入った場合はどうなるでしょうか?

割り込みでビット2はHになっている筈がメイン側に戻った後にLに書き換えられてしまいます。

そんな時はメイン処理のクリティカルな箇所は一時的に割り込み禁止にします。


ですので設計時に同じポートへの書き込みも表へ記入し確認しましょう。
作った表は保守用に設計資料へ入れておきます。