STM32F4 Daten passen nichts ins RAM

Gast #3582817
Lesenswert?

Hallo,

ich habe einen STM32F405 Controller in dessen RAM ich ein großes 
Datenpaket ablegen möchte.

Ohne dieses Datenpaket habe ich:
      text   data   bss    dec  hex
      6654   1292   2620  10566  2946


dann kommt folgender Code hintzu:
1
#define BUFFERSIZE 65536
2
volatile uint16_t Data[BUFFERSIZE];
somit sollten zu den 2620 Bytes nochmal 131072 Bytes dazu kommen.
Macht 133692. Dann habe ich noch den Stack mit
1
#define STACK_SIZE       0x00000200      /*!< The Stack size suggest using even number    */

Macht also 512Byte Stack, 2620 Bytes normale Daten und die 131072 Bytes. 
Sollte doch alles in die 192kB RAM reinpassen, oder?

Ich bekomme allerdings die Warnung:
section `.bss' will not fit in region `ram'
region ram  overflowed with stack
region `ram' overflowed by 3912 bytes

Warum bzw. wie kann ich das Problem beheben? Wer blockiert hier den 
Restlichen RAM?
Gast #3582820
Lesenswert?

Ingo schrieb:
> #define STACK_SIZE       0x00000200      /*!< The Stack size suggest
> using even number    */
Die Stack-Size muss im Linker-Script angegeben werden, damit die 
Berechnung da funktioniert. Außerdem sind die 192kB kein homogener Block 
sondern teilen sich auf 128kB SRAM und 64kB CCM auf (siehe 
Datasheet+Reference Manual), die will der Linker vermutlich nicht in 
einem reservieren.
Gast #3582859
Lesenswert?

Wenn dein "Data" Array nur von der Cpu, nicht von DMA oder so 
zugegriffen wird, pack das doch ins CCM, passt da ja genau rein... 
Ansonsten musst du andere Teile ins CCM packen und "Data" ins den 
normalen SRAM.
Gast #3582877
Lesenswert?

Dr. Sommer schrieb:
> Wenn dein "Data" Array nur von der Cpu, nicht von DMA oder so
> zugegriffen wird, pack das doch ins CCM, passt da ja genau rein...
> Ansonsten musst du andere Teile ins CCM packen und "Data" ins den
> normalen SRAM.

Das Data Array soll mit Werten von ADC über DMA vollgepackt werden, 
somit mit der DMA auch darauf zugreifen können => somit muss das dann 
wohl ins SRAM. Die Restlichen sachen werden nur von der CPU genutzt, 
also könnte das ins CCM.

Wie teile ich dem Linker mit, welche Daten wo landen sollen? Bin mit dem 
Linker nicht vertraut :(


Danke schonmal!
Gast #3582895
Lesenswert?

Ingo schrieb:
> Wie teile ich dem Linker mit, welche Daten wo landen sollen? Bin mit dem
> Linker nicht vertraut :(
Irgendwas mit __attribute__((section("blablub"))) im Code an der 
jeweiligen Variablen, wobei blablub der Section im Linker-Script 
entspricht... Musste schauen wie die CCM-Section in deinem Linkerscript 
heißt.
(Firma: EleLa - www.elela.de) #3583359
Lesenswert?

Man könnte auch den CCM RAM als Standard RAM deklarieren, dann landet 
automatisch alles darin und mit __attribute__((section("blablub"))) 
werden dann nur noch die Variablen deklariert die in das SRAM kommen.
Sogar der Stack kann im CCM RAM liegen, allerdings muss man erst den CCM 
RAM aktivieren (Clock), ansonsten kann man darin nichts rein 
schreiben/lesen.

Wie man das bei CoIDE einstellt weiß ich nicht. Ich nutze Eclipse, 
direkt mit GCC und Linker-Script und kann mir das von Hand 
zusammenschreiben wie ich mag - dafür ist alles Handarbeit.
Gast #3583476
Lesenswert?

Nein, es wird das Array mit Daten gefüllt, analysiert und auf bestimmte 
Charactarisrika untersucht. Danach werden die Daten verworfen und nur 
ein paar Sachen davon gespeichert. Danach beginnt das Spiel von vorn. Es 
ist daher nötig, so viele zusammenhängende Daten wie möglich auszuwerten
Gast #3583754
Lesenswert?

Ingo schrieb:
> Bzw. gibt es eine möglichkeit dem Linker zu sagen, er möge bitte beide
> Speicherblöcke als einen benutzen?

Das kann man dem Linker schon sagen, es nützt aber nichts, weil das 
Array dann über zwei physikalische Blöcke verteilt ist, und der Zugriff 
im Programm beim "Sprung" zum Speicherfehler führt.

Da der STM32F405 keine MMU hat, die daraus einen logischen Block machen 
könnte, gibt es nur eine Möglichkeit: eine struct aus zwei Arrays die in 
den beiden Blocks deklariert werden und Zugriff über Zeiger:

struct array
{
  __DATA(RAM1) char data_buffer[128*1024];
  __DATA(RAM2) char data_buffer[64*1024];
}
Gast #3583846
Lesenswert?

Ingo schrieb:
> Nein, es wird das Array mit Daten gefüllt, analysiert und auf bestimmte
> Charactarisrika untersucht. Danach werden die Daten verworfen und nur
> ein paar Sachen davon gespeichert. Danach beginnt das Spiel von vorn. Es
> ist daher nötig, so viele zusammenhängende Daten wie möglich auszuwerten

Das ist IMHO nur dann der Fall wenn das gesuchte Charakteristikum auch 
so groß ist dass es über den ganzen Speicher verteilt ist. Alternativ 
könnte man: die Samplefrequenz verdoppeln (also Abtastrate halbieren) 
und den Speicher halbieren oder den Algorithmus anderweitig anpassen. 
Wenn das nicht geht wäre zu überlegen ob die Wahl des Prozessors mit dem 
grenzwertigen RAM als geeignet zu bezeichnen ist.

rgds
Gast #3583920
Lesenswert?

Also ich habe mir jetzt folgendes überlegt:

Ich verkleinere meinen Datenpuffer auf 100kB (50000 Werte). Dann habe 
ich noch reichlich Reserven für Stack und sonstige kleinen Sachen.

Zusätzlich packe ich "normale" Variablen, die nicht über DMA sondern nur 
vom Prozessor angesprochen werden in den CCM.

Dazu habe ich im Linkerscript folgende Codezeilen hinzu gefügt:
.ccm :
{
 . = ALIGN(4);
 _sccm = .;
 *(.ccm)
 . = ALIGN(4);
 _eccm = .;
}>ram1

Dann werden die Variablen über _attribute_ ((section (".ccm")))
dort abgelegt.

Das sollte soweit funktionieren hoffe ich. Ich habe zwar keinen blassen 
Schimmer was diese Codezeilen genau machen, es scheint aber zu 
funktionieren, denn die Variablen landen nun nicht mehr unter .bss 
sonder werden zu .data gepackt.

unter CooCox muss man dann noch sagen "bitte eigenes Linkerscript 
verwenden" nämlich das mit den geänderten Codezeilen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren