PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Fragen zur Speicherbelegung



Kornhaas.net
04.09.2005, 21:15
Hallo Leute

hab hier ein kleines Problem. Versuche gerade ein Programm zu erstellen, welches mir ein Menü beim Reset des ATmega128 ausgibt.

Nun hab ich das Problem, das wenn ich das Array mit dem Menü normal mit const char initialisiere ergibt sich nach dem Compelieren das es mit das Menu nach dem Reset ausgibt aber der ca. 20 Zeile nur noch mist ausgibt.

WinGCC sagt nach dem Compilieren:
Program: 5942 bytes (4.5% Full)
Data: 5658 bytes ( 138,1% Full)

Somit kann ich mir auch den Fehler erklären. Es sieht so aus als würde er das char mit dem Menü in das RAM und nicht ins Flash legen.

Kann mir einer helfen und sagen wie es mit der pgmspace.h geht.

Hier nun mein Programm Auszug:



char help[][255] PROGMEM =
{ "\r\n\r\n",
"****** SPI to UART Umwandlung ******\r\n",
"****** Beta 1.0 Kornhaas.net ******\r\n\r\n",
"Bitte treffen Sie ihre Auswahl:\r\n",
"[?] - Status anzeiegn\r\n",
"[X] - Sequenz eingeben \r\n",
"[Q] - SCK Frequenz ( ----SPI2X=0----- ----SPI2X=1----- )\r\n",
" ( 0=F/4 921.6kHz 4=F/2 1.8432MHz )\r\n",
" ( 1=F/16 230.4kHz 5=F/8 460.8kHz )\r\n",
" ( 2=F/64 57.6kHz 6=F/32 115.2kHz )\r\n",
" ( 3=F/128 28.8kHz 7=F/64 57.6kHz )\r\n",
"[S] - Slave Select pin level (0=low, 1=high)\r\n",
"[P] - Auto-toggle SS control (0=low, 1=high, 2=off)\r\n",
"[T] - Bit Transmission Order (0=MSB first, 1=LSB first)\r\n",
"[M] - SPI Clock Mode (0 : 1 : 2 : 3)\r\n",
" Mode Leading-Edge Trailing-Edge CPOL CPHA\r\n",
" 0 Sample(Rising) Setup (Falling) 0 0\r\n",
" 1 Setup (Rising) Sample(Falling) 0 1\r\n",
" 2 Sample(Falling) Setup (Rising) 1 0\r\n",
" 3 Setup (Falling) Sample(Rising) 1 1\r\n",
"[W] - Write (save) configuration (auto loaded at reset)\r\n\r\n"
// 12345678901234567890123456789012345678901234567890 12345678901234 64 char
};


