例外処理
例外とは
想定していないことが起きたときに、問題の解決=回復を期待して呼び出し元にそれを伝えること
エラーの種類
どんな時起こるか。
API連携など、結合している外部のアプリケーションに問題があるとき
ゼロでの除算など、許されない演算を行ったとき
ユーザの入力にミスがあったとき
ライブラリにバグがあったり、アップデートにより互換性が失われたとき
ハードウェアが故障したとき
エラーと例外の違い
table:エラーと例外
用語 説明
エラー アプリケーションのユーザが解決できる問題
例外 アプリケーションの開発者が解決する必要のある問題
Javaなど言語によっては呼び出し元に例外処理を強要する機能をもつものがある。
table:チェック例外と非チェック例外
用語 説明 例
チェック例外 例外処理が必要な例外 ファイル読み込みなど
非チェック例外 例外処理を行う必要がない例外 メモリの枯渇など
例外の対応:
基本的な考え方は、『例外処理は回復するか投げっぱなしにするかのどちらか』で対応する
どこで例外処理をするか
呼び出し先で起こりうる例外を回復できるところで行う。
例:
APIにリクエストを送っているところ
ファイルの読み込みを行なっているところ
ユーザからの入力を処理しているところ
例外処理のすべきでないところ
呼び出し先で起こりうる例外を回復できないところ
事前条件を満たさない場合、または事前条件を満たさないことによりメソッド内でエラーが起きた場合
(事前条件を満たすのは呼び出し側の責任であるという「契約による設計」の考え方)
引数異常を起因としてメソッドが正常に動作できなくなった場合もここに該当する
事前条件を満たしているが、失敗責任の所在がメソッド内で閉じていない場合(失敗がネットワークなどに起因する場合)
事前条件を満たしているが、メソッド内で回復できないエラーが発生した場合
参考:https://applis.io/posts/how-to-design-exception-handling#例外処理とは
https://qiita.com/yuya_presto/items/3b651d6b0cf38f77e933
https://www.aps-web.jp/academy/cm7/240/
https://www.aps-web.jp/academy/cm/270/
データシート:https://www.st.com/resource/ja/programming_manual/pm0214-stm32-cortexm4-mcus-and-mpus-programming-manual-stmicroelectronics.pdf
https://www.stmcu.jp/wp/wp-content/uploads/files/presentation-ja/STM32WB/07_STM32WB-System-Nested-Vectored-Interrupt-Control-(NVIC)_J.pdf
エラーハンドリング
ソフトウェアの中で発生するエラーに適切に対処すること
エラーハンドリングは非常に重要である。
例:下記モジュール関数を利用した処理にエラーハンドリングを考慮すると。
https://gyazo.com/ba554ec43e4b72082162e2e931848677
各ステップのどれも失敗する恐れがある為、プログラマが記述するロジックは下記のように、失敗を考慮したものとなる。
https://gyazo.com/fb2453c87db8705c3bd87b05d993fe92
エラーへの主な対処方法:
スキップ:失敗した処理をスキップして先へ進んでよい状況。ただちに対策を施さなくても、のちに検証・修復を実施したい状況においては記録を残す。記録については以下のパターンも同様。
デフォルト値:情報の取得・生成に失敗しても、省略時解釈の余地がある状況。
別ロジック:ロジックAが失敗したらそれとは異なるロジックBを試みる余地のある状況。
入力の再要求:妥当でない入力パラメータに関し、ユーザに値の入力を再度求めたり、通信相手に再送信を求  めることができる状況。
ただし、一定の閾値でタイムアウトする必要がある。タイムアウトした場合は、反復全体がエラーであるとしてさらなる対処を行う。
同じ処理の再試行:無線通信等、処理の成功に不確実さがある状況。
ただし、一定の閾値でタイムアウトする必要がある。タイムアウトした場合は、反復全体がエラーであるとしてさらなる対処を行う。
自己プログラムの再起動:そのマシンにおける稼動の継続が見込める状況。
上位モジュールへの失敗の通知:当該モジュールでは意味のある対処はできないが、責任を委ねる先の上位プログラムが存在する状況。
他マシンへの役割りの引継ぎ:当該マシンにおける稼動の継続は困難であるが、バックアップマシンが存在する状況。
プログラムの停止、マシンのシャットダウン:自ら行えることが何もない状況。
検出:
対処すべきエラーは、その発生が的確に検出されなくてはならない。
伝達
検出されたエラーは、その事象への対処を担当するモジュールへ伝達されなければならない。
伝達手段には、関数の戻り値、関数が書き込む構造体のフィールド、C++の例外などがある。
参考:https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/c502.html
STM32の割込み、NVICについて。
例外処理も割込みの一種
STM32F4の場合: (STM32F767でも同様の考え方が出来ると思う)
• 63 種類の割込みソース
• 16 段階のプログラム可能な優先順位レベル
• 遅延時間の少ない例外および割込み処理
• 自動ネスティング
• 電源管理制御
アプリケーションは、
割込みレベルの動的優先順位付け
低遅延応答によるリクエストへの高速応答
テールチェインに加えて、ベクタテーブルの再配置による便益を受ける。
主な機能
ネスト化されたベクタ割込みコントローラによって、割込みリクエストへの高速応答が可能
アプリケーションは受信イベントに迅速に対応できる。
STM32WB には 63 種類を超える割込みが実装されている。
一部の割込みは、同一のネスト化されたベクタ割込みコントローラに集約されている。
ペリフェラル割込みレジスタを読み出すことで、ソフトウェアは割込みをリクエストしたペリフェラルを識別できる。
各割込みリクエストに割り当てられた優先順位はプログラム可能であり、動的な変更が可能。
割込みベクタテーブルは再配置可能
システム設計者は、割込みサービスルーチンの配置をアプリケーションのメモリレイアウトに適応させることができる。
例:ベクタテーブルは RAM に再配置できます。
https://gyazo.com/2d33e21f9c5811136062af72dd8e26eb
ソフトウェアは、それぞれの割り込みはもとより、リセットを除くすべての
例外ソース
ノンマスカブル割込み
ハードフォルト
に対する優先順位レベルの割当てを管理する。
スーパーバイザコール命令の実行と同時にペリフェラル割込みがリクエストされた場合
ハードウェアとソフトウェアの例外の相対的優先順位により、どれが最初に処理されるかが決定される。
STM32WB マイクロコントローラでは、ノンマスカブル割込み(NMI)は、
SRAM2 パリティエラー
Flash ダブル ECC エラー
クロック障害
のいずれかの原因により発生する。
63 種類のペリフェラル割込みリクエストのいずれかの優先順位は、
Cortex-M4 ネスト化されたベクタ割込みコントローラレジスタの中にある専用の優先順位フィールドにプログラム可能。
テールチェインとネスティングの説明:
https://gyazo.com/55bcea6df0405af3ed55e37c7ee9de40
ネスト化されたベクタ割込みコントローラにより、例外の効率的処理のためのいくつかの機能が提供される。
割込みの処理中にそれより優先順位の高い新規のリクエストが到着した場合、新しい例外が現在の例外をプリエンプトできる。
この処理は、ネスト化された例外処理と呼ばれる。
優先順位が高い方の例外が処理された後に、その前の例外ハンドラが実行を再開する。
Cortex-M4 の中に存在するマイクロコードにより、自動的にコンテキストが現在のスタックにプッシュされ、
割込みからの復帰時に復元される。
例外の開始と復帰
https://gyazo.com/64b8376f05c0d2e3601d2088c932f9c3
ある割込みハンドラの実行中に優先順位がそれ以下か同一の割込みリクエストが立つと、
そのリクエストはペンディング扱いとなる。
現在の割込みハンドラが終了した時点で、割込みの遅延低減のために、コンテキストの保存と復元のプ
ロセスはスキップされてる。
制御は新しい例外ハンドラに直接転送される。
連続した優先順位が低い(優先順位値が大きい)割込みは、数クロックサイクルという非常に短い遅延で連
鎖する。
https://gyazo.com/9698d254e37b12fb8a831dbda036fab0
割込みが到着すると、プロセッサは、割込みハンドラを実行する前にプログラムを保存する。
優先順位がより高い割込みが到着したときに、プロセッサがコンテキスト保存処理を実行中であった場合、
プロセッサは、プログラムコンテキストの保存が完了後、優先順位の高い方の割込みの処理に直接切り替える。
その後、IRQ_B 割込みサービスルーチンを実行する前に、テールチェインが用いられる。
すべての例外ハンドラの実行が終わって、それ以外の例外がペンディングになっていない場合、プロセッサは、前のコン
テキストをスタックから復元し、通常のアプリケーション実行に復帰する。
https://gyazo.com/fdb2d7b833c47981c0512c0f72434588
用語説明