2015-05-29 117 views
1

我正在将Codesourcery Codebench Lite for ARM EABI gcc(v4.7.2)中的编译器更改为arm GCC 2014 q1(v4.8.3),并且遇到问题在我的程序链接器文件中定义的某些内存地址的位置。该芯片是STM32F103RBT6。Cortex-M3链接_sidata位置不正确

重置处理程序函数是第一个调用的函数,它试图将数据段初始化程序从闪存复制到SRAM。下面的代码被执行:

void Reset_Handler(void) 
{ 
    unsigned long *pulSrc, *pulDest; 

    // 
    // Copy the data segment initializers from flash to SRAM. 
    // 
    pulSrc = &_sidata; 
    for(pulDest = &_sdata; pulDest < &_edata;) 
    { 
     *(pulDest++) = *(pulSrc++); 
    } 

    // 
    // Zero fill the bss segment. 
    // 
    for(pulDest = &_sbss; pulDest < &_ebss;) 
    { 
     *(pulDest++) = 0; 
    } 

    __libc_init_array(); 

    // 
    // Call the application's entry point. 
    // 
    main(); 
} 

存储器定义如下:

MEMORY 
{ 
     RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K /* also change _estack below */ 
     FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K 
} 

在程序的原始(工作)版本_sidata值被定义为0x8008400但该值发生变化时,我编译使用具有相同链接器脚本的新编译器。由于这个问题,该设备是严重错误的。我可以将这些值硬编码到重置处理程序中,并且代码执行得很好,所以这只是这些部分的一个问题,据我所知。我怎样才能确保这些地址是正确的,即使链接脚本没有被改变,它们为什么会改变?

stm32.ld:

/* 
Linker script for STM32F10x 
Copyright RAISONANCE 2007 (modified by Lanchon 1-Feb-2008) 
You can use, copy and distribute this file freely, but without any waranty. 
Configure memory sizes, end of stack and boot mode for your project here. 
*/ 


/* include the common STM32F10x sub-script */ 
INCLUDE "STM32_COMMON.ld" 

/* Memory Spaces Definitions */ 
MEMORY 
{ 
    RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K /* also change _estack below */ 
    FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K 
} 

/* highest address of the user mode stack */ 
_estack = 0x20005000; 

/* include the section management sub-script */ 
/* (either "STM32_SEC_FLASH.ld" or "STM32_SEC_RAM.ld") */ 
INCLUDE "STM32_SEC_FLASH.ld" 

STM32_COMMON.ld:

/* 
Common part of the linker scripts for STR32 devices 
Copyright RAISONANCE 2007 
You can use, modify and distribute thisfile freely, but without any waranty. 
*/ 


/* default stack sizes. 

These are used by the startup in order to allocate stacks for the different modes. 
*/ 

__Stack_Size = 2048 ; 

PROVIDE (_Stack_Size = __Stack_Size) ; 

__Stack_Init = _estack - __Stack_Size ; 

/*"PROVIDE" allows to easily override these values from an object file or the commmand line.*/ 
PROVIDE (_Stack_Init = __Stack_Init) ; 

/* 
There will be a link error if there is not this amount of RAM free at the end. 
*/ 
_Minimum_Stack_Size = 0x800 ; 



/* 
this sends all unreferenced IRQHandlers to reset 
*/ 


PROVIDE ( Undefined_Handler = 0) ; 
PROVIDE ( SWI_Handler = 0) ; 
PROVIDE ( IRQ_Handler = 0) ; 
PROVIDE ( Prefetch_Handler = 0) ; 
PROVIDE ( Abort_Handler = 0) ; 
PROVIDE ( FIQ_Handler = 0) ; 

