Estoy creando código para un ARM Cortex-M3 (LCP17xx de NXP). He estado usando memoria estática hasta ahora y todo funcionó bien. Intenté agregar compatibilidad con la memoria dinámica, pero una vez que llamé a malloc, el sistema se atascó.Uso de malloc de newlib en un ARM Cortex-M3
Estoy compilando con gcc para el brazo desnudo y usando newlib. Versión: gcc-arm-none-eabi-4_6-2012q1
Para agregar soporte malloc, implementé una función simple _sbrk y modifiqué mi script enlazador para hacer espacio para el montón (he leído muchos tutoriales diferentes sobre esto parte, pero ninguno cubre el problema que encontré después).
Con la ayuda de algunos leds, puedo estar seguro de que el código se ejecuta hasta el punto en que llama a malloc
, luego no se enciende. Ni siquiera alcanza mi función _sbrk
. Además, se bloqueará en una llamada al sizeof
, si incluyo una llamada al malloc
más adelante en el código.
Entonces, ¿qué puedo estar haciendo mal al llamar malloc
el código se bloquea sin llegar a _sbrk
o al volver?
Después de mirar durante un rato el mapa de memoria generado cuando se incluye la llamada malloc
y cuando no lo está, sospecho que está relacionado con las estructuras que usa malloc
.
Esta es la parte de la secuencia de comandos ld que define la memoria RAM:
.bss :
{
_start_bss = .;
*(.bss)
*(COMMON)
_ebss = .;
. = ALIGN (8);
_end = .;
} >sram
. = ALIGN(4);
_end_bss = .;
. = ALIGN(256);
_start_heap = .;
PROVIDE(__cs3_heap_start = _start_heap)
_end_stack = 0x10008000;
_end_stack se establece a continuación, en la tabla de vectores de interrupción.
Y ahora una comparación de los diferentes mapas. Sin utilizar malloc en el código:
*(COMMON)
0x1000000c _ebss = .
0x10000010 . = ALIGN (0x8)
*fill* 0x1000000c 0x4 00
0x10000010 _end = .
0x10000010 . = ALIGN (0x4)
0x10000010 _end_bss = .
0x10000100 . = ALIGN (0x100)
0x10000100 _start_heap = .
mapa de memoria usando malloc en el código:
*(COMMON)
COMMON 0x10000848 0x4 ...arm-none-eabi/lib/armv7-m/libc.a(lib_a-reent.o)
0x10000848 errno
0x1000084c _ebss = .
0x10000850 . = ALIGN (0x8)
*fill* 0x1000084c 0x4 00
0x10000850 _end = .
.bss.__malloc_max_total_mem
0x10000850 0x4
.bss.__malloc_max_total_mem
0x10000850 0x4 ...arm-none-eabi/lib/armv7-m/libc.a(lib_a-mallocr.o)
0x10000850 __malloc_max_total_mem
(...) It goes on (...)
0x1000085c __malloc_current_mallinfo
0x10000884 . = ALIGN (0x4)
0x10000884 _end_bss = .
0x10000900 . = ALIGN (0x100)
0x10000900 _start_heap = .
¿Estás seguro de que estás invocando el código de inicio correctamente, lo que inicializará las estructuras de montón? –
Obviamente estoy haciendo algo mal, el problema es que no sé LO QUE estoy haciendo mal. Agregué información adicional sobre los mapas de memoria, espero que ayude a encontrar el error. –
Un problema muy similar ocurre cuando se usa sprintf. Entonces no es solo un problema Malloc. Tiene que ver con todo el material newlib. Probablemente necesite un cambio en el script de enlace, aunque no puedo entender qué. –