2013-07-16 14 views
5

Ich entwickle eine C-Applikation mit atmega168a-pu und Interrupts. Ich verwende die folgenden Interrupts:AVR-Programmierung, Interrupt-Handling

ISR(TIMER0_COMPA_vect); 
ISR(TIMER0_COMPB_vect); 
ISR (TIMER2_COMPA_vect); 
ISR(SPI_STC_vect); 
ISR(TIMER1_COMPA_vect); 
ISR (PCINT1_vect); 

und mein Code sieht aus wie

int main(void){ 
///initialization etc. 
    sei(); 
    while(1){ 
    ///do some stuff and wait the interrupts 
    } 
return 0; 
} 

Ich möchte alle anderen Interrupts blockieren, wenn eine Unterbrechung auftritt und ermöglichen die Interrupts, kurz bevor die Interrupt-Funktion zu verlassen.

Könnten Sie bitte erklären Sie es auf einem Code-Snippet, wie ich es tun kann?

BEARBEITEN: http://www.nongnu.org/avr-libc/user-manual/optimization.html#optim_code_reorder besagt, dass solche Verwendung Ursache Neu-Probleme verursachen.

function(){ 
    cli(); 
    .. 
    sei(); 
} 

Antwort

2

Die vorherige Antwort, die ich hier gepostet habe, basierte auf der ursprünglichen Frage und erwähnte nicht das Umsortierungsproblem des avr-gcc. Offensichtlich ist es zu lange her, dass ich mit dem AVR gearbeitet, aber es gab eine Glocke läuten in Bezug auf die Interrupts deaktivieren

Überarbeitete Antwort auf die Frage

Schützen Interrupts unterbrochen wird

Atmel schreibt über die Interrupt-Behandlung im Datenbuch:

Wenn ein Interrupt auftritt, wird das globale Interrupt-Enable-I-Bit gelöscht und alle Daten werden gelöscht Unterbrechungen sind deaktiviert. Die Benutzersoftware kann eine logische 1 in das I-Bit schreiben, um verschachtelte Interrupts zu ermöglichen. Alle aktivierten Interrupts können dann die aktuelle Interrupt-Routine unterbrechen. Das I-Bit wird automatisch gesetzt, wenn eine Anweisung "Return from Interrupt" - RETI - ausgeführt wird.

Daher das Verhalten, das Sie fordern, ist bereits in Hardware implementiert.

Neuordnen Ausgabe

Ich habe auch einige Untersuchungen zu diesem Thema Neuordnungs. Offensichtlich gibt es große Uneinigkeit darüber, ob dies ein Fehler des Compilers ist oder nicht. Es scheint, dass das Hauptrisiko der Neuordnung darin besteht, dass die Interrupts für einen längeren Zeitraum deaktiviert sind, als sie erwartet werden. Während meiner Recherche habe ich keine Lösung gefunden, außer Lösungen, die mehr Lade/Speicher-Aktivität verursachen, was ich nicht wirklich für eine Option halte.

+0

Wie deaktivieren und aktivieren Sie globale Interrupts, ohne ein Problem zu verursachen? –

+0

Würden die Downvoters ihren Downvote erklären? Johan hat den Hinweis ungefähr 8 Minuten nach meiner Veröffentlichung hinzugefügt. – junix

+0

@JohanElmander Ich habe die Antwort auf Ihre geänderte Frage aktualisiert. – junix

1

Die Frage hier ist ein bisschen seltsam, weil das Standardverhalten von Interrupts ist, dass neue Interrupts deaktiviert werden (wie in wird nicht ausgelöst), während ein Interrupt bedient wird.

In Bezug auf das Schreiben von Code, der nicht unterbrochen werden muss, habe ich es im Allgemeinen genug gefunden, um nur die atomare Funktionalität in <util/atomic.h> zu verwenden. Wenn dies nicht ausreicht und Sie wirklich sicherstellen müssen, gibt es keine Neuordnung vielleicht können Sie die kritischen Abschnitte in Assembly schreiben.

Es ist möglich, dass Sie Speicherbarrieren zusammen mit alles in diesem Code Abschnitt volatile verwenden könnten, aber das wäre in vielen Fällen eine ziemlich beträchtliche Pessimierung. Die Assembly, die dadurch generiert wird, könnte darauf hinweisen, was Sie schreiben würden, wenn Sie die Assembly manuell schreiben würden.