Hallo zusammen,
für unsere Abschlussarbeit entwickeln wir ein Messgerät.
Allerdings weiß ich momentan nicht mehr weiter:
Ich weise in meiner Funktion "Einstellen" der Variablen uint16_t
parameter[4] Werte zu.
die Variablen initialisiere ich mit 0 am Anfang.
ich lasse mir die Variablen parameter[1] und [2] ausgeben.
in der Funktion "Einstellen" sind diese noch in Ordung.
Wenn ich aber nun zurückkehre ins "main.c" haben die Werte
Parameter[0],[1],[3] in meiner Testausgabe irgendwelche Werte. Einzig
Parameter [2] ist in Ordnung.
Ich bin absolut ratlos....
im RAM haben willst? Schau dir mal Progmem an:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29
Aber auch selbst damit sind die ganzen "*" absolute
Speicherverschwendung, da kann man lieber eine Funktion schreiben
"print_stars(uint8_t numberof_stars)..."
Um welchen Controller handelt es sich überhaupt?
Matthias Kugler schrieb:> was kann der Hintergrund sein? der von Roland genannte Stacküberlauf?
wahrscheinlich,
ist nun Mal ein mikrocontroller und da muss man sich schon Gedanken um
den Speicherverbrauch machen
Vermutlich eine Mischung aus zu viel RAM-Verbrauch und zu kleinem Stack.
Deklariere deine Strings als "const", dann landen die (bei korrekter
Implemetierung des Kompilers) erst mal im ROM und kosten weniger RAM.
Roland schrieb:> Deklariere deine Strings als "const", dann landen die (bei korrekter> Implemetierung des Kompilers) erst mal im ROM und kosten weniger RAM.
Nicht beim AVR.
Bei AVR-GCC verwendet man dafür PROGMEM bei IAR __flash
Um die Strings zu lesen kann man aber nicht einfach printf nehmen
sondern printf_P bzw. eine selbst programmierte Funktion wie uart_puts_P
via pgm_read_byte
Alleine diese 4 Zeilen fressen schonmal ~280 Bytes. Und wenn man sich
die ganzen anderen Strings so ansieht, dann sind auch schon fast die 1K
RAM voll und der Stack braucht ja auch noch ein bissl.
Auf einem µC kann man nunmal nicht einfach wie auf dem PC programmieren,
die Ressourcen sind da nunmal begrenzt. Also Strings kurz halten und
brav im Flash liegen lassen via PROGMEM bzw. PSTR
Timmo H. schrieb:> Also Strings kurz halten und> brav im Flash liegen lassen via PROGMEM bzw. PSTR
... oder die ganze Sache noch etwas intelligenter (und fauler :-)
angehen.
1
voidprintStars(uint8_tnumber)
2
{
3
uint8_ti;
4
for(i=0;i<number;i++)
5
uart_putc('*');
6
}
7
8
voidprintStarLine(uint8_tnumber)
9
{
10
printStars(number);
11
uart_puts("\r\n");
12
}
13
14
voidprintHeader(uint8_tnumber,constchar*title)
15
{
16
uint8_tlen=strlen(title);
17
18
uart_puts("\033[2J");// clear screen
19
printStarLine(number);
20
printStars(len/2);
21
uart_puts(title);
22
printStars(len-len/2);
23
uart_puts("\r\n");
24
printStarLine(number);
25
}
Dann erzeugt ein
1
...
2
printHeader(80,"HAUPT MENUE");
3
...
... den kompletten Kopf, wobei man dann den Vorteil hat, dass alle
Menüköpfe aller Menüs immer gleich aussehen und wenn einem dieser Kopf
nicht mehr gefällt man nur an einer einzigen Stelle den Hebel ansetzen
muss. Letzteres könnte zb dann interessant werden, wenn er den "special
graphics character set" des VT100 entdeckt :-)
Timmo H. schrieb:> Roland schrieb:>> Deklariere deine Strings als "const", dann landen die (bei korrekter>> Implemetierung des Kompilers) erst mal im ROM und kosten weniger RAM.> Nicht beim AVR.> Bei AVR-GCC verwendet man dafür PROGMEM bei IAR __flash> Um die Strings zu lesen kann man aber nicht einfach printf nehmen> sondern printf_P bzw. eine selbst programmierte Funktion wie uart_puts_P> via pgm_read_byte...
Urks. Da rächt sich wohl die Harvard-Architektur in einem
Mikrokontroller...
Roland
HAllo zusammen,
vielen Dank für Eure Hilfe. Ich habe etwas nachgelesen und hoffe ich
habe es verstanden:
Durch deklarieren eins Strings mit char xyz[] wird dieser beim Starten
direkt aus dem Flash in den SRAM geladen.
Zu Peters Funktion:
was passiert bei folgender Zeile:
1
voidprintHeader(uint8_tnumber,constchar*title)
Der Funktion wird ein char-Arrray übergeben, die Funktion erwartet einen
Zeiger auf das erste Element, da es mit const angegeben ist, sucht der
AVR im Flash-Speicher danach?
@ Roland was hat das mit der Harvard-Technologie zu tun?
@ A. K. Woher sehe ich wieviel RAM das Programm belegt?
Vielen Dank für Eure Hilfe.
Matthias
Matthias Kugler schrieb:> HAllo zusammen,>> vielen Dank für Eure Hilfe. Ich habe etwas nachgelesen und hoffe ich> habe es verstanden:> Durch deklarieren eins Strings mit char xyz[] wird dieser beim Starten> direkt aus dem Flash in den SRAM geladen.
JEDER String wird aus dem Flash ins SRAM geladen.
Es sei denn du markierst ihn explizit als 'bleibt im Flash'.
>
1
voidprintHeader(uint8_tnumber,constchar*title)
>> Der Funktion wird ein char-Arrray übergeben,
In C werden keine Arrays übergeben. Die Funktion kriegt einen Pointer
auf den Anfang des Strings. Immer. Das ist die Art und Weise, wie in C
Arrays übergeben werden.
-> du brauchst ein C-Buch!
> Zeiger auf das erste Element, da es mit const angegeben ist, sucht der> AVR im Flash-Speicher danach?
Nein.
Das const ist nur die Zusicherung an den Aufrufer, dass die Funktion
nicht versuchen wird, das worauf der Zeiger zeigt zu verändern. Dies ist
insforn wichtig, weil ja eine String-Konstante "Haus" für dich als
Programmierer unveränderbar ist.
Auf dem AVR-GCC ist mit dem const keinerlei Speicherzuordnung (Flash
oder SRAM) verknpft.
Karl Heinz Buchegger schrieb:>> Der Funktion wird ein char-Arrray übergeben,>> In C werden keine Arrays übergeben. Die Funktion kriegt einen Pointer> auf den Anfang des Strings. Immer. Das ist die Art und Weise, wie in C> Arrays übergeben werden.
Tschuldigung, das ist mir klar, ich hab mich falsch ausgedrückt.
das "bleibe im Flash" passiert dann durch "PROGMEM" ??
Danke für die Erklärung zu const, allerdings verstehe ich noch nicht
ganz den Nutzen.
Der Aufrufet weiß, das die Funktion "printHeader" die String Konstante
nicht ändert. Aber das ist doch im Vorfeld schon klar, da ich das ja als
Programmierer so programmiert habe, oder?
Matthias Kugler schrieb:> Der Aufrufet weiß, das die Funktion "printHeader" die String Konstante> nicht ändert. Aber das ist doch im Vorfeld schon klar, da ich das ja als> Programmierer so programmiert habe, oder?
Dann bist du der erste Programmierer, der mir begegnet, der unfehlbar
ist.
1
voidprintHeader(uint8_tnumber,constchar*title)
2
{
3
title[0]='a';
4
}
und schon klopft dir der Compiler auf die Finger, weil du dein
'Versprechen' nicht einhältst.
Ein Versprechen, auf das sich der Aufrufer hier
Matthias Kugler schrieb:> das "bleibe im Flash" passiert dann durch "PROGMEM" ??
Ja.
Oder bei einem neuern AVR-GCC dadurch, dass man den Modifier _flash
vergibt.
AVR-GCC-Tutorial
Abschnitt: 15.2 Programmspeicher_(Flash)
Karl Heinz Buchegger schrieb:> Dann bist du der erste Programmierer, der mir begegnet, der unfehlbar> ist.
:-) Das würde ich nie behaupten, ich wollte nur den Hintergrund
verstehen.
Vielen Dank, für die Infos.