Interrupt sperren - atomare Operationen

Hero_123

Mitglied
17. Sep. 2010
183
3
18
Sprachen
  1. ANSI C
Hallo

In einer TIMER-ISR (1ms) werden Zaehler hochgezaehlt; diese Zaehler sind vom TYP volatile uint8_t.

Diese Zaehler verwende ich im Programm, u.a.


CodeBox C
if(zaehler2_t0 >= USART_WRITE) {                /* 70 ms */
        if(zaehler2_t0 > zaehler21_t0)zaehler21_t0 = zaehler2_t0;
        zaehler2_t0 = 0;


oder auch



CodeBox C
uint8_t val;                    /* Neustart */
    zaehler1_t0 = 0;
    DDRC |= (1 << DDC3) ;        /* Pin C3 als Ausgang - Summer ON */
    PORT_ON(PORTD, PD5);            /* LED ON */
    while(zaehler1_t0 < 230);
    PORT_OFF(PORTD, PD5);                /* LED OFF */
    DDRC &= ~(1 << DDC3) ;            /* Pin C3 als Ausgang - Summer OFF */
    zaehler1_t0 = 0;


zwar sind die Zaehler jeweils vom Typ volatile uint8_t, aber muesste ich nicht die Vergleiche/Rechenoperationen per cli()/sei() vor Veraenderung schuetzen,will heissen:


CodeBox C
cli();
if(zaehler2_t0 >= USART_WRITE) {                /* 70 ms */
        if(zaehler2_t0 > zaehler21_t0)zaehler21_t0 = zaehler2_t0;
        zaehler2_t0 = 0;
sei();


oder auch


CodeBox C

uint8_t val;                    /* Neustart */
cli();
    zaehler1_t0 = 0;
sei();
    DDRC |= (1 << DDC3) ;        /* Pin C3 als Ausgang - Summer ON */
    PORT_ON(PORTD, PD5);            /* LED ON */
    while(zaehler1_t0 < 230);
    PORT_OFF(PORTD, PD5);                /* LED OFF */
    DDRC &= ~(1 << DDC3) ;            /* Pin C3 als Ausgang - Summer OFF */
cli();
    zaehler1_t0 = 0;
sei();


bzw anstatt mit cli()/sei() zu arbeiten besser das SREG zwischenspeichern, cli(), SREG wieder umspeichern

mfg

Hero_123
 
Hallo Hero,

der Zugriff auf uint8_t ist sicher, da musst du Interrupts nicht abschalten. Alles ab 2 Byte ist kritisch, das must du absichern.

Besser ist es immer die Interrupts nur dann wieder zu aktivieren, wenn die auch zuvor aktiviert waren. Also Inhalt vom SREG "merken".

Es gibt hierzu auch einige Makros, siehe dir mal atomic.h an.

Dirk :ciao:
 
Hallo Dirk

Vielen Dank für Hilfe :)

Ok, alles klar - keine Interruptsperre nötig (jedenfalls nicht hier bei uint8_t - Variablen).

Die Sache mit den Makros hatte ich schon mal gelesen und auch verwendet; wollte aber die atomic.h nicht mit inkludieren (habe ja schon die interrupt.h inkludiert).
Und Verwendung von SREG - claro ;) .

mfg

Hero_123