.ELF слишком велик при добавлении двух файлов C++ в проект ARM MCU
Я пытаюсь написать код на C++ для микроконтроллера Atmel SAM3S1. Я использую библиотеку ASF с включенной библиотекой FreeRTOS. Я написал простую и маленькую оболочку C++ (3 файла.cpp), чтобы легко унаследовать ее в своих классах устройств.
Atmel SAM ( таблица данных) имеет 64KB Flash и 16KB RAM, что, я думаю, более чем достаточно. хотя, когда я начинаю компилировать, я получаю сообщение:
section `.text' will not fit in region `rom'
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld: region `rom' overflowed by 13120 bytes
Я использую arm-none-eabi-g++ для компиляции и компоновки всего.
Когда я очищаю объявленный Class в Main.cpp, размеры просто нормальные, поэтому я думаю, что это как-то связано с C++. Может кто-нибудь объяснить мне, что я здесь делаю не так?
Test.elf :
section size addr
.text 0x102c 0x400000
.ARM.exidx 0x8 0x40102c
.relocate 0x844 0x20000000
.bss 0x154 0x20000844
.stack 0x2000 0x20000998
.ARM.attributes 0x29 0x0
.comment 0x70 0x0
.debug_info 0x57d1 0x0
.debug_abbrev 0x1058 0x0
.debug_aranges 0x430 0x0
.debug_ranges 0xb00 0x0
.debug_macro 0xf50a 0x0
.debug_line 0x5024 0x0
.debug_str 0x46ec7 0x0
.debug_frame 0xe04 0x0
.debug_loc 0x31f1 0x0
Total 0x6a5a8
text data bss dec hex filename
0x1034 0x844 0x2154 14796 39cc Test.elf
Это мои файлы CPP:
main.cpp
#include <asf.h>
#include <MMA8652.h>
extern "C" {
extern void vApplicationStackruHook(xTaskHandle *pxTask,
signed char *pcTaskName) {
}
}
int main(void) {
const taskConfig_t AccelTaskConfig = { "AccelRx", 3, 100 };
MMA8652 Accelero(AccelTaskConfig);
return(0);
}
Task.h
//#ifndef TASK_H
//#define TASK_H
#include <inttypes.h>
typedef struct {
char *taskName;
uint8_t priority;
uint16_t stackSize;
} taskConfig_t;
class Task {
private:
public:
Task(char *taskName, uint8_t priority, uint16_t stackSize);
~Task();
friend void run_helper(void *arg) {
return static_cast<Task*>(arg)->run();
}
virtual void run(void) const = 0;
protected:
};
//#endif
Task.cpp
#include <Task.h>
#include <asf.h>
void run_helper(void *arg);
Task::Task( char *taskName,
uint8_t priority,
uint16_t stackSize ) {
// check for minimal stacksize
if(stackSize < configMINIMAL_STACK_SIZE) {
stackSize = configMINIMAL_STACK_SIZE;
}
// check priority val
if(priority > configMAX_PRIORITIES) {
priority = configMAX_PRIORITIES;
}
// create a new FreeRTOS task with func ptr to run() member
xTaskCreate( &run_helper, (const signed char *) taskName,
stackSize, (Task*)this, priority, NULL);
}
MMA8652.h
#ifndef MMA8652_H
#define MMA8652_H
#include <Task.h>
class MMA8652: public Task {
private:
public:
void run(void) const;
MMA8652(const taskConfig_t &tConfig);
~MMA8652(void);
};
#endif // MMA8652_H
MMA8652.cpp
#include <asf.h>
#include <MMA8652.h>
MMA8652::MMA8652(const taskConfig_t &tConfig) :
Task(tConfig.taskName, tConfig.priority, tConfig.stackSize) {
}
void MMA8652::run(void) const {
pio_set_pin_high(TESTLED_GPIO);
vTaskDelay(1000);
pio_set_pin_low(TESTLED_GPIO);
vTaskDelay(1000);
}
linker_script.ld
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
/* Memory Spaces Definitions */
MEMORY
{
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00010000 /* Flash, 64K */
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000 /* sram, 16K */
}
/* The stack size used by the application. NOTE: you need to adjust */
__stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 0x2000;
__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;
/* Section Definitions */
SECTIONS
{
.text :
{
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors .vectors.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
*(.ARM.extab* .gnu.linkonce.armextab.*)
/* Support C constructors, and C destructors in both user code
and the C library. This also provides support for C++ code. */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
_efixed = .; /* End of text section */
} > rom
/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
PROVIDE_HIDDEN (__exidx_end = .);
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = . ;
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
_ezero = .;
} > ram
/* stack section */
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + __stack_size__;
. = ALIGN(8);
_estack = .;
} > ram
. = ALIGN(4);
_end = . ;
}
config.mk
# Path to top level ASF directory relative to this project directory.
PRJ_PATH = ASF
# Target CPU architecture: cortex-m3, cortex-m4
ARCH = cortex-m3
# Target part: none, sam3n4 or sam4l4aa
PART = sam3s1ab
# Application target name. Given with suffix .a for library and .elf for a
# standalone application.
TARGET_FLASH = $(PRJ_NAME).elf
TARGET_SRAM = $(PRJ_NAME).elf
# List of C source files.
CSRCS = \
Main.cpp \
lib/Task.cpp \
devices/MMA8652.cpp \
sam/boards/Board/init.c \
common/services/clock/sam3s/sysclk.c \
common/utils/interrupt/interrupt_sam_nvic.c \
common/utils/stdio/read.c \
common/utils/stdio/write.c \
sam/drivers/pio/pio.c \
sam/drivers/pio/pio_handler.c \
sam/drivers/pmc/pmc.c \
sam/drivers/pmc/sleep.c \
sam/utils/cmsis/sam3s/source/templates/exceptions.c \
sam/utils/cmsis/sam3s/source/templates/gcc/startup_sam3s.c \
sam/utils/cmsis/sam3s/source/templates/system_sam3s.c \
sam/utils/syscalls/gcc/syscalls.c \
thirdparty/freertos/freertos-7.0.0/source/croutine.c \
thirdparty/freertos/freertos-7.0.0/source/list.c \
thirdparty/freertos/freertos-7.0.0/source/portable/gcc/sam/port.c \
thirdparty/freertos/freertos-7.0.0/source/portable/memmang/heap_3.c \
thirdparty/freertos/freertos-7.0.0/source/queue.c \
thirdparty/freertos/freertos-7.0.0/source/tasks.c \
thirdparty/freertos/freertos-7.0.0/source/timers.c
# List of assembler source files.
ASSRCS =
# List of include paths.
INC_PATH = \
../lib/include \
../devices/include \
../config \
../ \
common/services/clock \
common/boards \
common/services/gpio \
common/services/ioport \
common/utils \
sam/drivers/pio \
sam/drivers/pmc \
sam/utils \
sam/utils/cmsis/sam3s/include \
sam/utils/cmsis/sam3s/source/templates \
sam/utils/header_files \
sam/utils/preprocessor \
thirdparty/CMSIS/Include \
thirdparty/CMSIS/Lib/GCC \
thirdparty/freertos/freertos-7.0.0/source/include \
thirdparty/freertos/freertos-7.0.0/source/portable/gcc/sam \
# Additional search paths for libraries.
LIB_PATH = \
thirdparty/CMSIS/Lib/GCC
# List of libraries to use during linking.
LIBS =
# Path relative to top level directory pointing to a linker script.
LINKER_SCRIPT_FLASH = sam/utils/linker_scripts/sam3s/sam3s1/gcc/flash.ld
LINKER_SCRIPT_SRAM = sam/utils/linker_scripts/sam3s/sam3s1/gcc/sram.ld
# Project type parameter: all, sram or flash
PROJECT_TYPE = flash
# Additional options for debugging. By default the common Makefile.in will
# add -g3.
DBGFLAGS =
# Application optimization used during compilation and linking:
# -O0, -O1, -O2, -O3 or -Os
OPTIMIZATION = -O3
# Extra flags to use when archiving.
ARFLAGS =
# Extra flags to use when assembling.
ASFLAGS =
# Extra flags to use when compiling.
CFLAGS =
# Extra flags to use when preprocessing.
#
# Preprocessor symbol definitions
# To add a definition use the format "-D name[=definition]".
# To cancel a definition use the format "-U name".
#
# The most relevant symbols to define for the preprocessor are:
# BOARD Target board in use, see boards/board.h for a list.
# EXT_BOARD Optional extension board in use, see boards/board.h for a list.
CPPFLAGS = \
-D __FREERTOS__ \
-D __SAM3S1B__ \
-D BOARD=BOARD \
-D printf=iprintf \
-D scanf=iscanf
# Extra flags to use when linking
LDFLAGS = \
# Pre- and post-build commands
PREBUILD_CMD =
POSTBUILD_CMD =
Makefile.sam.in
include config.mk
# Tool to use to generate documentation from the source code
DOCGEN ?= doxygen
# Look for source files relative to the top-level source directory
VPATH := $(PRJ_PATH)
# Output target file
project_type := $(PROJECT_TYPE)
# Output target file
ifeq ($(project_type),flash)
target := $(TARGET_FLASH)
linker_script := $(PRJ_PATH)/$(LINKER_SCRIPT_FLASH)
debug_script := $(PRJ_PATH)/$(DEBUG_SCRIPT_FLASH)
else
target := $(TARGET_SRAM)
linker_script := $(PRJ_PATH)/$(LINKER_SCRIPT_SRAM)
debug_script := $(PRJ_PATH)/$(DEBUG_SCRIPT_SRAM)
endif
# Output project name (target name minus suffix)
project := $(basename $(target))
# Output target file (typically ELF or static library)
ifeq ($(suffix $(target)),.a)
target_type := lib
else
ifeq ($(suffix $(target)),.elf)
target_type := elf
else
$(error "Target type $(target_type) is not supported")
endif
endif
# Allow override of operating system detection. The user can add OS=Linux or
# OS=Windows on the command line to explicit set the host OS.
#
# This allows to work around broken uname utility on certain systems.
ifdef OS
ifeq ($(strip $(OS)), Linux)
os_type := Linux
endif
ifeq ($(strip $(OS)), Windows)
os_type := windows32_64
endif
endif
os_type ?= $(strip $(shell uname))
ifeq ($(os_type),windows32)
os := Windows
else
ifeq ($(os_type),windows64)
os := Windows
else
ifeq ($(os_type),windows32_64)
os ?= Windows
else
ifeq ($(os_type),)
os := Windows
else
# Default to Linux style operating system. Both Cygwin and mingw are fully
# compatible (for this Makefile) with Linux.
os := Linux
endif
endif
endif
endif
# Output documentation directory and configuration file.
docdir := ../doxygen/html
doccfg := ../doxygen/doxyfile.doxygen
CROSS ?= arm-none-eabi-
AR := $(CROSS)ar
AS := $(CROSS)as
CC := $(CROSS)gcc
CPP := $(CROSS)gcc -E
CXX := $(CROSS)g++
LD := $(CROSS)g++
NM := $(CROSS)nm
OBJCOPY := $(CROSS)objcopy
OBJDUMP := $(CROSS)objdump
SIZE := $(CROSS)size
GDB := $(CROSS)gdb
RM := rm
ifeq ($(os),Windows)
RMDIR := rmdir /S /Q
else
RMDIR := rmdir -p --ignore-fail-on-non-empty
endif
# On Windows, we need to override the shell to force the use of cmd.exe
ifeq ($(os),Windows)
SHELL := cmd
endif
# Strings for beautifying output
MSG_CLEAN_FILES = "RM *.o *.d"
MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))"
MSG_CLEAN_DOC = "RMDIR $(docdir)"
MSG_MKDIR = "MKDIR $(dir $@)"
MSG_INFO = "INFO "
MSG_PREBUILD = "PREBUILD $(PREBUILD_CMD)"
MSG_POSTBUILD = "POSTBUILD $(POSTBUILD_CMD)"
MSG_ARCHIVING = "AR $@"
MSG_ASSEMBLING = "AS $@"
MSG_BINARY_IMAGE = "OBJCOPY $@"
MSG_COMPILING = "CC $@"
MSG_COMPILING_CXX = "CXX $@"
MSG_EXTENDED_LISTING = "OBJDUMP $@"
MSG_IHEX_IMAGE = "OBJCOPY $@"
MSG_LINKING = "LN $@"
MSG_PREPROCESSING = "CPP $@"
MSG_SIZE = "SIZE $@"
MSG_SYMBOL_TABLE = "NM $@"
MSG_GENERATING_DOC = "DOXYGEN $(docdir)"
# Don't use make's built-in rules and variables
MAKEFLAGS += -rR
# Don't print 'Entering directory ...'
MAKEFLAGS += --no-print-directory
# Function for reversing the order of a list
reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
# Hide command output by default, but allow the user to override this
# by adding V=1 on the command line.
#
# This is inspired by the Kbuild system used by the Linux kernel.
ifdef V
ifeq ("$(origin V)", "command line")
VERBOSE = $(V)
endif
endif
ifndef VERBOSE
VERBOSE = 0
endif
ifeq ($(VERBOSE), 1)
Q =
else
Q = @
endif
arflags-gnu-y := $(ARFLAGS)
asflags-gnu-y := $(ASFLAGS)
cflags-gnu-y := $(CFLAGS)
cxxflags-gnu-y := $(CXXFLAGS)
cppflags-gnu-y := $(CPPFLAGS)
cpuflags-gnu-y :=
dbgflags-gnu-y := $(DBGFLAGS)
libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB))
ldflags-gnu-y := $(LDFLAGS)
flashflags-gnu-y :=
clean-files :=
clean-dirs :=
clean-files += $(wildcard $(target) $(project).map)
clean-files += $(wildcard $(project).hex $(project).bin)
clean-files += $(wildcard $(project).lss $(project).sym)
clean-files += $(wildcard $(build))
# Use pipes instead of temporary files for communication between processes
cflags-gnu-y += -pipe
asflags-gnu-y += -pipe
ldflags-gnu-y += -pipe
# Archiver flags.
arflags-gnu-y += rcs
# Always enable warnings. And be very careful about implicit
# declarations.
cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes
cflags-gnu-y += -Werror-implicit-function-declaration
cxxflags-gnu-y += -Wall
# IAR doesn't allow arithmetic on void pointers, so warn about that.
cflags-gnu-y += -Wpointer-arith
cxxflags-gnu-y += -Wpointer-arith
# Preprocessor flags.
cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC))
asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)')
# CPU specific flags.
cpuflags-gnu-y += -mcpu=$(ARCH) -mthumb -D=__$(PART)__
# Dependency file flags.
depflags = -MD -MP -MQ $@
# Debug specific flags.
ifdef BUILD_DEBUG_LEVEL
dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL)
else
dbgflags-gnu-y += -g3
endif
# Optimization specific flags.
ifdef BUILD_OPTIMIZATION
optflags-gnu-y = -O$(BUILD_OPTIMIZATION)
else
optflags-gnu-y = $(OPTIMIZATION)
endif
# Always preprocess assembler files.
asflags-gnu-y += -x assembler-with-cpp
# Compile C files using the GNU99 standard.
cflags-gnu-y += -std=gnu99
# Compile C++ files using the GNU++98 standard.
cxxflags-gnu-y += -std=gnu++98
# Don't use strict aliasing (very common in embedded applications).
cflags-gnu-y += -fno-strict-aliasing
cxxflags-gnu-y += -fno-strict-aliasing
# Separate each function and data into its own separate section to allow
# garbage collection of unused sections.
cflags-gnu-y += -ffunction-sections -fdata-sections
cxxflags-gnu-y += -ffunction-sections -fdata-sections
# Various cflags.
cflags-gnu-y += -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int
cflags-gnu-y += -Wmain -Wparentheses
cflags-gnu-y += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused
cflags-gnu-y += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef
cflags-gnu-y += -Wshadow -Wbad-function-cast -Wwrite-strings
cflags-gnu-y += -Wsign-compare -Waggregate-return
cflags-gnu-y += -Wmissing-declarations
cflags-gnu-y += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
cflags-gnu-y += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long
cflags-gnu-y += -Wunreachable-code
cflags-gnu-y += -Wcast-align
cflags-gnu-y += --param max-inline-insns-single=500
# Garbage collect unreferred sections when linking.
ldflags-gnu-y += -Wl,--gc-sections
# Use the linker script if provided by the project.
ifneq ($(strip $(linker_script)),)
ldflags-gnu-y += -Wl,-T $(linker_script)
endif
# Output a link map file and a cross reference table
ldflags-gnu-y += -Wl,-Map=$(project).map,--cref
# Add library search paths relative to the top level directory.
ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH))
a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__
c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y)
cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y)
l_flags = -Wl,--entry=Reset_Handler -Wl,--cref $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y)
ar_flags = $(arflags-gnu-y)
# Source files list and part informations must already be included before
# running this makefile
# If a custom build directory is specified, use it -- force trailing / in directory name.
ifdef BUILD_DIR
build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/)
else
build-dir =
endif
# Create object files list from source files list.
obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS))))
# Create dependency files list from source files list.
dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d))
clean-files += $(wildcard $(obj-y))
clean-files += $(dep-files)
clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y)))))
# Default target.
.PHONY: all
ifeq ($(project_type),all)
all:
$(MAKE) all PROJECT_TYPE=flash
$(MAKE) all PROJECT_TYPE=sram
else
ifeq ($(target_type),lib)
all: $(target) $(project).lss $(project).sym
else
ifeq ($(target_type),elf)
all: prebuild $(target) $(project).lss $(project).sym $(project).hex $(project).bin postbuild
endif
endif
endif
prebuild:
ifneq ($(strip $(PREBUILD_CMD)),)
@echo $(MSG_PREBUILD)
$(Q)$(PREBUILD_CMD)
endif
postbuild:
ifneq ($(strip $(POSTBUILD_CMD)),)
@echo $(MSG_POSTBUILD)
$(Q)$(POSTBUILD_CMD)
endif
# Clean up the project.
.PHONY: clean
clean:
@$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES))
$(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),)
@$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS))
# Remove created directories, and make sure we only remove existing
# directories, since recursive rmdir might help us a bit on the way.
ifeq ($(os),Windows)
$(Q)$(if $(strip $(clean-dirs)), \
$(RMDIR) $(strip $(subst /,\,$(clean-dirs))))
else
$(Q)$(if $(strip $(clean-dirs)), \
for directory in $(strip $(clean-dirs)); do \
if [ -d "$$directory" ]; then \
$(RMDIR) $$directory; \
fi \
done \
)
endif
# Rebuild the project.
.PHONY: rebuild
rebuild: clean all
# Debug the project in flash.
.PHONY: debug_flash
debug_flash: all
$(GDB) -x "$(PRJ_PATH)/$(DEBUG_SCRIPT_FLASH)" -ex "reset" -readnow -se $(TARGET_FLASH)
# Debug the project in sram.
.PHONY: debug_sram
debug_sram: all
$(GDB) -x "$(PRJ_PATH)/$(DEBUG_SCRIPT_SRAM)" -ex "reset" -readnow -se $(TARGET_SRAM)
.PHONY: objfiles
objfiles: $(obj-y)
# Create object files from C source files.
$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
ifeq ($(os),Windows)
$(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@))
else
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
endif
@echo $(MSG_COMPILING)
$(Q)$(CC) $(c_flags) -c $< -o $@
# Create object files from C++ source files.
$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
ifeq ($(os),Windows)
$(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@))
else
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
endif
@echo $(MSG_COMPILING_CXX)
$(Q)$(CXX) $(cxx_flags) -c $< -o $@
# Preprocess and assemble: create object files from assembler source files.
$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
ifeq ($(os),Windows)
$(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@))
else
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
endif
@echo $(MSG_ASSEMBLING)
$(Q)$(CC) $(a_flags) -c $< -o $@
# Include all dependency files to add depedency to all header files in use.
include $(dep-files)
ifeq ($(target_type),lib)
# Archive object files into an archive
$(target): $(MAKEFILE_PATH) config.mk $(obj-y)
@echo $(MSG_ARCHIVING)
$(Q)$(AR) $(ar_flags) $@ $(obj-y)
@echo $(MSG_SIZE)
$(Q)$(SIZE) -Bxt $@
else
ifeq ($(target_type),elf)
# Link the object files into an ELF file. Also make sure the target is rebuilt
# if the common Makefile.sam.in or project config.mk is changed.
$(target): $(linker_script) $(MAKEFILE_PATH) config.mk $(obj-y)
@echo $(MSG_LINKING)
$(Q)$(LD) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@
@echo $(MSG_SIZE)
$(Q)$(SIZE) -Ax $@
$(Q)$(SIZE) -Bx $@
endif
endif
# Create extended function listing from target output file.
%.lss: $(target)
@echo $(MSG_EXTENDED_LISTING)
$(Q)$(OBJDUMP) -h -S $< > $@
# Create symbol table from target output file.
%.sym: $(target)
@echo $(MSG_SYMBOL_TABLE)
$(Q)$(NM) -n $< > $@
# Create Intel HEX image from ELF output file.
%.hex: $(target)
@echo $(MSG_IHEX_IMAGE)
$(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@
# Create binary image from ELF output file.
%.bin: $(target)
@echo $(MSG_BINARY_IMAGE)
$(Q)$(OBJCOPY) -O binary $< $@
# Provide information about the detected host operating system.
.SECONDARY: info-os
info-os:
@echo $(MSG_INFO)$(os) build host detected
# Build Doxygen generated documentation.
.PHONY: doc
doc:
@echo $(MSG_GENERATING_DOC)
$(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg))
# Clean Doxygen generated documentation.
.PHONY: cleandoc
cleandoc:
@$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC))
$(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir))
# Rebuild the Doxygen generated documentation.
.PHONY: rebuilddoc
rebuilddoc: cleandoc doc
4 ответа
Согласно моим расчетам, ваш .text
Сегмент около 4к.
Многие приложения компоновщика для встроенных систем имеют командный или конфигурационный файл. Файл конфигурации сообщает начальные адреса сегментов и размер.
Вам нужно будет найти файл конфигурации и убедиться, что раздел ПЗУ находится по правильному адресу и имеет правильную емкость.
Я наконец исправил это! я добавил fno-rtti и fno-exception и перегрузил оператор new, delete и destructor. http://www.embedded.com/design/mcus-processors-and-socs/4007134/Building-Bare-Metal-ARM-Systems-with-GNU-Part-4.
К сожалению, я не могу перегрузить оператор static_cast, используемый в Task.h->action_helper() . Кто-нибудь знает как это решить?
Попробуй с -Os
вместо -O3
в OPTIMIZATION
флаг внутри config.mk
; Вы также можете использовать -flto -Os
как при компиляции, так и при компоновке (для оптимизации времени компоновки)
В общем:
- fno-exception - хороший способ начать, если вы его не используете.
- RTTI тоже можно отключить, но я думаю, что стоит сохранить. Это действительно мощная функция с минимальными затратами.
- Перегрузка new / delete не нужна. Если вы никогда не используете его и отключаете исключения, он может быть оптимизирован с помощью LTO. Вы должны беспокоиться об этом, только если вы выделяете динамически.
- перегрузка static_cast? Это "статично", потому что это время компиляции. Нет причин перегружать его, я не уверен, возможно ли это вообще.
- попробуйте изменить параметры генерации отладочной информации (-g flags в gcc)
- оптимизировать по размеру, если это возможно. Это делает отладку очень сложной.
Не забывайте, что все ваши ASF-источники - C, так что настройка C-toolchain также необходима.