外部割り込みプログラムについて質問があります。DS89C450のINT1(立ち下がりエッジに設定された外部割り込み1)を使用していて、外部割り込みのプログラムが非常に長い場合、正しく機能しますか?それとも何か問題がありますか?KeilEmbeddedCを使用しています。
2 に答える
RTOS を使用せずにこれを行う別の方法は、イベント フラグとステート マシンを使用することです。プログラムは、特定のイベントが呼び出されたときに遷移する個別の状態に図式化できます。たとえば、この図では、Google を使用して見つけました。
ボタンのクリックはイベントです。たとえば、INT1割り込みからトリガーできるもの。次に、次のループをフォアグラウンドに配置します。
#define STATE_POWER_OFF 1
#define STATE_POWER_ON 2
#define EVENT_BUTTON_CLICK 0x01
volatile unsigned char bEventFlags = 0;
unsigned char bState = STATE_POWER_OFF;
unsigned char getEventFlags( void ) ;
int main(void)
{
for(;;)
{
unsigned char flags = getEventflags() ;
if (flags != 0)
{
switch (bState)
{
case STATE_POWER_OFF:
if (flags & EVENT_BUTTON_CLICK)
{
// Do something
bState = STATE_POWER_ON;
}
break;
case STATE_POWER_ON:
if (flags & EVENT_BUTTON_CLICK)
{
// Do something
bState = STATE_POWER_OFF;
}
break;
}
}
}
}
unsigned char getEventFlags( void )
{
unsigned char flags = 0 ;
// Get copy of flags in critical section and clear down
_disable_interrupts() ;
flags = bEventFlags ;
bEventFlags = 0 ;
_enable_interrupts ;
return flags ;
}
そして、あなたの ISR は非常に短くなります:
void INT1_ISR(void)
{
bEventFlags |= EVENT_BUTTON_CLICK;
}
割り込みハンドラーが関係なく完了するまで実行されるという意味では、「長すぎる」ことはできません。ただし、割り込みが処理されている間は、割り込みアーキテクチャに応じて、他に何も実行されないか、優先度の高い割り込みのみが実行されます。この結果、リアルタイムの締め切りに間に合わない可能性があります。
処理中の割り込みソースからの後続の割り込みを見逃すことさえあります。一部のアーキテクチャでは、処理中に割り込みが無効にされていない場合、再入可能性が発生する可能性があり、ハンドラーが再入可能でない場合やスタックが不十分な場合に問題が発生する可能性があります。
したがって、それが機能するかどうかという質問に対する答えは、アプリケーション、リアルタイムのデッドライン、および発生する可能性のある他の割り込みソースに完全に依存します。そのような割り込みハンドラーが優れた設計であるかどうかの答えは、確かにノーです。現在動作していても、他のアプリケーションでは一般的に役に立たず、メンテナンス中に壊れる可能性があります。
より良い解決策は、部品に単純な RTOS スケジューラ カーネルを展開し、割り込みハンドラが適切な優先度レベルでタスクに信号を送るようにすることです。MCS-51 アーキテクチャは、8 つの重複レジスタ バンクによりスケジューラを効率的に実装できます。最大 8 つのタスクの場合、コンテキスト スイッチは非常に高速です。