ARM: malloc & Null pointer Vergleich

Gast #570189
Lesenswert?

Hallo,
bei meinen AVR's hab ich den freien sram immer so getestet:
1
void sramtest(){
2
  //allocates memory up to null pointer
3
  uint16_t i;
4
  uint8_t *sram;
5

6
  for(i=1;i<65500;i++){
7
    if((sram = (uint8_t *) malloc(i*sizeof(uint8_t))) == (void *) 0) {
8
      free(sram);
9
      lcd_string_P("free bytes: ");
10
      lcd_writei(i-1);
11
      i=65500;
12
    }
13
    else{
14
      free(sram);
15
    }
16

17
  }//for

beim ARM (at91sam7s64) funktioniert das nicht.
ich habe auch schon sowas probiert:
1
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
Gast #570215
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?
Gast #570603
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:
1
// <h> Memory Configuration
2
//   <h> Code (Read Only)
3
//     <o>  Start <0x0-0xFFFFFFFF>
4
//     <o1> Size  <0x0-0xFFFFFFFF>
5
//   </h>
6
//   <h> Data (Read/Write)
7
//     <o2> Start <0x0-0xFFFFFFFF>
8
//     <o3> Size  <0x0-0xFFFFFFFF>
9
//   </h>
10
//   <h> Top of Stack (Read/Write)
11
//     <o4> STACK <0x0-0xFFFFFFFF>
12
//   </h>
13
// </h>
14
*/
15

16
/* Memory Definitions */
17

18
MEMORY
19
{
20
  CODE (rx) : ORIGIN = 0x00100000, LENGTH = 0x00010000
21
  DATA (rw) : ORIGIN = 0x00200000, LENGTH = 0x00004000
22
  STACK (rw) : ORIGIN = 0x00204000,LENGTH = 0x00000000
23
}
24

25

26
/* Section Definitions */
27

28
SECTIONS
29
{
30
  /* first section is .text which is used for code */
31
  . = 0x0000000;
32
  .text : { *Cstartup.o (.text) }>CODE =0
33
  .text :
34
  {
35
    *(.text)                   /* remaining code */
36

37
    *(.glue_7t) *(.glue_7)
38

39
  } >CODE =0
40

41
  . = ALIGN(4);
42

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

45
  .rodata :
46
  {
47
    *(.rodata)
48
  } >CODE
49

50
  . = ALIGN(4);
51

52
  _etext = . ;
53
  PROVIDE (etext = .);
54

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

57
  .data : AT (_etext)
58
  {
59
    _data = . ;
60
    *(.data)
61
    SORT(CONSTRUCTORS)
62
  } >DATA
63
  . = ALIGN(4);
64

65
  _edata = . ;
66
   PROVIDE (edata = .);
67

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

70
  .bss :
71
  {
72
    __bss_start = . ;
73
    __bss_start__ = . ;
74
    *(.bss)
75
    *(COMMON)
76
  } 
77
  . = ALIGN(4);
78
  __bss_end__ = . ;
79
  __bss_end__ = . ;
80
  _end = .;
81
  PROVIDE (end = .);
82

83

84
   .int_data :  
85
   { 
86
   *(.internal_ram_top) 
87
   }> STACK 
88

89

90

91
  /* Stabs debugging sections.  */


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

Alex




Gast #570613
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?
Gast #570755
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...









Moderator Persönliche Seite #571032
Lesenswert?

alexatmk wrote:
> Hallo Martin,

>
1
> ...
2
>   _end = .;
3
>   PROVIDE (end = .);
4
> 
5
> 
6
>    .int_data :
7
>    {
8
>    *(.internal_ram_top)
9
>    }> STACK
10
> 
11
> 
12
> 
13
>   /* Stabs debugging sections.  */
14
> 
15
>
>
>
> 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

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