PROVIDE ( NMIException = 0) ; 
PROVIDE ( HardFaultException = 0) ; 
PROVIDE ( MemManageException = 0) ; 
PROVIDE ( BusFaultException = 0) ; 
PROVIDE ( UsageFaultException = 0) ; 
/* PROVIDE ( SVCHandler = 0) ; */ 
PROVIDE ( DebugMonitor = 0) ; 
/* PROVIDE ( PendSVC = 0) ; */ 
/* PROVIDE ( SysTickHandler = 0) ; */ 
PROVIDE ( WWDG_IRQHandler = 0) ; 
PROVIDE ( PVD_IRQHandler = 0) ; 
PROVIDE ( TAMPER_IRQHandler = 0) ; 
PROVIDE ( RTC_IRQHandler = 0) ; 
PROVIDE ( FLASH_IRQHandler = 0) ; 
PROVIDE ( RCC_IRQHandler = 0) ; 
PROVIDE ( EXTI0_IRQHandler = 0) ; 
PROVIDE ( EXTI1_IRQHandler = 0) ; 
PROVIDE ( EXTI2_IRQHandler = 0) ; 
PROVIDE ( EXTI3_IRQHandler = 0) ; 
PROVIDE ( EXTI4_IRQHandler = 0) ; 
PROVIDE ( DMAChannel1_IRQHandler = 0) ; 
PROVIDE ( DMAChannel2_IRQHandler = 0) ; 
PROVIDE ( DMAChannel3_IRQHandler = 0) ; 
PROVIDE ( DMAChannel4_IRQHandler = 0) ; 
PROVIDE ( DMAChannel5_IRQHandler = 0) ; 
PROVIDE ( DMAChannel6_IRQHandler = 0) ; 
PROVIDE ( DMAChannel7_IRQHandler = 0) ; 
PROVIDE ( ADC_IRQHandler = 0) ; 
PROVIDE ( USB_HP_CAN_TX_IRQHandler = 0) ; 
PROVIDE ( USB_LP_CAN_RX0_IRQHandler = 0) ; 
PROVIDE ( CAN_RX1_IRQHandler = 0) ; 
PROVIDE ( CAN_SCE_IRQHandler = 0) ; 
PROVIDE ( EXTI9_5_IRQHandler = 0) ; 
PROVIDE ( TIM1_BRK_IRQHandler = 0) ; 
PROVIDE ( TIM1_UP_IRQHandler = 0) ; 
PROVIDE ( TIM1_TRG_COM_IRQHandler = 0) ; 
PROVIDE ( TIM1_CC_IRQHandler = 0) ; 
PROVIDE ( TIM2_IRQHandler = 0) ; 
PROVIDE ( TIM3_IRQHandler = 0) ; 
PROVIDE ( TIM4_IRQHandler = 0) ; 
PROVIDE ( I2C1_EV_IRQHandler = 0) ; 
PROVIDE ( I2C1_ER_IRQHandler = 0) ; 
PROVIDE ( I2C2_EV_IRQHandler = 0) ; 
PROVIDE ( I2C2_ER_IRQHandler = 0) ; 
PROVIDE ( SPI1_IRQHandler = 0) ; 
PROVIDE ( SPI2_IRQHandler = 0) ; 
PROVIDE ( USART1_IRQHandler = 0) ; 
PROVIDE ( USART2_IRQHandler = 0) ; 
PROVIDE ( USART3_IRQHandler = 0) ; 
PROVIDE ( EXTI15_10_IRQHandler = 0) ; 
PROVIDE ( RTCAlarm_IRQHandler = 0) ; 
PROVIDE ( USBWakeUp_IRQHandler = 0) ; 



/******************************************************************************/ 
/*      Peripheral memory map        */ 
/******************************************************************************/ 
/*this allows to compile the ST lib in "non-debug" mode*/ 


/* Peripheral and SRAM base address in the alias region */ 
PERIPH_BB_BASE  = 0x42000000; 
SRAM_BB_BASE   = 0x22000000; 

/* Peripheral and SRAM base address in the bit-band region */ 
SRAM_BASE    = 0x20000000; 
PERIPH_BASE   = 0x40000000; 

