use startup files and linker scripts from LibreUCpp

This commit is contained in:
Hubert Denkmair 2019-10-26 22:40:33 +02:00 committed by fenugrec
parent d7332a3173
commit fef1d397b5
23 changed files with 341 additions and 10535 deletions

View File

@ -4,23 +4,25 @@ project(candleLightFirmware C ASM)
add_compile_options(
-std=gnu11
-mcpu=cortex-m0 -mthumb
-Wall -Wextra -Werror -Wno-deprecated
-Wall -Wextra -Werror
-fmessage-length=0
-fsigned-char
-ffunction-sections -fdata-sections
-ffreestanding
-fno-move-loop-invariants
-Os -g3
--specs=nano.specs
--specs=nosys.specs
)
add_link_options(
-mcpu=cortex-m0 -mthumb -O
-Wall -Wextra -g3
-nostartfiles -Xlinker --gc-sections --specs=nano.specs
-T ${CMAKE_SOURCE_DIR}/ldscripts/ldscript.ld
-Xlinker --gc-sections
--specs=nano.specs
--specs=nosys.specs
)
add_subdirectory(libs/STM32_HAL)
add_subdirectory(libs/STM32_USB_Device_Library)
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake )
@ -43,6 +45,7 @@ set(
include/timer.h src/timer.c
include/util.h src/util.c
src/startup.c
src/main.c
src/interrupts.c
)

139
ldscripts/STM32F042X6.ld Normal file
View File

@ -0,0 +1,139 @@
__STACK_SIZE = 512;
__HEAP_SIZE = 2560;
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 6K
}
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.vectors))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
__copy_table_end__ = .;
} > FLASH
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
__zero_table_end__ = .;
} > FLASH
__etext = ALIGN (4);
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data)
*(.data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM AT > RAM
.heap (COPY) :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
. = . + __HEAP_SIZE;
. = ALIGN(8);
__HeapLimit = .;
} > RAM
.stack (ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE) (COPY) :
{
. = ALIGN(8);
__StackLimit = .;
. = . + __STACK_SIZE;
. = ALIGN(8);
__StackTop = .;
} > RAM
PROVIDE(__stack = __StackTop);
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

139
ldscripts/STM32F072XB.ld Normal file
View File

@ -0,0 +1,139 @@
__STACK_SIZE = 512;
__HEAP_SIZE = 2560;
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
}
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.vectors))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
__copy_table_end__ = .;
} > FLASH
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
__zero_table_end__ = .;
} > FLASH
__etext = ALIGN (4);
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data)
*(.data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM AT > RAM
.heap (COPY) :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
. = . + __HEAP_SIZE;
. = ALIGN(8);
__HeapLimit = .;
} > RAM
.stack (ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE) (COPY) :
{
. = ALIGN(8);
__StackLimit = .;
. = . + __STACK_SIZE;
. = ALIGN(8);
__StackTop = .;
} > RAM
PROVIDE(__stack = __StackTop);
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View File

@ -17,16 +17,6 @@ set(SOURCES
src/stm32f0xx/stm32f0xx_hal_tim_ex.c
src/stm32f0xx/stm32f0xx_ll_usb.c
src/newlib/assert.c
src/newlib/_exit.c
src/newlib/_sbrk.c
src/newlib/_startup.c
src/newlib/_syscalls.c
src/cortexm/exception_handlers.c
src/cortexm/_initialize_hardware.c
src/cortexm/_reset_hardware.c
src/cmsis/system_stm32f0xx.c
)
@ -38,12 +28,12 @@ set(INCLUDE_DIRS
config/
)
add_library(STM32_HAL_STM32F042x6 OBJECT ${SOURCES} src/cmsis/startup_stm32f042x6.s)
add_library(STM32_HAL_STM32F042x6 OBJECT ${SOURCES})
target_include_directories(STM32_HAL_STM32F042x6 PUBLIC ${INCLUDE_DIRS})
target_compile_options(STM32_HAL_STM32F042x6 PRIVATE -Wno-unused-parameter)
target_compile_definitions(STM32_HAL_STM32F042x6 PUBLIC STM32F042x6)
add_library(STM32_HAL_STM32F072xB OBJECT ${SOURCES} src/cmsis/startup_stm32f072xb.s)
add_library(STM32_HAL_STM32F072xB OBJECT ${SOURCES})
target_include_directories(STM32_HAL_STM32F072xB PUBLIC ${INCLUDE_DIRS})
target_compile_options(STM32_HAL_STM32F072xB PRIVATE -Wno-unused-parameter)
target_compile_definitions(STM32_HAL_STM32F072xB PUBLIC STM32F072xB)

View File

@ -1,94 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
#ifndef CORTEXM_EXCEPTION_HANDLERS_H_
#define CORTEXM_EXCEPTION_HANDLERS_H_
#include <stdint.h>
#if defined(DEBUG)
#define __DEBUG_BKPT() asm volatile ("bkpt 0")
#endif
// ----------------------------------------------------------------------------
#if defined(__cplusplus)
extern "C"
{
#endif
// External references to cortexm_handlers.c
extern void
Reset_Handler (void);
extern void
NMI_Handler (void);
extern void
HardFault_Handler (void);
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
extern void
MemManage_Handler (void);
extern void
BusFault_Handler (void);
extern void
UsageFault_Handler (void);
extern void
DebugMon_Handler (void);
#endif
extern void
SVC_Handler (void);
extern void
PendSV_Handler (void);
extern void
SysTick_Handler (void);
// Exception Stack Frame of the Cortex-M3 or Cortex-M4 processor.
typedef struct
{
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uint32_t lr;
uint32_t pc;
uint32_t psr;
#if defined(__ARM_ARCH_7EM__)
uint32_t s[16];
#endif
} ExceptionStackFrame;
#if defined(TRACE)
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
void
dumpExceptionStack (ExceptionStackFrame* frame, uint32_t cfsr, uint32_t mmfar,
uint32_t bfar, uint32_t lr);
#endif // defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
#if defined(__ARM_ARCH_6M__)
void
dumpExceptionStack (ExceptionStackFrame* frame, uint32_t lr);
#endif // defined(__ARM_ARCH_6M__)
#endif // defined(TRACE)
void
HardFault_Handler_C (ExceptionStackFrame* frame, uint32_t lr);
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
void
UsageFault_Handler_C (ExceptionStackFrame* frame, uint32_t lr);
void
BusFault_Handler_C (ExceptionStackFrame* frame, uint32_t lr);
#endif // defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
#if defined(__cplusplus)
}
#endif
// ----------------------------------------------------------------------------
#endif // CORTEXM_EXCEPTION_HANDLERS_H_

View File

@ -1,146 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
#ifndef DIAG_TRACE_H_
#define DIAG_TRACE_H_
// ----------------------------------------------------------------------------
#include <unistd.h>
// ----------------------------------------------------------------------------
// The trace device is an independent output channel, intended for debug
// purposes.
//
// The API is simple, and mimics the standard output calls:
// - trace_printf()
// - trace_puts()
// - trace_putchar();
//
// The implementation is done in
// - trace_write()
//
// Trace support is enabled by adding the TRACE definition.
// By default the trace messages are forwarded to the ITM output,
// but can be rerouted via any device or completely suppressed by
// changing the definitions required in system/src/diag/trace_impl.c
// (currently OS_USE_TRACE_ITM, OS_USE_TRACE_SEMIHOSTING_DEBUG/_STDOUT).
//
// When TRACE is not defined, all functions are inlined to empty bodies.
// This has the advantage that the trace call do not need to be conditionally
// compiled with #ifdef TRACE/#endif
#if defined(TRACE)
#if defined(__cplusplus)
extern "C"
{
#endif
void
trace_initialize(void);
// Implementation dependent
ssize_t
trace_write(const char* buf, size_t nbyte);
// ----- Portable -----
int
trace_printf(const char* format, ...);
int
trace_puts(const char *s);
int
trace_putchar(int c);
void
trace_dump_args(int argc, char* argv[]);
#if defined(__cplusplus)
}
#endif
#else // !defined(TRACE)
#if defined(__cplusplus)
extern "C"
{
#endif
inline void
trace_initialize(void);
// Implementation dependent
inline ssize_t
trace_write(const char* buf, size_t nbyte);
inline int
trace_printf(const char* format, ...);
inline int
trace_puts(const char *s);
inline int
trace_putchar(int c);
inline void
trace_dump_args(int argc, char* argv[]);
#if defined(__cplusplus)
}
#endif
inline void
__attribute__((always_inline))
trace_initialize(void)
{
}
// Empty definitions when trace is not defined
inline ssize_t
__attribute__((always_inline))
trace_write(const char* buf __attribute__((unused)),
size_t nbyte __attribute__((unused)))
{
return 0;
}
inline int
__attribute__((always_inline))
trace_printf(const char* format __attribute__((unused)), ...)
{
return 0;
}
inline int
__attribute__((always_inline))
trace_puts(const char *s __attribute__((unused)))
{
return 0;
}
inline int
__attribute__((always_inline))
trace_putchar(int c)
{
return c;
}
inline void
__attribute__((always_inline))
trace_dump_args(int argc __attribute__((unused)),
char* argv[] __attribute__((unused)))
{
}
#endif // defined(TRACE)
// ----------------------------------------------------------------------------
#endif // DIAG_TRACE_H_

