Frage:
Ich habe 2 Arrays (arr1[11] und arr2[11]) und möchte deren Inhalte
vertauschen. Darf ich arr1 und arr2 als Pointer interpretieren und deren
Werte tauschen?
Hintergrund ist, dass ich mit dem einem Array gemütlich arbeiten möchte
während Interruptroutinen mit dem zweiten Array arbeiten (nur lesen),
wie ein Puffer.
Wenn meine Hauptroutine fertig ist mit allen Berechnungen, sollen die
Arrays getauscht werden und die Interruproutinen arbeiten mit den
aktualisierten werten weiter.
Also nichts anderes als ein Puffer.
also so:
die länge ist dabei sogar egal
ich denke schon das das geht, saubere ist es eventuell wenn du einen
zusätzlichen zeiger verwendest der auf den aktuellen wert zeigt.
uint8_t arr1[11];
uint8_t arr2[11];
uint8_t *akt_list;
cli();
akt_list = arr1;
sei();
Richard schrieb:> Frage:> Ich habe 2 Arrays (arr1[11] und arr2[11]) und möchte deren Inhalte> vertauschen. Darf ich arr1 und arr2 als Pointer interpretieren und deren> Werte tauschen?
Nein.
Ein Array ist kein Pointer.
> Hintergrund ist, dass ich mit dem einem Array gemütlich arbeiten möchte> während Interruptroutinen mit dem zweiten Array arbeiten (nur lesen),> wie ein Puffer.
Ah. ok.
Das kannst du anders machen.
Du kannst dir ja 2 Pointer Variablen einrichten, die auf die Arrays
zeigen. Und wenn es Zeit ist zu wechseln, dann tauscht du die beiden
Pointer.
1
//globale Arrays
2
uint8_tarr1[11];
3
uint8_tarr2[11];
4
5
uint8_t*actualBuffer=arr1;
6
uint8_t*backupBuffer=arr2;
7
8
voidvertausche(void){
9
uint8_t*ptr;
10
11
cli();
12
ptr=actualBuffer;
13
actualBuffer=backupBuffer;
14
backupBuffer=ptr;
15
sei();
16
}
die Interrupt Routine arbeitet immer über actualBuffer während die
Hauptroutine immer über den backupBuffer geht. Syntaxmässig ändert sich
in der Verwendung noch nicht einmal etwas. Du kannst weiterhin zb über
actualBuffer[i] zugreifen. Nur landet der Zugriff dann entweder in arr1
oder arr2, je nachdem wo der Pointer hinzeigt.
der mechatroniker schrieb:> So wie du es geschrieben hast, gehts nicht, so wie Peter vorgeschlagen> hat, schon.
Das von Peter ist doch eigentlich das selbe, nur daß eben die Hälfte
fehlt.
Übrigens ist "geht nicht" eine ziemlich unbrauchbahre
Fehlerbeschreibung.
Karl heinz Buchegger schrieb:> void vertausche( void ) {> uint8_t *ptr;>> cli();> ptr = actualBuffer;> actualBuffer = backupBuffer;> backupBuffer = ptr;> sei();> }
Mit den cli()/sei() ist das ganz finster, das ist schlechter Stil den
man sich nicht angewöhnen sollte. Eher so:
Eugenius Fragikus schrieb:> ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
Ich wusste gar nicht, dass es dieses Makro für jede Architektur gibt,
auf der ein GCC verfügbar ist... ;-)
atomic schrieb:> Eugenius Fragikus schrieb:>> Mit den cli()/sei() ist das ganz finster, das...>> Weshalb?
Gar nicht. Da wollte nur jemand beweisen, dass er die neuen
atomic-Macros kennt. Die sind zwar schön, und es ist meistens schön wenn
man sie benutzt. Aber an der cli/sei Methode ist eigentlich auch nichts
auszusetzen.
Klaus schrieb:> atomic schrieb:>> Eugenius Fragikus schrieb:>>> Mit den cli()/sei() ist das ganz finster, das...>>>> Weshalb?>> Gar nicht. Da wollte nur jemand beweisen, dass er die neuen> atomic-Macros kennt. Die sind zwar schön, und es ist meistens schön wenn> man sie benutzt. Aber an der cli/sei Methode ist eigentlich auch nichts> auszusetzen.
Gleich vorweg: Ich hab das noch nicht überprüft
In der Doku zu den Makros steht, dass sie in jedem Fall sicher stellen,
dass das Interrupt Flag wieder richtig und je nach Makroargument richtig
gesetzt wird, wenn der Block verlassen wird.
dh. auch in diesem Fall
1
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
2
{
3
...
4
5
return;
6
}
machen die Makros das richtige.
Wie gesagt, ich habs noch nicht überprüft, aber für mich wär das ein
'Vorteil' der Makros gegenüber händischem cli/sei. Ausserdem
restaurieren die Makros auf Anforderung wieder in den vorherghenden
Zustand, was bei Funktionen die Funktionen aufrufen kein Nachteil sein
soll :-)
Klaus schrieb:> atomic schrieb:>> Eugenius Fragikus schrieb:>>> Mit den cli()/sei() ist das ganz finster, das...>>>> Weshalb?>> Gar nicht. Da wollte nur jemand beweisen, dass er die neuen> atomic-Macros kennt. Die sind zwar schön, und es ist meistens schön wenn> man sie benutzt. Aber an der cli/sei Methode ist eigentlich auch nichts> auszusetzen.
Leider falsch...
Stell dir mal vor die IRQs sind aus irgendeinem Grund disabled bevor
cli()/sei() aufgerufen werden.. Was sind die IRQs danach?
Lies dir mal die Help der ATOMIC Macros durch.
Hier der Text der Help..
Two possible macro parameters are permitted, ATOMIC_RESTORESTATE and
ATOMIC_FORCEON.
#define ATOMIC_FORCEON
This is a possible parameter for ATOMIC_BLOCK. When used, it will cause
the ATOMIC_BLOCK to force the state of the SREG register on exit,
enabling the Global Interrupt Status flag bit. This saves on flash space
as the previous value of the SREG register does not need to be saved at
the start of the block.
Care should be taken that ATOMIC_FORCEON is only used when it is known
that interrupts are enabled before the block's execution or when the
side effects of enabling global interrupts at the block's completion are
known and understood.
#define ATOMIC_RESTORESTATE
This is a possible parameter for ATOMIC_BLOCK. When used, it will cause
the ATOMIC_BLOCK to restore the previous state of the SREG register,
saved before the Global Interrupt Status flag bit was disabled. The net
effect of this is to make the ATOMIC_BLOCK's contents guaranteed atomic,
without changing the state of the Global Interrupt Status flag when
execution of the block completes.
Cheers
Mark Brandis schrieb:> Ich wusste gar nicht, dass es dieses Makro für jede Architektur gibt,> auf der ein GCC verfügbar ist... ;-)
Ich hab das - vllt fälschlich - von den cli()/sei() Funktionen
abgeleitet, dass es hier um die avr-gcc geht. Folgende "Schreibweise"
wird gängiger sein, hier ein Beispiel für den icc430:
1
__istate_ts=__get_interrupt_state();
2
__disable_interrupt();
3
4
/* Do something */
5
6
__set_interrupt_state(s);
Klaus schrieb:> Aber an der cli/sei Methode ist eigentlich auch nichts> auszusetzen.
Machen kann man das, aber wie ich bereits schrieb: Ich bin der Meinung,
dass man sich das nicht angewöhnen sollte.
Karl heinz Buchegger schrieb:> In der Doku zu den Makros steht, dass sie in jedem Fall sicher stellen,> dass das Interrupt Flag wieder richtig und je nach Makroargument richtig> gesetzt wird, wenn der Block verlassen wird.> dh. auch in diesem Fall>> ATOMIC_BLOCK( ATOMIC_RESTORESTATE )> {> ...>> return;> }>> machen die Makros das richtige.
Wusste ich gar nicht, das ist natürlich praktisch bei verschachtelten
Strukturen - solchen Komfort hat man leider nicht überall. :^)
Eugenius Fragikus schrieb:> Wusste ich gar nicht, das ist natürlich praktisch bei verschachtelten> Strukturen
Mein Problem ist eher: Ein alter Hund lernt nur schwer neuen Tricks
Karl heinz Buchegger schrieb:> Mein Problem ist eher: Ein alter Hund lernt nur schwer neuen Tricks
Gucken tust du trotzdem, hehe. Du packst das schon... ;^)