プログラムからexit()を呼び出すとどうなりますか?


17

setupまたはのいずれかでloopexit(0)コールを追加する場合、どこに制御が渡されますか?マイクロコントローラーの次の状態はどうなりますか?実行を停止して電源を切りますか?

リビジョン2のArduino Unoを使用しています。


止まると思います。クロックをシャットダウンしたり、電源を落としたりすることはありません。
TheDoctor

メモリの残りの部分はで満たされる必要があるNOPだけのカップルのクロック・サイクルのために一時停止のアセンブリ文、
TheDoctor

回答:


12

私の最初の推測は間違っています。ループから単純に戻り、コアライブラリはloop()を再度呼び出すだけだと思っていたでしょう。ただし、次のコードが作成されました。__stop_programはハードループであることに注意してください...

exit(0)が追加されたBlink.inoのリストの抜粋:

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
  exit(0);
}

上記の分解:

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 100:   80 91 00 01     lds r24, 0x0100
 104:   61 e0           ldi r22, 0x01   ; 1
 106:   0e 94 ca 01     call    0x394   ; 0x394 <digitalWrite>
  delay(1000);               // wait for a second
 10a:   68 ee           ldi r22, 0xE8   ; 232
 10c:   73 e0           ldi r23, 0x03   ; 3
 10e:   80 e0           ldi r24, 0x00   ; 0
 110:   90 e0           ldi r25, 0x00   ; 0
 112:   0e 94 f7 00     call    0x1ee   ; 0x1ee <delay>
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 116:   80 91 00 01     lds r24, 0x0100
 11a:   60 e0           ldi r22, 0x00   ; 0
 11c:   0e 94 ca 01     call    0x394   ; 0x394 <digitalWrite>
  delay(1000);               // wait for a second
 120:   68 ee           ldi r22, 0xE8   ; 232
 122:   73 e0           ldi r23, 0x03   ; 3
 124:   80 e0           ldi r24, 0x00   ; 0
 126:   90 e0           ldi r25, 0x00   ; 0
 128:   0e 94 f7 00     call    0x1ee   ; 0x1ee <delay>
  exit(0);
 12c:   80 e0           ldi r24, 0x00   ; 0
 12e:   90 e0           ldi r25, 0x00   ; 0
 130:   0e 94 1e 02     call    0x43c   ; 0x43c <_exit>

...

0000043c <_exit>:
 43c:   f8 94           cli

0000043e <__stop_program>:
 43e:   ff cf           rjmp    .-2         ; 0x43e <__stop_program>

_exitがcliを呼び出さなかった場合、割り込みが何かを行えることに注意してください。しかし、そうではありません。


avr-objdump -S {compiled *.elf file}アセンブリコードの各セクションにつながるCコードを含むファイルを生成します。フォローするのがずっと簡単です。
コナーウルフ14

aaaand私はそれを試してみましたが、ループ関数のインラインCコードを正しく出力していません。なんてこったい?
コナーウルフ14

おっと、非常に奇妙です。私はプロジェクトをコンパイルStinoの代わりに、arduinoの編集、逆コンパイル*.elfことから、そしてその後、私は適切なデバッグシンボルを取得します。私は(私はそれがありませんので、IDE、それを呼び出すことを拒否する)事からデバッグ情報をストリッピングされたArduinoのテキストエディタ/ボタンマクロを考えるだけで、いくつかの奇妙な愚かな理由のために、コンパイル済みのメインC ++ファイル。
コナーウルフ14

そこの説明は、それが一時的な場所に道をIDEコピーしてファイルを実行することです。ソースの場所をavr-objdumpに伝えることで、それを「修正」できますavr-objdump -S -I/path/to/the/sketch/folder xxx.elf 。これは、.inoファイル自体ではなく、スケッチフォルダーのパスです。次に、ダンプでCソースを取得する必要があります。
ニックギャモン

11

さて、Arduino Unoでテストしたところ、コードが完全に停止し、コードの実行が停止したときのすべての出力がそのまま残りました(したがって、LEDがオンのままになりました)。exitを呼び出すと、IOクリーンアップは行われないようです。他のAVR IDEでATMEGA * 28をプログラムする場合、すべてのC / C ++プログラムのようなメイン関数から開始する場合、Arduino IDEがセットアップおよびループ機能を提供するため、これは私が期待したものでした。セットアップおよびループ機能は、AVR MCUでは標準ではありません。

注:リセットボタンを押すと、コードが再起動します。


知っておくといい。より詳細で、より低いレベルで何かを探していました。呼び出しでexit(0)逆アセンブル命令です(IIRC) __stop_programcliおよびスピンロックを。コントロールが渡される方法の説明、つまりコールスタックポップ?、ISRコールで説明が正しいかどうかを確認したかったのです。
asheeshr

ああ、私はそのような低レベルでarduinoを調べていません。その情報のために、あなたはatmelのウェブサイトをチェックしたいかもしれません。
ジェシーラニング
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.