View File

@ -1,309 +0,0 @@
/**
******************************************************************************
* @file startup_stm32f042x6.s
* @author MCD Application Team
* @brief STM32F042x4/STM32F042x6 devices vector table for GCC toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M0 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
.syntax unified
.cpu cortex-m0
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr r0, =_estack
mov sp, r0 /* set stack pointer */
/*Check if boot space corresponds to test memory*/
LDR R0,=0x00000004
LDR R1, [R0]
LSRS R1, R1, #24
LDR R2,=0x1F
CMP R1, R2
BNE ApplicationStart
/*SYSCFG clock enable*/
LDR R0,=0x40021018
LDR R1,=0x00000001
STR R1, [R0]
/*Set CFGR1 register with flash memory remap at address 0*/
LDR R0,=0x40010000
LDR R1,=0x00000000
STR R1, [R0]
ApplicationStart:
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
movs r3, #0
b LoopCopyDataInit
CopyDataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyDataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyDataInit
/* Zero fill the bss segment. */
ldr r2, =_sbss
ldr r4, =_ebss
movs r3, #0
b LoopFillZerobss
FillZerobss:
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
cmp r2, r4
bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
LoopForever:
b LoopForever
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M0. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word 0
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word WWDG_IRQHandler /* Window WatchDog */
.word PVD_VDDIO2_IRQHandler /* PVD and VDDIO2 through EXTI Line detect */
.word RTC_IRQHandler /* RTC through the EXTI line */
.word FLASH_IRQHandler /* FLASH */
.word RCC_CRS_IRQHandler /* RCC and CRS */
.word EXTI0_1_IRQHandler /* EXTI Line 0 and 1 */
.word EXTI2_3_IRQHandler /* EXTI Line 2 and 3 */
.word EXTI4_15_IRQHandler /* EXTI Line 4 to 15 */
.word TSC_IRQHandler /* TSC */
.word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
.word DMA1_Channel2_3_IRQHandler /* DMA1 Channel 2 and Channel 3 */
.word DMA1_Channel4_5_IRQHandler /* DMA1 Channel 4 and Channel 5 */
.word ADC1_IRQHandler /* ADC1 */
.word TIM1_BRK_UP_TRG_COM_IRQHandler /* TIM1 Break, Update, Trigger and Commutation */
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
.word TIM2_IRQHandler /* TIM2 */
.word TIM3_IRQHandler /* TIM3 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word TIM14_IRQHandler /* TIM14 */
.word 0 /* Reserved */
.word TIM16_IRQHandler /* TIM16 */
.word TIM17_IRQHandler /* TIM17 */
.word I2C1_IRQHandler /* I2C1 */
.word 0 /* Reserved */
.word SPI1_IRQHandler /* SPI1 */
.word SPI2_IRQHandler /* SPI2 */
.word USART1_IRQHandler /* USART1 */
.word USART2_IRQHandler /* USART2 */
.word 0 /* Reserved */
.word CEC_CAN_IRQHandler /* CEC and CAN */
.word USB_IRQHandler /* USB */
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
.weak PVD_VDDIO2_IRQHandler
.thumb_set PVD_VDDIO2_IRQHandler,Default_Handler
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak RCC_CRS_IRQHandler
.thumb_set RCC_CRS_IRQHandler,Default_Handler
.weak EXTI0_1_IRQHandler
.thumb_set EXTI0_1_IRQHandler,Default_Handler
.weak EXTI2_3_IRQHandler
.thumb_set EXTI2_3_IRQHandler,Default_Handler
.weak EXTI4_15_IRQHandler
.thumb_set EXTI4_15_IRQHandler,Default_Handler
.weak TSC_IRQHandler
.thumb_set TSC_IRQHandler,Default_Handler
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak DMA1_Channel2_3_IRQHandler
.thumb_set DMA1_Channel2_3_IRQHandler,Default_Handler
.weak DMA1_Channel4_5_IRQHandler
.thumb_set DMA1_Channel4_5_IRQHandler,Default_Handler
.weak ADC1_IRQHandler
.thumb_set ADC1_IRQHandler,Default_Handler
.weak TIM1_BRK_UP_TRG_COM_IRQHandler
.thumb_set TIM1_BRK_UP_TRG_COM_IRQHandler,Default_Handler
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak TIM3_IRQHandler
.thumb_set TIM3_IRQHandler,Default_Handler
.weak TIM14_IRQHandler
.thumb_set TIM14_IRQHandler,Default_Handler
.weak TIM16_IRQHandler
.thumb_set TIM16_IRQHandler,Default_Handler
.weak TIM17_IRQHandler
.thumb_set TIM17_IRQHandler,Default_Handler
.weak I2C1_IRQHandler
.thumb_set I2C1_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak CEC_CAN_IRQHandler
.thumb_set CEC_CAN_IRQHandler,Default_Handler
.weak USB_IRQHandler
.thumb_set USB_IRQHandler,Default_Handler
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -1,294 +0,0 @@
/**
******************************************************************************
* @file startup_stm32f072xb.s
* @author MCD Application Team
* @brief STM32F072x8/STM32F072xB devices vector table for GCC toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M0 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
.syntax unified
.cpu cortex-m0
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr r0, =_estack
mov sp, r0 /* set stack pointer */
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
movs r3, #0
b LoopCopyDataInit
CopyDataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyDataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyDataInit
/* Zero fill the bss segment. */
ldr r2, =_sbss
ldr r4, =_ebss
movs r3, #0
b LoopFillZerobss
FillZerobss:
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
cmp r2, r4
bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
LoopForever:
b LoopForever
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M0. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word 0
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word WWDG_IRQHandler /* Window WatchDog */
.word PVD_VDDIO2_IRQHandler /* PVD and VDDIO2 through EXTI Line detect */
.word RTC_IRQHandler /* RTC through the EXTI line */
.word FLASH_IRQHandler /* FLASH */
.word RCC_CRS_IRQHandler /* RCC and CRS */
.word EXTI0_1_IRQHandler /* EXTI Line 0 and 1 */
.word EXTI2_3_IRQHandler /* EXTI Line 2 and 3 */
.word EXTI4_15_IRQHandler /* EXTI Line 4 to 15 */
.word TSC_IRQHandler /* TSC */
.word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
.word DMA1_Channel2_3_IRQHandler /* DMA1 Channel 2 and Channel 3 */
.word DMA1_Channel4_5_6_7_IRQHandler /* DMA1 Channel 4, Channel 5, Channel 6 and Channel 7*/
.word ADC1_COMP_IRQHandler /* ADC1, COMP1 and COMP2 */
.word TIM1_BRK_UP_TRG_COM_IRQHandler /* TIM1 Break, Update, Trigger and Commutation */
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
.word TIM2_IRQHandler /* TIM2 */
.word TIM3_IRQHandler /* TIM3 */
.word TIM6_DAC_IRQHandler /* TIM6 and DAC */
.word TIM7_IRQHandler /* TIM7 */
.word TIM14_IRQHandler /* TIM14 */
.word TIM15_IRQHandler /* TIM15 */
.word TIM16_IRQHandler /* TIM16 */
.word TIM17_IRQHandler /* TIM17 */
.word I2C1_IRQHandler /* I2C1 */
.word I2C2_IRQHandler /* I2C2 */
.word SPI1_IRQHandler /* SPI1 */
.word SPI2_IRQHandler /* SPI2 */
.word USART1_IRQHandler /* USART1 */
.word USART2_IRQHandler /* USART2 */
.word USART3_4_IRQHandler /* USART3 and USART4 */
.word CEC_CAN_IRQHandler /* CEC and CAN */
.word USB_IRQHandler /* USB */
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
.weak PVD_VDDIO2_IRQHandler
.thumb_set PVD_VDDIO2_IRQHandler,Default_Handler
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak RCC_CRS_IRQHandler
.thumb_set RCC_CRS_IRQHandler,Default_Handler
.weak EXTI0_1_IRQHandler
.thumb_set EXTI0_1_IRQHandler,Default_Handler
.weak EXTI2_3_IRQHandler
.thumb_set EXTI2_3_IRQHandler,Default_Handler
.weak EXTI4_15_IRQHandler
.thumb_set EXTI4_15_IRQHandler,Default_Handler
.weak TSC_IRQHandler
.thumb_set TSC_IRQHandler,Default_Handler
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak DMA1_Channel2_3_IRQHandler
.thumb_set DMA1_Channel2_3_IRQHandler,Default_Handler
.weak DMA1_Channel4_5_6_7_IRQHandler
.thumb_set DMA1_Channel4_5_6_7_IRQHandler,Default_Handler
.weak ADC1_COMP_IRQHandler
.thumb_set ADC1_COMP_IRQHandler,Default_Handler
.weak TIM1_BRK_UP_TRG_COM_IRQHandler
.thumb_set TIM1_BRK_UP_TRG_COM_IRQHandler,Default_Handler
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak TIM3_IRQHandler
.thumb_set TIM3_IRQHandler,Default_Handler
.weak TIM6_DAC_IRQHandler
.thumb_set TIM6_DAC_IRQHandler,Default_Handler
.weak TIM7_IRQHandler
.thumb_set TIM7_IRQHandler,Default_Handler
.weak TIM14_IRQHandler
.thumb_set TIM14_IRQHandler,Default_Handler
.weak TIM15_IRQHandler
.thumb_set TIM15_IRQHandler,Default_Handler
.weak TIM16_IRQHandler
.thumb_set TIM16_IRQHandler,Default_Handler
.weak TIM17_IRQHandler
.thumb_set TIM17_IRQHandler,Default_Handler
.weak I2C1_IRQHandler
.thumb_set I2C1_IRQHandler,Default_Handler
.weak I2C2_IRQHandler
.thumb_set I2C2_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak USART3_4_IRQHandler
.thumb_set USART3_4_IRQHandler,Default_Handler
.weak CEC_CAN_IRQHandler
.thumb_set CEC_CAN_IRQHandler,Default_Handler
.weak USB_IRQHandler
.thumb_set USB_IRQHandler,Default_Handler
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -1,87 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// ----------------------------------------------------------------------------
#include "cmsis_device.h"
// ----------------------------------------------------------------------------
extern unsigned int __vectors_start;
// Forward declarations.
void
__initialize_hardware_early(void);
void
__initialize_hardware(void);
// ----------------------------------------------------------------------------
// This is the early hardware initialisation routine, it can be
// redefined in the application for more complex cases that
// require early inits (before BSS init).
//
// Called early from _start(), right before data & bss init.
//
// After Reset the Cortex-M processor is in Thread mode,
// priority is Privileged, and the Stack is set to Main.
void
__attribute__((weak))
__initialize_hardware_early(void)
{
// Call the CSMSIS system initialisation routine.
SystemInit();
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
// Set VTOR to the actual address, provided by the linker script.
// Override the manual, possibly wrong, SystemInit() setting.
SCB->VTOR = (uint32_t)(&__vectors_start);
#endif
// The current version of SystemInit() leaves the value of the clock
// in a RAM variable (SystemCoreClock), which will be cleared shortly,
// so it needs to be recomputed after the RAM initialisations
// are completed.
#if defined(OS_INCLUDE_STARTUP_INIT_FP) || (defined (__VFP_FP__) && !defined (__SOFTFP__))
// Normally FP init is done by SystemInit(). In case this is not done
// there, it is possible to force its inclusion by defining
// OS_INCLUDE_STARTUP_INIT_FP.
// Enable the Cortex-M4 FPU only when -mfloat-abi=hard.
// Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C)
// Set bits 20-23 to enable CP10 and CP11 coprocessor
SCB->CPACR |= (0xF << 20);
#endif // (__VFP_FP__) && !(__SOFTFP__)
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk;
#endif
}
// This is the second hardware initialisation routine, it can be
// redefined in the application for more complex cases that
// require custom inits (before constructors), otherwise these can
// be done in main().
//
// Called from _start(), right after data & bss init, before
// constructors.
void
__attribute__((weak))
__initialize_hardware(void)
{
// Call the CSMSIS system clock routine to store the clock frequency
// in the SystemCoreClock global RAM location.
SystemCoreClockUpdate();
}
// ----------------------------------------------------------------------------

