Forum: Compiler & IDEs Arrays gleicher länge tauschen


von Richard (Gast)


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:
1
//globale Arrays
2
uint8_t arr1[11];
3
uint8_t arr2[11];
4
5
void vertausche( void ) {
6
    uint8_t *ptr;
7
8
    cli();
9
    ptr = arr1;
10
    arr1 = arr2;
11
    arr2 = ptr;
12
    sei();
13
}

von Peter (Gast)


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();

von Karl H. (kbuchegg)


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.

1
//globale Arrays
2
uint8_t arr1[11];
3
uint8_t arr2[11];
4
5
uint8_t * actualBuffer = arr1;
6
uint8_t * backupBuffer = arr2;
7
8
void vertausche( 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.

von der mechatroniker (Gast)


Lesenswert?

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

von Rolf M. (rmagnus)


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.

von Richard (Gast)


Lesenswert?

Danke danke, hab die pointerlösung genommen, mal sehn obs 
funktioniert...

Vielen Dank
lg Richard

von Eugenius Fragikus (Gast)


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:
1
void 
2
vertausche( void ) 
3
{
4
  uint8_t *ptr;
5
6
  ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
7
  {
8
    ptr = actualBuffer;
9
    actualBuffer = backupBuffer;
10
    backupBuffer = ptr;
11
  }
12
}

von Mark B. (markbrandis)


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... ;-)

von atomic (Gast)


Lesenswert?

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

Weshalb?

von Klaus (Gast)


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.

von Karl H. (kbuchegg)


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

von Praktiker (Gast)


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

von Eugenius Fragikus (Gast)


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:

1
__istate_t s = __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.

von Eugenius Fragikus (Gast)


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

von Karl H. (kbuchegg)


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

von Eugenius Fragikus (Gast)


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...  ;^)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.