¿Qué sucede cuando llamo a exit () desde mi programa?


17

En cualquiera de setupo loop, si tuviera que agregar una exit(0)llamada, ¿a dónde pasaría el control? ¿Cuál sería el próximo estado del microcontrolador? ¿Pararía la ejecución y apagaría?

Estoy usando una revisión 2 Arduino Uno.


Creo que simplemente se detiene. No apagaría el reloj ni se apagaría.
TheDoctor

El resto de la memoria debe llenarse con NOPdeclaraciones de ensamblaje, que solo se detienen por un par de ciclos de reloj
TheDoctor

Respuestas:


12

Mi suposición inicial es incorrecta. Pensé que simplemente regresaría del bucle y la biblioteca principal simplemente llamaría al bucle () nuevamente. Sin embargo, veo que se creó el siguiente código. Notando que __stop_program es un bucle duro ...

Un extracto de la lista de Blink.ino, con la salida (0) agregada:

// 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);
}

El desmontaje de lo anterior:

// 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>

Tenga en cuenta que si _exit no hubiera llamado a cli, las interrupciones podrían hacer cosas. Pero ese no es el caso.


avr-objdump -S {compiled *.elf file}produce un archivo que incluye el código C que conduce a cada sección del código de ensamblaje. Es mucho más fácil de seguir.
Connor Wolf

aaa y acabo de probarlo, y no emite correctamente el código C en línea para la función de bucle. ¿Que demonios?
Connor Wolf

Whoa, extremadamente extraño. Compilé el proyecto con Stino en lugar del editor arduino, descompuse el *.elfde eso y luego obtuve los símbolos de depuración adecuados. Creo que el editor de texto Arduino / botón-macro (me niego a llamarlo IDE porque no lo es) está quitando la información de depuración solo del archivo C ++ principal compilado, por alguna razón extraña y estúpida.
Connor Wolf

No es una explicación, y es que ver con la forma en que las copias IDE sus archivos en una ubicación temporal. Se puede "arreglar" que al contar avr-objdump donde la fuente es: avr-objdump -S -I/path/to/the/sketch/folder xxx.elf . Esa es la ruta de la carpeta de croquis , no el archivo .ino en sí. Entonces deberías obtener la fuente C en el basurero.
Nick Gammon

11

Bueno, acabo de probarlo con mi Arduino Uno y simplemente detuvo completamente el código y dejó todas las salidas como estaban cuando el código dejó de funcionar (por lo que dejó un LED que tenía encendido). Parece que no hay una limpieza de E / S cuando llamas a exit. Esto era lo que esperaba porque el Arduino IDE proporciona las funciones de configuración y bucle, si programa el ATMEGA * 28 con cualquier otro IDR AVR, comienza con la función principal como todos los programas C / C ++. Las funciones de configuración y bucle no son estándar en las MCU AVR.

Nota: La presión del botón de reinicio reinicia el código, si se lo preguntaba.


Bueno saber. Estaba buscando algo más detallado y en un nivel inferior . Al llamar exit(0)las instrucciones desmontadas son (IIRC) __stop_program, cliy un spinlock. Quería verificar si eso es correcto con una explicación de cómo se pasa el control, es decir, ¿pila de llamadas pop ?, ¿llamada ISR?
asheeshr

Ah, bueno, no he buscado en Arduino en un nivel tan bajo, para esa información es posible que desee consultar el sitio web de Atmel.
Jesse Laning
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.