View File

@ -1,37 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// ----------------------------------------------------------------------------
#include "cmsis_device.h"
// ----------------------------------------------------------------------------
extern void
__attribute__((noreturn))
NVIC_SystemReset(void);
// ----------------------------------------------------------------------------
// Forward declarations
void
__reset_hardware(void);
// ----------------------------------------------------------------------------
// This is the default hardware reset routine; it can be
// redefined in the application for more complex applications.
//
// Called from _exit().
void
__attribute__((weak,noreturn))
__reset_hardware()
{
NVIC_SystemReset();
}
// ----------------------------------------------------------------------------

View File

@ -1,599 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// ----------------------------------------------------------------------------
#include "cortexm/ExceptionHandlers.h"
#include "cmsis_device.h"
#include "diag/Trace.h"
#include <string.h>
// ----------------------------------------------------------------------------
extern void
__attribute__((noreturn,weak))
_start (void);
// ----------------------------------------------------------------------------
// Default exception handlers. Override the ones here by defining your own
// handler routines in your application code.
// ----------------------------------------------------------------------------
#if defined(DEBUG)
// The DEBUG version is not naked, but has a proper stack frame,
// to allow setting breakpoints at Reset_Handler.
void __attribute__ ((section(".after_vectors"),noreturn))
Reset_Handler (void)
{
_start ();
}
#else
// The Release version is optimised to a quick branch to _start.
void __attribute__ ((section(".after_vectors"),naked))
Reset_Handler(void)
{
asm volatile
(
" ldr r0,=_start \n"
" bx r0"
:
:
:
);
}
#endif
void __attribute__ ((section(".after_vectors"),weak))
NMI_Handler (void)
{
#if defined(DEBUG)
__DEBUG_BKPT();
#endif
while (1)
{
}
}
// ----------------------------------------------------------------------------
#if defined(TRACE)
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
// The values of BFAR and MMFAR stay unchanged if the BFARVALID or
// MMARVALID is set. However, if a new fault occurs during the
// execution of this fault handler, the value of the BFAR and MMFAR
// could potentially be erased. In order to ensure the fault addresses
// accessed are valid, the following procedure should be used:
// 1. Read BFAR/MMFAR.
// 2. Read CFSR to get BFARVALID or MMARVALID. If the value is 0, the
// value of BFAR or MMFAR accessed can be invalid and can be discarded.
// 3. Optionally clear BFARVALID or MMARVALID.
// (See Joseph Yiu's book).
void
dumpExceptionStack (ExceptionStackFrame* frame,
uint32_t cfsr, uint32_t mmfar, uint32_t bfar,
uint32_t lr)
{
trace_printf ("Stack frame:\n");
trace_printf (" R0 = %08X\n", frame->r0);
trace_printf (" R1 = %08X\n", frame->r1);
trace_printf (" R2 = %08X\n", frame->r2);
trace_printf (" R3 = %08X\n", frame->r3);
trace_printf (" R12 = %08X\n", frame->r12);
trace_printf (" LR = %08X\n", frame->lr);
trace_printf (" PC = %08X\n", frame->pc);
trace_printf (" PSR = %08X\n", frame->psr);
trace_printf ("FSR/FAR:\n");
trace_printf (" CFSR = %08X\n", cfsr);
trace_printf (" HFSR = %08X\n", SCB->HFSR);
trace_printf (" DFSR = %08X\n", SCB->DFSR);
trace_printf (" AFSR = %08X\n", SCB->AFSR);
if (cfsr & (1UL << 7))
{
trace_printf (" MMFAR = %08X\n", mmfar);
}
if (cfsr & (1UL << 15))
{
trace_printf (" BFAR = %08X\n", bfar);
}
trace_printf ("Misc\n");
trace_printf (" LR/EXC_RETURN= %08X\n", lr);
}
#endif // defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
#if defined(__ARM_ARCH_6M__)
void
dumpExceptionStack (ExceptionStackFrame* frame, uint32_t lr)
{
trace_printf ("Stack frame:\n");
trace_printf (" R0 = %08X\n", frame->r0);
trace_printf (" R1 = %08X\n", frame->r1);
trace_printf (" R2 = %08X\n", frame->r2);
trace_printf (" R3 = %08X\n", frame->r3);
trace_printf (" R12 = %08X\n", frame->r12);
trace_printf (" LR = %08X\n", frame->lr);
trace_printf (" PC = %08X\n", frame->pc);
trace_printf (" PSR = %08X\n", frame->psr);
trace_printf ("Misc\n");
trace_printf (" LR/EXC_RETURN= %08X\n", lr);
}
#endif // defined(__ARM_ARCH_6M__)
#endif // defined(TRACE)
// ----------------------------------------------------------------------------
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
#if defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
#include "arm/semihosting.h"
int
isSemihosting (ExceptionStackFrame* frame, uint16_t opCode);
/**
* This function provides the minimum functionality to make a semihosting program execute even without the debugger present.
* @param frame pointer to an exception stack frame.
* @param opCode the 16-bin word of the BKPT instruction.
* @return 1 if the instruction was a valid semihosting call; 0 otherwise.
*/
int
isSemihosting (ExceptionStackFrame* frame, uint16_t opCode)
{
uint16_t* pw = (uint16_t*) frame->pc;
if (*pw == opCode)
{
uint32_t r0 = frame->r0;
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS) || defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
uint32_t r1 = frame->r1;
#endif
#if defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
uint32_t* blk = (uint32_t*) r1;
#endif
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
// trace_printf ("sh r0=%d\n", r0);
#endif
switch (r0)
{
#if defined(OS_USE_SEMIHOSTING)
case SEMIHOSTING_SYS_CLOCK:
case SEMIHOSTING_SYS_ELAPSED:
case SEMIHOSTING_SYS_FLEN:
case SEMIHOSTING_SYS_GET_CMDLINE:
case SEMIHOSTING_SYS_REMOVE:
case SEMIHOSTING_SYS_RENAME:
case SEMIHOSTING_SYS_SEEK:
case SEMIHOSTING_SYS_SYSTEM:
case SEMIHOSTING_SYS_TICKFREQ:
case SEMIHOSTING_SYS_TMPNAM:
case SEMIHOSTING_SYS_ISTTY:
frame->r0 = (uint32_t)-1; // the call is not successful or not supported
break;
case SEMIHOSTING_SYS_CLOSE:
frame->r0 = 0; // call is successful
break;
case SEMIHOSTING_SYS_ERRNO:
frame->r0 = 0; // the value of the C library errno variable.
break;
case SEMIHOSTING_SYS_HEAPINFO:
blk[0] = 0; // heap_base
blk[1] = 0; // heap_limit
blk[2] = 0; // stack_base
blk[3] = 0; // stack_limit
break;
case SEMIHOSTING_SYS_ISERROR:
frame->r0 = 0; // 0 if the status word is not an error indication
break;
case SEMIHOSTING_SYS_READ:
// If R0 contains the same value as word 3, the call has
// failed and EOF is assumed.
frame->r0 = blk[2];
break;
case SEMIHOSTING_SYS_READC:
frame->r0 = '\0'; // the byte read from the console.
break;
case SEMIHOSTING_SYS_TIME:
frame->r0 = 0; // the number of seconds since 00:00 January 1, 1970.
break;
case SEMIHOSTING_ReportException:
NVIC_SystemReset ();
// Should not reach here
return 0;
#endif // defined(OS_USE_SEMIHOSTING)
#if defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
#define HANDLER_STDIN (1)
#define HANDLER_STDOUT (2)
#define HANDLER_STDERR (3)
case SEMIHOSTING_SYS_OPEN:
// Process only standard io/out/err and return 1/2/3
if (strcmp ((char*) blk[0], ":tt") == 0)
{
if ((blk[1] == 0))
{
frame->r0 = HANDLER_STDIN;
break;
}
else if (blk[1] == 4)
{
frame->r0 = HANDLER_STDOUT;
break;
}
else if (blk[1] == 8)
{
frame->r0 = HANDLER_STDERR;
break;
}
}
frame->r0 = (uint32_t)-1; // the call is not successful or not supported
break;
case SEMIHOSTING_SYS_WRITE:
// Silently ignore writes to stdout/stderr, fail on all other handler.
if ((blk[0] == HANDLER_STDOUT) || (blk[0] == HANDLER_STDERR))
{
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
frame->r0 = (uint32_t) blk[2]
- trace_write ((char*) blk[1], blk[2]);
#else
frame->r0 = 0; // all sent, no more.
#endif // defined(OS_DEBUG_SEMIHOSTING_FAULTS)
}
else
{
// If other handler, return the total number of bytes
// as the number of bytes that are not written.
frame->r0 = blk[2];
}
break;
#endif // defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
#if defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
case SEMIHOSTING_SYS_WRITEC:
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
{
char ch = *((char*) r1);
trace_write (&ch, 1);
}
#endif
// Register R0 is corrupted.
break;
case SEMIHOSTING_SYS_WRITE0:
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
{
char* p = ((char*) r1);
trace_write (p, strlen (p));
}
#endif
// Register R0 is corrupted.
break;
#endif
default:
return 0;
}
// Alter the PC to make the exception returns to
// the instruction after the faulty BKPT.
frame->pc += 2;
return 1;
}
return 0;
}
#endif
// Hard Fault handler wrapper in assembly.
// It extracts the location of stack frame and passes it to handler
// in C as a pointer. We also pass the LR value as second
// parameter.
// (Based on Joseph Yiu's, The Definitive Guide to ARM Cortex-M3 and
// Cortex-M4 Processors, Third Edition, Chap. 12.8, page 402).
void __attribute__ ((section(".after_vectors"),weak,naked))
HardFault_Handler (void)
{
asm volatile(
" tst lr,#4 \n"
" ite eq \n"
" mrseq r0,msp \n"
" mrsne r0,psp \n"
" mov r1,lr \n"
" ldr r2,=HardFault_Handler_C \n"
" bx r2"
: /* Outputs */
: /* Inputs */
: /* Clobbers */
);
}
void __attribute__ ((section(".after_vectors"),weak,used))
HardFault_Handler_C (ExceptionStackFrame* frame __attribute__((unused)),
uint32_t lr __attribute__((unused)))
{
#if defined(TRACE)
uint32_t mmfar = SCB->MMFAR; // MemManage Fault Address
uint32_t bfar = SCB->BFAR; // Bus Fault Address
uint32_t cfsr = SCB->CFSR; // Configurable Fault Status Registers
#endif
#if defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
// If the BKPT instruction is executed with C_DEBUGEN == 0 and MON_EN == 0,
// it will cause the processor to enter a HardFault exception, with DEBUGEVT
// in the Hard Fault Status register (HFSR) set to 1, and BKPT in the
// Debug Fault Status register (DFSR) also set to 1.
if (((SCB->DFSR & SCB_DFSR_BKPT_Msk) != 0)
&& ((SCB->HFSR & SCB_HFSR_DEBUGEVT_Msk) != 0))
{
if (isSemihosting (frame, 0xBE00 + (AngelSWI & 0xFF)))
{
// Clear the exception cause in exception status.
SCB->HFSR = SCB_HFSR_DEBUGEVT_Msk;
// Continue after the BKPT
return;
}
}
#endif
#if defined(TRACE)
trace_printf ("[HardFault]\n");
dumpExceptionStack (frame, cfsr, mmfar, bfar, lr);
#endif // defined(TRACE)
#if defined(DEBUG)
__DEBUG_BKPT();
#endif
while (1)
{
}
}
#endif // defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
#if defined(__ARM_ARCH_6M__)
// Hard Fault handler wrapper in assembly.
// It extracts the location of stack frame and passes it to handler
// in C as a pointer. We also pass the LR value as second
// parameter.
// (Based on Joseph Yiu's, The Definitive Guide to ARM Cortex-M0
// First Edition, Chap. 12.8, page 402).
void __attribute__ ((section(".after_vectors"),weak,naked))
HardFault_Handler (void)
{
asm volatile(
" movs r0,#4 \n"
" mov r1,lr \n"
" tst r0,r1 \n"
" beq 1f \n"
" mrs r0,psp \n"
" b 2f \n"
"1: \n"
" mrs r0,msp \n"
"2:"
" mov r1,lr \n"
" ldr r2,=HardFault_Handler_C \n"
" bx r2"
: /* Outputs */
: /* Inputs */
: /* Clobbers */
);
}
void __attribute__ ((section(".after_vectors"),weak,used))
HardFault_Handler_C (ExceptionStackFrame* frame __attribute__((unused)),
uint32_t lr __attribute__((unused)))
{
// There is no semihosting support for Cortex-M0, since on ARMv6-M
// faults are fatal and it is not possible to return from the handler.
#if defined(TRACE)
trace_printf ("[HardFault]\n");
dumpExceptionStack (frame, lr);
#endif // defined(TRACE)
#if defined(DEBUG)
__DEBUG_BKPT();
#endif
while (1)
{
}
}
#endif // defined(__ARM_ARCH_6M__)
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
void __attribute__ ((section(".after_vectors"),weak))
MemManage_Handler (void)
{
#if defined(DEBUG)
__DEBUG_BKPT();
#endif
while (1)
{
}
}
void __attribute__ ((section(".after_vectors"),weak,naked))
BusFault_Handler (void)
{
asm volatile(
" tst lr,#4 \n"
" ite eq \n"
" mrseq r0,msp \n"
" mrsne r0,psp \n"
" mov r1,lr \n"
" ldr r2,=BusFault_Handler_C \n"
" bx r2"
: /* Outputs */
: /* Inputs */
: /* Clobbers */
);
}
void __attribute__ ((section(".after_vectors"),weak,used))
BusFault_Handler_C (ExceptionStackFrame* frame __attribute__((unused)),
uint32_t lr __attribute__((unused)))
{
#if defined(TRACE)
uint32_t mmfar = SCB->MMFAR; // MemManage Fault Address
uint32_t bfar = SCB->BFAR; // Bus Fault Address
uint32_t cfsr = SCB->CFSR; // Configurable Fault Status Registers
trace_printf ("[BusFault]\n");
dumpExceptionStack (frame, cfsr, mmfar, bfar, lr);
#endif // defined(TRACE)
#if defined(DEBUG)
__DEBUG_BKPT();
#endif
while (1)
{
}
}
void __attribute__ ((section(".after_vectors"),weak,naked))
UsageFault_Handler (void)
{
asm volatile(
" tst lr,#4 \n"
" ite eq \n"
" mrseq r0,msp \n"
" mrsne r0,psp \n"
" mov r1,lr \n"
" ldr r2,=UsageFault_Handler_C \n"
" bx r2"
: /* Outputs */
: /* Inputs */
: /* Clobbers */
);
}
void __attribute__ ((section(".after_vectors"),weak,used))
UsageFault_Handler_C (ExceptionStackFrame* frame __attribute__((unused)),
uint32_t lr __attribute__((unused)))
{
#if defined(TRACE)
uint32_t mmfar = SCB->MMFAR; // MemManage Fault Address
uint32_t bfar = SCB->BFAR; // Bus Fault Address
uint32_t cfsr = SCB->CFSR; // Configurable Fault Status Registers
#endif
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
if ((cfsr & (1UL << 16)) != 0) // UNDEFINSTR
{
// For testing purposes, instead of BKPT use 'setend be'.
if (isSemihosting (frame, AngelSWITestFaultOpCode))
{
return;
}
}
#endif
#if defined(TRACE)
trace_printf ("[UsageFault]\n");
dumpExceptionStack (frame, cfsr, mmfar, bfar, lr);
#endif // defined(TRACE)
#if defined(DEBUG)
__DEBUG_BKPT();
#endif
while (1)
{
}
}
#endif
void __attribute__ ((section(".after_vectors"),weak))
SVC_Handler (void)
{
#if defined(DEBUG)
__DEBUG_BKPT();
#endif
while (1)
{
}
}
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
void __attribute__ ((section(".after_vectors"),weak))
DebugMon_Handler (void)
{
#if defined(DEBUG)
__DEBUG_BKPT();
#endif
while (1)
{
}
}
#endif
void __attribute__ ((section(".after_vectors"),weak))
PendSV_Handler (void)
{
#if defined(DEBUG)
__DEBUG_BKPT();
#endif
while (1)
{
}
}
void __attribute__ ((section(".after_vectors"),weak))
SysTick_Handler (void)
{
// DO NOT loop, just return.
// Useful in case someone (like STM HAL) inadvertently enables SysTick.
;
}
// ----------------------------------------------------------------------------

