2015-05-29 120 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 = .;