Decir si las interrupciones están habilitadas

¿Hay alguna forma de saber si sei()/ interrupts()o cli()/ noInterrupts()fue la última llamada?

Necesito esto para poder habilitar las interrupciones, ejecutar algún código y configurar las interrupciones, deshabilitar las interrupciones si estaban deshabilitadas.

Aquí hay un código de muestra:

void function_requiring_interrupts(void) {
    bool interruptsEnabled = getInterrupsState(); // what function / variable here?

    interrupts();

    // Code requiring interrups are enabled

    if(!interruptsEnabled) {
        noInterrupts();
    }
}

Respuestas (1)

Una forma de hacer esto es guardar y luego restaurar el registro de estado SREG, guardando y luego restaurando el estado de interrupción a lo que fuera, así:

  uint8_t oldSREG = SREG; // Save the status
  cli();

  // Do stuff, as little as possible.

  SREG = oldSREG;

Además, la lógica descrita en la pregunta tiene problemas inherentes: si algún otro código ya tenía las interrupciones deshabilitadas, y su código las habilita, se podrían dañar los datos o fallar el programa. Cualquier bloque de código "inhabilitado para interrupciones" esperaría que todos los registros y la memoria / variables permanezcan intactos, mientras que habilitar las interrupciones puede hacer que eso cambie.

Por lo tanto, la lógica inversa, como en el fragmento de código anterior, es la mejor práctica: deshabilite explícitamente las interrupciones para su propio código según sea necesario, pero restaure las interrupciones lo antes posible, luego continúe con el resto de su procesamiento.

Anindo tiene razón sobre la advertencia. Nunca debe habilitar las interrupciones en una biblioteca u otra llamada que no esté específicamente diseñada para hacer eso. El código que tiene las interrupciones deshabilitadas lo hizo por una razón y habilitar las interrupciones en la rutina de su biblioteca podría causar todo tipo de estragos con el otro código.
¿Importaría si ocurriera una interrupción después de guardar el registro de estado, pero antes de desactivar las interrupciones?