View File

@ -1,76 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// ----------------------------------------------------------------------------
#if defined(TRACE)
#include <stdio.h>
#include <stdarg.h>
#include "diag/Trace.h"
#include "string.h"
#ifndef OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE
#define OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE (128)
#endif
// ----------------------------------------------------------------------------
int
trace_printf(const char* format, ...)
{
int ret;
va_list ap;
va_start (ap, format);
// TODO: rewrite it to no longer use newlib, it is way too heavy
static char buf[OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE];
// Print to the local buffer
ret = vsnprintf (buf, sizeof(buf), format, ap);
if (ret > 0)
{
// Transfer the buffer to the device
ret = trace_write (buf, (size_t)ret);
}
va_end (ap);
return ret;
}
int
trace_puts(const char *s)
{
trace_write(s, strlen(s));
return trace_write("\n", 1);
}
int
trace_putchar(int c)
{
trace_write((const char*)&c, 1);
return c;
}
void
trace_dump_args(int argc, char* argv[])
{
trace_printf("main(argc=%d, argv=[", argc);
for (int i = 0; i < argc; ++i)
{
if (i != 0)
{
trace_printf(", ");
}
trace_printf("\"%s\"", argv[i]);
}
trace_printf("]);\n");
}
// ----------------------------------------------------------------------------
#endif // TRACE

