I am trying to cross-compile with target as STM32F030F4P6,I set up my startup.c & startup.h files containing my vector table. I have written 2 linker scripts one for memory & other for sections. as per the datasheet the STM32f030F4 after a system reset sets the PC to 0x00000000,& vector table must be present at this address as after incrementing it must execute Reset_Handler(system reset) at 0x00000004 and the initialize the system.
When I link this the linker gives me the following warning
" warning: cannot find entry symbol _start; defaulting to 00008000"
Question
Why is the linker not detecting my Entry point defined by ENTRY(Reset_Handler)?
Please find my source & Header files & the linker scripts.
script.ld This contains the sections
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
*(.isr_vector)
*(.text)
*(.rodata)
_etext= .;
}> FLASH
.data :
{
_sdata = .;
*(.data)
_edata = .;
}> SRAM AT> FLASH
.bss :
{
_sbss = .;
*(.bss)
_ebss = .;
}> SRAM
}
memory.ld This file contains memory definitions. Note-STM32F030F4P has only FLASH & RAM and so EXTMEMBx is defined as 0x00000000 of LENGTH 4K
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K
EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0K
EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0K
EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0K
EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0K
}
Startup.h containing the vector definitions
#include "stdint.h"
/* Calculate the vlaue of stack. */
/* Full- descending stack in cortex-m0 means stack must be placed at the end of SRAM. */
/* Stack pointer is decremented as a a PUSH operation is executed */
#define SRAM_Start 0x20000000U
#define SRAM_End SRAM_Start+4096U
#define Stack_Start SRAM_End
/* Vector Definitions */
void Reset_Handler(void);
void NMI_Handler(void) __attribute__((weak, alias("Default_Handler")));
void HardFault_Handler(void) __attribute__((weak, alias("Default_Handler")));
void SVCall_Handler(void) __attribute__((weak, alias("Default_Handler")));
void PendSV_Handler(void) __attribute__((weak, alias("Default_Handler")));
void SysTick_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ0_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ1_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ2_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ3_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ4_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ5_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ6_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ7_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ8_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ9_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ10_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ11_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ12_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ13_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ14_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ15_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ16_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ17_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ18_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ19_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ20_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ21_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ22_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ23_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ24_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ25_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ26_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ27_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ28_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ29_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ30_Handler(void) __attribute__((weak, alias("Default_Handler")));
void IRQ31_Handler(void) __attribute__((weak, alias("Default_Handler")));
& finally startup.c
//Set initial SP value
// PC increments to reset handler
// branch to main
#include "startup.h"
// __attribute__((weak, alias("")))
/* Vector Table */
/* Subsequent to a system RESET PC is set to 0x00000000 */
/* Vector Table must be present at 0x00000000 use __atribute__((section("section_name"))) to place vector table at "section_name" */
/* Use arm-none-eabi-objdump -h/-S to verify if "section_name" is generated for vector table */
/* Value of SP is the first item in the vector table & henceforth msp is loaded */
/* Second value of vector table is RESET HANDLER, */
/* Core Systems must be initialized here such as CLOCK, etc.*/
/* it is from RESET HANDLER the program flow is branched to user application */
uint32_t vector[] __attribute__((section(".isr_vector"))) = {
Stack_Start,
(uint32_t)&Reset_Handler,
(uint32_t)&NMI_Handler,
(uint32_t)&HardFault_Handler,
(uint32_t)0x00000000,
(uint32_t)0x00000000,
(uint32_t)0x00000000,
(uint32_t)0x00000000,
(uint32_t)0x00000000,
(uint32_t)0x00000000,
(uint32_t)0x00000000,
(uint32_t)&SVCall_Handler,
(uint32_t)0x00000000,
(uint32_t)0x00000000,
(uint32_t)&PendSV_Handler,
(uint32_t)&SysTick_Handler,
(uint32_t)&IRQ0_Handler,
(uint32_t)&IRQ1_Handler,
(uint32_t)&IRQ2_Handler,
(uint32_t)&IRQ3_Handler,
(uint32_t)&IRQ4_Handler,
(uint32_t)&IRQ5_Handler,
(uint32_t)&IRQ6_Handler,
(uint32_t)&IRQ7_Handler,
(uint32_t)&IRQ8_Handler,
(uint32_t)&IRQ9_Handler,
(uint32_t)&IRQ10_Handler,
(uint32_t)&IRQ11_Handler,
(uint32_t)&IRQ12_Handler,
(uint32_t)&IRQ13_Handler,
(uint32_t)&IRQ14_Handler,
(uint32_t)&IRQ15_Handler,
(uint32_t)&IRQ16_Handler,
(uint32_t)&IRQ17_Handler,
(uint32_t)&IRQ18_Handler,
(uint32_t)&IRQ19_Handler,
(uint32_t)&IRQ20_Handler,
(uint32_t)&IRQ21_Handler,
(uint32_t)&IRQ22_Handler,
(uint32_t)&IRQ23_Handler,
(uint32_t)&IRQ24_Handler,
(uint32_t)&IRQ25_Handler,
(uint32_t)&IRQ26_Handler,
(uint32_t)&IRQ27_Handler,
(uint32_t)&IRQ28_Handler,
(uint32_t)&IRQ29_Handler,
(uint32_t)&IRQ30_Handler,
(uint32_t)&IRQ31_Handler,
};
/*Function defenition of reset handler*/
/* it is from RESET HANDLER the program flow is branched to user application */
void Reset_Handler(void)
{
// copy .data section
// init .bss/SRAM to 0
// init clocks etc..
// call the application procedure
}
void Default_Handler(void)
{
for(;;)
{
}
// Just loop as completion of this procedure will give other faults
}
my toolchain file arm-none-eabi.camke
MESSAGE("Running : arm-none-eabi.cmake")
SET(CMAKE_SYSTEM_PROCESSOR arm)
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_C_COMPILER_WORKS TRUE)
SET(CMAKE_CXX_COMPILER_WORKS TRUE)
SET(CMAKE_TRY_COMPILE_TARGTE_TYPE STATIC_LIBRARY)
SET(TARGET STM32F030x4)
SET(ARCH armv6-m)
SET(CPU cortex-m0)
SET(ARM_ISA mthumb)
SET(CMAKE_C_COMPILER arm-none-eabi-gcc)
SET(CMAKE_CXX_COMPILER arm-none-eabi-g++)
SET(CMAKE_ASM_COMPILER arm-none-eabi-g++)
SET(CMAKE_SIZE arm-none-eabi-size)
SET(CMAKE_OBJDUMP arm-none-eabi-objdump)
SET(CMAKE_OBJCOPY arm-none-eabi-objcopy)
SET(OPTIMISATION Og)
SET(DEBUG "ggdb")
SET(CMAKE_COMMON_FLAGS "-march=${ARCH} -mcpu=${CPU} -${ARM_ISA} -D${TARGET} -${OPTIMISATION} -${DEBUG} -Wall -Wextra -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -nostdlib")
SET(CMAKE_ASM_FLAGS "${CMAKE_COMMON_FLAGS}")
SET(CMAKE_C_FLAGS "${CMAKE_COMMON_FLAGS} ")
SET(CMAKE_CXX_FLAGS "${CMAKE_COMMON_FLAGS} -fno-rtti -fno-exceptions -Wno-volatile -std=c++1z")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_COMMON_FLAGS} -nostartfiles -Wl,-Map,\"${TARGET}.map\" -nostartfiles -nolibc --specs=nosys.specs")
message("CMAKE_C_FLAGS = " ${CMAKE_C_FLAGS})
message("CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS})
message("CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS})
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 3.20)
INCLUDE("CMake/arm-none-eabi.cmake")
SET(CMAKE_C_STANDARD 11)
SET(CMAKE_CXX_STANDARD 17)
PROJECT(BLINKY VERSION 1.0.1 DESCRIPTION "Blinky Example")
MESSAGE("Building " ${PROJECT_NAME})
FILE(GLOB_RECURSE
LDSCRIPTS
"ldscripts/*.ld"
)
FOREACH(file ${LDSCRIPTS})
SET(CMAKE_LINKER_FLAGS "${CAMKE_LINKER_FLAGS} -T \"${file}\" ")
MESSAGE("Linker is Running " ${CMAKE_LINKER_FLAGS})
ENDFOREACH()
#Setup project headers
INCLUDE_DIRECTORIES(
"Core/"
"Drivers/"
)
#Setup porject sources
FILE(GLOB_RECURSE
APPLICATION_SOURCE
"Application/*.c"
"Application/*.cpp"
"Application/*.s"
"Core/*.c"
"Core/*cpp"
"Core/*.s"
"Drivers/*.c"
"Drivers/*.cpp"
"Drivers/*.s"
)
MESSAGE("CMake build directory" ${CMAKE_BINARY_DIR})
ADD_EXECUTABLE(${TARGET}.elf ${APPLICATION_SOURCE})
#ADD_CUSTOM_TARGET(${TARGET}.bin ALL DEPENDS ${TARGET}.elf COMMAND ${CMAKE_OBJCOPY} -O binary ${TARGET}.elf ${TARGET}.bin)
#ADD_CUSTOM_TARGET(${TARGET}.hex ALL DEPENDS ${TARGET}.elf COMMAND ${CMAKE_OBJCOPY} -O ihex ${TARGET}.elf ${TARGET}.hex)
ADD_CUSTOM_COMMAND(OUTPUT ${TARGET}.bin DEPENDS ${TARGET}.elf COMMAND ${CMAKE_OBJCOPY} -O binary ${TARGET}.elf ${TARGET}.bin)
ADD_CUSTOM_COMMAND(OUTPUT ${TARGET}.hex DEPENDS ${TARGET}.elf COMMAND ${CMAKE_OBJCOPY} -O ihex ${TARGET}.elf ${TARGET}.hex)
ADD_CUSTOM_TARGET(${TARGET}_bin DEPENDS ${TARGET}.bin)
ADD_CUSTOM_TARGET(${TARGET}_hex DEPENDS ${TARGET}.hex)
ADD_CUSTOM_TARGET(SIZE ALL ${CMAKE_SIZE} ${TARGET}.elf DEPENDS ${TARGET}.elf)
I understand this is definitely not the best way to write startup files. but the point is to make it run & improve to write startup file.
--specs=nosys.specs --specs=nano.specs
– PierreOlivierReset_Handler
listed? Is_Reset_Handler
(with a leading underscore) listed? – TonyK