Stellen Sie fest, ob Interrupts aktiviert sind

7

Gibt es eine Möglichkeit zu sagen, ob sei()/ interrupts()oder cli()/ noInterrupts()zuletzt angerufen wurde?

Ich brauche dies, um Interrupts aktivieren, Code ausführen und Interrupts setzen zu können, um Interrupts zu deaktivieren, wenn sie deaktiviert wurden.

Hier ist ein Beispielcode:

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

    interrupts();

    // Code requiring interrups are enabled

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

Antworten:

9

Eine Möglichkeit, dies zu tun, besteht darin, das SREG-Statusregister zu speichern und später wiederherzustellen. Auf diese Weise wird der Interrupt-Status gespeichert und später auf das zurückgesetzt, was er war.

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

  // Do stuff, as little as possible.

  SREG = oldSREG;

Die in der Frage beschriebene Begründung weist auch inhärente Probleme auf: Wenn für einen anderen Code bereits Interrupts deaktiviert wurden und Ihr Code Interrupts aktiviert, kann es zu Datenkorruption oder Programmfehlern kommen. Jeder "Interrupt-deaktivierte" Codeblock würde erwarten, dass alle Register und Speicher / Variablen unversehrt bleiben, während das Aktivieren von Interrupts dazu führen kann, dass sich dies ändert.

Daher ist die umgekehrte Logik, wie im obigen Codefragment, die beste Vorgehensweise: Deaktivieren Sie Interrupts für Ihren eigenen Code explizit nach Bedarf, stellen Sie Interrupts jedoch so bald wie möglich wieder her und fahren Sie dann mit dem Rest Ihrer Verarbeitung fort.

Anindo Ghosh
quelle
Anindo hat Recht mit der Warnung. Sie sollten niemals Interrupts in einer Bibliothek oder einem anderen Aufruf aktivieren, der nicht speziell dafür ausgelegt ist. Code, bei dem Interrupts deaktiviert sind, hat dies aus einem bestimmten Grund getan. Das Aktivieren von Interrupts in Ihrer Bibliotheksroutine kann zu allen möglichen Schäden mit dem anderen Code führen.
Wäre es wichtig, wenn nach dem Speichern des Statusregisters, aber vor dem Deaktivieren von Interrupts ein Interrupt auftreten würde?
Shepmaster