View File

@ -1,252 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// ----------------------------------------------------------------------------
#if defined(TRACE)
#include "cmsis_device.h"
#include "diag/Trace.h"
// ----------------------------------------------------------------------------
// One of these definitions must be passed via the compiler command line
// Note: small Cortex-M0/M0+ might implement a simplified debug interface.
//#define OS_USE_TRACE_ITM
//#define OS_USE_TRACE_SEMIHOSTING_DEBUG
//#define OS_USE_TRACE_SEMIHOSTING_STDOUT
#if !(defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
#if defined(OS_USE_TRACE_ITM)
#undef OS_USE_TRACE_ITM
#warning "ITM unavailable"
#endif // defined(OS_USE_TRACE_ITM)
#endif // !(defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
#if defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
#error "Cannot debug semihosting using semihosting trace; use OS_USE_TRACE_ITM"
#endif
#endif
// ----------------------------------------------------------------------------
// Forward definitions.
#if defined(OS_USE_TRACE_ITM)
static ssize_t
_trace_write_itm (const char* buf, size_t nbyte);
#endif
#if defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
static ssize_t
_trace_write_semihosting_stdout(const char* buf, size_t nbyte);
#endif
#if defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
static ssize_t
_trace_write_semihosting_debug(const char* buf, size_t nbyte);
#endif
// ----------------------------------------------------------------------------
void
trace_initialize(void)
{
// For regular ITM / semihosting, no inits required.
}
// ----------------------------------------------------------------------------
// This function is called from _write() for fd==1 or fd==2 and from some
// of the trace_* functions.
ssize_t
trace_write (const char* buf __attribute__((unused)),
size_t nbyte __attribute__((unused)))
{
#if defined(OS_USE_TRACE_ITM)
return _trace_write_itm (buf, nbyte);
#elif defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
return _trace_write_semihosting_stdout(buf, nbyte);
#elif defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
return _trace_write_semihosting_debug(buf, nbyte);
#endif
return -1;
}
// ----------------------------------------------------------------------------
#if defined(OS_USE_TRACE_ITM)
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
// ITM is the ARM standard mechanism, running over SWD/SWO on Cortex-M3/M4
// devices, and is the recommended setting, if available.
//
// The JLink probe and the GDB server fully support SWD/SWO
// and the JLink Debugging plug-in enables it by default.
// The current OpenOCD does not include support to parse the SWO stream,
// so this configuration will not work on OpenOCD (will not crash, but
// nothing will be displayed in the output console).
#if !defined(OS_INTEGER_TRACE_ITM_STIMULUS_PORT)
#define OS_INTEGER_TRACE_ITM_STIMULUS_PORT (0)
#endif
static ssize_t
_trace_write_itm (const char* buf, size_t nbyte)
{
for (size_t i = 0; i < nbyte; i++)
{
// Check if ITM or the stimulus port are not enabled
if (((ITM->TCR & ITM_TCR_ITMENA_Msk) == 0)
|| ((ITM->TER & (1UL << OS_INTEGER_TRACE_ITM_STIMULUS_PORT)) == 0))
{
return (ssize_t)i; // return the number of sent characters (may be 0)
}
// Wait until STIMx is ready...
while (ITM->PORT[OS_INTEGER_TRACE_ITM_STIMULUS_PORT].u32 == 0)
;
// then send data, one byte at a time
ITM->PORT[OS_INTEGER_TRACE_ITM_STIMULUS_PORT].u8 = (uint8_t) (*buf++);
}
return (ssize_t)nbyte; // all characters successfully sent
}
#endif // defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
#endif // OS_USE_TRACE_ITM
// ----------------------------------------------------------------------------
#if defined(OS_USE_TRACE_SEMIHOSTING_DEBUG) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
#include "arm/semihosting.h"
// Semihosting is the other output channel that can be used for the trace
// messages. It comes in two flavours: STDOUT and DEBUG. The STDOUT channel
// is the equivalent of the stdout in POSIX and in most cases it is forwarded
// to the GDB server stdout stream. The debug channel is a separate
// channel. STDOUT is buffered, so nothing is displayed until a \n;
// DEBUG is not buffered, but can be slow.
//
// Choosing between semihosting stdout and debug depends on the capabilities
// of your GDB server, and also on specific needs. It is recommended to test
// DEBUG first, and if too slow, try STDOUT.
//
// The JLink GDB server fully support semihosting, and both configurations
// are available; to activate it, use "monitor semihosting enable" or check
// the corresponding button in the JLink Debugging plug-in.
// In OpenOCD, support for semihosting can be enabled using
// "monitor arm semihosting enable".
//
// Note: Applications built with semihosting output active normally cannot
// be executed without the debugger connected and active, since they use
// BKPT to communicate with the host. However, with a carefully written
// HardFault_Handler, the semihosting BKPT calls can be processed, making
// possible to run semihosting applications as standalone, without being
// terminated with hardware faults.
#endif // OS_USE_TRACE_SEMIHOSTING_DEBUG_*
// ----------------------------------------------------------------------------
#if defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
static ssize_t
_trace_write_semihosting_stdout (const char* buf, size_t nbyte)
{
static int handle;
void* block[3];
int ret;
if (handle == 0)
{
// On the first call get the file handle from the host
block[0] = ":tt"; // special filename to be used for stdin/out/err
block[1] = (void*) 4; // mode "w"
// length of ":tt", except null terminator
block[2] = (void*) (sizeof(":tt") - 1);
ret = call_host (SEMIHOSTING_SYS_OPEN, (void*) block);
if (ret == -1)
return -1;
handle = ret;
}
block[0] = (void*) handle;
block[1] = (void*) buf;
block[2] = (void*) nbyte;
// send character array to host file/device
ret = call_host (SEMIHOSTING_SYS_WRITE, (void*) block);
// this call returns the number of bytes NOT written (0 if all ok)
// -1 is not a legal value, but SEGGER seems to return it
if (ret == -1)
return -1;
// The compliant way of returning errors
if (ret == (int) nbyte)
return -1;
// Return the number of bytes written
return (ssize_t) (nbyte) - (ssize_t) ret;
}
#endif // OS_USE_TRACE_SEMIHOSTING_STDOUT
// ----------------------------------------------------------------------------
#if defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
#define OS_INTEGER_TRACE_TMP_ARRAY_SIZE (16)
static ssize_t
_trace_write_semihosting_debug (const char* buf, size_t nbyte)
{
// Since the single character debug channel is quite slow, try to
// optimise and send a null terminated string, if possible.
if (buf[nbyte] == '\0')
{
// send string
call_host (SEMIHOSTING_SYS_WRITE0, (void*) buf);
}
else
{
// If not, use a local buffer to speed things up
char tmp[OS_INTEGER_TRACE_TMP_ARRAY_SIZE];
size_t togo = nbyte;
while (togo > 0)
{
unsigned int n = ((togo < sizeof(tmp)) ? togo : sizeof(tmp));
unsigned int i = 0;
for (; i < n; ++i, ++buf)
{
tmp[i] = *buf;
}
tmp[i] = '\0';
call_host (SEMIHOSTING_SYS_WRITE0, (void*) tmp);
togo -= n;
}
}
// All bytes written
return (ssize_t) nbyte;
}
#endif // OS_USE_TRACE_SEMIHOSTING_DEBUG
#endif // TRACE
// ----------------------------------------------------------------------------

