向ARM MCU项目添加两个C++文件时.ELF太大

.ELF too big when adding two C++ files to ARM MCU project

本文关键字:C++ 两个 文件 太大 ELF MCU ARM 项目 添加      更新时间:2023-10-16

我正在为Atmel SAM3S1微控制器编写一些C++代码。我正在使用包含FreeRTOS库的ASF库。我写了一个简单而小的C++包装器(3.cpp文件),这样我就可以很容易地在我的设备类中继承它。

Atmel SAM(数据表)有64KB闪存和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++来编译和链接所有内容。

当我清除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文件:

主要.cpp

#include <asf.h>
#include <MMA8652.h>
extern "C" { 
  extern void vApplicationStackOverflowHook(xTaskHandle *pxTask,
          signed char *pcTaskName) {
  }
}

int main(void) {
  const taskConfig_t AccelTaskConfig = { "AccelRx", 3, 100 };
  MMA8652 Accelero(AccelTaskConfig);

    return(0);
}

任务.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

任务.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

根据我的计算,您的.text段大约为4k。

许多用于嵌入式系统的链接器应用程序都有一个命令或配置文件。配置文件告诉段的起始地址和大小。

您需要找到配置文件,并验证ROM部分的地址是否正确,容量是否正确。

config.mk内的OPTIMIZATION标志中尝试使用-Os而不是-O3;您也可以在编译和链接时使用-flto -Os(用于链接时间优化)

我终于修复了它!我添加了fno-rtti和fno异常,并重载了new、delete和destructor运算符。http://www.embedded.com/design/mcus-processors-and-socs/4007134/Building-Bare-Metal-ARM-Systems-with-GNU-Part-4.

不幸的是,我无法重载Task.h->action_helper()中使用的static_cast运算符。有人知道如何解决这个问题吗?

一般情况下:

  • 如果不使用fno异常,那么它是一个很好的开始方式
  • RTTI也可以关闭,但我认为它值得保留。这是一个非常强大的功能,成本最低
  • 重载new/delete是不必要的。如果您从不使用它并禁用异常,则可以通过LTO对其进行优化。只有在动态分配的情况下,您才需要担心它
  • 重载static_cast?它是"静态"的,因为它是编译时。没有理由让它超载,我不确定这是否可能
  • 尝试更改调试信息生成设置(gcc中的-g标志)
  • 尽可能优化尺寸。这使得调试非常困难

不要忘记,您的所有ASF源都是C,因此设置C工具链也是必要的。