メイン関数よりも ISR に多くのコードが書き込まれている場合、スタック スペースに問題が生じるのはなぜだろうと思っていました。
スタック スペースは、おそらく ISR の主な関心事ではありません。レイテンシを最小限に抑えるために、ISR は可能な限りシンプルかつ高速である必要があるため、とにかく大きなスタックは必要ありません。重要な処理を行う必要がある場合、ISR はタスクをキューに入れ、後で通常のスレッドで実行してジョブを完了する必要があります (上半分と下半分と呼ばれることもあります)。これは、条件変数、セマフォ、またはメッセージ キュー (IPC メカニズムをいくつか挙げると) を使用して実現できます。したがって、ISR が大量のスタックを使用している場合は、タイミングが重要なスケジューリング期間中に過剰な処理を実行しようとしていることを示している可能性があります。
また、多くのシステム (RTOS など) では、スレッドと ISR のスタック サイズを宣言する必要があります。
コールバックからいくつかの異なる関数を呼び出したいと思います。このコールバックが実際に ISR から呼び出される場合、ISR からさらに多くの関数を呼び出すことは問題になりますか?
上記で説明したように、ISR からの他の関数の呼び出しを最小限に抑える必要がある場合に限ります。他の関数を呼び出すことはできますが、ISR がカーネル スケジューラに戻った後(およびマスクされていない割り込み!) は、できるだけ実行を延期する必要があります。
また、競合状態に注意してください!共有状態を保護するには、ミューテックスを慎重に使用する必要があります。
各関数を呼び出すと、各関数には独自の最大スタック サイズがあるため、追加のスタック スペースが許可されますか? これは少し混乱します。
いいえ - 関数には独自のスタック サイズがありません - スレッドにはあります。ISR の場合、OS によって異なります。ただし、各関数を呼び出すと、(呼び出しのネスト レベルに基づいて) より多くのスタック スペースが消費されます。
関数と ISR は、完全に割り当てられたスタックまで、好きなだけスタック スタック スペースを使用できると常に考えていました。
はい。ただし、スタックはスレッドごとであり、ヒープのようにプロセスごとではありません。大量のスタック領域を使用することは、設計上の問題の兆候である可能性があります: ヒープではなくスタックに大きなオブジェクトを割り当てる、ネストされた関数呼び出しが多すぎるなど。
メイン関数が他の関数よりもスタックの大きな部分を持っていることを意味しますか?
いいえ、スタックはスレッドごとなので。関数はアプリケーションのmain
コール スタックの一番下にありますが、ローカル変数のみに応じて、少量または大量のスタックを消費する場合があります。
いくつかの良い読書: