« 導体? | トップページ | 変則3輪 »

2020年12月 4日 (金)

stm32で一つのベクタで複数の割り込みを処理するとき、など

ブログに時々、stm32とかのハマりポイントを
備忘録として書くことがあるのですが、最近書いてないのと、
身近で苦労しているような人がいるので、ヒントとして書きます。

これだけだと解決しないだろうけど...


------

自分がよく使っているstm32は、NVICをコアの
機能に持ち、ベクタ割り込みに対応しています。


ワンチップマイコンが、ハードウエアだけで動作する
割り込みコントローラーを持っているのは
今では当たり前になりすぎていて、だれも疑問に思いませんが
ついこないだ?例えば、arm7-TDMIのコアの頃には
ベクタ割り込みは、半自動でした。

 ※割り込み時に呼ばれるアドレスはすべて共通で、
 割り込みハンドラ内で、どの割り込みの要求かを
 自前のコードで判断、自力で処理ハンドラにジャンプしていました。
 当然、アセンブラコード記述必須。


Cortexコアになって、ベクタ割り込みコントローラーがコアに
実装され、普通?に使えるようになりました。


割り込み、便利に使えるようになったので、幸せにはなったのですが
動作が分かりにくくなったのも確か。

クリティカルなタイミングで動かしていると、
一見不思議な動きをしているように見えたりします。

実体験から、2つTipsを選んで置いておきます。

------

①一つの割り込みベクタで、複数のイベントを管理

 これに、個別に割り込み禁止/許可を組み合わせ、
 かつ(ついつい)自分の都合のよいように
 動作を解釈するときに、インシデント発生します。

 ※タイマー割り込みで、よくやりがちです。


 例えば、TIM2には割り込み要因がいくつかありますが、
 割り込みベクタはすべて共通で、どのイベントが発生しても
 同じイベントハンドラ関数が呼ばれます。


 ここで、割り込み分岐許可自体は、チャネルごとに設定できるので
 割り込みは、TIM2のch1のコンペアマッチだけで発生させる、
 という設定は出来て、これは正しく動作します。

 この時、たとえばch1に加え、ch2もコンペアマッチ動作等で
 初期化されていると、割り込みを使わないつもりでも
 個別に割り込み禁止されていても、
 SRレジスタのフラグは立ってしまいます。
 (割り込みハンドラは呼ばれない:正しい動作)

 この状態で、たまたまch1のイベントが発生して、
 SRレジスタのフラグしかチェックしないと、
 ch1とch2 両方の処理をしてしまうことになり、
 ch2は割り込み禁止している(つもりな)のに、
 なぜか処理が行われるように見えます。

 割り込みハンドラの中で処理の
 選択をする場合、SRだけでなく、
  DIERも参照する必要があります。

 ※クリティカルパスが発生しない
  ように、参照のタイミング自体も
  よく吟味する必要があります。


------


②割り込みを動的に許可/禁止する場合

 こちらは定番ですが、個別に割り込み許可する前に
 要因となるSRをクリアしておく必要があります。
 
 割り込み禁止期間の間に、イベント発生して
 いると、割り込み許可した瞬間に、
 ハンドラに分岐します。
 

 ※至極正しい動作ですが、大体の場合、
  意図した動きではないでしょう。


 通信などでは、一般的に割り込み禁止/許可を
 動的に切り替えることは少なく、
 考慮しなくても意図しない動作はしにくいですが。
 フリーランタイマーのコンペアマッチなどでは
 一定時間後にイベントが発生するので、
 この動作を見落としがちです。

 ※こちらもクリティカルパス要注意


------

マイクロマウス系のソフトウエアでは、タイマーの
コンペアマッチ割り込みを、動的にON/OFF
することは少ないでしょうが、各種タイマーは
上手く使うと、色々なことが出来るようになります。

さらにDMAと組み合わせれば、相当複雑なことができますが、
上手く行かないときのデバッグの難易度も相当なものです。


まあ、ハードウエア設計時によく考えて、
個別に割り込み許可/禁止しなくても良いように、
構成すれば、あまり気にしなくても問題でないのですが。


何かの助けになれば、こそ
と取り急ぎ。

| |

« 導体? | トップページ | 変則3輪 »

コメント

コメントを書く



(ウェブ上には掲載しません)




« 導体? | トップページ | 変則3輪 »