Startup code for MCUs
=========================================================================💬💬💬Note: Online resources are used to derive the startup code such as STM32 MCU documents, GCC compiler commands, ARM processor documents, Linker Script commands and some technical blogs
=========================================================================
1. What is the start-up code?
A start-up code is called before the main function, it creates a basic platform for the application. It is a small block of code that is written in assembly language and C language
There are the following parts of the start-up code.
Declaration of the Stack area.
Declaration of the Heap area.
Vector table.
Reset handler code.
Other exception handler code.
2. Boot-loader code vs Start-up code?
Bootloader is application which allow to you erase main application and load new version of this application back to flash.
Start-up code is short code which will clear your RAM after reset and initialize variables (copy from flash to RAM).
Tasks for start-up code depend on your definitions, but initialize RAM is most important step
3. What are the start-up code steps?
Start-up code for C programs usually consists of the following actions, performed in the order described:
4. Prerequisites to write startup code.
1. What is the start-up code?
A start-up code is called before the main function, it creates a basic platform for the application. It is a small block of code that is written in assembly language and C language
There are the following parts of the start-up code.
Declaration of the Stack area.
Declaration of the Heap area.
Vector table.
Reset handler code.
Other exception handler code.
2. Boot-loader code vs Start-up code?
Bootloader is application which allow to you erase main application and load new version of this application back to flash.
Start-up code is short code which will clear your RAM after reset and initialize variables (copy from flash to RAM).
Tasks for start-up code depend on your definitions, but initialize RAM is most important step
3. What are the start-up code steps?
Start-up code for C programs usually consists of the following actions, performed in the order described:
- Disable all interrupts.
- Copy any initialized data from ROM to RAM.
- Zero the uninitialized data area.
- Allocate space for and initialize the stack.
- Initialize the processor’s stack pointer.
- Create and initialize the heap.
- Enable interrupts.
- Call main.
4. Prerequisites to write startup code.
- Knowledge of linker script because we need to initialize the different memory sections, Need to know the boundaries of each section.
- Knowlege of memory map and vector table implementation.
- Basic knowlege of compiler attributes such as weak, alias and subroutine call.
- Basic knowledge of assembly because we need to initialize the stack pointer.
- startup code procedure.
if we look into vector table, "Reset" is the first exception is occurring after power-on the MCU hence reset exception called as "Reset_Handler"
As mentioned above this the first exception occurring hence we need to implement startup code in Reset_Handler.
Please refer Linker script command ENTRY. most of the MCUs, Entry point is Reset_Handler
6. Why we need to copy data from flash to SRAM?
RAM isn’t persisted while power is off, those sections need to be loaded from flash.
At boot, the Reset_Handler copies the data from flash to RAM before the main function is called.
=========================================================================
Different MCUs startup codes.
ARM Cortex-M3 Processor: implemented by referring the STM32F407/417 MCU documents.
Renesas: Renesas provide the startup code along with MCU. we need to modify sample code provided by vendor code according the requirement.
Tricore: Compilers for the TriCore processor are available by third party Infineon tool partners and offers user’s startup code with their tool chain. It is provided as C source code or assembler source code. The source file for the user’s startup code named cstart.c
Note: The location and contents of startup file are usually described in the documentation supplied with the compiler.
=========================================================================
Online resource Links:
STM32 MCU documents: STM32 Technical documents
ARM Cortex Program Manual: ARM Coretx-M4 Manual
STM32 MCU documents: STM32 Technical documents
ARM Cortex Program Manual: ARM Coretx-M4 Manual
Processor Technical Ref Manual: Processor Manual
Procedure call standard : Procedure call standard
GNU Compiler: GCC Compiler
Basic Linker Script: Linker script
Tricore Application Note for startup code: Tricore Startup code
GNU Compiler: GCC Compiler
Basic Linker Script: Linker script
Tricore Application Note for startup code: Tricore Startup code
Renesas Startup code:
Technical blogs:
=========================================================================
=========================================================================
Refer STM32F407/417 Datasheet, Reference manual, Application Notes and Technical notes
Refer A GNU Manual : Using the GNU Compiler Collection (GCC)
In the compiler manual refer Declaring Attributes of Functions
Go to Common Function Attributes section and look into the function alias and weak attributes
alias: The alias attribute causes the declaration to be emitted as an alias for another symbol.
weak: The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions that can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker.
- Refer Data sheet: Go to Memory Map and identify the start address of SRAM and size of SRAM.
- Refer Reference Manual: Go to Memory and bus architecture and Refer Embedded SRAM section. The STM32F405xx/07xx and STM32F415xx/17xx feature 4 Kbytes of backup SRAM (see Section 5.1.2: Battery backup domain) plus 192 Kbytes of system SRAM. SRAM1 and SRAM2 mapped at address 0x2000 0000 and accessible by all AHB masters.
- Refer Reference Manual: Vector table for STM32F405xx/07xx and STM32F415xx/17xx (Reference manual: RM0090)
- Refer Programming manual: to understand the stack implementation
=========================================================================
Refer A GNU Manual : Using the GNU Compiler Collection (GCC)
In the compiler manual refer Declaring Attributes of Functions
Go to Common Function Attributes section and look into the function alias and weak attributes
alias: The alias attribute causes the declaration to be emitted as an alias for another symbol.
weak: The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions that can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker.
=========================================================================
=========================================================================
/*Create file name with startup.c*/
#include <stdint.h>
#define SRAM_START 0x20000000U
#define SRAM_SIZE (128U*1024U) /* 128KB*/
#define SRAM_END ((SRAM_START)+(SRAM_SIZE))
#define STACK_START SRAM_END
#define STACK_SIZE (40U*1024U) /*40KB*/
#define STACK_END SRAM_END - STACKSIZE
/*Symbols from the linker file, defined for the boundaries for each memory segment*/
extern unit32_t _etext;
extern unit32_t _sdata;
extern unit32_t _edata;
extern unit32_t _sbss;
extern unit32_t _ebss;
extern unit32_t _sstack;
extern unit32_t _estack;
extern unit32_t _sheap;
extern unit32_t _eheap;
/*main prototype*/
extern unit32_t _sdata;
extern unit32_t _edata;
extern unit32_t _sbss;
extern unit32_t _ebss;
extern unit32_t _sstack;
extern unit32_t _estack;
extern unit32_t _sheap;
extern unit32_t _eheap;
/*main prototype*/
int main(void);
void Reset_Handler();
void NMI_Handler (void) __attribute__ ((weak, alias ("Common_Handler")));
void HardFault_Handler (void) __attribute__ ((weak, alias("Common_Handler")));
void MemManage_Handler (void) __attribute__ ((weak, alias("Common_Handler")));
void BusFault_Handler (void) __attribute__ ((weak, alias("Common_Handler")));void UsageFault_Handler (void) __attribute__ ((weak, alias("Common_Handler")));void SVC_Handler (void) __attribute__ ((weak, alias("Common_Handler")));void DebugMon_Handler (void) __attribute__ ((weak, alias("Common_Handler")));void PendSV_Handler (void) __attribute__ ((weak, alias("Common_Handler")));void SysTick_Handler (void) __attribute__ ((weak, alias("Common_Handler")));void WWDG_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void PVD_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TAMP_STAMP_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void RTC_WKUP_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void FLASH_IRQHandler void) __attribute__ ((weak, alias("Common_Handler")));void RCC_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void EXTI0_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void EXTI1_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void EXTI2_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void EXTI3_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void EXTI4_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA1_Stream0_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA1_Stream1_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA1_Stream2_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA1_Stream3_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA1_Stream4_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA1_Stream5_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA1_Stream6_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void ADC_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void CAN1_TX_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void CAN1_RX0_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void CAN1_RX1_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void CAN1_SCE_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void EXTI9_5_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM1_BRK_TIM9_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM1_UP_TIM10_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM1_TRG_COM_TIM11_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM1_CC_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM2_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM3_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM4_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void I2C1_EV_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void I2C1_ER_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void I2C2_EV_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void I2C2_ER_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void SPI1_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void SPI2_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void USART1_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void USART2_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void USART3_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void EXTI15_10_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void RTC_Alarm_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void OTG_FS_WKUP_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM8_BRK_TIM12_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM8_UP_TIM13_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM8_TRG_COM_TIM14_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM8_CC_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA1_Stream7_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void FSMC_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void SDIO_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM5_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void SPI3_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void UART4_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void UART5_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM6_DAC_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void TIM7_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA2_Stream0_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA2_Stream1_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA2_Stream2_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA2_Stream3_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA2_Stream4_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void ETH_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void ETH_WKUP_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void CAN2_TX_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void CAN2_RX0_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void CAN2_RX1_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void CAN2_SCE_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void OTG_FS_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA2_Stream5_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA2_Stream6_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DMA2_Stream7_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void USART6_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void I2C3_EV_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void I2C3_ER_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void OTG_HS_EP1_OUT_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void OTG_HS_EP1_IN_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void OTG_HS_WKUP_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void OTG_HS_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void DCMI_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void CRYP_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void HASH_RNG_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));void FPU_IRQHandler (void) __attribute__ ((weak, alias("Common_Handler")));
unit32_t vectors[]= __attribute__ ((section (".vectortable"))) {
STACK_START,(uint32_t)&Reset_Handler,(uint32_t)&NMI_Handler,(uint32_t)&HardFault_Handler,(uint32_t)&MemManage_Handler,(uint32_t)&BusFault_Handler,(uint32_t)&UsageFault_Handler,0,(uint32_t)&SVC_Handler,(uint32_t)&DebugMon_Handler,(uint32_t)&PendSV_Handler,(uint32_t)&SysTick_Handler,(uint32_t)&WWDG_IRQHandler,(uint32_t)&PVD_IRQHandler,(uint32_t)&TAMP_STAMP_IRQHandler,(uint32_t)&RTC_WKUP_IRQHandler,(uint32_t)&FLASH_IRQHandler,(uint32_t)&RCC_IRQHandler,(uint32_t)&EXTI0_IRQHandler,(uint32_t)&EXTI1_IRQHandler,(uint32_t)&EXTI2_IRQHandler,(uint32_t)&EXTI3_IRQHandler,(uint32_t)&EXTI4_IRQHandler,(uint32_t)&DMA1_Stream0_IRQHandler,(uint32_t)&DMA1_Stream1_IRQHandler,(uint32_t)&DMA1_Stream2_IRQHandler,(uint32_t)&DMA1_Stream3_IRQHandler,(uint32_t)&DMA1_Stream4_IRQHandler,(uint32_t)&DMA1_Stream5_IRQHandler,(uint32_t)&DMA1_Stream6_IRQHandler,(uint32_t)&ADC_IRQHandler,(uint32_t)&CAN1_TX_IRQHandler,(uint32_t)&CAN1_RX0_IRQHandler,(uint32_t)&CAN1_RX1_IRQHandler,(uint32_t)&CAN1_SCE_IRQHandler,(uint32_t)&EXTI9_5_IRQHandler,(uint32_t)&TIM1_BRK_TIM9_IRQHandler,(uint32_t)&TIM1_UP_TIM10_IRQHandler,(uint32_t)&TIM1_TRG_COM_TIM11_IRQHandler,(uint32_t)&TIM1_CC_IRQHandler,(uint32_t)&TIM2_IRQHandler,(uint32_t)&TIM3_IRQHandler,(uint32_t)&TIM4_IRQHandler,(uint32_t)&I2C1_EV_IRQHandler,(uint32_t)&I2C1_ER_IRQHandler,(uint32_t)&I2C2_EV_IRQHandler,(uint32_t)&I2C2_ER_IRQHandler,(uint32_t)&SPI1_IRQHandler,(uint32_t)&SPI2_IRQHandler,(uint32_t)&USART1_IRQHandler ,(uint32_t)&USART2_IRQHandler ,(uint32_t)&USART3_IRQHandler ,(uint32_t)&EXTI15_10_IRQHandler,(uint32_t)&RTC_Alarm_IRQHandler,(uint32_t)&OTG_FS_WKUP_IRQHandler,(uint32_t)&TIM8_BRK_TIM12_IRQHandler,(uint32_t)&TIM8_UP_TIM13_IRQHandler,(uint32_t)&TIM8_TRG_COM_TIM14_IRQHandl,(uint32_t)&TIM8_CC_IRQHandler,(uint32_t)&DMA1_Stream7_IRQHandler,(uint32_t)&FSMC_IRQHandler ,(uint32_t)&SDIO_IRQHandler ,(uint32_t)&TIM5_IRQHandler ,(uint32_t)&SPI3_IRQHandler,(uint32_t)&UART4_IRQHandler,(uint32_t)&UART5_IRQHandler,(uint32_t)&TIM6_DAC_IRQHandler,(uint32_t)&TIM7_IRQHandler ,(uint32_t)&DMA2_Stream0_IRQHandler,(uint32_t)&DMA2_Stream1_IRQHandler,(uint32_t)&DMA2_Stream2_IRQHandler,(uint32_t)&DMA2_Stream3_IRQHandler,(uint32_t)&DMA2_Stream4_IRQHandler,(uint32_t)Ð_IRQHandler ,(uint32_t)Ð_WKUP_IRQHandler,(uint32_t)&CAN2_TX_IRQHandler ,(uint32_t)&CAN2_RX0_IRQHandler ,(uint32_t)&CAN2_RX1_IRQHandler ,(uint32_t)&CAN2_SCE_IRQHandler ,(uint32_t)&OTG_FS_IRQHandler ,(uint32_t)&DMA2_Stream5_IRQHandler,(uint32_t)&DMA2_Stream6_IRQHandler ,(uint32_t)&DMA2_Stream7_IRQHandler,(uint32_t)&USART6_IRQHandler ,(uint32_t)&I2C3_EV_IRQHandler,(uint32_t)&I2C3_ER_IRQHandler ,(uint32_t)&OTG_HS_EP1_OUT_IRQHandler,(uint32_t)&OTG_HS_EP1_IN_IRQHandler,(uint32_t)&OTG_HS_WKUP_IRQHandler,(uint32_t)&OTG_HS_IRQHandler,(uint32_t)&DCMI_IRQHandler ,(uint32_t)&CRYP_IRQHandler ,(uint32_t)&HASH_RNG_IRQHandler,(uint32_t)&FPU_IRQHandler
}
=========================================================================
/*Reset_Handler function implementation*/
void Reset_Handler(void)
{
/********************************************************************************************/
Step1: Disable all interrupts. use system call*
/********************************************************************************************/
Step2: Copy any initialized data from ROM to RAM. or text to data*/
uint32_t *pDstdata=(unit32_t*)_sdata; /*this is the destination address : SRAM*/
uint32_t size =((&_ebss) -(&_sbss));
uint32_t *pSrcbss=(unit32_t*)_sbss; // this is start address of .bss section
Here look into the where is stack placed at end of RAM or after the .bss section and type of stack
check the size of stack it is defined in the linker file*/
/*stack placed at end of RAM */
#if 0
uint32_t *pSrcstack =&.ramend;
uint32_t size = SRAM_END-STACK_END
for(uint32_t i=SRAM_END; i>= size;i--)
{
*pSrcstack--=0;
}
#endif
/********************************************************************************************/
/********************************************************************************************/
uint32_t size =((&_edata) - (&_sdata));
uint32_t *pSrcdata=(unit32_t*)_etext; /* this is source address to copy : Flash*/uint32_t *pDstdata=(unit32_t*)_sdata; /*this is the destination address : SRAM*/
for (uint32_t i=0;i<size;i++){*pDstdata++= *pSrcdata++;}
/********************************************************************************************/
Step3: Zero the uninitialized data area
uint32_t size =((&_ebss) -(&_sbss));
uint32_t *pSrcbss=(unit32_t*)_sbss; // this is start address of .bss section
for (uint32_t i=0;i<size;i++){*pSrcbss++=0;}
/********************************************************************************************/
/*Step4:Allocate space for and initialize the stack.*/
Here look into the where is stack placed at end of RAM or after the .bss section and type of stack
check the size of stack it is defined in the linker file*/
/*stack placed at end of RAM */
#if 0
uint32_t *pSrcstack =&.ramend;
uint32_t size = SRAM_END-STACK_END
for(uint32_t i=SRAM_END; i>= size;i--)
{
*pSrcstack--=0;
}
#endif
/********************************************************************************************/
Step5:Initialize the processor’s stack pointer.
Stack pointer initialization
The vector table contains the reset values of stack pointer and reset handler.
After reset, the vector table is mapped at address 0, and the SP register is initialized with the same value as in the vector table. So technically there is no need to initialize the SP unless: The Reset_Handler is explicitly called in the code.*/
Stack pointer initialization
The vector table contains the reset values of stack pointer and reset handler.
After reset, the vector table is mapped at address 0, and the SP register is initialized with the same value as in the vector table. So technically there is no need to initialize the SP unless: The Reset_Handler is explicitly called in the code.*/
/********************************************************************************************/
Step6:Create and initialize the heap.
/*if placed Heap memory placed at top of RAM
heapsize = RAM_TOP address - address of heapbaseaddress
if Heap memory place at end of .bss section.
heapsize = &._eheap-&._sheap*/
heapsize = RAM_TOP address - address of heapbaseaddress
if Heap memory place at end of .bss section.
heapsize = &._eheap-&._sheap*/
#if 0
uint32_t size =((&_eheap) -(&_sheap));
uint32_t *pSrcheap=(unit32_t*)_ebss; // this is start address of .bss section
for (uint32_t i=0;i<size;i++)
{
*pSrcheap++=0;
}#endif
/********************************************************************************************/
Step7: Initialize the system clock and other information. Enable all interrupts. use system call
/*if system initialization available in your vendor code. call the */
SystemInit();
/********************************************************************************************/
/*Step8:Call main. */
main();
Put the function in infinite-loop
while(1);
}
/*This function called from vector table and aliased from the implementation. Actual implementation done in user code*/
void Common_Handler(void)
{while(1);}
/********************************************************************************************/
=========================================================================
💬💬💬Important Note: we created separate memory section for ".vectortable" symbol because we don't want to keep in .data section.
💬💬💬Important Note: we created separate memory section for ".vectortable" symbol because we don't want to keep in .data section.
In the .ld file should start the Section command like below. it is known as keep vector table in zeroth memory location.
/*define the output sections*/
SECTIONS
{
/*startup code first going to FLASH hence .vectortable symbol place in FLASH*/
.vectortable :
{
.=ALIGN(4);
KEEP(*(.vectortable))
.=ALIGN(4);
}>FLASH
/*define remaining sections like .text, .data. .bss, .stack and .heap*/
.end
.vectortable :
{
.=ALIGN(4);
KEEP(*(.vectortable))
.=ALIGN(4);
}>FLASH
/*define remaining sections like .text, .data. .bss, .stack and .heap*/
.end
}
No comments:
Post a Comment