www.mikrocontroller.net

Forum: Compiler & IDEs ARM: malloc & Null pointer Vergleich


Autor: alexatmk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
bei meinen AVR's hab ich den freien sram immer so getestet:
void sramtest(){
  //allocates memory up to null pointer
  uint16_t i;
  uint8_t *sram;

  for(i=1;i<65500;i++){
    if((sram = (uint8_t *) malloc(i*sizeof(uint8_t))) == (void *) 0) {
      free(sram);
      lcd_string_P("free bytes: ");
      lcd_writei(i-1);
      i=65500;
    }
    else{
      free(sram);
    }

  }//for

beim ARM (at91sam7s64) funktioniert das nicht.
ich habe auch schon sowas probiert:
if((sram = (uint8_t *) malloc(i*sizeof(uint8_t))) == (uint8_t *) 0) 


aber die abfrage wird nie .true.

was muss ich beim arm anders machen?

danke
alex

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
== 0 oder == NULL ist beim Vergleich von Zeigern ausreichend, der Cast 
ist überflüssig. Aber: woher soll malloc wissen, wie groß der Heap 
werden darf? Das ist erst dem Linker bekannt.

Autor: alexatmk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Aber: woher soll malloc wissen, wie groß der Heap
werden darf? Das ist erst dem Linker bekannt."

es geht ja hier um einen laufzeittest. wie geschrieben, bei den avr's 
erhält man einen Null pointer wenn man versucht mehr als den noch freien 
speicher zu  reservieren. müsste doch beim arm auch gehen. oder habe ich 
was grundsätzliches missverstanden?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö, so sollte sich malloc auf allen Plattformen verhalten, auf denen 
eine dynamische Speicherverwaltung implementiert ist.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Trotzdem bleibt die Frage offen: woher soll malloc wissen, ob der 
Speicher reserviert werden kann, oder ob das Ende des Blocks schon 
längst im Stack, potentiellen Stack oder Nirvana liegt?

Autor: Martin Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welche libc? Falls newlib: sbrk selbst implementiert? Wenn ja wie? Oder 
sbrk aus libnosys?  Welches Memorylayout (z.B. Data, BSS, Stack, Heap 
oder Data, BSS, Heap, Platz, Stack)?

Autor: alexatmk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Martin,

ich verwende die newlib (binutils-2.17, gcc-4.1.1, newlib-1.14.0, 
insight-6.5) und linke arm-elf-4.1.1/arm-elf/lib/redboot-syscalls.o 
dazu. Früher hab ich mal die libnosys verwendet.

Mein linker script sieht so aus:
// <h> Memory Configuration
//   <h> Code (Read Only)
//     <o>  Start <0x0-0xFFFFFFFF>
//     <o1> Size  <0x0-0xFFFFFFFF>
//   </h>
//   <h> Data (Read/Write)
//     <o2> Start <0x0-0xFFFFFFFF>
//     <o3> Size  <0x0-0xFFFFFFFF>
//   </h>
//   <h> Top of Stack (Read/Write)
//     <o4> STACK <0x0-0xFFFFFFFF>
//   </h>
// </h>
*/

/* Memory Definitions */

MEMORY
{
  CODE (rx) : ORIGIN = 0x00100000, LENGTH = 0x00010000
  DATA (rw) : ORIGIN = 0x00200000, LENGTH = 0x00004000
  STACK (rw) : ORIGIN = 0x00204000,LENGTH = 0x00000000
}


/* Section Definitions */

SECTIONS
{
  /* first section is .text which is used for code */
  . = 0x0000000;
  .text : { *Cstartup.o (.text) }>CODE =0
  .text :
  {
    *(.text)                   /* remaining code */

    *(.glue_7t) *(.glue_7)

  } >CODE =0

  . = ALIGN(4);

  /* .rodata section which is used for read-only data (constants) */

  .rodata :
  {
    *(.rodata)
  } >CODE

  . = ALIGN(4);

  _etext = . ;
  PROVIDE (etext = .);

  /* .data section which is used for initialized data */

  .data : AT (_etext)
  {
    _data = . ;
    *(.data)
    SORT(CONSTRUCTORS)
  } >DATA
  . = ALIGN(4);

  _edata = . ;
   PROVIDE (edata = .);

  /* .bss section which is used for uninitialized data */

  .bss :
  {
    __bss_start = . ;
    __bss_start__ = . ;
    *(.bss)
    *(COMMON)
  } 
  . = ALIGN(4);
  __bss_end__ = . ;
  __bss_end__ = . ;
  _end = .;
  PROVIDE (end = .);


   .int_data :  
   { 
   *(.internal_ram_top) 
   }> STACK 



  /* Stabs debugging sections.  */



wenn ich das richtig sehe hab ich keinen heap - oder? ich kenn mich mit 
linker scripts überhaupt nicht aus...

Alex





Autor: alexatmk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ach so,
hätte jemand nen link auf eine vernünftige docu über linker scripts?
danke!

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Doku vom Linker reicht nicht?

Autor: alexatmk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die scheint gut zu sein, finde sie nur leider nicht in meinen binutils 
(komme mir schon doof vor ;-). ich hab im netz die html seiten gefunden, 
sind halt schlecht zu drucken.
gibts das irgendwo als pdf?

Autor: alexatmk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein make ld.pdf hilft, jetzt hab ich's.

Autor: alexatmk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die funktion mallinfo liefert (zumindest in meinem setup) ganz nüttliche 
informationen. insbesondere arena und uordblks.
ich sehe, daß ich mit malloc immer neuen speicher alloziieren kann, die 
zahl wächst über die eigentliche größe des sram hinaus.
Andreas hat da wohl recht: woher weiß malloc wie weit er gehen darf?
ich hatte gedacht, daß der heap automatisch nach .bss bis top end of 
sram ist. malloc bekommt ja vom 'system' speicher zugewiesen.
nun hatte ich angenommen, daß malloc 'mitgeteilt bekommt', wenn der heap 
ausgeschöpft ist.

wenn ich die docu richtig verstehe, ist es nicht üblich einen heap 
explizit einzurichten - oder?

ich konnte mit meminfo mein memory-leakage finden. mein erstes problem 
ist damit gelöst.

trotzdem würde mich interessieren, ob es eine möglichkeit gibt, den noch 
zu alloziierenden sram zu laufzeit zu ermitteln...










Autor: Martin Thomas (mthomas) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
alexatmk wrote:
> Hallo Martin,

>
> ...
>   _end = .;
>   PROVIDE (end = .);
> 
> 
>    .int_data :
>    {
>    *(.internal_ram_top)
>    }> STACK
> 
> 
> 
>   /* Stabs debugging sections.  */
> 
> 
>
>
> wenn ich das richtig sehe hab ich keinen heap - oder? ich kenn mich mit
> linker scripts überhaupt nicht aus...

Layout ist somit .data, .bss, Heap Anfang, Platz für Heap  --->, <--- 
Platz für Stack, Top-Stack. Heap "wächst" zu "grossen" 
Speicheraddressen, Stack "wächst" zu "niedrigen" Speicheraddressen. Out 
of Memory ist also, wenn der Heap-Pointer >= dem Stack-Pointer ist. sbrk 
als syscall für die dynamische Speicherverwaltung "interessiert" sich 
eigentlich erstmal nur dafür wo der Heap anfängt. Üblicherweise durch 
das im  Linkerscript definierte ".end", dem vom Linker ein Wert 
zugewiesen wird. Die sbrk-Implementierung aus 
newlib-Quellcode/libc/sys/arm/syscalls.c zeigt das Prinzip für eine "out 
of memory"-Prüfung ganz anschaulich: wenn aktueller 
Heap-Pointer+angeforderter Speicher > Stack-Pointer -> out of memory. 
Analog kann man die "Lücke" zwischen Heap und Stack errechnen und hat 
damit "available memory". redboot-sbrk hab ich mir bisher nicht 
angeschaut, kann ich also nichts zu sagen.

Hoffe, es bringt ein wenig weiter.
Martin Thomas




Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.