/* Flash registers base address */ 
PROVIDE (FLASH_BASE   = 0x40022000); 
/* Flash Option Bytes base address */ 
PROVIDE (OB_BASE    = 0x1FFFF800); 

/* Peripheral memory map */ 
APB1PERIPH_BASE  = PERIPH_BASE ; 
APB2PERIPH_BASE  = (PERIPH_BASE + 0x10000) ; 
AHBPERIPH_BASE  = (PERIPH_BASE + 0x20000) ; 

PROVIDE (TIM2   = (APB1PERIPH_BASE + 0x0000)) ; 
PROVIDE (TIM3   = (APB1PERIPH_BASE + 0x0400)) ; 
PROVIDE (TIM4   = (APB1PERIPH_BASE + 0x0800)) ; 
PROVIDE (RTC    = (APB1PERIPH_BASE + 0x2800)) ; 
PROVIDE (WWDG   = (APB1PERIPH_BASE + 0x2C00)) ; 
PROVIDE (IWDG   = (APB1PERIPH_BASE + 0x3000)) ; 
PROVIDE (SPI2   = (APB1PERIPH_BASE + 0x3800)) ; 
PROVIDE (USART2   = (APB1PERIPH_BASE + 0x4400)) ; 
PROVIDE (USART3   = (APB1PERIPH_BASE + 0x4800)) ; 
PROVIDE (I2C1   = (APB1PERIPH_BASE + 0x5400)) ; 
PROVIDE (I2C2   = (APB1PERIPH_BASE + 0x5800)) ; 
PROVIDE (CAN    = (APB1PERIPH_BASE + 0x6400)) ; 
PROVIDE (BKP    = (APB1PERIPH_BASE + 0x6C00)) ; 
PROVIDE (PWR    = (APB1PERIPH_BASE + 0x7000)) ; 

PROVIDE (AFIO   = (APB2PERIPH_BASE + 0x0000)) ; 
PROVIDE (EXTI   = (APB2PERIPH_BASE + 0x0400)) ; 
PROVIDE (GPIOA   = (APB2PERIPH_BASE + 0x0800)) ; 
PROVIDE (GPIOB   = (APB2PERIPH_BASE + 0x0C00)) ; 
PROVIDE (GPIOC   = (APB2PERIPH_BASE + 0x1000)) ; 
PROVIDE (GPIOD   = (APB2PERIPH_BASE + 0x1400)) ; 
PROVIDE (GPIOE   = (APB2PERIPH_BASE + 0x1800)) ; 
PROVIDE (ADC1   = (APB2PERIPH_BASE + 0x2400)) ; 
PROVIDE (ADC2   = (APB2PERIPH_BASE + 0x2800)) ; 
PROVIDE (TIM1   = (APB2PERIPH_BASE + 0x2C00)) ; 
PROVIDE (SPI1   = (APB2PERIPH_BASE + 0x3000)) ; 
PROVIDE (USART1   = (APB2PERIPH_BASE + 0x3800)) ; 

PROVIDE (DMA    = (AHBPERIPH_BASE + 0x0000)) ; 
PROVIDE (DMA_Channel1 = (AHBPERIPH_BASE + 0x0008)) ; 
PROVIDE (DMA_Channel2 = (AHBPERIPH_BASE + 0x001C)) ; 
PROVIDE (DMA_Channel3 = (AHBPERIPH_BASE + 0x0030)) ; 
PROVIDE (DMA_Channel4 = (AHBPERIPH_BASE + 0x0044)) ; 
PROVIDE (DMA_Channel5 = (AHBPERIPH_BASE + 0x0058)) ; 
PROVIDE (DMA_Channel6 = (AHBPERIPH_BASE + 0x006C)) ; 
PROVIDE (DMA_Channel7 = (AHBPERIPH_BASE + 0x0080)) ; 
PROVIDE (RCC    = (AHBPERIPH_BASE + 0x1000)) ; 