int main (void)
{
char tmp,uart_input;
int i=0;

USART0_Init(); // UART-Port initialisiernen
SPI_Init (); // SPI-Port initialisieren

DDRA=0xff; // Port B als AUsgang


for(i=0; i<20;i++)
{
_delay_ms(10);
USART0_TransmitString(help[i]); // Menü soll über Uart ausgegeben werden
}
for (;;)
{
// Weiterer Code folgt hier noch

gruß Holger

Kjion
04.09.2005, 21:29
Es sieht so aus als würde er das char mit dem Menü in das RAM und nicht ins Flash legen.
Ja, genau richtig.

Schau dir mal folgendes Beispiel an:
http://www.kreatives-chaos.com/index.php?seite=c_uart_flash

Daten aus dem Flash laden ist bei den AVRs aufgrund der Harvard Architektur leider ein bißchen umständlicher.

MfG Kjion

cavegn
04.09.2005, 21:29
hi

wie sieht denn deine USART0_TransmitString Funktion aus?
sollte etwa so aussehen:

void USART0_TransmitString_p(const char *progmem_s){
register char c;

while ( (c = pgm_read_byte(progmem_s++)) ) {
_zeichen_senden_(c);
}
}


ahja, char help[][255] PROGMEM - ich würde das 255 soweit verkleinern wie möglich - sonst belegst du nur flash für nix :-)

cu

chris

linux_80
04.09.2005, 21:34
Hallo,
ich weiss ja nicht genau wie das mit den Variablen gehandelt wird,
sieht aber so aus wenn alles ins RAM gelegt wird, und deshalb wirds ein wenig eng.
Da Du aber einen 128er hast, könntest ihm etwas externen RAM verpassen !?

Kornhaas.net
04.09.2005, 21:43
Danke Chris

mit deinem Tip geht es *freu*

Mfg

Holger

SprinterSB
05.09.2005, 08:46
Eigentlich so:


const char STR_1[] PROGMEM = "...";

const char *help[] PROGMEM =
{
STR_1,
...
};


Wobei dann sowohl sie Strings als auch die Tabelle ihrer Adressen im Flash liegen.

Mit


const char *help[] PROGMEM =
{
"foo",
...
};

Hast du nur die Tabelle im Flash, die Strings wohnen überflüssigerweise im RAM.

Kornhaas.net
05.09.2005, 10:39
Du meinst ich habe im moment nur die Tabelle im Flash liegen und der Inhalt liegt nicht im String ???



const char help[20][58] PROGMEM =
{ "\r\n\r\n",
"****** SPI Gateway - USART to SPI ******\r\n",
"****** V1.11 Holger Kornhaas Siemens AG 2005 ******\r\n\r\n",
"Enter hex encoded byte to send via SPI, or commands:\r\n",
"[?] - Show current status\r\n",
"[X] - Extended hex sequence ( maximum 16 bytes )\r\n",
"[Q] - SCK freq ( ----SPI2X=0----- ----SPI2X=1----- )\r\n",
" ( 0=F/4 921.6kHz 4=F/2 1.8432MHz )\r\n",
" ( 1=F/16 230.4kHz 5=F/8 460.8kHz )\r\n",
" ( 2=F/64 57.6kHz 6=F/32 115.2kHz )\r\n",
" ( 3=F/128 28.8kHz 7=F/64 57.6kHz )\r\n",
"[S] - Slave Select pin level (0=low, 1=high)\r\n",
"[P] - Auto-toggle SS control (0=low, 1=high, 2=off)\r\n",
"[T] - Bit Transmission Order (0=MSB first, 1=LSB first)\r\n",
"[M] - SPI Clock Mode (0 : 1 : 2 : 3)\r\n",
" Mode Leading-Edge Trailing-Edge CPOL CPHA\r\n",
" 0 Sample(Rising) Setup (Falling) 0 0\r\n",
" 1 Setup (Rising) Sample(Falling) 0 1\r\n",
" 2 Sample(Falling) Setup (Rising) 1 0\r\n",
" 3 Setup (Falling) Sample(Rising) 1 1\r\n",
"[W] - Write (save) configuration (auto loaded at reset)\r\n\r\n"
// 12345678901234567890123456789012345678901234567890 12345678901234 64 char
};

hmm nur wenn ich mir nach der Änderung mit dem PROGMEM nach dem Kompilieren anschaue sieht es doch recht gut aus. Unter der Voraussetzung das der Kompilier es richtig anzeigt.

Size after:
main.elf :
section size addr
.data 40 8388864
.text 2234 0
.bss 260 8388904
.noinit 0 8389164
.eeprom 4 8454144
.stab 4044 0
.stabstr 2826 0
Total 9408


AVR Memory Usage:
-----------------
Device: atmega128

Program: 2274 bytes (1.7% Full)
(.text + .data + .bootloader)

Data: 300 bytes (7.3% Full)
(.data + .bss + .noinit)

Gruß Holger

SprinterSB
05.09.2005, 10:59
Doch die Strings liegen dann auch im Flash.
Allerdings ist es etwas fehleranfällig, weil du die max-Länge wissen musst, und endende '\0' nicht vergessen. Zudem braucht es mehr Speicherplatz, weil *alle* Strings die maximale Länge belegen.
Die Anzahl der Strings musst du nicht wissen, kannst also
help[][58] hinschreiben.
Bei meiner Lösung ist die Schreibarbeit mehr.
Ausserdem werden die Daten in beiden Fällen anders abgelegt.
Bei mir stehen nur die Adressen der Strings in der Tabelle. Zum Zugriff braucht ne 2fache Indirektion. Bei dir stehen die Strings en Block hintereinander (einfache Indirektion und Multiplikation mit 58)

SprinterSB
05.09.2005, 11:01
soll heissen 'Multiplikation mit 58 )

bluebrother
05.09.2005, 18:20
"****** SPI to UART Umwandlung ******\r\n"
es gibt übrigens eine AppNote von Atmel die einen SPI Slave macht und das Ergebnis über usart ausgibt. Einfach mal bei Atmel suchen ...