mirror of
https://github.com/candle-usb/candleLight_fw.git
synced 2025-01-28 06:02:52 +08:00
use startup files and linker scripts from LibreUCpp
This commit is contained in:
parent
d7332a3173
commit
fef1d397b5
@ -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
139
ldscripts/STM32F042X6.ld
Normal 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
139
ldscripts/STM32F072XB.ld
Normal 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")
|
||||
}
|
@ -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)
|
||||
|
@ -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_
|
@ -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_
|
@ -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>© 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****/
|
||||
|
@ -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>© 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****/
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
@ -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();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
@ -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.
|
||||
;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
@ -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
|
@ -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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
@ -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;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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
@ -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
@ -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>© 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
54
src/startup.c
Normal 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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user