Incorporar con Elliot: interrupciones, lo bueno …

¿Cuál es la mayor diferencia entre escribir código para una computadora grande y un microcontrolador? Bueno, la memoria y los recursos limitados, claro. Pero pensamos más en la necesidad de interactuar directamente con el hardware. Y con ese fin, una de las herramientas más útiles y, por supuesto, también peligrosas en su caja de herramientas integrada es la interrupción.

Las interrupciones hacen exactamente lo que suena: interrumpen el flujo normal de la operación de su programa cuando sucede algo, y en su lugar ejecutan otro código (rutina de servicio de interrupción o ISR). Cuando finaliza el ISR, el microcontrolador se agarra exactamente donde lo dejó en su flujo principal.

Digamos que conectó su microcontrolador a un acelerómetro y que un acelerómetro tiene un pin “listo para datos”, que es alto cuando tiene una nueva muestra lista. Puede conectar ese pin a una entrada del microcontrolador que sea interrumpible, escribir un ISR para procesar los datos del acelerómetro y configurar el sistema de interrupción del microcontrolador para operar ese código cuando el acelerómetro tenga nuevos datos listos. ¡Y desde entonces todo lo relacionado con un acelerómetro ocurre automáticamente! (Teoría.)

Esta es la primera parte de una serie de tres partes: Interrupciones, lo bueno, lo malo y lo feo. En esta columna, nos centraremos en cómo funcionan las interrupciones y cómo aprovecharlas al máximo: Lo bueno. La segunda columna abordará los peligros de las rutinas de interrupciones intensas, los conceptos erróneos de prioridad y un hambre de bucle importante: el lado malvado de las interrupciones. Finalmente, abordaremos algunos de los errores completamente difíciles que pueden surgir con las interrupciones, principalmente debido a una falla de atomicidad que puede resultar en fallas lógicas y datos corruptos; eso es ciertamente feo.

El lado bueno de las interrupciones

Las interrupciones permiten que su microcontrolador inicie “programas” específicos cuando ocurren varios eventos. Puede utilizar una interrupción casi en cualquier momento que desee un código para responder de forma automática y rápida a un evento. Todo tipo de periféricos, desde acelerómetros hasta radios, tarjetas SD y módulos GPS, necesitan algo de tiempo para hacer todo lo que hacen. Esperar a que el periférico esté listo (o terminado) y luego actuar es una tarea de programación integrada sorprendentemente importante, y las interrupciones son nuestra forma favorita de lidiar con estos eventos generados por periféricos y aún así dejar la CPU libre para hacer otras cosas entre sí. . .

Para aclarar esto, comparemos las interrupciones con las otras opciones. Imagine, para ser concretos, que estamos esperando que un acelerómetro nos presente una nueva muestra de datos. Suponga además que el acelerómetro indicará que tiene una nueva muestra, elevando el voltaje lógico en un cable.

Una posibilidad es sentarse y esperar hasta que entre la señal de listo. Este es el enfoque para “bloquear la espera”.

int main(void){
	while(1){
		do_stuff();
		while(line_is_low()){ /* wait here                */
			;                 /* doing nothing            */
		}                     /* until the line goes high */
		handle_new_data();
		carry_on();
	}
}

Otra posibilidad es seguir haciendo otras cosas, pero comprobar periódicamente el estado de la línea de señal siempre que tengamos la oportunidad. Esto es “votar”.

int main(void){
	while(1){
		do_stuff_repeatedly();
		if (line_is_high()){  /* ready yet? */
			handle_new_data();
		}
	}
}

Y finalmente, podemos configurar el interruptor del microcontrolador para que se inicie cuando la línea sea alta y escribir ISR para manejar los nuevos datos cuando haya terminado. (El código de inicialización y definición de ISR es específico del AVR, pero las ideas básicas no lo son).

ISR(INT0_vect){
	handle_new_data();
}

int main(void){

	EICRA |= (1<<INT0);                 /* enable individual interrupt             */
	sei();                              /* enable global interrupts                */

	while(1){
		always_do_stuff();
	}
}

Como puede ver con el código de interrupción, hay una carga de configuración adicional que diferirá entre los microcontroladores, pero luego de eso no hay señales de la interrupción en el principal while lazo. El código en sí se define fuera del código principal en lo que se denomina una rutina de servicio de interrupción. No es del todo obvio cuándo funcionará el ISR; funciona cuando se activa.

Bloqueo contra sondeo contra interrupción