/* System Control Space memory map */ 
SCS_BASE    = 0xE000E000; 

PROVIDE (SysTick   = (SCS_BASE + 0x0010)) ; 
PROVIDE (NVIC   = (SCS_BASE + 0x0100)) ; 
PROVIDE (SCB    = (SCS_BASE + 0x0D00)) ; 

STM32_SEC_FLASH.ld:

/* 
Common part of the linker scripts for STR71x devices in FLASH mode 
(that is, the FLASH is seen at 0) 
Copyright RAISONANCE 2005 
You can use, modify and distribute thisfile freely, but without any waranty. 
*/ 


EXTERN(Reset_Handler) 
ENTRY(Reset_Handler) 

/* Sections Definitions */ 

SECTIONS 
{ 
    /* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */ 
    .isr_vector : 
    { 
    . = ALIGN(4); 
     KEEP(*(.isr_vector))   /* Startup code */ 
    . = ALIGN(4); 
    } >FLASH 

    /* the program code is stored in the .text section, which goes to Flash */ 
    .text : 
    { 
    *(.text .text.* .gnu.linkonce.t.*) 
     *(.rodata .rodata.* .gnu.linkonce.r.*) 

     *(.eh_frame_hdr) 
     *(.eh_frame) 
     *(.gcc_except_table) 
     *(.eh_frame_hdr) 
     *(.eh_frame) 

     . = 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)) 

     _etext = .; 

     /* This is used by the startup in order to initialize the .data secion */ 
     _sidata = _etext; 
    } >FLASH 

    /* .ARM.exidx is sorted, so has to go in its own output section. */ 
    __exidx_start = .; 
    .ARM.exidx : 
    { 
     *(.ARM.exidx* .gnu.linkonce.armexidx.*) 
    } > FLASH 
    . = ALIGN(4); 
    __exidx_end = .; 

    .data : 
    { 
     _flash_data = LOADADDR(.data); 
     _data = .; 
     _sdata = .; 
     *(vtable) 
     *(.data .data.* .gnu.linkonce.d.*) 
     _edata = .; 
    } >RAM AT >FLASH 

    /* This is the uninitialized data section */ 
    .bss : 
    { 
     _bss = .; 
     /* This is used by the startup in order to initialize the .bss secion */ 
     _sbss = .; 
     __bss_start__ = _sbss; 

     *(.bss .bss.* .gnu.linkonce.b.*) 
     *(COMMON) 

     . = ALIGN(4); 
     /* This is used by the startup in order to initialize the .bss secion */ 
     _ebss = . ; 
     __bss_end__ = _ebss; 
    } >RAM 

    PROVIDE (end = _ebss); 
    PROVIDE (_end = _ebss); 

    /* end of allocated ram _end */ 

    /* This is the user stack section 
    This is just to check that there is enough RAM left for the User mode stack 
    It should generate an error if it's full. 
    */ 
    ._usrstack : 
    { 
     . = ALIGN(4); 
     _susrstack = . ; 

     . = . + _Minimum_Stack_Size ; 

     . = ALIGN(4); 
     _eusrstack = . ; 
    } >RAM 

} 
+0

,其余的链接脚本是...? –

+0

将编辑整个链接器文件集 – Chris

+0

什么是'sidata'在hardfaults时发生了变化?你可以试试'_flash_data'而不是'sidata'吗? – domen

回答

0

我也有类似的问题。出于某种原因,链接器不会根据链接描述文件中的内容设置_sidata = _etext。相反,链接器设置_sidata = _etext-2。这导致_sidata值位于半字边界,这导致CPU最终在Default_Handler()中结束。

在你的链接脚本您显示以下内容:“”

_etext = .; 
/* This is used by the startup in order to initialize the .data secion */ 
_sidata = _etext; 

要解决该问题,更改为以下,这样_sidata明确设置为:

_etext = .; 
/* This is used by the startup in order to initialize the .data secion */ 
_sidata = .;