РЕШЕНО. СМОТРИТЕ РАЗДЕЛ РЕШЕНИЯ НИЖЕ.
У меня проблема, когда моя среда сборки выводит большой двоичный файл, и я надеюсь, что кто-то поможет мне снова двигаться.
Я использую процессор STM32F105, компилятор Eclipse, FreeRTOS и CodeSourcery, чтобы попытаться запустить на этом устройстве некоторый оценочный код AHRS. У меня работает большая часть кода, но я столкнулся с проблемой при реализации раздела кода eval, который использует malloc для выделения памяти. Мне пришлось добавить код для _sbrk, чтобы он скомпилировался, и теперь мой двоичный файл увеличился с 35 КБ до почти 400 МБ. Я думаю, что это проблема компоновщика, так как файл .out (до objcopy) примерно того же размера. Даже файлы .s, выводимые из objdump, выглядят довольно сопоставимыми.
Вот некоторые (надеюсь) относящиеся к делу фрагменты:
MEMORY
{
RAM (RWX) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 128K
}
_estack = ORIGIN(RAM)+LENGTH(RAM);
SECTIONS
{
.text ORIGIN(FLASH):
{
*(.isr_vector)
*(.text)
*(.text.*)
*(.rodata)
_sidata = .;
}
.data ORIGIN(RAM):
AT (_sidata)
{
_sdata = . ;
*(.data)
_edata = . ;
}
.bss (_edata) (NOLOAD):
{
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
_ebss = . ;
. = ALIGN(4);
_end = .;
}
}
/* end of allocated ram _end */
PROVIDE( _HEAP_START = _end );
/* end of the heap -> align 4 byte */
PROVIDE ( _HEAP_END = ALIGN(ORIGIN(RAM) + LENGTH(RAM) - 4 ,4) );
Makefile:
BOOT = boot
RTOS = FreeRTOSSource
FREERTOS = $(RTOS)/port.c $(RTOS)/tasks.c $(RTOS)/croutine.c $(RTOS)/heap_2.c $(RTOS)/list.c $(RTOS)/queue.c
APP_SOURCE = app_source/sysmon.c app_source/hscan.c app_source/gps.c app_source/mems.c app_source/gpio.c app_source/mainstates.c app_source/leds.c app_source/database.c
INEMO_LIB = inemo/mems/LSM303DLH.c inemo/mems/L3GD20.c
OBJS = main.o \
$(BOOT)/core_cm3.o \
$(BOOT)/system_stm32f10x.o \
$(BOOT)/stm32f10x_rcc.o \
$(BOOT)/stm32f10x_gpio.o \
$(BOOT)/stm32f10x_can.o \
$(BOOT)/stm32f10x_iwdg.o \
$(BOOT)/stm32f10x_i2c.o \
$(BOOT)/startup.o \
$(BOOT)/mx_gpio.o \
$(FREERTOS:%.c=%.o) \
$(INEMO_LIB:%.c=%.o) \
$(APP_SOURCE:%.c=%.o)
CFLAGS = -O0 -gdwarf-2 -mcpu=cortex-m3 -mthumb -fno-common -I$(BOOT) -std=gnu99 -c -mfloat-abi=soft -Wall -g
LFLAGS = -mthumb -mcpu=cortex-m3 -Tscripts/stm32f103.ld -nostartfiles -lgcc -lm -lc -mfloat-abi=soft -Wall -g -O0
CPFLAGS = -O binary
TARGET = arm-none-eabi
#TARGET = arm-elf
CC = $(TARGET)-gcc
LD = $(TARGET)-gcc
CP = $(TARGET)-objcopy
OD = $(TARGET)-objdump
all: version $(OBJS) link
$(BOOT)/startup.o:
$(CC) $(CFLAGS) $(BOOT)/startup_stm32f10x_cl.s -lm -lc -lnosys -o $@
%.o: %.c
$(CC) $(CFLAGS) $< -o $@
version:
$(CC) --version
link: $(OBJS)
$(LD) -o main.out $(OBJS) $(LFLAGS)
$(CP) $(CPFLAGS) main.out main.bin
$(OD) -D -h main.out > main.S
clean:
rm -rf $(OBJS) main.bin main.out main.S
Добавление этого кода плюс вызов malloc приводит к увеличению двоичного файла почти до 400 МБ:
#include <sys/types.h>
extern unsigned int _HEAP_START;
caddr_t * _sbrk(int incr) {
static unsigned char *heap = NULL;
unsigned char *prev_heap;
if (heap == NULL) {
heap = (unsigned char *)_HEAP_START;
}
prev_heap = heap;
heap += incr;
return (caddr_t) prev_heap;
}
Есть мысли о том, как снова двигаться? Спасибо за любую помощь, которую вы можете оказать!
РЕШЕНИЕ
Из комментариев Notlikethat я увидел, что в процессе сборки создается еще один раздел кода, но в сценарии компоновщика не было раздела с таким же именем. Компоновщик решил поместить этот раздел в RAM, тогда как он должен был поместить его во FLASH. Поскольку он занимал RAM и FLASH, файл bin заполнял область между ними, создавая большой двоичный файл. Добавление следующей строки в сценарий компоновщика (в разделе FLASH) позволило снова построить код с нормальным размером.
*(.rodata.str1.4)
Новый полный скрипт компоновщика выглядит так:
MEMORY
{
RAM (RWX) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 128K
}
_estack = ORIGIN(RAM)+LENGTH(RAM);
SECTIONS
{
.text ORIGIN(FLASH):
{
*(.isr_vector)
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.str1.4)
_sidata = .;
}
.data ORIGIN(RAM):
AT (_sidata)
{
_sdata = . ;
*(.data)
_edata = . ;
}
.bss (_edata) (NOLOAD):
{
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
_ebss = . ;
. = ALIGN(4);
_end = .;
}
}
/* end of allocated ram _end */
PROVIDE( _HEAP_START = _end );
/* end of the heap -> align 4 byte */
PROVIDE ( _HEAP_END = ALIGN(ORIGIN(RAM) + LENGTH(RAM) - 4 ,4) );
Спасибо за помощь!
*(.rodata.str1.4)
как*(.rodata.*)
, чтобы охватить любые другие неожиданные разделы данных только для чтения, которые могут появиться, когда вы поддерживаете код. Я также поинтересовался, не стоит ли включать*(.data.*)
сразу после*(.data)
для подобного упрочнения. Но, по крайней мере, вы знаете, что ваши инструменты могут иногда создавать разделы с интересными названиями, которые необходимо учитывать в сценарии компоновщика. - person RBerteig   schedule 13.02.2015