Fehler im avr-gcc Tutorial?

OP #548858
Lesenswert?
• ▲
▼
Hallo,
In diesem Tutorial steckt möglicherweise ein Fehler:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts

Es geht um das Code-Segment nach diesem Abschnitt:
Oft steht man vor der Aufgabe, dass eine Codesequenz nicht unterbrochen 
werden darf. Es liegt dann nahe, zu Beginn dieser Sequenz ein cli() und 
am Ende ein sei() einzufügen. ...

In diesem Codesegment ist main Funktion wie folgt enthalten:
1
int main(void)
2
{
3
   //...
4
 
5
   cli();  
6
   // Interrupts global deaktiviert 
7
 
8
   NichtUnterbrechenBitte();
9
   // auch nach Aufruf der Funktion deaktiviert
10
 
11
   sei();
12
   // Interrupts global aktiviert 
13
 
14
   NichtUnterbrechenBitte();
15
   // weiterhin aktiviert
16
   //...
17
 
18
   /* Verdeutlichung der unguenstigen Vorgehensweise mit cli/sei: */
19
   cli();  
20
   // Interrupts jetzt global deaktiviert 
21
 
22
   NichtSoGut();
23
   // nach Aufruf der Funktion sind Interrupts global aktiviert 
24
   // dies ist mglw. ungewollt!
25
   //...
26

27
}

Nun steht nach dem zweiten "NichtUnterbrechenBitte()" der Kommentar 
"weiterhin aktiviert".
Genau da sehe ich aber das Problem: In der Funktion wird cli() 
ausgeführt, ab Ende aber kein sei() mehr.
Somit kann nach dem zweiten Aufruf der Funktion doch GlobalIRQ nicht 
"weiterhin aktiviert" sein?

Gruss, Martin
#548886
Lesenswert?
• ▲
▼
Was das Code-Beispiel sagen will, ist folgendes:

Man sollte nicht "sei()" zum Wieder-Aktivieren der Interrupts verwenden, 
sondern man sichert vor dem "cli()" das Statusregister, macht dann 
"cli()" (damit werden die Interrupts deaktiviert), und später wird 
einfach das Statusregister rückgespeichert; damit wird einfach der 
Zustand wiederhergestellt, der vor dem "cli()" bestand. Wenn nämlich 
vorher schon an anderer Stelle die Interrupts dekativiert wurden, 
bleiben sie nun immer noch deaktiviert, bis an dieser anderen Stelle 
seinerseits das Statusregister ebenfalls (mit ggf. aktivem I-Bit) 
rückgespeichert wird. Damit soll genau die Situation vermieden werden, 
daß an einer Stelle "sei()" gemacht wird ohne Rücksicht darauf, daß 
vielleicht eine übergeordnete Funktion aktiv ist, die weiterhin 
dekativierte Interrupts benötigt.

Daher: nicht die Sequenz "cli()" / "sei()" verwenden, sondern

uint8_t tmp_sreg = SREG;
cli();

...

SREG = tmp_sreg;

Insofern steckt im Tutorial kein Fehler. Lies es nochmal aufmerksam 
durch, dann wird Dir das aufgehen.


Gruß, Günter

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.