We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
I need help with heap initialization using scatter file and C++ startup.
MCU is STM32F407VGT6 (Cortex-M4).
Compiler is ARM Compiler 6.7, C++14.
The problem is that all variables which I create dinamically on the heap have wrong addresses. My HEAP locates in CCM (starts from 0x10000000) but those variables have address from 0x08000000. And it is a FLASH memory! And I don't understand how it is happened. While initialization of stack performs in correct way... Below are my C++ startup and scatter file.
#ifndef STARTUP_HPP #define STARTUP_HPP #include <common/core.hpp> #include <registers/Scb.hpp> #include <registers/Rcc.hpp> #define ATTR_DEFAULT_HANDLER __attribute__((weak, alias ("_ZN5mylib3mcu10interrupts14defaultHandlerEv"))) int main(); extern int Image$$STACK$$ZI$$Limit; int &__initial_sp = Image$$STACK$$ZI$$Limit; extern "C" { __attribute__((naked, used)) void __user_setup_stackheap() { asm( "LDR sp, =__initial_sp\n" "LDR r0, =Image$$HEAP$$ZI$$Base\n" "LDR r2, =Image$$HEAP$$ZI$$Limit\n" "BX lr" ); } [[noreturn]] void _sys_exit(int ch) { forever; } char *_sys_command_string(char *cmd, int length) { return cmd; } void _ttywrch(int ch) { using namespace xmcu::mcu::core::registers; $ITM.$PORT0.wait(); $ITM.$PORT0.setValue(ch); } } BEGIN_NAMESPACE(mylib) BEGIN_NAMESPACE(mcu) void initializeSystem() { using namespace registers; using namespace core::registers; #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) $SCB.$CPACR.setAccess(SCB::CPACR::Full, SCB::CPACR::CP10, SCB::CPACR::CP11); #endif $RCC.$CR.setBits<true>(RCC::CR::WBit::HSION); $RCC.$CFGR.reset(); $RCC.$CR.setBits<false>(RCC::CR::WBit::HSEON, RCC::CR::WBit::CSSON, RCC::CR::WBit::PLLON); $RCC.$PLLCFGR.reset(); $RCC.$CR.setBits<false>(RCC::CR::WBit::HSEBYP); $RCC.$CIR.reset(); #ifdef STM32F407_STARTUP_VTOR_SRAM $SCB.$VTOR.setTable(SCB::VTOR::SRAM, periphery::SRAM_BASE); #else $SCB.$VTOR.setTable(SCB::VTOR::Flash, periphery::FLASH_BASE); #endif } BEGIN_NAMESPACE(interrupts) [[noreturn]] void ResetHandler() { initializeSystem(); main(); forever; } [[noreturn]] void defaultHandler() { forever; } void NMIHandler() ATTR_DEFAULT_HANDLER; void HardFaultHandler() ATTR_DEFAULT_HANDLER; void MemManageHandler() ATTR_DEFAULT_HANDLER; void BusFaultHandler() ATTR_DEFAULT_HANDLER; void UsageFaultHandler() ATTR_DEFAULT_HANDLER; void SVCHandler() ATTR_DEFAULT_HANDLER; void DebugMonHandler() ATTR_DEFAULT_HANDLER; void PendSVHandler() ATTR_DEFAULT_HANDLER; void SysTickHandler() ATTR_DEFAULT_HANDLER; void WWDGHandler() ATTR_DEFAULT_HANDLER; void PVDHandler() ATTR_DEFAULT_HANDLER; void TAMP_STAMPHandler() ATTR_DEFAULT_HANDLER; void RTC_WKUPHandler() ATTR_DEFAULT_HANDLER; void FLASHHandler() ATTR_DEFAULT_HANDLER; void RCCHandler() ATTR_DEFAULT_HANDLER; void EXTI0Handler() ATTR_DEFAULT_HANDLER; void EXTI1Handler() ATTR_DEFAULT_HANDLER; void EXTI2Handler() ATTR_DEFAULT_HANDLER; void EXTI3Handler() ATTR_DEFAULT_HANDLER; void EXTI4Handler() ATTR_DEFAULT_HANDLER; void DMA1_Stream0Handler() ATTR_DEFAULT_HANDLER; void DMA1_Stream1Handler() ATTR_DEFAULT_HANDLER; void DMA1_Stream2Handler() ATTR_DEFAULT_HANDLER; void DMA1_Stream3Handler() ATTR_DEFAULT_HANDLER; void DMA1_Stream4Handler() ATTR_DEFAULT_HANDLER; void DMA1_Stream5Handler() ATTR_DEFAULT_HANDLER; void DMA1_Stream6Handler() ATTR_DEFAULT_HANDLER; void ADCHandler() ATTR_DEFAULT_HANDLER; void CAN1_TXHandler() ATTR_DEFAULT_HANDLER; void CAN1_RX0Handler() ATTR_DEFAULT_HANDLER; void CAN1_RX1Handler() ATTR_DEFAULT_HANDLER; void CAN1_SCEHandler() ATTR_DEFAULT_HANDLER; void EXTI9_5Handler() ATTR_DEFAULT_HANDLER; void TIM1_BRK_TIM9Handler() ATTR_DEFAULT_HANDLER; void TIM1_UP_TIM10Handler() ATTR_DEFAULT_HANDLER; void TIM1_TRG_COM_TIM11Handler() ATTR_DEFAULT_HANDLER; void TIM1_CCHandler() ATTR_DEFAULT_HANDLER; void TIM2Handler() ATTR_DEFAULT_HANDLER; void TIM3Handler() ATTR_DEFAULT_HANDLER; void TIM4Handler() ATTR_DEFAULT_HANDLER; void I2C1_EVHandler() ATTR_DEFAULT_HANDLER; void I2C1_ERHandler() ATTR_DEFAULT_HANDLER; void I2C2_EVHandler() ATTR_DEFAULT_HANDLER; void I2C2_ERHandler() ATTR_DEFAULT_HANDLER; void SPI1Handler() ATTR_DEFAULT_HANDLER; void SPI2Handler() ATTR_DEFAULT_HANDLER; void USART1Handler() ATTR_DEFAULT_HANDLER; void USART2Handler() ATTR_DEFAULT_HANDLER; void USART3Handler() ATTR_DEFAULT_HANDLER; void EXTI15_10Handler() ATTR_DEFAULT_HANDLER; void RTC_AlarmHandler() ATTR_DEFAULT_HANDLER; void OTG_FS_WKUPHandler() ATTR_DEFAULT_HANDLER; void TIM8_BRK_TIM12Handler() ATTR_DEFAULT_HANDLER; void TIM8_UP_TIM13Handler() ATTR_DEFAULT_HANDLER; void TIM8_TRG_COM_TIM14Handler() ATTR_DEFAULT_HANDLER; void TIM8_CCHandler() ATTR_DEFAULT_HANDLER; void DMA1_Stream7Handler() ATTR_DEFAULT_HANDLER; void FSMCHandler() ATTR_DEFAULT_HANDLER; void SDIOHandler() ATTR_DEFAULT_HANDLER; void TIM5Handler() ATTR_DEFAULT_HANDLER; void SPI3Handler() ATTR_DEFAULT_HANDLER; void UART4Handler() ATTR_DEFAULT_HANDLER; void UART5Handler() ATTR_DEFAULT_HANDLER; void TIM6_DACHandler() ATTR_DEFAULT_HANDLER; void TIM7Handler() ATTR_DEFAULT_HANDLER; void DMA2_Stream0Handler() ATTR_DEFAULT_HANDLER; void DMA2_Stream1Handler() ATTR_DEFAULT_HANDLER; void DMA2_Stream2Handler() ATTR_DEFAULT_HANDLER; void DMA2_Stream3Handler() ATTR_DEFAULT_HANDLER; void DMA2_Stream4Handler() ATTR_DEFAULT_HANDLER; void ETHHandler() ATTR_DEFAULT_HANDLER; void ETH_WKUPHandler() ATTR_DEFAULT_HANDLER; void CAN2_TXHandler() ATTR_DEFAULT_HANDLER; void CAN2_RX0Handler() ATTR_DEFAULT_HANDLER; void CAN2_RX1Handler() ATTR_DEFAULT_HANDLER; void CAN2_SCEHandler() ATTR_DEFAULT_HANDLER; void OTG_FSHandler() ATTR_DEFAULT_HANDLER; void DMA2_Stream5Handler() ATTR_DEFAULT_HANDLER; void DMA2_Stream6Handler() ATTR_DEFAULT_HANDLER; void DMA2_Stream7Handler() ATTR_DEFAULT_HANDLER; void USART6Handler() ATTR_DEFAULT_HANDLER; void I2C3_EVHandler() ATTR_DEFAULT_HANDLER; void I2C3_ERHandler() ATTR_DEFAULT_HANDLER; void OTG_HS_EP1_OUTHandler() ATTR_DEFAULT_HANDLER; void OTG_HS_EP1_INHandler() ATTR_DEFAULT_HANDLER; void OTG_HS_WKUPHandler() ATTR_DEFAULT_HANDLER; void OTG_HSHandler() ATTR_DEFAULT_HANDLER; void DCMIHandler() ATTR_DEFAULT_HANDLER; void HASH_RNGHandler() ATTR_DEFAULT_HANDLER; void FPUHandler() ATTR_DEFAULT_HANDLER; using Handler = void (*)(); const Handler vectors[] __attribute__ ((section("interrupts"), used)) = { reinterpret_cast<Handler>(&__initial_sp), &ResetHandler, &NMIHandler, &HardFaultHandler, &MemManageHandler, &BusFaultHandler, &UsageFaultHandler, nullptr, nullptr, nullptr, nullptr, &SVCHandler, &DebugMonHandler, nullptr, &PendSVHandler, &SysTickHandler, &WWDGHandler, &PVDHandler, &TAMP_STAMPHandler, &RTC_WKUPHandler, &FLASHHandler, &RCCHandler, &EXTI0Handler, &EXTI1Handler, &EXTI2Handler, &EXTI3Handler, &EXTI4Handler, &DMA1_Stream0Handler, &DMA1_Stream1Handler, &DMA1_Stream2Handler, &DMA1_Stream3Handler, &DMA1_Stream4Handler, &DMA1_Stream5Handler, &DMA1_Stream6Handler, &ADCHandler, &CAN1_TXHandler, &CAN1_RX0Handler, &CAN1_RX1Handler, &CAN1_SCEHandler, &EXTI9_5Handler, &TIM1_BRK_TIM9Handler, &TIM1_UP_TIM10Handler, &TIM1_TRG_COM_TIM11Handler, &TIM1_CCHandler, &TIM2Handler, &TIM3Handler, &TIM4Handler, &I2C1_EVHandler, &I2C1_ERHandler, &I2C2_EVHandler, &I2C2_ERHandler, &SPI1Handler, &SPI2Handler, &USART1Handler, &USART2Handler, &USART3Handler, &EXTI15_10Handler, &RTC_AlarmHandler, &OTG_FS_WKUPHandler, &TIM8_BRK_TIM12Handler, &TIM8_UP_TIM13Handler, &TIM8_TRG_COM_TIM14Handler, &TIM8_CCHandler, &DMA1_Stream7Handler, &FSMCHandler, &SDIOHandler, &TIM5Handler, &SPI3Handler, &UART4Handler, &UART5Handler, &TIM6_DACHandler, &TIM7Handler, &DMA2_Stream0Handler, &DMA2_Stream1Handler, &DMA2_Stream2Handler, &DMA2_Stream3Handler, &DMA2_Stream4Handler, ÐHandler, Ð_WKUPHandler, &CAN2_TXHandler, &CAN2_RX0Handler, &CAN2_RX1Handler, &CAN2_SCEHandler, &OTG_FSHandler, &DMA2_Stream5Handler, &DMA2_Stream6Handler, &DMA2_Stream7Handler, &USART6Handler, &I2C3_EVHandler, &I2C3_ERHandler, &OTG_HS_EP1_OUTHandler, &OTG_HS_EP1_INHandler, &OTG_HS_WKUPHandler, &OTG_HSHandler, &DCMIHandler, nullptr, &HASH_RNGHandler, &FPUHandler }; END_NAMESPACE END_NAMESPACE END_NAMESPACE #undef ATTR_DEFAULT_HANDLER #endif //STARTUP_HPP
FLASH 0x08000000 0x00100000 { ER_IROM1 +0 0x00100000 { *.o (interrupts, +First) *(InRoot$$Sections) .ANY (+RO) .ANY (+XO) } } SRAM 0x20000000 0x00020000 { ZI +0 ZEROPAD { .ANY (+ZI, +RW) } } CCM 0x10000000 0x00010000 { STACK +0 ALIGN 8 EMPTY 0x4000 {} HEAP +0 ALIGN 8 EMPTY 0x0200 {} }
As you see - these files use the same logic like in standart startup_stm32f407xx.s.But standart file works and my - no...
I also want to note that if I eneble MICROLIB in settings of Keil, add ARM_LIB_STACK and ARM_LIB_HEAP to scatter file, my implementation begins to work correctly.
But I want to do my startup without MICROLIB.
If you know where I am wrong in my code, please help.
Best regards, Andrey.