Comparemos los tres enfoques. El bloqueo responde más rápido a una nueva señal, pero su micrófono no puede hacer nada más hasta que llega la señal. Es una opción razonable cuando el tiempo de respuesta extremadamente rápido es absolutamente necesario, pero solo entonces. ¿Qué pasa si la señal nunca llega? ¿Si un cable se apaga o la batería del periférico se agota? ¿Tu CPU no tiene mejores cosas? En general, no bloquee a menos que realmente lo necesite o sea un programador muy vago que trabaje en un proyecto no exigente. (¡¿Quiénes, nosotros?! A veces).

La investigación de la línea de señal es factible si el tiempo de respuesta no es crítico, ya que el tiempo requerido para notar el cambio de estado depende de dónde se encuentre el código dentro del do_stuff_continually() operar cuando la señal entra. En promedio, el tiempo de respuesta será la mitad del tiempo que necesita do_stuff_continually(), pero el peor de los casos es la ejecución completa.

Las interrupciones combinan casi lo mejor de ambos mundos sin sus desventajas. El tiempo de respuesta a la señal entrante no será inmediato, como ocurre con el código de espera de bloqueo, pero suele ser bastante rápido: unos 20 ciclos de reloj para el AVR y el MSP430. (Los chips ARM Cortex expanden las amplitudes para minimizar y regular los tiempos de interrupción). Sin embargo, lo más importante es que el resto del código puede ejecutarse normalmente mientras espera la interrupción. Es muy raro que tenga un evento con un momento tan crítico que no valga la pena hacer nada solo para esperarlo, por lo que las interrupciones del bloqueo son casi siempre.

En comparación con la votación, el tiempo de respuesta de la interrupción es muy constante (generalmente dentro de un ciclo o dos) y más rápido que todos los casos de votación, excepto los más triviales. Las interrupciones, si se activan en medio de su código de votación, tendrán prioridad. Esto significa que votar es más adecuado para tareas no prioritarias en las que no te importa el tiempo. Pero, por supuesto, todos los sistemas tienen tales tareas; manejar cosas que suceden en una escala de tiempo humana (dentro de decenas de milisegundos) generalmente es bueno en el código encuestado y libera sus interrupciones para manejar las cosas realmente importantes.

Entonces, en resumen: use las interrupciones para cosas que son importantes para el tiempo y la coherencia, especialmente para comunicarse con otras máquinas, y no dude en investigar los eventos no críticos.

Bajo el capó: ¿Cómo funcionan las interrupciones?

Si está comenzando a usar interrupciones, vale la pena considerar un poco cómo se implementan realmente dentro del microcontrolador. Le dará información importante sobre los comportamientos más profundos del sistema.

Cada posible evento que puede desencadenar una interrupción tiene una bandera (un bit en un registro de memoria especial) dedicada a él. La mayoría de los microcontroladores también tienen un bit de habilitación para cada posible vector de interrupción y, además, un indicador de habilitación de interrupciones global que cubre todas las interrupciones a la vez. Cuando ocurre un evento, se coloca su bandera. Si el indicador de habilitación de interrupciones específico que corresponde a ese evento y el indicador de habilitación de interrupciones global también están completamente dispuestos, ¡entonces la interrupción está bien! Si alguna de estas tres condiciones falla, naturalmente, no pasa nada.

Tenga en cuenta que este sistema significa que si ya ha ocurrido un evento, y su bandera está configurada, cuando se configuran los bits de habilitación global y específica, esa interrupción se activará inmediatamente. Como consecuencia de esta condición, imagine que ha habilitado muchas interrupciones específicas, pero ha deshabilitado el bit de interrupción global. Esto puede suceder, por ejemplo, durante el procesamiento de ISR, si no desea que se interrumpan sus interrupciones. De todos modos, para cuando finalmente configuró la opción de interrupción global, ya habían sucedido muchos eventos. Ahora la máquina está buscando muchas interrupciones para procesar. ¿Cuál eliges primero?

Cuando se activa cualquier número de interrupciones al mismo tiempo, los microcontroladores AVR y MSP430 tienen un sistema simple de prioridad fija. Por ejemplo, en AVR, las interrupciones del pin externo tienen una prioridad más alta, luego el temporizador / calculadora y luego el USART (puerto serie). Cada uno de estos se trata a su vez, pasando a la siguiente prioridad más alta como los primeros finales. Si, mientras tanto, se producen interrupciones de mayor prioridad, se encargarán de ellas para la próxima oportunidad. Puede buscar las prioridades en las hojas de datos cuando sea relevante.

