www.mikrocontroller.net

Forum: Compiler & IDEs Arrays gleicher länge tauschen


Autor: Richard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
//globale Arrays
uint8_t arr1[11];
uint8_t arr2[11];

void vertausche( void ) {
    uint8_t *ptr;

    cli();
    ptr = arr1;
    arr1 = arr2;
    arr2 = ptr;
    sei();
}

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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();

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

//globale Arrays
uint8_t arr1[11];
uint8_t arr2[11];

uint8_t * actualBuffer = arr1;
uint8_t * backupBuffer = arr2;

void vertausche( void ) {
    uint8_t *ptr;

    cli();
    ptr = actualBuffer;
    actualBuffer = backupBuffer;
    backupBuffer = ptr;
    sei();
}

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.

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So wie du es geschrieben hast, gehts nicht, so wie Peter vorgeschlagen 
hat, schon.

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Richard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke danke, hab die pointerlösung genommen, mal sehn obs 
funktioniert...

Vielen Dank
lg Richard

Autor: Eugenius Fragikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
void 
vertausche( void ) 
{
  uint8_t *ptr;

  ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
  {
    ptr = actualBuffer;
    actualBuffer = backupBuffer;
    backupBuffer = ptr;
  }
}

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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... ;-)

Autor: atomic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eugenius Fragikus schrieb:
> Mit den cli()/sei() ist das ganz finster, das...

Weshalb?

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
 ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
  {
     ...

    return;
  }

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 :-)

Autor: Praktiker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Eugenius Fragikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:

__istate_t s = __get_interrupt_state(); 
__disable_interrupt(); 
 
  /* Do something */ 
 
__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.

Autor: Eugenius Fragikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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. :^)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Eugenius Fragikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...  ;^)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.