View File

@ -1,16 +0,0 @@
The following files extend or replace some of the the newlib functionality:
_startup.c: a customised startup sequence, written in C
_exit.c: a customised exit() implementation
_syscalls.c: local versions of the libnosys/librdimon code
_sbrk.c: a custom _sbrk() to match the actual linker scripts
assert.c: implementation for the asserion macros
_cxx.cpp: local versions of some C++ support, to avoid references to
large functions.

View File

@ -1,50 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// ----------------------------------------------------------------------------
// These functions are redefined locally, to avoid references to some
// heavy implementations in the standard C++ library.
// ----------------------------------------------------------------------------
#include <cstdlib>
#include <sys/types.h>
#include "diag/Trace.h"
// ----------------------------------------------------------------------------
namespace __gnu_cxx
{
void
__attribute__((noreturn))
__verbose_terminate_handler();
void
__verbose_terminate_handler()
{
trace_puts(__func__);
abort();
}
}
// ----------------------------------------------------------------------------
extern "C"
{
void
__attribute__((noreturn))
__cxa_pure_virtual();
void
__cxa_pure_virtual()
{
trace_puts(__func__);
abort();
}
}
// ----------------------------------------------------------------------------

View File

@ -1,59 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// ----------------------------------------------------------------------------
#include <stdlib.h>
#include "diag/Trace.h"
// ----------------------------------------------------------------------------
#if !defined(DEBUG)
extern void
__attribute__((noreturn))
__reset_hardware(void);
#endif
// ----------------------------------------------------------------------------
// Forward declaration
void
_exit(int code);
// ----------------------------------------------------------------------------
// On Release, call the hardware reset procedure.
// On Debug we just enter an infinite loop, to be used as landmark when halting
// the debugger.
//
// It can be redefined in the application, if more functionality
// is required.
void
__attribute__((weak))
_exit(int code __attribute__((unused)))
{
#if !defined(DEBUG)
__reset_hardware();
#endif
// TODO: write on trace
while (1)
;
}
// ----------------------------------------------------------------------------
void
__attribute__((weak,noreturn))
abort(void)
{
trace_puts("abort(), exiting...");
_exit(1);
}
// ----------------------------------------------------------------------------

View File

@ -1,65 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// ----------------------------------------------------------------------------
#include <sys/types.h>
#include <errno.h>
// ----------------------------------------------------------------------------
caddr_t
_sbrk(int incr);
// ----------------------------------------------------------------------------
// The definitions used here should be kept in sync with the
// stack definitions in the linker script.
caddr_t
_sbrk(int incr)
{
extern char _Heap_Begin; // Defined by the linker.
extern char _Heap_Limit; // Defined by the linker.
static char* current_heap_end;
char* current_block_address;
if (current_heap_end == 0)
{
current_heap_end = &_Heap_Begin;
}
current_block_address = current_heap_end;
// Need to align heap to word boundary, else will get
// hard faults on Cortex-M0. So we assume that heap starts on
// word boundary, hence make sure we always add a multiple of
// 4 to it.
incr = (incr + 3) & (~3); // align value to 4
if (current_heap_end + incr > &_Heap_Limit)
{
// Some of the libstdc++-v3 tests rely upon detecting
// out of memory errors, so do not abort here.
#if 0
extern void abort (void);
_write (1, "_sbrk: Heap and stack collision\n", 32);
abort ();
#else
// Heap has overflowed
errno = ENOMEM;
return (caddr_t) - 1;
#endif
}
current_heap_end += incr;
return (caddr_t) current_block_address;
}
// ----------------------------------------------------------------------------

View File