En el sistema ARM, el sistema de prioridades es significativamente más complicado. Las interrupciones vectoriales anidadas no tienen uno, sino dos conjuntos de niveles de prioridad, y cada uno puede asignarse a cualquier evento de interrupción. Los controles de nivel superior que interrumpen pueden interrumpirse entre sí, y las selecciones de nivel inferior que interrumpen desde dentro de un grupo de prioridad dado se ejecutan primero. Los sistemas de prioridad anidados que puede crear con esto son llamativos y están más allá del alcance de este artículo. Baste decir que si tiene dos USART en un sistema y desea que ambos USART interrumpan el SPI ISR pero no entre sí, y le gustaría que USART0 se manejara siempre antes que USART1, por ejemplo, puede hacerlo.

Finalmente, en AVR o MSP430, cada posible interrupción tiene una ubicación fija en la memoria de código, donde busca una instrucción para ejecutar cuando se activa esa interrupción. Cada una de estas ubicaciones contiene un comando de salto con una dirección: la dirección de memoria de la rutina que le gustaría asociar con la interrupción. De forma predeterminada, esta tabla de salto (enlace) está llena de comandos que no van a ninguna parte o devuelven el chip a su estado recientemente restaurado. Pero al poner la dirección de algún código que le gustaría llamar en el lugar correcto de la memoria, el chip comenzará a ejecutar ese código cuando comience la interrupción.

Otras interrupciones estúpidas

No podemos dejar de lado la sección “Bueno” de interrupciones sin mencionar dos plantillas separadas que usamos en casi todos los proyectos con un microcontrolador AVR.

La mayoría de los microcontroladores tienen un temporizador / contador lateral o dos o tres. Estos simplemente cuentan a una velocidad determinada, independientemente de la CPU. Establecer una interrupción para que se dispare cuando un contador se desborda o alcanza un cierto valor y luego aumentar una variable global de “tick del sistema” dentro del ISR proporciona una base de tiempo variable muy conveniente que puede ralentizarse a escalas de tiempo casi humanas si lo desea. Por ejemplo con eso el Arduino hace millis(). (Los chips AR de ST, por ejemplo, tienen un reloj de tic-tac sistemático dedicado que es muy sexy).

Para AVR, configurar una calculadora como un reloj del sistema podría ser tan fácil como:

volatile uint16_t ticks;

ISR(TIMER0_OVF_vect){
	++ticks;
}

void initTicks(void){
	TCCR0B |= ((1<<CS02) | (1<<CS00)); /* set largest clock divisor */
	TIMSK0 |= ((1<<TOIE0)); /* enable overflow interrupt */
	sei(); /* enable global interrupts */
}

(Abordando el ticks variable no es muy simple, y trataremos por qué esto es así en la transmisión “Ugly”.)

Las interrupciones también son una excelente manera de despertar a un microcontrolador de un modo de suspensión frugal. Cuando la CPU no hace nada, puede reducir su consumo de energía a una mera corriente (unos pocos microamperios, o incluso fracciones de microamperio para el MSP430) apagando los relojes de la CPU y poniendo el sistema en suspensión. Pero entonces, ¿cómo se despierta el chip cuando sucede algo? Interrupciones, por supuesto.

En el AVR, incluso puede definir ISR vacíos que no hacen nada pero se usan explícitamente para regresar del modo de suspensión.

EMPTY_INTERRUPT(INT0_vect);         /* instead of ISR()                */

void sleep(void){
	EIMSK |= (1 << INT0);           /* set individual interrupt enable */
	sei();                          /* enable global interrupts        */
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
	sleep_mode();                   /* now to sleep                    */
}

La sleep() La función anterior asegura que tanto los bits de interrupción individuales como los de interrupción global estén configurados, le dice al procesador en qué modo de suspensión debe ingresar y luego se apaga. Cuando se presiona el botón externo (vinculado a INT0), se llama al ISR de aniquilación, el chip se activa y el flujo del programa vuelve al comando inmediatamente después de la llamada a sleep().

Conclusión

Y aquí lo tienes. Las interrupciones son buenas para responder a dispositivos externos, crear bases de tiempo, despertar el chip de los modos de ahorro y más. Esperamos que analizar cómo funcionan las interrupciones y para qué son adecuadas lo ayudará a pensar más como el microcontrolador y a encontrar los lugares adecuados para incorporarlas en sus proyectos.

