Forum: Compiler & IDEs Array in AVR Studio GCC mit variabler Länge


von Philipp (Gast)


Lesenswert?

Hallo alle zusammen,

ich bin gerade dabei einen AT90CAN128 auf dem STK500/501 mit AVR Studio 
4.18 und WIN Avr 4.3.3 zu programmieren. Ist nicht das erste Programm 
das ich für einen Atmel µP schreibe, allerdings das erste für einen 
AT90, was ja aber eigentlich keinen unterschied macht (außer Register 
und Co.).
Mein Problem ist, dass ich zu beginn des Programms ein Array aufbauen, 
dessen Länge pro Programmdurchlauf verschiedene Werte hat. Die Länge 
wird nicht zur Laufzeit geändert, sondern ist konstant während des 
Ablaufes. Wird das Programm unterbrochen, kann es allerdings sein, dass 
das Array deleted wird und mit einer neuen länge wieder aufgebaut. Sieht 
dann im Code so aus:
1
//START
2
#include "common.h"
3
#include "interrupt.h"
4
#include "inttypes.h"
5
#include "io.h"
6
#include "math.h"
7
#include "stdint.h"
8
#include "stdio.h"
9
#include "stdlib.h"
10
#include "string.h"
11
12
...
13
14
int main(void)
15
{
16
...
17
18
//Berechnung der Array-Laenge
19
int var_laenge = var_Drehzahl / var_steigung;
20
//               (int)          (int)
21
22
volatile double sinoid[var_laenge];
23
...
24
}

Später im Code werden die Werte aus dem Array dann zu Erzeugung einer 
PWM genutzt...sollen sie zumindest.

Das Problem ist, dass egal bei welchem Optimierer, entweder das Array 
die Länge 1 bekommt oder ich die Fehlermeldung in der Watch bekomme: 
"Location not valid".
Nur und Ausschließlich wenn ich es mit einer festen Länge aufbaue, 
bekomme ich keinen Fehler. Das klaut aber Speicherplatz ohne Ende. Hat 
einer eine Idee woran es liegen kann???

von Karl H. (kbuchegg)


Lesenswert?

Philipp schrieb:
> Hallo alle zusammen,
>
> ich bin gerade dabei einen AT90CAN128 auf dem STK500/501 mit AVR Studio
> 4.18 und WIN Avr 4.3.3 zu programmieren. Ist nicht das erste Programm
> das ich für einen Atmel µP schreibe, allerdings das erste für einen
> AT90, was ja aber eigentlich keinen unterschied macht (außer Register
> und Co.).
> Mein Problem ist, dass ich zu beginn des Programms ein Array aufbauen,
> dessen Länge pro Programmdurchlauf verschiedene Werte hat. Die Länge
> wird nicht zur Laufzeit geändert, sondern ist konstant während des
> Ablaufes. Wird das Programm unterbrochen, kann es allerdings sein, dass
> das Array deleted wird und mit einer neuen länge wieder aufgebaut.

Definiere das Array mit der maximalen Größe, die sich im Speicher gerade 
noch ausgeht, lass es dabei bewenden und benutze nur den Teil den du 
brauchst.
Achtung: Vom verfügbaren SRAM musst du noch einen Anteil für lokale 
Variablen bzw. den Stack abziehen. Aber was dann noch übrig bleibt, 
kannst du alles in das Array buttern.

> Nur und Ausschließlich wenn ich es mit einer festen Länge aufbaue,
> bekomme ich keinen Fehler. Das klaut aber Speicherplatz ohne Ende.

Speicherplatz, der ansonsten Brach liegen würde und für nichts gut ist.


Du baust ein Parkhaus auch nicht um, nur weil am Dienstag nicht mehr als 
20 Autos parken wollen.

von Karl H. (kbuchegg)


Lesenswert?

Du musst bei der µC Programmierung anders denken als bei der 
PC-Programmierung.
Du musst dein Programm für den Worst-Case auslegen. Wenn dann Speicher 
nicht benutzt wird, weil er in diesem einen Programlauf nicht gebraucht 
wird, ist es auch gut. Es stört niemanden, wenn du von einem 100 
Einträge Array momentan nur 20 benutzt. Davon profitiert keiner, weil 
dein Programm das einzige was läuft. Wenn du aber die 100 brauchst, dann 
hast du sie auch.
Schlimmer wäre es umgekehrt: Wenn du mehr Speicher verbrauchen würdest 
als du hast.