@ -1,327 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
// ----------------------------------------------------------------------------
// This module contains the startup code for a portable embedded
// C/C++ application, built with newlib.
//
// Control reaches here from the reset handler via jump or call.
//
// The actual steps performed by _start are:
// - copy the initialised data region(s)
// - clear the BSS region(s)
// - initialise the system
// - run the preinit/init array (for the C++ static constructors)
// - initialise the arc/argv
// - branch to main()
// - run the fini array (for the C++ static destructors)
// - call _exit(), directly or via exit()
//
// If OS_INCLUDE_STARTUP_INIT_MULTIPLE_RAM_SECTIONS is defined, the
// code is capable of initialising multiple regions.
//
// The normal configuration is standalone, with all support
// functions implemented locally.
//
// For this to be called, the project linker must be configured without
// the startup sequence (-nostartfiles).
// ----------------------------------------------------------------------------
#include <stdint.h>
#include <sys/types.h>
// ----------------------------------------------------------------------------
#if !defined(OS_INCLUDE_STARTUP_GUARD_CHECKS)
#define OS_INCLUDE_STARTUP_GUARD_CHECKS (1)
#endif
// ----------------------------------------------------------------------------
#if !defined(OS_INCLUDE_STARTUP_INIT_MULTIPLE_RAM_SECTIONS)
// Begin address for the initialisation values of the .data section.
// defined in linker script
extern unsigned int _sidata;
// Begin address for the .data section; defined in linker script
extern unsigned int _sdata;
// End address for the .data section; defined in linker script
extern unsigned int _edata;
// Begin address for the .bss section; defined in linker script
extern unsigned int __bss_start__;
// End address for the .bss section; defined in linker script
extern unsigned int __bss_end__;
#else
// The following symbols are constructs generated by the linker, indicating
// the location of various points in the "Memory regions initialisation arrays".
// These arrays are created by the linker via the managed linker script
// of each RW data mechanism. It contains the load address, execution address
// and length section and the execution and length of each BSS (zero
// initialised) section.
extern unsigned int __data_regions_array_start;
extern unsigned int __data_regions_array_end;
extern unsigned int __bss_regions_array_start;
extern unsigned int __bss_regions_array_end;
#endif
extern void
__initialize_args (int*, char***);
// main() is the entry point for newlib based applications.
// By default, there are no arguments, but this can be customised
// by redefining __initialize_args(), which is done when the
// semihosting configurations are used.
extern int
main (int argc, char* argv[]);
// The implementation for the exit routine; for embedded
// applications, a system reset will be performed.
extern void
__attribute__((noreturn))
_exit (int);
// ----------------------------------------------------------------------------
// Forward declarations
void
_start (void);
void
__initialize_data (unsigned int* from, unsigned int* region_begin,
unsigned int* region_end);
void
__initialize_bss (unsigned int* region_begin, unsigned int* region_end);
void
__run_init_array (void);
void
__run_fini_array (void);
void
__initialize_hardware_early (void);
void
__initialize_hardware (void);
// ----------------------------------------------------------------------------
inline void
__attribute__((always_inline))
__initialize_data (unsigned int* from, unsigned int* region_begin,
unsigned int* region_end)
{
// Iterate and copy word by word.
// It is assumed that the pointers are word aligned.
unsigned int *p = region_begin;
while (p < region_end)
*p++ = *from++;
}
inline void
__attribute__((always_inline))
__initialize_bss (unsigned int* region_begin, unsigned int* region_end)
{
// Iterate and clear word by word.
// It is assumed that the pointers are word aligned.
unsigned int *p = region_begin;
while (p < region_end)
*p++ = 0;
}
// These magic symbols are provided by the linker.
extern void
(*__preinit_array_start[]) (void) __attribute__((weak));
extern void
(*__preinit_array_end[]) (void) __attribute__((weak));
extern void
(*__init_array_start[]) (void) __attribute__((weak));
extern void
(*__init_array_end[]) (void) __attribute__((weak));
extern void
(*__fini_array_start[]) (void) __attribute__((weak));
extern void
(*__fini_array_end[]) (void) __attribute__((weak));
// Iterate over all the preinit/init routines (mainly static constructors).
inline void
__attribute__((always_inline))
__run_init_array (void)
{
int count;
int i;
count = __preinit_array_end - __preinit_array_start;
for (i = 0; i < count; i++)
__preinit_array_start[i] ();
// If you need to run the code in the .init section, please use
// the startup files, since this requires the code in crti.o and crtn.o
// to add the function prologue/epilogue.
//_init(); // DO NOT ENABE THIS!
count = __init_array_end - __init_array_start;
for (i = 0; i < count; i++)
__init_array_start[i] ();
}
// Run all the cleanup routines (mainly static destructors).
inline void
__attribute__((always_inline))
__run_fini_array (void)
{
int count;
int i;
count = __fini_array_end - __fini_array_start;
for (i = count; i > 0; i--)
__fini_array_start[i - 1] ();
// If you need to run the code in the .fini section, please use
// the startup files, since this requires the code in crti.o and crtn.o
// to add the function prologue/epilogue.
//_fini(); // DO NOT ENABE THIS!
}
#if defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
// These definitions are used to check if the routines used to
// clear the BSS and to copy the initialised DATA perform correctly.
#define BSS_GUARD_BAD_VALUE (0xCADEBABA)
static uint32_t volatile __attribute__ ((section(".bss_begin")))
__bss_begin_guard;
static uint32_t volatile __attribute__ ((section(".bss_end")))
__bss_end_guard;
#define DATA_GUARD_BAD_VALUE (0xCADEBABA)
#define DATA_BEGIN_GUARD_VALUE (0x12345678)
#define DATA_END_GUARD_VALUE (0x98765432)
static uint32_t volatile __attribute__ ((section(".data_begin")))
__data_begin_guard = DATA_BEGIN_GUARD_VALUE;
static uint32_t volatile __attribute__ ((section(".data_end")))
__data_end_guard = DATA_END_GUARD_VALUE;
#endif // defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
// This is the place where Cortex-M core will go immediately after reset,
// via a call or jump from the Reset_Handler.
//
// For the call to work, and for the call to __initialize_hardware_early()
// to work, the reset stack must point to a valid internal RAM area.
void __attribute__ ((section(".after_vectors"),noreturn,weak))
_start (void)
{
// Initialise hardware right after reset, to switch clock to higher
// frequency and have the rest of the initialisations run faster.
//
// Mandatory on platforms like Kinetis, which start with the watch dog
// enabled and require an early sequence to disable it.
//
// Also useful on platform with external RAM, that need to be
// initialised before filling the BSS section.
__initialize_hardware_early ();
// Use Old Style DATA and BSS section initialisation,
// that will manage a single BSS sections.
#if defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
__data_begin_guard = DATA_GUARD_BAD_VALUE;
__data_end_guard = DATA_GUARD_BAD_VALUE;
#endif
#if !defined(OS_INCLUDE_STARTUP_INIT_MULTIPLE_RAM_SECTIONS)
// Copy the DATA segment from Flash to RAM (inlined).
__initialize_data(&_sidata, &_sdata, &_edata);
#else
// Copy the data sections from flash to SRAM.
for (unsigned int* p = &__data_regions_array_start;
p < &__data_regions_array_end;)
{
unsigned int* from = (unsigned int *) (*p++);
unsigned int* region_begin = (unsigned int *) (*p++);
unsigned int* region_end = (unsigned int *) (*p++);
__initialize_data (from, region_begin, region_end);
}
#endif
#if defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
if ((__data_begin_guard != DATA_BEGIN_GUARD_VALUE)
|| (__data_end_guard != DATA_END_GUARD_VALUE))
{
for (;;)
;
}
#endif
#if defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
__bss_begin_guard = BSS_GUARD_BAD_VALUE;
__bss_end_guard = BSS_GUARD_BAD_VALUE;
#endif
#if !defined(OS_INCLUDE_STARTUP_INIT_MULTIPLE_RAM_SECTIONS)
// Zero fill the BSS section (inlined).
__initialize_bss(&__bss_start__, &__bss_end__);
#else
// Zero fill all bss segments
for (unsigned int *p = &__bss_regions_array_start;
p < &__bss_regions_array_end;)
{
unsigned int* region_begin = (unsigned int*) (*p++);
unsigned int* region_end = (unsigned int*) (*p++);
__initialize_bss (region_begin, region_end);
}
#endif
#if defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
if ((__bss_begin_guard != 0) || (__bss_end_guard != 0))
{
for (;;)
;
}
#endif
// Hook to continue the initialisations. Usually compute and store the
// clock frequency in the global CMSIS variable, cleared above.
__initialize_hardware ();
// Get the argc/argv (useful in semihosting configurations).
int argc;
char** argv;
__initialize_args (&argc, &argv);
// Call the standard library initialisation (mandatory for C++ to
// execute the constructors for the static objects).
__run_init_array ();
// Call the main entry point, and save the exit code.
int code = main (argc, argv);
// Run the C++ static destructors.
__run_fini_array ();
_exit (code);
// Should never reach this, _exit() should have already
// performed a reset.
for (;;)
;
}
// ----------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +0,0 @@
//
// This file is part of the µOS++ III distribution.
// Copyright (c) 2014 Liviu Ionescu.
//
#include <assert.h>
#include <stdlib.h>
#include <stdint.h>
#include "diag/Trace.h"
// ----------------------------------------------------------------------------
void
__attribute__((noreturn))
__assert_func (const char *file, int line, const char *func,
const char *failedexpr)
{
trace_printf ("assertion \"%s\" failed: file \"%s\", line %d%s%s\n",
failedexpr, file, line, func ? ", function: " : "",
func ? func : "");
abort ();
/* NOTREACHED */
}
// ----------------------------------------------------------------------------
// This is STM32 specific, but can be used on other platforms too.
// If you need it, add the following to your application header:
//#ifdef USE_FULL_ASSERT
//#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
//void assert_failed(uint8_t* file, uint32_t line);
//#else
//#define assert_param(expr) ((void)0)
//#endif // USE_FULL_ASSERT
#if defined(USE_FULL_ASSERT)
void
assert_failed (uint8_t* file, uint32_t line);
// Called from the assert_param() macro, usually defined in the stm32f*_conf.h
void
__attribute__((noreturn, weak))
assert_failed (uint8_t* file, uint32_t line)
{
trace_printf ("assert_param() failed: file \"%s\", line %d\n", file, line);
abort ();
/* NOTREACHED */
}
#endif // defined(USE_FULL_ASSERT)
// ----------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -1,333 +0,0 @@
/**
******************************************************************************
* @file stm32f0xx_hal_i2c_ex.c
* @author MCD Application Team
* @brief I2C Extended HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of I2C Extended peripheral:
* + Extended features functions
*
@verbatim
==============================================================================
##### I2C peripheral Extended features #####
==============================================================================
[..] Comparing to other previous devices, the I2C interface for STM32F0xx
devices contains the following additional features
(+) Possibility to disable or enable Analog Noise Filter
(+) Use of a configured Digital Noise Filter
(+) Disable or enable wakeup from Stop mode(s)
(+) Disable or enable Fast Mode Plus
##### How to use this driver #####
==============================================================================
[..] This driver provides functions to configure Noise Filter and Wake Up Feature
(#) Configure I2C Analog noise filter using the function HAL_I2CEx_ConfigAnalogFilter()
(#) Configure I2C Digital noise filter using the function HAL_I2CEx_ConfigDigitalFilter()
(#) Configure the enable or disable of I2C Wake Up Mode using the functions :
(++) HAL_I2CEx_EnableWakeUp()
(++) HAL_I2CEx_DisableWakeUp()
(#) Configure the enable or disable of fast mode plus driving capability using the functions :
(++) HAL_I2CEx_EnableFastModePlus()
(++) HAL_I2CEx_DisableFastModePlus()
@endverbatim
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx_hal.h"
/** @addtogroup STM32F0xx_HAL_Driver
* @{
*/
/** @defgroup I2CEx I2CEx
* @brief I2C Extended HAL module driver
* @{
*/
#ifdef HAL_I2C_MODULE_ENABLED
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup I2CEx_Exported_Functions I2C Extended Exported Functions
* @{
*/
/** @defgroup I2CEx_Exported_Functions_Group1 Extended features functions
* @brief Extended features functions
*
@verbatim
===============================================================================
##### Extended features functions #####
===============================================================================
[..] This section provides functions allowing to:
(+) Configure Noise Filters
(+) Configure Wake Up Feature
(+) Configure Fast Mode Plus
@endverbatim
* @{
*/
/**
* @brief Configure I2C Analog noise filter.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2Cx peripheral.
* @param AnalogFilter New state of the Analog filter.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter));
if (hi2c->State == HAL_I2C_STATE_READY)
{
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Reset I2Cx ANOFF bit */
hi2c->Instance->CR1 &= ~(I2C_CR1_ANFOFF);
/* Set analog filter bit*/
hi2c->Instance->CR1 |= AnalogFilter;
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Configure I2C Digital noise filter.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2Cx peripheral.
* @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter)
{
uint32_t tmpreg;
/* Check the parameters */
assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter));
if (hi2c->State == HAL_I2C_STATE_READY)
{
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Get the old register value */
tmpreg = hi2c->Instance->CR1;
/* Reset I2Cx DNF bits [11:8] */
tmpreg &= ~(I2C_CR1_DNF);
/* Set I2Cx DNF coefficient */
tmpreg |= DigitalFilter << 8U;
/* Store the new register value */
hi2c->Instance->CR1 = tmpreg;
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
#if defined(I2C_CR1_WUPEN)
/**
* @brief Enable I2C wakeup from Stop mode(s).
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2Cx peripheral.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c)
{
/* Check the parameters */
assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance));
if (hi2c->State == HAL_I2C_STATE_READY)
{
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Enable wakeup from stop mode */
hi2c->Instance->CR1 |= I2C_CR1_WUPEN;
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Disable I2C wakeup from Stop mode(s).
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2Cx peripheral.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c)
{
/* Check the parameters */
assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance));
if (hi2c->State == HAL_I2C_STATE_READY)
{
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Enable wakeup from stop mode */
hi2c->Instance->CR1 &= ~(I2C_CR1_WUPEN);
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
#endif
/**
* @brief Enable the I2C fast mode plus driving capability.
* @param ConfigFastModePlus Selects the pin.
* This parameter can be one of the @ref I2CEx_FastModePlus values
* @note For I2C1, fast mode plus driving capability can be enabled on all selected
* I2C1 pins using I2C_FASTMODEPLUS_I2C1 parameter or independently
* on each one of the following pins PB6, PB7, PB8 and PB9.
* @note For remaining I2C1 pins (PA14, PA15...) fast mode plus driving capability
* can be enabled only by using I2C_FASTMODEPLUS_I2C1 parameter.
* @note For all I2C2 pins fast mode plus driving capability can be enabled
* only by using I2C_FASTMODEPLUS_I2C2 parameter.
* @retval None
*/
void HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus)
{
/* Check the parameter */
assert_param(IS_I2C_FASTMODEPLUS(ConfigFastModePlus));
/* Enable SYSCFG clock */
__HAL_RCC_SYSCFG_CLK_ENABLE();
/* Enable fast mode plus driving capability for selected pin */
SET_BIT(SYSCFG->CFGR1, (uint32_t)ConfigFastModePlus);
}
/**
* @brief Disable the I2C fast mode plus driving capability.
* @param ConfigFastModePlus Selects the pin.
* This parameter can be one of the @ref I2CEx_FastModePlus values
* @note For I2C1, fast mode plus driving capability can be disabled on all selected
* I2C1 pins using I2C_FASTMODEPLUS_I2C1 parameter or independently
* on each one of the following pins PB6, PB7, PB8 and PB9.
* @note For remaining I2C1 pins (PA14, PA15...) fast mode plus driving capability
* can be disabled only by using I2C_FASTMODEPLUS_I2C1 parameter.
* @note For all I2C2 pins fast mode plus driving capability can be disabled
* only by using I2C_FASTMODEPLUS_I2C2 parameter.
* @retval None
*/
void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus)
{
/* Check the parameter */
assert_param(IS_I2C_FASTMODEPLUS(ConfigFastModePlus));
/* Enable SYSCFG clock */
__HAL_RCC_SYSCFG_CLK_ENABLE();
/* Disable fast mode plus driving capability for selected pin */
CLEAR_BIT(SYSCFG->CFGR1, (uint32_t)ConfigFastModePlus);
}
/**
* @}
*/
/**
* @}
*/
#endif /* HAL_I2C_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

54
src/startup.c Normal file
View File

@ -0,0 +1,54 @@
#include <stdint.h>
#include <stddef.h>
typedef struct _copy_table_t
{
uint32_t const* src;
uint32_t* dest;
uint32_t wlen;
} copy_table_t;
typedef struct _zero_table_t
{
uint32_t* dest;
uint32_t wlen;
} zero_table_t;
extern const copy_table_t __copy_table_start__;
extern const copy_table_t __copy_table_end__;
extern const zero_table_t __zero_table_start__;
extern const zero_table_t __zero_table_end__;
void SystemInit();
void _start() __attribute__((noreturn));
void Reset_Handler()
{
SystemInit();
for (copy_table_t const* table = &__copy_table_start__; table < &__copy_table_end__; ++table)
{
for (size_t i=0; i<table->wlen; ++i)
{
table->dest[i] = table->src[i];
}
}
for (zero_table_t const* table = &__zero_table_start__; table < &__zero_table_end__; ++table)
{
for (size_t i=0; i<table->wlen; ++i)
{
table->dest[i] = 0u;
}
}
_start();
}
void _exit(int code)
{
(void) code;
__asm__("BKPT");
while (1);
}