Trabajar con interrupciones elimina el flujo de código del ciclo principal lineal de una función tras otra que escribió. Esto viene con problemas de planificación y un potencial serio de fallas, y estos será el tema de las próximas dos columnas, donde abordaremos el lado malo y el lado feo del uso de interrupciones. Estén atentos y háganos saber lo que piensan en los comentarios.

  • Vilaca dice:

    Los procesadores recientes también tienen interrupciones. Simplemente no juegas mucho con ellos sin dejar un “usuario” o aparecen ocultos como “eventos”.

    • Jacques1956 dice:

      “Los procesadores nuevos también tienen interrupciones”.
      ¿Qué quieres decir?
      La interrupción por microprocesador siempre ha existido. El 6502, 8080, z80, etc. lo tenía. Y, obviamente, una CPU nueva también lo tiene. Si se refiere a una CPU de uso general utilizada en teléfonos, tabletas y computadoras, solo el kernel puede acceder a las interrupciones, desde un país de usuario solo syscall () puede acceder a recursos de bajo nivel como interrupciones.

      • Vilaca dice:

        Apuntaba a la CPU de “tu gran computadora”, nueva y vieja.

  • RandyKC dice:

    Dame un buen multinúcleo n-core y manejaré n-1 eventos sin problemas.

    • tekkieneet dice:

      siempre que cada núcleo tenga la velocidad suficiente para lidiar con sus eventos. : PAG

    • Artenz dice:

      Siempre que los núcleos no necesiten mantenerse actualizados entre sí sobre los eventos.

    • SteveT dice:

      Siempre que esté dispuesto a pagar n * x + y dólares (o euros o yenes …) para hacer frente a n-1 eventos.

      x = costo del núcleo de silicio
      y = integración y costo del paquete

      • tekkieneet dice:

        y no olvide pagar el programa y la licencia del sistema operativo por núcleo de CPU o por “socket”. : PAG

      • camillus blockx dice:

        Para obtener el costo correcto, debe ser n * (x + y). p.ej. n = 5, x = 10, y = 15 entonces el tuyo es 5 * 10 + 15 = 65 mientras que tiene que ser 5 * (10 + 15) = 5 * 25 = 125 $ 60 de diferencia difícil de explicar al IRS. . JAJAJA

    • Mate dice:

      Hélice de paralaje FTW

  • Tagmezov dice:

    ¡Gracias por un artículo genial!

  • Maximiliano dice:

    Buena escritura, estoy deseando que lleguen “los malos y los feos” !!

  • jcreedon dice:

    Ayudo un poco en arduino.stackexchange.com un poco ahora y las interrupciones y los temporizadores son uno de los problemas más comunes. No estoy seguro de si esto es malo o desagradable, pero la fuente de la mayoría de estos problemas es que la biblioteca Arduino oculta cómo configura los temporizadores e interrumpe todas sus funciones de biblioteca (por ejemplo, Millis (), etc.,). Una de las preguntas más comunes es: ¿Puedo usar A, B y C con Uno / Due / Whatever? La respuesta suele ser sí, tiene suficientes pines para hacer esto, pero no, porque las bibliotecas que se utilizan para admitir esos dispositivos utilizan temporizadores de conflictos. Un cambio que creo (mi opinión, por supuesto) ayudaría a mejorar el ecosistema de Arduino es llevar los temporizadores y la configuración de interrupciones desde el fondo y más a la vanguardia para que los aficionados puedan ser más conscientes de cómo las bibliotecas usan los recursos del microcontrolador. porque son un límite además de tener un número X de pines digitales o un número Y de pines analógicos.

    • Emil dice:

      ¿Y todavía quieres usar arduino?

    • NeLogika dice:

      @jcreedon Estoy de acuerdo contigo en que esta es una buena idea.

      También he visto esto varias veces, y descubrí que los usuarios a menudo se sienten frustrados por cosas que son conceptualmente simples: “Quiero usar ‘esto’ y ‘eso’ juntos, pero cuando trato de compilar, obtengo muchos errores que no entiendo … “

      También estaba pensando en otra posible solución, con algo de magia C-macro. Imagina que cada biblioteca tiene que declarar / definir los recursos que usa. Si se incluyen dos bibliotecas que usan los mismos recursos, las macros arrojarían algunas advertencias / excepciones que dirigirían al usuario hacia dónde comenzar a solucionar problemas.

      Por supuesto, esto requeriría que todas las bibliotecas de creación utilicen un conjunto de macros comúnmente definido que coincidiría con una plataforma de destino específica.

    • al3xsh dice:

      No estoy de acuerdo, si quieres eso, ¡usa las bibliotecas avr!

      Todo el atractivo de Arduino es que oculta cierta complejidad al desarrollador. Si necesita acceso de bajo nivel a interrupciones, etc., puede obtenerlo, con la condición de que “aquí hay dragones” …

  • Sean dice:

    Esto es genial. Casi terminado (creo) con mi primer gran proyecto MSP430, un simple juguete musical para mi segundo año que se interrumpe casi por completo. Así que estoy ansioso, aunque un poco incómodo, ¡espero con ansias las próximas dos entregas!

  • Voja Antonic dice:

    Buen articulo.
    Timer Interrupt torque es una herramienta muy útil en aplicaciones en tiempo real, incluso la simple policlínica con pantalla LED es difícil de controlar sin ella. Actualmente estoy involucrado en el proyecto, que gobierna motores de cinco pasos, con diferentes (y, en algunos casos, variables) velocidades, con controles de estado del sensor y “start-stop-change_direction-adjust_speed” para cada motor después de casi cada paso. Es pan comido con cinco temporizadores y cinco interrupciones, pero me pregunto si es posible sin ellos.

    • Arlet dice:

      Una vez hice 4 controladores de puente H PWM 50 kHz con un solo temporizador y 16 pines GPIO. El controlador de interrupciones usó una tabla preparada con un valor de salida GPIO, y un temporizador posterior compara el valor, por lo que solo requirió unas pocas instrucciones para manejar un cambio. La matriz se calcularía a una frecuencia mucho más baja (10 Hz) por otra parte del firmware cada vez que cambiaran los valores de PWM.

  • RP dice:

    Un buen enfoque híbrido es una técnica mixta de votación + interrupción.

    En este caso, configura un temporizador para activar una interrupción cada milisegundo y el ISR actualiza todos sus contadores y también hace solo una verificación de las entradas, indicadores, etc.que pueden haber sido configurados en otro lugar y los procesa. Esto funciona bien para cosas que no necesitan una precisión absoluta del ciclo del reloj, como copiar un búfer de texto a una pantalla, verificar o configurar bits de E / S, etc.

    • tekkieneet dice:

      Configuré una bandera de la rutina de interrupción para pasar un tiempo mínimo en la interrupción.
      El bucle principal simplemente vota la bandera y lanza la tarea (para multitarea cooperativa). Al final del ciclo de tareas grande, el procesador ejecuta una instrucción de suspensión que se activará con la siguiente interrupción.
      Funciona bastante bien para 8 bits con poco espacio de memoria. Cada una de estas tareas termina siendo una máquina de estado que recuerda dónde estaban las variables de estado. Es doloroso para algunos códigos, como la interfaz de usuario, que no encajan demasiado bien en ese modelo.

      • Forrest Voight dice:

        ¡Aquí es cuando implementas las rutinas!

  • Mate dice:

    Ahora mismo estoy escribiendo un programa para transmitir 3 señales PWM al mismo tiempo sin interrupciones. Porque la hélice de paralaje es impresionante.

    • cierto dice:

      También tengo 16 señales PWM a la vez sin interrupciones, y también sin ninguna operación de CPU. Porque el PSoC está temblando 🙂

      (en otras palabras, se incluyen demasiadas formas de hacer la misma tarea, se trata de la religión del proveedor)

  • Slyclops dice:

    Sin embargo, probablemente valga la pena señalar que incluso con interrupciones anidadas, generalmente es una buena idea no ser diligente en los ISR. Mover datos dentro y fuera de búferes de dispositivos o establecer indicadores booleanos suelen ser las mejores aplicaciones.

    Además, si usa una interrupción solo para activar el procesador, generalmente no es necesario definir un ISR, incluso si está vacío.

    • Elliot Williams dice:

      Totalmente de acuerdo en acortar los ISR. Es uno de los pocos departamentos de software a los que me uno (la mayor parte del tiempo) incluso cuando no lo necesito.

      La razón para definir un ISR en blanco en AVR-GCC es que el valor predeterminado se establece en el vector de “interrupción incorrecta”, que luego se alias con el ISR de restablecimiento de chip, de modo que las llamadas a un ISR indefinido restablecerán el chip en lugar de extinguirse en memoria indefinida y solo funciona.

      Si desea que el chip restablezca la activación, está bien. Pero si desea que comience donde se detuvo, debe definir una interrupción vacía para evitar el reinicio.

  • fede.tft dice:

    “Los chips ARM de ST, por ejemplo, tienen un reloj de tic del sistema dedicado que es muy atractivo”. De hecho, todos los microcontroladores ARM Cortex-M tienen este temporizador, no solo los ST. Se llama SysTick y se puede considerar como parte del núcleo de la CPU, no de los periféricos. ARM lo colocó allí para admitir cambios de contexto en entornos RTOS.

    • RandyKC dice:

      Ese es un rasgo sexual. Tiene mucho sentido configurar el soporte para RTOS en el nivel central en lugar de tratarlo como periférico. Por eso me mantuve alejado de FreeRTOS.

    • W dice:

      Cortex-M tiene una gran variedad de dispositivos diseñados específicamente para soportar RTOS, p. Ej. El evento PendSV (como una interrupción, pero programado manualmente y siempre funciona DESPUÉS de todas las interrupciones pendientes; el remitente ingresa allí), dos punteros de pila (uno para subprocesos de usuario), uno para subprocesos de SO privilegiados), generalmente una unidad de protección de memoria, la capacidad Prevenir de forma selectiva interrupciones por debajo del umbral de prioridad, instrucciones de modificación nuclear, etc.

      Un efecto secundario de la compatibilidad de este dispositivo es que básicamente solo hay una forma de escribir el remitente correctamente, pero tiene una pequeña cantidad de código para escribir para obtener un RTOS previo funcional. Creo que el mío es de unas 400 líneas en total C ++ (encabezados y fuente que incluyen muchos comentarios) para hilos bloqueables, planificador y remitente. El remitente tiene solo 8 líneas de ensamblador y 1 línea de C (o 5 si incluye el interruptor GPIO que muestra la carga de la CPU en el LED).

    • Elliot Williams dice:

      Gracias. Es bueno saberlo. Tengo mucha experiencia en la programación de chips ST, por lo que no quería generalizar demasiado.

  • Delaware dice:

    ¡Entendí solo el 5% de lo que estaba escrito! Aunque no me quejo. Estoy aqui para aprender. Tengo Arduino y Pi y estoy muy interesado en aprender a usar microcontroladores como hobby. Artículos como este me ayudarán mucho a aprenderlos y comprenderlos mejor. ¡Gracias!

    • BobbyMac dice:

      Piénselo de esta manera: en un sistema “grande”, como una computadora (¡ja!), Es un conjunto de procesadores con los que todos funcionan. señales de reloj separadas que les permiten coexistir y acceder a la dirección principal y al bus de datos juntos, pero retrasándose ligeramente entre sí, y simplemente gritando “¡¡Eh !!” a la CPU principal (o viceversa) cuando tienen algo que decir. Procesadores visuales, coprocesador matemático, chips de acceso directo a memoria, chips de E / S en serie, etc. – todos tienen prioridades en el sistema y reciben solicitudes atendidas de acuerdo a sus necesidades de acuerdo con las reglas de ese sistema. Debido a que las interrupciones se pueden disfrazar para que no se den cuenta (que suele ser lo primero que hace en una interrupción del servicio para que no lo vuelvan a interrumpir), debe asegurarse de no pasar mucho tiempo en ellas. . Por eso es importante calcular los ciclos de su reloj y mantener el código muy ajustado. Cosas memorables son que las interrupciones son absolutas desde el código principal, por lo que cualquier pila que use debe cambiarse a otra área interna, o puede estropear las cosas bastante mal, las mejores prácticas de programación son programar para que la interrupción no sea notada por el código del sistema principal que usa, a menos que lo desee de esa manera, por lo que los registros de banderas, los registros estándar, las calculadoras, las pilas, cualquier cosa, todo se guarda inmediatamente después de ingresar a la interrupción (cosas que la interrupción usará), y se restaura lo último al salir . En algunos sistemas, es posible que no pueda acceder al núcleo donde las interrupciones hacen que las cosas funcionen libremente, o puede cambiar y ejecutar cualquier otro proceso, una violación de la protección. Sin embargo, debe tenerse en cuenta que casi TODOS los procesadores que componen estos sistemas mientras están separados en el sistema se pueden reprogramar con comandos de entrada / salida (dependiendo del sistema) o acceso directo a la memoria (también dependiendo del sistema) para realizar su función de usted, si tiene los privilegios, son procesadores después de todo. La mayoría de ustedes, con la excepción de los programadores anticuados, nunca han programado en Ensamblador, o de hecho han codificado manualmente un chip directamente para el procesador, esas personas están más acostumbradas a las necesidades de las cosas.

América Aguilar
América Aguilar

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *