From 2155ab2b72cc4f076dc0a25d0e3a5fdd4d218998 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 15 Jan 2017 15:04:02 +0100 Subject: o Adding a generic binutils part for creating the info files (.nm, disassembly, size, hex and bin files.) o Adding initial support for STM32F103xx chips. Can easily be expanded to all at least the F1 series. --- binutils.cmake | 40 ++++ mcu.cmake | 9 +- nrf5x.cmake | 12 +- stm32f103/include/mcu/init.h | 136 ++++++++++++++ stm32f103/index.cmake | 81 ++++++++ stm32f103/src/default_handler.cpp | 7 + stm32f103/src/init_high.cpp | 384 ++++++++++++++++++++++++++++++++++++++ stm32f103/src/init_low.s | 47 +++++ stm32f103/stm32f103.ld | 62 ++++++ stm32f103/toolchain.cmake | 26 +++ 10 files changed, 797 insertions(+), 7 deletions(-) create mode 100644 binutils.cmake create mode 100644 stm32f103/include/mcu/init.h create mode 100644 stm32f103/index.cmake create mode 100644 stm32f103/src/default_handler.cpp create mode 100644 stm32f103/src/init_high.cpp create mode 100644 stm32f103/src/init_low.s create mode 100644 stm32f103/stm32f103.ld create mode 100644 stm32f103/toolchain.cmake diff --git a/binutils.cmake b/binutils.cmake new file mode 100644 index 0000000..742fb06 --- /dev/null +++ b/binutils.cmake @@ -0,0 +1,40 @@ +function(mcu_binutils_create_dump_targets TARGET) + if (MCU_ARM_OBJDUMP) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${TARGET}-info + COMMAND ${MCU_ARM_OBJDUMP} -D ${TARGET} > ${TARGET}-info/${TARGET}.asm + BYPRODUCTS ${TARGET}-info/${TARGET}.asm) + endif () + + if (MCU_ARM_NM) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${TARGET}-info + COMMAND ${MCU_ARM_NM} -C ${TARGET} > ${TARGET}-info/${TARGET}.nm + BYPRODUCTS ${TARGET}-info/${TARGET}.nm) + endif () + + if (MCU_ARM_SIZE) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${TARGET}-info + COMMAND ${MCU_ARM_SIZE} ${TARGET} > ${TARGET}-info/${TARGET}.size + BYPRODUCTS ${TARGET}-info/${TARGET}.size) + endif () + + if (MCU_ARM_READELF) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${TARGET}-info + COMMAND ${MCU_ARM_READELF} -a ${TARGET} > ${TARGET}-info/${TARGET}.readelf + BYPRODUCTS ${TARGET}-info/${TARGET}.readelf) + endif () + + if (MCU_ARM_OBJCOPY) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${TARGET}-info + COMMAND ${MCU_ARM_OBJCOPY} -O ihex ${TARGET} ${TARGET}-info/${TARGET}.hex + BYPRODUCTS ${TARGET}-info/${TARGET}.hex) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${TARGET}-info + COMMAND ${MCU_ARM_OBJCOPY} -O binary ${TARGET} ${TARGET}-info/${TARGET}.bin + BYPRODUCTS ${TARGET}-info/${TARGET}.bin) + endif () +endfunction() diff --git a/mcu.cmake b/mcu.cmake index 00795ab..94c134a 100644 --- a/mcu.cmake +++ b/mcu.cmake @@ -1,5 +1,8 @@ +set(MCU_BASEDIR "${CMAKE_CURRENT_LIST_DIR}" CACHE PATH "The mcu.cmake installation path" FORCE) +message("MCU_BASEDIR=${MCU_BASEDIR}") + if (NOT MCU_CHIP) - message(FATAL_ERROR "Missing required argument CHIP.") + message(FATAL_ERROR "Missing required argument MCU_CHIP.") elseif (MCU_CHIP MATCHES "nrf5.*") set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/nrf5x.cmake") @@ -7,11 +10,15 @@ elseif (MCU_CHIP MATCHES "nrf5.*") include(${CMAKE_CURRENT_LIST_DIR}/nrf5x/utils.cmake) elseif (MCU_CHIP MATCHES D2000) set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/intel-quark-d2000.toolchain.cmake") +elseif (MCU_CHIP MATCHES "stm32f103.*") + set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/stm32f103/toolchain.cmake") + include(${CMAKE_CURRENT_LIST_DIR}/stm32f103/index.cmake) else () message(FATAL_ERROR "Unsupported MCU_CHIP setting: ${MCU_CHIP}") endif () include(${CMAKE_CURRENT_LIST_DIR}/mcu_include_directories_from_sources.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/binutils.cmake) # Required on Windows set(CMAKE_SYSTEM_NAME Generic) diff --git a/nrf5x.cmake b/nrf5x.cmake index ee3a814..fe76731 100644 --- a/nrf5x.cmake +++ b/nrf5x.cmake @@ -94,18 +94,18 @@ _mcu_find_toolchain() find_program(MCU_ARM_CC arm-none-eabi-gcc ${MCU_TOOLCHAIN_DIR}/bin) find_program(MCU_ARM_CXX arm-none-eabi-g++ ${MCU_TOOLCHAIN_DIR}/bin) find_program(MCU_ARM_OBJCOPY arm-none-eabi-objcopy ${MCU_TOOLCHAIN_DIR}/bin) -find_program(MCU_ARM_SIZE_TOOL arm-none-eabi-size ${MCU_TOOLCHAIN_DIR}/bin) +find_program(MCU_ARM_SIZE arm-none-eabi-size ${MCU_TOOLCHAIN_DIR}/bin) find_program(MCU_ARM_NM arm-none-eabi-nm ${MCU_TOOLCHAIN_DIR}/bin) set(_CMAKE_TOOLCHAIN_PREFIX arm-none-eabi-) include(CMakeFindBinUtils) -#message("MCU_ARM_CC = ${MCU_ARM_CC}") -#message("MCU_ARM_CXX = ${MCU_ARM_CXX}") -#message("MCU_ARM_OBJCOPY = ${MCU_ARM_OBJCOPY}") -#message("MCU_ARM_SIZE_TOOL = ${MCU_ARM_SIZE_TOOL}") +#message("MCU_ARM_CC = ${MCU_ARM_CC}") +#message("MCU_ARM_CXX = ${MCU_ARM_CXX}") +#message("MCU_ARM_OBJCOPY = ${MCU_ARM_OBJCOPY}") +#message("MCU_ARM_SIZE = ${MCU_ARM_SIZE}") -if (NOT MCU_ARM_CC OR NOT MCU_ARM_CXX OR NOT MCU_ARM_OBJCOPY OR NOT MCU_ARM_SIZE_TOOL) +if (NOT MCU_ARM_CC OR NOT MCU_ARM_CXX OR NOT MCU_ARM_OBJCOPY OR NOT MCU_ARM_SIZE) message(FATAL_ERROR "Could not find required compiler tools.") endif() diff --git a/stm32f103/include/mcu/init.h b/stm32f103/include/mcu/init.h new file mode 100644 index 0000000..6c870c2 --- /dev/null +++ b/stm32f103/include/mcu/init.h @@ -0,0 +1,136 @@ +#ifndef INIT_HIGH_H +#define INIT_HIGH_H + +extern "C" +int halt(); + +extern "C" +int main(); + +extern "C" { + +// Symbols for interrupt handlers. They all have a default implementation, but can be overridden by creating a function +// with the same name. + +extern void _Reset_Handler(); + +extern void NMI_Handler(); + +extern void HardFault_Handler(); + +extern void MemManage_Handler(); + +extern void BusFault_Handler(); + +extern void UsageFault_Handler(); + +extern void SVC_Handler(); + +extern void DebugMon_Handler(); + +extern void PendSV_Handler(); + +extern void SysTick_Handler(); + +extern void WWDG_IRQHandler(); + +extern void PVD_IRQHandler(); + +extern void TAMPER_IRQHandler(); + +extern void RTC_IRQHandler(); + +extern void FLASH_IRQHandler(); + +extern void RCC_IRQHandler(); + +extern void EXTI0_IRQHandler(); + +extern void EXTI1_IRQHandler(); + +extern void EXTI2_IRQHandler(); + +extern void EXTI3_IRQHandler(); + +extern void EXTI4_IRQHandler(); + +extern void DMA1_Channel1_IRQHandler(); + +extern void DMA1_Channel2_IRQHandler(); + +extern void DMA1_Channel3_IRQHandler(); + +extern void DMA1_Channel4_IRQHandler(); + +extern void DMA1_Channel5_IRQHandler(); + +extern void DMA1_Channel6_IRQHandler(); + +extern void DMA1_Channel7_IRQHandler(); + +extern void ADC1_2_IRQHandler(); + +extern void USB_HP_CAN1_TX_IRQHandler(); + +extern void USB_LP_CAN1_RX0_IRQHandler(); + +extern void CAN1_RX1_IRQHandler(); + +extern void CAN1_SCE_IRQHandler(); + +extern void EXTI9_5_IRQHandler(); + +extern void TIM1_BRK_IRQHandler(); + +extern void TIM1_UP_IRQHandler(); + +extern void TIM1_TRG_COM_IRQHandler(); + +extern void TIM1_CC_IRQHandler(); + +extern void TIM2_IRQHandler(); + +extern void TIM3_IRQHandler(); + +extern void TIM4_IRQHandler(); + +extern void I2C1_EV_IRQHandler(); + +extern void I2C1_ER_IRQHandler(); + +extern void I2C2_EV_IRQHandler(); + +extern void I2C2_ER_IRQHandler(); + +extern void SPI1_IRQHandler(); + +extern void SPI2_IRQHandler(); + +extern void USART1_IRQHandler(); + +extern void USART2_IRQHandler(); + +extern void USART3_IRQHandler(); + +extern void EXTI15_10_IRQHandler(); + +extern void RTCAlarm_IRQHandler(); + +extern void USBWakeUp_IRQHandler(); +} + + +#include + +namespace mcu { + +template +static inline constexpr +R SizeOfArray(const T(&)[N]) { + static_assert(std::numeric_limits::max() >= N, "N does not fit in R"); + return static_cast(N); +} + +}; // namespace mcu + +#endif diff --git a/stm32f103/index.cmake b/stm32f103/index.cmake new file mode 100644 index 0000000..c840aa5 --- /dev/null +++ b/stm32f103/index.cmake @@ -0,0 +1,81 @@ +set(CMAKE_C_STANDARD "11") +set(CMAKE_CXX_STANDARD "14") + +set(MCU_INIT_SOURCES "") +list(APPEND MCU_INIT_SOURCES "${MCU_BASEDIR}/stm32f103/src/init_low.s") +list(APPEND MCU_INIT_SOURCES "${MCU_BASEDIR}/stm32f103/src/init_high.cpp") +list(APPEND MCU_INIT_SOURCES "${MCU_BASEDIR}/stm32f103/src/default_handler.cpp") +list(APPEND MCU_INIT_SOURCES "${MCU_BASEDIR}/stm32f103/include/mcu/init.h") +set(MCU_INIT_INCLUDES "") +list(APPEND MCU_INIT_INCLUDES "${MCU_BASEDIR}/stm32f103/include") + +function(mcu_add_executable) + + set(options) + set(oneValueArgs TARGET LINKER_SCRIPT) + set(multiValueArgs) + cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (NOT ARGS_TARGET) + message(FATAL_ERROR "MCU: Missing required argument: TARGET") + endif () + + if (MCU_CHIP MATCHES "stm32f103.4" OR MCU_CHIP MATCHES "stm32f103.6") + set(size_define STM32F10X_SM) + elseif (MCU_CHIP MATCHES "stm32f103.8" OR MCU_CHIP MATCHES "stm32f103.b") + set(size_define STM32F10X_MD) + elseif (MCU_CHIP MATCHES "stm32f103.c" OR MCU_CHIP MATCHES "stm32f103.d" OR MCU_CHIP MATCHES "stm32f103.e") + set(size_define STM32F10X_LD) + else () + message(FATAL_ERROR "Unknown STM32 version: ${MCU_CHIP}") + endif () + + target_compile_definitions(${ARGS_TARGET} PUBLIC ${size_define}) + + # Compile and linker options + + set(o_level "$") + target_compile_options(${ARGS_TARGET} PUBLIC + "$<$:-O${o_level}>$<$>:-O3>") + unset(o_level) + + target_compile_options(${ARGS_TARGET} PUBLIC + -mcpu=cortex-m3 + -mthumb + -g + ) + + target_link_libraries(${ARGS_TARGET} PUBLIC + -mcpu=cortex-m3 + -mthumb + -nostdlib + -nostartfiles + -Wl,--gc-sections + ) + + # Linker script + + if (ARGS_LINKER_SCRIPT) + if (NOT IS_ABSOLUTE "${ARGS_LINKER_SCRIPT}") + set(ARGS_LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_LINKER_SCRIPT}") + endif () + set_target_properties(${ARGS_TARGET} PROPERTIES MCU_LINKER_SCRIPT "${ARGS_LINKER_SCRIPT}") + endif () + + stm32_configure_linker_script(${ARGS_TARGET}) + +endfunction() + +function(stm32_configure_linker_script T) + get_target_property(MCU_LINKER_SCRIPT ${T} MCU_LINKER_SCRIPT) + + if (NOT MCU_LINKER_SCRIPT) + set(ld "${MCU_BASEDIR}/stm32f103/stm32f103.ld") + message("MCU: Using built-in linker script: ${ld}") + + set_target_properties(${T} PROPERTIES MCU_LINKER_SCRIPT ${ld}) + endif () + + target_link_libraries(${T} PUBLIC + "-T\"$\"") +endfunction() diff --git a/stm32f103/src/default_handler.cpp b/stm32f103/src/default_handler.cpp new file mode 100644 index 0000000..68a5dff --- /dev/null +++ b/stm32f103/src/default_handler.cpp @@ -0,0 +1,7 @@ +#include +#include +#include +#include + +#include "mcu/init.h" + diff --git a/stm32f103/src/init_high.cpp b/stm32f103/src/init_high.cpp new file mode 100644 index 0000000..ca083de --- /dev/null +++ b/stm32f103/src/init_high.cpp @@ -0,0 +1,384 @@ +#include +#include +#include "stm32f10x.h" +#include "mcu/init.h" + +// This is required to keep the compiler from replacing parts of a function with calls to library functions like memcpy. +# define disable_replace_with_library_calls \ + __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns"))) + +using namespace mcu; + +/** + * Symbols that are defined by the linker + */ +extern "C" +{ +extern uint8_t _copy_data_load, _copy_data_store, _copy_data_store_end; +extern uint8_t _bss_start, _bss_end; + +typedef void(*constructor_t)(); +extern constructor_t _init_array_start[], _init_array_end[]; +} + +extern "C" +__attribute__((used)) +void __cxa_pure_virtual() +{ + halt(); +} + +extern "C" +__attribute__((used)) +void __aeabi_unwind_cpp_pr0() +{ +} + +extern "C" +__attribute__((used)) +void __aeabi_unwind_cpp_pr1() +{ +} + +extern "C" +__attribute__((used)) +void __aeabi_unwind_cpp_pr2() +{ +} + +extern "C" +__attribute__((used)) +disable_replace_with_library_calls +void *memset(void *dst, int i, size_t n) +{ + auto *d = static_cast(dst); + auto c = (uint8_t) i; + while (n > 0) { + *d = c; + d++; + n--; + } + return dst; +} + +extern "C" +__attribute__((used)) +disable_replace_with_library_calls +void *memcpy(void *destination, void *source, size_t num) +{ + auto *d = (uint8_t *) destination; + auto *s = (uint8_t *) source; + for (size_t i = 0; i < num; i++) { + d[i] = s[i]; + } + return destination; +} + +extern "C" +__attribute__((used)) +void init_high() +{ + // Copy data from flash to ram + size_t num = &_copy_data_store_end - &_copy_data_store; + memcpy(&_copy_data_store, &_copy_data_load, num); + + // Clear the BSS segment + memset(&_bss_start, 0, &_bss_end - &_bss_start); + + // Initialize c++ constructors + for (constructor_t *fn = _init_array_start; fn < _init_array_end; fn++) { + (*fn)(); + } + + main(); +} + +__attribute__((used)) +struct { + uint32_t CFSR; + uint32_t HFSR; + uint32_t DFSR; + uint32_t AFSR; +// uint32_t MMAR; + uint32_t BFAR; +} Default_Handler_Info; + +#define dbg_printf +//void dbg_printf(...); + +extern "C" +__attribute__((weak, used)) +void HardFault_Handler_C() +{ + halt(); +} + +extern "C" +__attribute__((used)) +void Default_Handler() +{ + Default_Handler_Info = { + CFSR: SCB->CFSR, + HFSR: SCB->HFSR, + DFSR: SCB->DFSR, + AFSR: SCB->AFSR, + BFAR: SCB->BFAR, + }; + + dbg_printf("Default handler:\n"); + + dbg_printf("HFSR: 0x%08lx\n", Default_Handler_Info.HFSR); + if (Default_Handler_Info.HFSR & SCB_HFSR_DEBUGEVT) { + dbg_printf(" HFSR.DEBUGEVT\n"); + } + if (Default_Handler_Info.HFSR & SCB_HFSR_FORCED) { + dbg_printf(" HFSR.FORCED\n"); + } + if (Default_Handler_Info.HFSR & SCB_HFSR_VECTTBL) { + dbg_printf(" HFSR.VECTTBL\n"); + } + + dbg_printf("CFSR: 0x%08lx\n", Default_Handler_Info.CFSR); + if (Default_Handler_Info.CFSR & SCB_CFSR_DIVBYZERO) { + dbg_printf(" UFSR.DIVBYZERO\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_UNALIGNED) { + dbg_printf(" UFSR.UNALIGED\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_NOCP) { + dbg_printf(" UFSR.NOCP\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_INVPC) { + dbg_printf(" UFSR.INVPC\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_INVSTATE) { + dbg_printf(" UFSR.INVSTATE\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_UNDEFINSTR) { + dbg_printf(" UFSR.UNDEFINSTR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_BFARVALID) { + dbg_printf(" BFSR.BFARVALID\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_STKERR) { + dbg_printf(" BFSR.STKERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_UNSTKERR) { + dbg_printf(" BFSR.UNSTKERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_IMPRECISERR) { + dbg_printf(" BFSR.IMPRECISERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_PRECISERR) { + dbg_printf(" BFSR.PRECISERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_IBUSERR) { + dbg_printf(" BFSR.IBUSERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_MMARVALID) { + dbg_printf(" MMFSR.MMARVALID\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_MSTKERR) { + dbg_printf(" MMFSR.MSTKERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_MUNSTKERR) { + dbg_printf(" MMFSR.MUNSTKERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_DACCVIOL) { + dbg_printf(" MMFSR.DACCVIOL\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_IACCVIOL) { + dbg_printf(" MMFSR.IACCVIOL\n"); + } + dbg_printf("DFSR: 0x%08lx\n", Default_Handler_Info.DFSR); + dbg_printf("AFSR: 0x%08lx\n", Default_Handler_Info.AFSR); + + if (Default_Handler_Info.CFSR & SCB_CFSR_BFARVALID) { + dbg_printf("BFAR: 0x%08lx\n", Default_Handler_Info.BFAR); + } else { + dbg_printf("BFAR: \n"); + } + + dbg_printf("NVIC:\n"); + for (size_t i = 0; i < SizeOfArray(NVIC->IABR); i++) { + dbg_printf(" IABR[%d]: 0x%08lx\n", i, NVIC->IABR[i]); + } + + halt(); +} + +void _Reset_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void NMI_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void HardFault_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void MemManage_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void BusFault_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void UsageFault_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void SVC_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void DebugMon_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void PendSV_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void SysTick_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void WWDG_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void PVD_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TAMPER_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void RTC_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void FLASH_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void RCC_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI4_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel4_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel5_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel6_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel7_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void ADC1_2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USB_HP_CAN1_TX_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USB_LP_CAN1_RX0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void CAN1_RX1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void CAN1_SCE_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI9_5_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM1_BRK_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM1_UP_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM1_TRG_COM_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM1_CC_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM4_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void I2C1_EV_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void I2C1_ER_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void I2C2_EV_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void I2C2_ER_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void SPI1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void SPI2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USART1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USART2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USART3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI15_10_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void RTCAlarm_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USBWakeUp_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +__attribute__((section(".isr_vectors"), used)) +uint32_t isr_vectors[74] = { + (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, + 0, + 0, + 0, + (uint32_t) SVC_Handler, + (uint32_t) DebugMon_Handler, + 0, + (uint32_t) PendSV_Handler, + (uint32_t) SysTick_Handler, + (uint32_t) WWDG_IRQHandler, + (uint32_t) PVD_IRQHandler, + (uint32_t) TAMPER_IRQHandler, + (uint32_t) RTC_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_Channel1_IRQHandler, + (uint32_t) DMA1_Channel2_IRQHandler, + (uint32_t) DMA1_Channel3_IRQHandler, + (uint32_t) DMA1_Channel4_IRQHandler, + (uint32_t) DMA1_Channel5_IRQHandler, + (uint32_t) DMA1_Channel6_IRQHandler, + (uint32_t) DMA1_Channel7_IRQHandler, + (uint32_t) ADC1_2_IRQHandler, + (uint32_t) USB_HP_CAN1_TX_IRQHandler, + (uint32_t) USB_LP_CAN1_RX0_IRQHandler, + (uint32_t) CAN1_RX1_IRQHandler, + (uint32_t) CAN1_SCE_IRQHandler, + (uint32_t) EXTI9_5_IRQHandler, + (uint32_t) TIM1_BRK_IRQHandler, + (uint32_t) TIM1_UP_IRQHandler, + (uint32_t) TIM1_TRG_COM_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) RTCAlarm_IRQHandler, + (uint32_t) USBWakeUp_IRQHandler, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; diff --git a/stm32f103/src/init_low.s b/stm32f103/src/init_low.s new file mode 100644 index 0000000..b666ed4 --- /dev/null +++ b/stm32f103/src/init_low.s @@ -0,0 +1,47 @@ +.syntax unified +.cpu cortex-m3 +.thumb + +.section .text + +.thumb_func +.global _Reset_Handler +_Reset_Handler: + bl init_high + b halt + +.thumb_func +.global halt +halt: + b . + +.thumb_func +.global NMI_Handler +NMI_Handler: + b halt + +.thumb_func +.global HardFault_Handler +HardFault_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + b HardFault_Handler_C + +.thumb_func +.global MemManage_Handler +MemManage_Handler: + b halt + +.thumb_func +.global BusFault_Handler +BusFault_Handler: + b halt + +.thumb_func +.global UsageFault_Handler +UsageFault_Handler: + b halt + +.end diff --git a/stm32f103/stm32f103.ld b/stm32f103/stm32f103.ld new file mode 100644 index 0000000..bafd520 --- /dev/null +++ b/stm32f103/stm32f103.ld @@ -0,0 +1,62 @@ +ENTRY(_Reset_Handler) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20k + MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K +} + +_estack = ORIGIN(RAM) + LENGTH(RAM); + +SECTIONS +{ + /* Put the ISR section at the start of the flash area */ + .isr : + { + /* The first word has to be the initial stack pointer */ + LONG(__initial_stack_pointer); + KEEP(*/init_high.cpp.obj(.isr_vectors)) + } >FLASH + ASSERT(SIZEOF(.isr) > 100, "The isr_vectors section is too small") + ASSERT(SIZEOF(.isr) < 1000, "The isr_vectors section is too big") + ASSERT(ADDR(.isr) == ORIGIN(FLASH), "The isr_vectors section was not placed at the start of the flash area") + + .text : + { + *(.text) + KEEP(*(.text.*)) + *(.rodata*) + } >FLASH + + .init_arrays : + { + _init_array_start = .; + KEEP(*(.init_array)) + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*))) + _init_array_end = .; + } >FLASH + + . = ORIGIN(RAM); + + .data ALIGN(4) : + { + *(.data) + *(.data.*) + } >RAM AT >FLASH + + .bss ALIGN(4) (NOLOAD) : + { + *(.bss) + *(.bss.*) + } >RAM + + _copy_data_store = ADDR(.data); + _copy_data_store_end = _copy_data_store + SIZEOF(.data); + _copy_data_load = LOADADDR(.data); + + _bss_start = ADDR(.bss); + _bss_end = _bss_start + SIZEOF(.bss); + + __initial_stack_pointer = ORIGIN(RAM) + LENGTH(RAM) - 1; +} diff --git a/stm32f103/toolchain.cmake b/stm32f103/toolchain.cmake new file mode 100644 index 0000000..2a0e5b8 --- /dev/null +++ b/stm32f103/toolchain.cmake @@ -0,0 +1,26 @@ +find_program(MCU_ARM_CC arm-none-eabi-gcc ${MCU_TOOLCHAIN_DIR}/bin) +find_program(MCU_ARM_CXX arm-none-eabi-g++ ${MCU_TOOLCHAIN_DIR}/bin) +find_program(MCU_ARM_OBJCOPY arm-none-eabi-objcopy ${MCU_TOOLCHAIN_DIR}/bin) +find_program(MCU_ARM_OBJDUMP arm-none-eabi-objdump ${MCU_TOOLCHAIN_DIR}/bin) +find_program(MCU_ARM_READELF arm-none-eabi-readelf ${MCU_TOOLCHAIN_DIR}/bin) +find_program(MCU_ARM_SIZE arm-none-eabi-size ${MCU_TOOLCHAIN_DIR}/bin) +find_program(MCU_ARM_NM arm-none-eabi-nm ${MCU_TOOLCHAIN_DIR}/bin) + +#message("MCU_ARM_CC = ${MCU_ARM_CC}") +#message("MCU_ARM_CXX = ${MCU_ARM_CXX}") +#message("MCU_ARM_OBJCOPY = ${MCU_ARM_OBJCOPY}") +#message("MCU_ARM_SIZE = ${MCU_ARM_SIZE}") + +set(_CMAKE_TOOLCHAIN_PREFIX arm-none-eabi-) +include(CMakeFindBinUtils) + +if (NOT MCU_ARM_CC OR NOT MCU_ARM_CXX OR NOT MCU_ARM_OBJCOPY OR NOT MCU_ARM_SIZE) + message(FATAL_ERROR "Could not find required compiler tools.") +endif() + +set(CMAKE_C_COMPILER ${MCU_ARM_CC} CACHE FILE "") +set(CMAKE_CXX_COMPILER ${MCU_ARM_CXX} CACHE FILE "") +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 14) -- cgit v1.2.3