von Oliver (Gast)


Lesenswert?

Philipp schrieb:
> Nur und Ausschließlich wenn ich es mit einer festen Länge aufbaue,
> bekomme ich keinen Fehler.

Das liegt nicht an dem gezeigten Code-Auschnitt. Der ist soweit in 
Ordnung.

Oliver

von Philipp (Gast)


Lesenswert?

Danke für die schnellen Antworten. Ja, habe zwar irgendwann mal bei 
"Programmierung für embedded Systeme" gehört, dass es unelegant ist aber 
naja... =) werde es wohl so machen!

von Klaus W. (mfgkw)


Lesenswert?

Der avr-gcc akzeptiert in diesem Fall diese beiden Versionen:
1
  int var_Drehzahl = 1000;
2
  int var_steigung = 100;
3
  //Berechnung der Array-Laenge
4
  int var_laenge = var_Drehzahl / var_steigung;
5
  {
6
    volatile double *sinoid = (double*)alloca( var_laenge*sizeof(double) );
7
    sinoid[0] = 1.0;
8
    sinoid[9] = 1.0;
9
  }
1
  int var_Drehzahl = 1000;
2
  int var_steigung = 100;
3
  //Berechnung der Array-Laenge
4
  int var_laenge = var_Drehzahl / var_steigung;
5
  {
6
    volatile double sinoid[var_laenge];
7
    sinoid[0] = 1.0;
8
    sinoid[9] = 1.0;
9
  }

Für die erste ist #include <alloca.h> nötig.

In beiden Fällen landet das Feld auf dem Stack und wird
automatisch bei Blockende aufgeräumt.
Die üblichen Heapprobleme bei kleinen Rechnern schlagen also
hier nicht zu.
Solange die Feldlänge im Rahmen bleibt, sehe ich da auch
nichts unelegantes daran.

Wieso includest du eigentlich alle Header mit "" ?
Gelinde gesagt ungewöhnlich...

von Philipp (Gast)


Lesenswert?

Ähm....gute Frage...damit ich nicht durcheinander komme, wenn ich sehe, 
dass include kleiner sein soll als der Header under der Header wiederum 
größer als der Kommentar?! :D Gewohnheitssache, ist aber doch seit c90 
eh egal, oder habe ich da was verpasst?

von Klaus W. (mfgkw)


Lesenswert?

Keine Ahnung.
Was sollte sich mit C90 bzgl. <> und "" geändert haben?

von Philipp (Gast)


Lesenswert?

war es nicht so, das bis c90 <> immer die standartlibs aufgerufen wurden 
und mit "" die im eingenen projekt ordner? da ich zu den menschen 
gehöre, die der meinung sind, benutzte header gehören in den projekt 
ordner (weitergabe von programmen, keine default installationen, 
eigenbrödlerei...), kann ich sie ja lokal aufrufen. oder sehe ich da 
einen unterschied nicht?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Philipp schrieb:
> war es nicht so, das bis c90 <> immer die standartlibs aufgerufen wurden
> und mit "" die im eingenen projekt ordner?

Das ist auch in C99 so geblieben.  Genauer gesagt, bei "" beginnt
die Suchreihenfolge im aktuellen Verzeichnis, geht danach aber
bei den mit -I genannten Verzeichnissen weiter, abschließend werden
die Systemverzeichnisse durchsucht.

> da ich zu den menschen
> gehöre, die der meinung sind, benutzte header gehören in den projekt
> ordner (weitergabe von programmen, keine default installationen,
> eigenbrödlerei...), kann ich sie ja lokal aufrufen. oder sehe ich da
> einen unterschied nicht?

Dann musst du aber auch alle Bibliotheksdateien der Standard-
bibliothek mit kopieren, denn die Header sind nur ein kleiner Teil
der Bibliothek, und die Systemheader müssen nun mal zur Bibliothek
passen (bzw. zum Compiler, manche Header stammen von diesem).  Du
wirst dann auch nicht umhin kommen, dem Compiler die neue Lage der
Bibliotheksverzeichnisse mit -B-Optionen mitzuteilen.

Alles in allem eine reichlich umständliche Vorgehensweise, finde ich.

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.