AVR SEI命令(http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_SEI.html)は、割り込みを有効にする前に次の命令が完了するのを待ちます。
別の命令を使用してSREGのIフラグを設定した場合、これも1命令待機しますか?
つまり、待機はSEI命令またはステータスレジスタの機能ですか?
SEI命令の機能である場合、SEIを実行するサイクルで、または次の命令で、実際にどの時点でフラグが設定されますか?
AVR SEI命令(http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_SEI.html)は、割り込みを有効にする前に次の命令が完了するのを待ちます。
別の命令を使用してSREGのIフラグを設定した場合、これも1命令待機しますか?
つまり、待機はSEI命令またはステータスレジスタの機能ですか?
SEI命令の機能である場合、SEIを実行するサイクルで、または次の命令で、実際にどの時点でフラグが設定されますか?
回答:
他の答えは思慮深く根拠のあるものですが、それらはすべて不完全または推測にすぎません。文書があいまいな場合は、実験し、すべてのケースをテストする必要があります。
この質問は決定的な答えに値するので、AVRを引き出していくつかのビットを設定しましょう!
テストするために、次のような小さなArduino(ATMEGA328P)プログラムを作成しました。
while (1)
)INT0
ローになります)割り込みが有効になった後、単一の命令でLEDをオンにするテストベッドを使用しました。テストベッドで割り込みを有効にするさまざまな方法を試し、LEDを確認することで、有効にする命令の後の命令が実行されたかどうかを確認できました。
LEDが点灯しなかった場合、割り込みが有効になった直後にISRが実行(およびロック)されたことがわかります。
LEDが点灯した場合、ISRが呼び出される前に次の命令の実行が許可されていることがわかります。
SEI
指示(基本ケース)コード:
sei
結果:LEDが点灯します。次の命令が実行されました。
OUT
命令コード:
in r16,0x3f // Get SREG
ori r16,128 // Set I bit
out 0x3f,r16 // Save back to SREG
結果:
LEDが点灯します。次の命令が実行されました。
ST
命令コード:
clr r29 // Clear Y high byte
ldi r28,0x5f // Set Y low byte to point to SREG
ld r16, Y // Get SREG
ori r16,128 // Set I bit
st Y,r16 // Put SREG
結果:
LEDが点灯します。次の命令が実行されました。
Q:待機はSEI命令またはステータスレジスタの機能ですか?
A:I
ビットを変更することSREG
は、a 0
からa1
ビットを設定するために使用される命令に関係なく、保留中の割り込みがある場合でもと、次の命令が次に実行できるようです。
これは実際、多くの複雑な問題を伴う非常に興味深い質問に変わりました。詳細に興味がある場合は、チェックしてください...
http://wp.josh.com/2016/01/05/different-ways-to-set-i-bit-in-avr-sreg-besides-sei/
ドキュメントから、sei
命令を実行することは、SREGのIビットに直接1を書き込むことと同じであると理解しています。この命令の利点は、1<<I
SREGを変更するために最初に値を作業レジスタにロードする必要がないため、時間を節約できることです。
詳しく説明するには、次を使用しsei
ます。
sei ; One cycle
を使用してビットを設定しますsbi
(SREGがレジスタマップの下位32バイトにあった場合にのみ機能しますが、すべてではないにしてもほとんどではないようです)。
sbi SREG,7 ; Two cycles
SREGに直接Iビットを書き込む:
in r24,SREG ;
ori r24,0x80 ;
out SREG,r24 ; Three cycles
I
ビットはとすぐSREGに設定されるべきsei
命令(またはsbi
あるいはout
)完了。ただし、保留中の割り込みは、次の命令が完了するまで処理されません。ビットが設定されますが、割り込みが有効になるまでに余分なサイクルがかかります。割り込みは命令の途中で処理することができず、一部の命令は実行に複数のサイクルを要するため、1つの命令として有効になるまでにかかる時間を指定します。これは、コードのすべてのバージョンに当てはまります。つまり、上記のそれぞれが命令の遅延を引き起こします。
少し検索した後、私はこれを見つけました Arduinoフォーラムでスレッドた。そこでは、動作を検証するためにいくつかの異なるテストが実行されました。私が上で言ったことに同意するようです。
さらに、そのスレッドによれば、I
フラグが既に設定されsei
ている場合、遅延応答は命令自体ではなく、I
フラグによって制御される内部ハードウェアによって引き起こされることを意味する割り込みの遅延応答はありません- SREGのフラグを変更するあらゆる操作が、それもそうsei
か、out
またはsts
必要があります正確に同じ動作を。
SBI
を設定するために使用することはできないため、これを行うコードは実際には実際にはテストされていないことに注意してください。下位32レジスタでのみ動作し、SREGはスロット63にあります。I
SREG
SBI
out
私が元々使用していたものでした。下位32レジスタにSREGがあるAVR(おそらくはATTiny)に出くわすと思っていましたが、想像するかもしれません。