diff --git a/Makefile b/Makefile index d435fa4..3c9a7df 100755 --- a/Makefile +++ b/Makefile @@ -8,36 +8,26 @@ MAINFILE = $(EXE_DIR)/$(APP)$(ELF_EXT) BINFILE = $(EXE_DIR)/$(APP)$(BIN_EXT) HEXFILE = $(EXE_DIR)/$(APP)$(HEX_EXT) SIZEFILE = $(SIZE_DIR)/$(APP)$(SIZE_EXT) - +MAP_FILE = $(MAP_DIR)/$(APP)$(MAP_EXT) INCLUDES += $(SRC_DIR) -SUB_FOLDER := -CHECK_FOLDER := SOURCES := $(wildcard $(SRC_DIR)/*.c) -ASM_SOURCES := $(wildcard $(SRC_DIR)/*.s) OBJECTS = $(SOURCES:$(ROOT_DIR)/%.c=$(OBJ_DIR)/%.o) -ASM_OBJECTS = $(ASMSOURCES:$(ROOT_DIR)/%.s=$(OBJ_DIR)/%.o) DEPS = $(SOURCES:$(ROOT_DIR)/%.c=$(OBJ_DIR)/%.d) #include subfolders include source/application/application.mk SOURCES += $(foreach folder, $(SUB_FOLDER), $(wildcard $(ROOT_DIR)/$(folder)/*.c)) -CHECKSOURCES += $(foreach folder, $(CHECK_FOLDER), $(wildcard $(ROOT_DIR)/$(folder)/*.c)) -ASMSOURCES += $(foreach folder, $(SUB_FOLDER), $(wildcard $(ROOT_DIR)/$(folder)/*.s)) -all: check $(MAINFILE) +all: $(MAINFILE) -check: - $(CPPCHECK) $(CPPCHECK_FLAGS) $(CHECKSOURCES) - - -$(MAINFILE): $(OBJECTS) $(ASM_OBJECTS) +$(MAINFILE): $(OBJECTS) @$(MKDIR) $(EXE_DIR) @$(MKDIR) $(MAP_DIR) @$(MKDIR) $(SIZE_DIR) - $(CC) $(CFLAGS) -L$(LIB_DIR) $(LDFLAGS) -o $(MAINFILE) $(OBJECTS) $(ASM_OBJECTS) $(addprefix -l, $(LIBS)) + $(CXX) $(GEN_FLAGS) $(L_FLAGS) -L$(LIB_DIR) -Wl,-Map,"$(MAP_FILE)" -o "$(MAINFILE)" $(OBJECTS) $(addprefix -l, $(LIBS)) $(OBJCOPY) $(MAINFILE) -O binary $(BINFILE) $(OBJCOPY) $(MAINFILE) -O ihex $(HEXFILE) $(NM) --size-sort --print-size $(MAINFILE) > $(SIZEFILE) @@ -48,13 +38,8 @@ $(MAINFILE): $(OBJECTS) $(ASM_OBJECTS) $(OBJ_DIR)/%.o: $(ROOT_DIR)/%.c @$(MKDIR) $(OBJ_DIR) @$(foreach folder, $(SUB_FOLDER), $(shell mkdir -p $(OBJ_DIR)/$(folder))) - $(call makedep,$<,$@,$(subst .o,.d,$@)) - $(CC) $(CFLAGS) -c $< -o $@ - -$(OBJ_DIR)/%.o: $(ROOT_DIR)/%.s - @$(MKDIR) $(OBJ_DIR) - @$(foreach folder, $(SUB_FOLDER), $(shell mkdir -p $(OBJ_DIR)/$(folder))) - $(CC) $(CFLAGS) -c $< -o $@ + $(call makedep,$<,$@,$(subst .o,.d,$@),$(GEN_FLAGS) $(C_FLAGS)) + $(CC) $(GEN_FLAGS) $(C_FLAGS) -c -o "$@" "$<" clean: $(foreach folder, $(SUB_FOLDER), $(shell rm -f $(OBJ_DIR)/$(folder)/*.o)) @@ -73,10 +58,6 @@ install: all $(PRE_PROGRAM) $(PROGRAM) -doc: - @$(MKDIR) $(DOC_DIR) - (cat $(DOXYFILE) ; echo "INPUT=$(DOC_SRC)" ; echo "OUTPUT_DIRECTORY=$(DOC_DIR)") | doxygen - - ifneq "$(MAKECMDGOALS)" "clean" -include $(DEPS) else diff --git a/config/make/rules.mk b/config/make/rules.mk index f09f8a2..c12c972 100755 --- a/config/make/rules.mk +++ b/config/make/rules.mk @@ -12,18 +12,6 @@ LIB_DIR += $(SRC_DIR)/os/$(DBG_REL_DIR) OS_LIB = kosmos-$(ARCH)-$(BOARD)$(DBG_EXT) LIBS += $(OS_LIB) -CFLAGS += \ - -O$(OPTIM) \ - $(addprefix -I, $(INCLUDES)) \ - -Wall - -CPPCHECK_FLAGS += \ - --template=gcc \ - --error-exitcode=1 \ - --enable=warning,performance,information,style \ - --inline-suppr \ - $(addprefix -I, $(INCLUDES)) - include $(ROOT_DIR)/config/make/tools.mk SRC_DIR = $(ROOT_DIR)/source @@ -48,23 +36,15 @@ HEX_EXT = .hex LIB_EXT = .a SIZE_EXT = .size TEST_EXT = +MAP_EXT = .map DOXYFILE=$(ROOT_DIR)/config/doxygen/Doxyfile define makedep - $(CC) -MM \ - -MF $3 \ - -MP \ - -MT $2 \ - $(CFLAGS) \ - $1 -endef - -define maketestdep - $(NATIVE_CC) -MM \ - -MF $3 \ - -MP \ - -MT $2 \ - $(TEST_CFLAGS) \ + $(CC) -MM \ + -MF $3 \ + -MP \ + -MT $2 \ + $4 \ $1 endef diff --git a/config/make/stm32f4xx.mk b/config/make/stm32f4xx.mk index 83791ec..7394a12 100644 --- a/config/make/stm32f4xx.mk +++ b/config/make/stm32f4xx.mk @@ -6,53 +6,81 @@ endif ifeq ($(BOARD), stm32f4-discovery) CFLAGS += -DBOARD_STM32F4_DISCOVERY endif -CROSS_COMPILE=arm-none-eabi- +CROSS_COMPILE ?= arm-none-eabi- + +INCLUDES += source/system/stm32f4xx +SUB_FOLDER += source/system/stm32f4xx INCLUDES += \ - /opt/arm-2011.09/arm-none-eabi/include \ - /opt/arm-2011.09/lib/gcc/arm-none-eabi/4.6.1/include + /opt/gcc-arm-none-eabi-5_4-2016q2/arm-none-eabi/include \ + /opt/gcc-arm-none-eabi-5_4-2016q2/lib/gcc/arm-none-eabi/5.4.1/include + +GEN_FLAGS += \ + -mcpu=cortex-m4 \ + -mthumb \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -O$(OPTIM) \ + -fmessage-length=0 \ + -fsigned-char \ + -ffunction-sections \ + -fdata-sections \ + -ffreestanding \ + -fno-move-loop-invariants \ + -Werror \ + -Wunused \ + -Wuninitialized \ + -Wall \ + -Wextra \ + -Wmissing-declarations \ + -Wconversion \ + -Wpointer-arith \ + -Wpadded \ + -Wshadow \ + -Wlogical-op \ + -Waggregate-return \ + -Wfloat-equal + +C_FLAGS += \ + -DDEBUG \ + -DUSE_FULL_ASSERT \ + -DTRACE \ + -DOS_USE_TRACE_SEMIHOSTING_DEBUG \ + -DSTM32F407xx \ + -DUSE_HAL_DRIVER \ + -DHSE_VALUE=8000000 \ + $(addprefix -I, $(INCLUDES)) \ + -std=gnu11 \ + -Wmissing-prototypes \ + -Wstrict-prototypes \ + -Wbad-function-cast \ + -Wno-bad-function-cast \ + -Wno-conversion \ + -Wno-sign-conversion \ + -Wno-unused-parameter \ + -Wno-sign-compare \ + -Wno-missing-prototypes \ + -Wno-missing-declarations + +L_FLAGS := \ + -T mem.ld \ + -T libs.ld \ + -T sections.ld \ + -nostartfiles \ + -Xlinker --gc-sections \ + -L"config/linker" \ + --specs=nano.specs +# --specs=nosys.specs ifeq ($(DEBUG),y) -OPTIM = 0 -CFLAGS += -g +OPTIM = g +GEN_FLAGS += -g3 DBG_EXT = -dbg else OPTIM = s -LDFLAGS += -s DBG_EXT = endif -CFLAGS += \ - -mthumb \ - -T $(ROOT_DIR)/config/linker/stm32_flash.ld \ - -D USE_STDPERIPH_DRIVER\ - -D VECT_TAB_FLASH\ - -D GCC_ARMCM4\ - -D THUMB_INTERWORK\ - -D PACK_STRUCT_END=__attribute\(\(packed\)\)\ - -D ALIGN_STRUCT_END=__attribute\(\(aligned\(4\)\)\)\ - -mcpu=cortex-m4 \ - -mfpu=fpv4-sp-d16 \ - -mfloat-abi=softfp \ - -fdata-sections \ - -ffunction-sections -# -D inline= -mthumb\ - -CPPCHECK_FLAGS += \ - -D USE_STDPERIPH_DRIVER\ - -D VECT_TAB_FLASH\ - -D GCC_ARMCM4\ - -D THUMB_INTERWORK\ - -D PACK_STRUCT_END=__attribute\(\(packed\)\)\ - -D ALIGN_STRUCT_END=__attribute\(\(aligned\(4\)\)\)\ - -D __thumb__ \ - --check-config - -LDFLAGS=\ - -Wl,--gc-sections \ - -Xlinker -M > $(MAP_DIR)/$(APP).map - -ASFLAGS=-mapcs-32 -g ARFLAGS=rcs OOCD_IMAGE=$(BINFILE) diff --git a/source/application/main.c b/source/application/main.c index fc7f263..4544360 100644 --- a/source/application/main.c +++ b/source/application/main.c @@ -17,7 +17,9 @@ int main(void) shell_init(&uart_1); shell_commands_init(); - schedule_start(); + while(1) { + sleep_ms(1000); + } return 0; } diff --git a/source/os/debug/include/board_devices.h b/source/os/debug/include/board_devices.h deleted file mode 100644 index ec42636..0000000 --- a/source/os/debug/include/board_devices.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Board devices include file */ - -#ifndef BOARD_DEVICES_H -#define BOARD_DEVICES_H - -extern const struct driver gpio_c0; -extern const struct driver gpio_c1; -extern const struct driver gpio_c2; -extern const struct driver gpio_c3; -extern const struct driver pwm_4; -extern const struct driver pwm_3; -extern const struct driver pwm_2; -extern const struct driver pwm_1; -extern const struct driver uart_1; - -#endif /* BOARD_DEVICES_H */ diff --git a/source/os/debug/include/driver.h b/source/os/debug/include/driver.h deleted file mode 100644 index e91349d..0000000 --- a/source/os/debug/include/driver.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * driver.h - * - * Created on: Jul 27, 2016 - * Author: tkl - */ - -#ifndef SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_ -#define SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_ - -#define IOCTL_PWM_SET_DUTY_CYCLE 0 - -enum driver_type { - DRIVER_TYPE_ADC, - DRIVER_TYPE_GPIO, - DRIVER_TYPE_I2C, - DRIVER_TYPE_PWM, - DRIVER_TYPE_RTC, - DRIVER_TYPE_SPI, - DRIVER_TYPE_UART -}; - -#pragma pack(push) -#pragma pack(1) -struct driver { - enum driver_type driver_type; - const void *device_driver; -}; -#pragma pack(pop) - -int drv_open(const struct driver *driver); -int drv_close(const struct driver *driver); -int drv_read(const struct driver *driver, char *buffer, int len); -int drv_write(const struct driver *driver, const char *buffer, int len); -int drv_ioctl(const struct driver *driver, unsigned int cmd, const void *data); - -#endif /* SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_ */ diff --git a/source/os/debug/include/kernel.h b/source/os/debug/include/kernel.h deleted file mode 100644 index e69f607..0000000 --- a/source/os/debug/include/kernel.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * kernel.h - * - * Created on: Jul 28, 2016 - * Author: tkl - */ - -#ifndef SOURCE_FIRMWARE_KERNEL_INTERFACE_KERNEL_H_ -#define SOURCE_FIRMWARE_KERNEL_INTERFACE_KERNEL_H_ - -void schedule_start(void); - -enum thread_priority { - THREAD_PRIO_IDLE = 0, - THREAD_PRIO_LOW, - THREAD_PRIO_MEDIUM, - THREAD_PRIO_HIGH -}; - -enum thread_status { - THREAD_STATUS_INIT = 0, - THREAD_STATUS_EXECUTING, - THREAD_STATUS_WAITING, - THREAD_STATUS_SLEEPING, - THREAD_STATUS_BLOCKING -}; - -#pragma pack(push) -#pragma pack(1) -struct thread_context { - stack_t *sp; /**< thread's stack pointer */ - stack_t *stack; /**< thread's stack start address */ - unsigned int stack_size; /**< thread's stack size */ - unsigned int pid; /**< thread's process id */ - enum thread_priority priority; /**< thread's priority */ - enum thread_status status; /**< thread's status */ - unsigned long next_executing_time; - void *wakeup_blocking_source; - struct queue_node sem_queue_node; -}; -#pragma pack(pop) - -struct kernel_version { - unsigned int kernel_version; - unsigned int major_version; - unsigned int minor_version; - unsigned int build_number; -}; - -int get_kernel_version(struct kernel_version *version); - -struct thread_context *thread_create( - struct thread_context *thread, - stack_t *stack, - unsigned int stack_size, - void (*thread_func)(void *), - void *arg, - enum thread_priority priority); - - -void thread_exit(void); -void sleep_ms(unsigned int ms); - -#endif /* SOURCE_FIRMWARE_KERNEL_INTERFACE_KERNEL_H_ */ diff --git a/source/os/debug/include/list.h b/source/os/debug/include/list.h deleted file mode 100644 index f26b4fe..0000000 --- a/source/os/debug/include/list.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * list.h - * - * Created on: Jul 27, 2016 - * Author: tkl - */ - -#ifndef SOURCE_FIRMWARE_KERNEL_LIST_H_ -#define SOURCE_FIRMWARE_KERNEL_LIST_H_ - -struct list_node { - struct list_node *next; - unsigned int data; -}; - -struct list { - struct list_node *front; - struct list_node *rear; -}; - -int list_init(struct list *head); -int list_add(struct list *head, struct list_node *node); -int list_get_len(struct list *head); - -#endif /* SOURCE_FIRMWARE_KERNEL_LIST_H_ */ diff --git a/source/os/debug/include/queue.h b/source/os/debug/include/queue.h deleted file mode 100644 index 996ef90..0000000 --- a/source/os/debug/include/queue.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * queue.h - * - * Created on: Oct 25, 2015 - * Author: tkl - */ - -#ifndef QUEUE_H_ -#define QUEUE_H_ - -struct queue_node { - struct queue_node *next; - unsigned int data; -}; - -struct queue { - struct queue_node *front; - struct queue_node *rear; -}; - -int queue_init(struct queue *head); -int queue_push(struct queue *head, struct queue_node *node); -int queue_pop(struct queue *head, struct queue_node *node); -bool queue_is_empty(struct queue *head); - -#endif /* QUEUE_H_ */ diff --git a/source/os/debug/include/shell.h b/source/os/debug/include/shell.h deleted file mode 100644 index c242e8d..0000000 --- a/source/os/debug/include/shell.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * shell.h - * - * Created on: Aug 1, 2016 - * Author: tkl - */ - -#ifndef SOURCE_FIRMWARE_KERNEL_INTERFACE_SHELL_H_ -#define SOURCE_FIRMWARE_KERNEL_INTERFACE_SHELL_H_ - -typedef void *(*command_callback)(const char*); - -struct command { - const char *command; - const char *description; - const command_callback command_callback; - struct list_node item; -}; - -int shell_init(const struct driver *shell_device); -int shell_add_command(struct command *command); - -#endif /* SOURCE_FIRMWARE_KERNEL_INTERFACE_SHELL_H_ */ diff --git a/source/os/debug/include/stack.h b/source/os/debug/include/stack.h deleted file mode 100644 index b792758..0000000 --- a/source/os/debug/include/stack.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Stack include file */ - -#ifndef STACK_H -#define STACK_H - -typedef uint32_t stack_t; - -#endif /* STACK_H */ diff --git a/source/os/debug/libkosmos-arm-stm32f4-discovery-0.1.1-dbg.a b/source/os/debug/libkosmos-arm-stm32f4-discovery-0.1.1-dbg.a deleted file mode 100644 index 89d74e5..0000000 Binary files a/source/os/debug/libkosmos-arm-stm32f4-discovery-0.1.1-dbg.a and /dev/null differ diff --git a/source/os/debug/libkosmos-arm-stm32f4-discovery-dbg.a b/source/os/debug/libkosmos-arm-stm32f4-discovery-dbg.a deleted file mode 120000 index d9926c8..0000000 --- a/source/os/debug/libkosmos-arm-stm32f4-discovery-dbg.a +++ /dev/null @@ -1 +0,0 @@ -libkosmos-arm-stm32f4-discovery-0.1.1-dbg.a \ No newline at end of file diff --git a/source/system/stm32f4xx/ExceptionHandlers.h b/source/system/stm32f4xx/ExceptionHandlers.h new file mode 100644 index 0000000..b69b8eb --- /dev/null +++ b/source/system/stm32f4xx/ExceptionHandlers.h @@ -0,0 +1,94 @@ +// +// 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 + +#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_ diff --git a/source/system/stm32f4xx/_cxx.cpp b/source/system/stm32f4xx/_cxx.cpp new file mode 100644 index 0000000..efcb451 --- /dev/null +++ b/source/system/stm32f4xx/_cxx.cpp @@ -0,0 +1,50 @@ +// +// 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 +#include +#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(); + } +} + +// ---------------------------------------------------------------------------- + diff --git a/source/system/stm32f4xx/_exit.c b/source/system/stm32f4xx/_exit.c new file mode 100644 index 0000000..fb1d71a --- /dev/null +++ b/source/system/stm32f4xx/_exit.c @@ -0,0 +1,59 @@ +// +// This file is part of the µOS++ III distribution. +// Copyright (c) 2014 Liviu Ionescu. +// + +// ---------------------------------------------------------------------------- + +#include +//#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..."); + while(1); + _exit(1); +} + +// ---------------------------------------------------------------------------- diff --git a/source/system/stm32f4xx/_sbrk.c b/source/system/stm32f4xx/_sbrk.c new file mode 100644 index 0000000..ac3a8aa --- /dev/null +++ b/source/system/stm32f4xx/_sbrk.c @@ -0,0 +1,65 @@ +// +// This file is part of the µOS++ III distribution. +// Copyright (c) 2014 Liviu Ionescu. +// + +// ---------------------------------------------------------------------------- + +#include +#include + +// ---------------------------------------------------------------------------- + +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; +} + +// ---------------------------------------------------------------------------- + diff --git a/source/system/stm32f4xx/_startup.c b/source/system/stm32f4xx/_startup.c new file mode 100644 index 0000000..169538c --- /dev/null +++ b/source/system/stm32f4xx/_startup.c @@ -0,0 +1,327 @@ +// +// 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 +#include + +// ---------------------------------------------------------------------------- + +#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 +start_application (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 = start_application (argc, argv); + + // Run the C++ static destructors. + __run_fini_array (); + + _exit (code); + + // Should never reach this, _exit() should have already + // performed a reset. + for (;;) + ; +} + +// ---------------------------------------------------------------------------- diff --git a/source/system/stm32f4xx/_syscalls.c b/source/system/stm32f4xx/_syscalls.c new file mode 100644 index 0000000..3e930c5 --- /dev/null +++ b/source/system/stm32f4xx/_syscalls.c @@ -0,0 +1,1219 @@ +// +// This file is part of the µOS++ III distribution. +// Parts of this file are from the newlib sources, issued under GPL. +// Copyright (c) 2014 Liviu Ionescu +// + +// ---------------------------------------------------------------------------- + +int errno; +void *__dso_handle __attribute__ ((weak)); + +// ---------------------------------------------------------------------------- + +#if !defined(OS_USE_SEMIHOSTING) + +#include <_ansi.h> +#include <_syslist.h> +#include +//#include +#include +#include +#include +#include +#include + +void +__initialize_args(int* p_argc, char*** p_argv); + +// This is the standard default implementation for the routine to +// process args. It returns a single empty arg. +// For semihosting applications, this is redefined to get the real +// args from the debugger. You can also use it if you decide to keep +// some args in a non-volatile memory. + +void __attribute__((weak)) +__initialize_args(int* p_argc, char*** p_argv) +{ + // By the time we reach this, the data and bss should have been initialised. + + // The strings pointed to by the argv array shall be modifiable by the + // program, and retain their last-stored values between program startup + // and program termination. (static, no const) + static char name[] = ""; + + // The string pointed to by argv[0] represents the program name; + // argv[0][0] shall be the null character if the program name is not + // available from the host environment. argv[argc] shall be a null pointer. + // (static, no const) + static char* argv[2] = + { name, NULL }; + + *p_argc = 1; + *p_argv = &argv[0]; + return; +} + +// These functions are defined here to avoid linker errors in freestanding +// applications. They might be called in some error cases from library +// code. +// +// If you detect other functions to be needed, just let us know +// and we'll add them. + +int +raise(int sig __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int +kill(pid_t pid, int sig); + +int +kill(pid_t pid __attribute__((unused)), int sig __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +#endif // !defined(OS_USE_SEMIHOSTING) + +// ---------------------------------------------------------------------------- + +// If you need the empty definitions, remove the -ffreestanding option. + +#if __STDC_HOSTED__ == 1 + +char* __env[1] = + { 0 }; +char** environ = __env; + +#if !defined(OS_USE_SEMIHOSTING) + +// Forward declarations + +int +_chown(const char* path, uid_t owner, gid_t group); + +int +_close(int fildes); + +int +_execve(char* name, char** argv, char** env); + +int +_fork(void); + +int +_fstat(int fildes, struct stat* st); + +int +_getpid(void); + +int +_gettimeofday(struct timeval* ptimeval, void* ptimezone); + +int +_isatty(int file); + +int +_kill(int pid, int sig); + +int +_link(char* existing, char* _new); + +int +_lseek(int file, int ptr, int dir); + +int +_open(char* file, int flags, int mode); + +int +_read(int file, char* ptr, int len); + +int +_readlink(const char* path, char* buf, size_t bufsize); + +int +_stat(const char* file, struct stat* st); + +int +_symlink(const char* path1, const char* path2); + +clock_t +_times(struct tms* buf); + +int +_unlink(char* name); + +int +_wait(int* status); + +int +_write(int file, char* ptr, int len); + +// Definitions + +int __attribute__((weak)) +_chown(const char* path __attribute__((unused)), + uid_t owner __attribute__((unused)), gid_t group __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_close(int fildes __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_execve(char* name __attribute__((unused)), char** argv __attribute__((unused)), + char** env __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_fork(void) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_fstat(int fildes __attribute__((unused)), + struct stat* st __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_getpid(void) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_gettimeofday(struct timeval* ptimeval __attribute__((unused)), + void* ptimezone __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_isatty(int file __attribute__((unused))) +{ + errno = ENOSYS; + return 0; +} + +int __attribute__((weak)) +_kill(int pid __attribute__((unused)), int sig __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_link(char* existing __attribute__((unused)), + char* _new __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_lseek(int file __attribute__((unused)), int ptr __attribute__((unused)), + int dir __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_open(char* file __attribute__((unused)), int flags __attribute__((unused)), + int mode __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_read(int file __attribute__((unused)), char* ptr __attribute__((unused)), + int len __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_readlink(const char* path __attribute__((unused)), + char* buf __attribute__((unused)), size_t bufsize __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_stat(const char* file __attribute__((unused)), + struct stat* st __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_symlink(const char* path1 __attribute__((unused)), + const char* path2 __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +clock_t __attribute__((weak)) +_times(struct tms* buf __attribute__((unused))) +{ + errno = ENOSYS; + return ((clock_t) -1); +} + +int __attribute__((weak)) +_unlink(char* name __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_wait(int* status __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +int __attribute__((weak)) +_write(int file __attribute__((unused)), char* ptr __attribute__((unused)), + int len __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +// ---------------------------------------------------------------------------- + +#else // defined(OS_USE_SEMIHOSTING) + +// ---------------------------------------------------------------------------- + +/* Support files for GNU libc. Files in the system namespace go here. + Files in the C namespace (ie those that do not start with an + underscore) go in .c. */ + +#include <_ansi.h> +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "arm/semihosting.h" + +int +_kill (int pid, int sig); + +void +__attribute__((noreturn)) +_exit (int status); + +// Forward declarations. +int +_system (const char*); +int +_rename (const char*, const char*); +int +_isatty (int); +clock_t +_times (struct tms*); +int +_gettimeofday (struct timeval *, void*); +int +_unlink (const char*); +int +_link (void); + +int +_stat (const char*, struct stat*); + +int +_fstat (int, struct stat*); +int +_swistat (int fd, struct stat* st); +int +_getpid (int); +int +_close (int); +clock_t +_clock (void); +int +_swiclose (int); +int +_open (const char*, int, ...); +int +_swiopen (const char*, int); +int +_write (int, char*, int); +int +_swiwrite (int, char*, int); +int +_lseek (int, int, int); +int +_swilseek (int, int, int); +int +_read (int, char*, int); +int +_swiread (int, char*, int); + +void +initialise_monitor_handles (void); + +void +__initialize_args (int* p_argc, char*** p_argv); + +static int +checkerror (int); +static int +error (int); +static int +get_errno (void); + +// ---------------------------------------------------------------------------- + +#define ARGS_BUF_ARRAY_SIZE 80 +#define ARGV_BUF_ARRAY_SIZE 10 + +typedef struct +{ + char* pCommandLine; + int size; +} CommandLineBlock; + +void +__initialize_args (int* p_argc, char*** p_argv) +{ + + // Array of chars to receive the command line from the host + static char args_buf[ARGS_BUF_ARRAY_SIZE]; + + // Array of pointers to store the final argv pointers (pointing + // in the above array). + static char* argv_buf[ARGV_BUF_ARRAY_SIZE]; + + int argc = 0; + int isInArgument = 0; + + CommandLineBlock cmdBlock; + cmdBlock.pCommandLine = args_buf; + cmdBlock.size = sizeof(args_buf) - 1; + + int ret = call_host (SEMIHOSTING_SYS_GET_CMDLINE, &cmdBlock); + if (ret == 0) + { + + // In case the host send more than we can chew, limit the + // string to our buffer. + args_buf[ARGS_BUF_ARRAY_SIZE - 1] = '\0'; + + // The command line is a null terminated string + char* p = cmdBlock.pCommandLine; + + int delim = '\0'; + int ch; + + while ((ch = *p) != '\0') + { + if (isInArgument == 0) + { + if (!isblank(ch)) + { + if (argc + >= (int) ((sizeof(argv_buf) / sizeof(argv_buf[0])) - 1)) + break; + + if (ch == '"' || ch == '\'') + { + // Remember the delimiter to search for the + // corresponding terminator + delim = ch; + ++p; // skip the delimiter + ch = *p; + } + // Remember the arg beginning address + argv_buf[argc++] = p; + isInArgument = 1; + } + } + else if (delim != '\0') + { + if ((ch == delim)) + { + delim = '\0'; + *p = '\0'; + isInArgument = 0; + } + } + else if (isblank(ch)) + { + delim = '\0'; + *p = '\0'; + isInArgument = 0; + } + ++p; + } + } + + if (argc == 0) + { + // No args found in string, return a single empty name. + args_buf[0] = '\0'; + argv_buf[0] = &args_buf[0]; + ++argc; + } + + // Must end the array with a null pointer. + argv_buf[argc] = NULL; + + *p_argc = argc; + *p_argv = &argv_buf[0]; + + // temporary here + initialise_monitor_handles (); + + return; +} + +// ---------------------------------------------------------------------------- + +void +_exit (int status) +{ + /* There is only one SWI for both _exit and _kill. For _exit, call + the SWI with the second argument set to -1, an invalid value for + signum, so that the SWI handler can distinguish the two calls. + Note: The RDI implementation of _kill throws away both its + arguments. */ + report_exception ( + status == 0 ? ADP_Stopped_ApplicationExit : ADP_Stopped_RunTimeError); +} + +// ---------------------------------------------------------------------------- + +int __attribute__((weak)) +_kill (int pid __attribute__((unused)), int sig __attribute__((unused))) +{ + errno = ENOSYS; + return -1; +} + +// ---------------------------------------------------------------------------- + +/* Struct used to keep track of the file position, just so we + can implement fseek(fh,x,SEEK_CUR). */ +struct fdent +{ + int handle; + int pos; +}; + +#define MAX_OPEN_FILES 20 + +/* User file descriptors (fd) are integer indexes into + the openfiles[] array. Error checking is done by using + findslot(). + + This openfiles array is manipulated directly by only + these 5 functions: + + findslot() - Translate entry. + newslot() - Find empty entry. + initilise_monitor_handles() - Initialize entries. + _swiopen() - Initialize entry. + _close() - Handle stdout == stderr case. + + Every other function must use findslot(). */ + +static struct fdent openfiles[MAX_OPEN_FILES]; + +static struct fdent* +findslot (int); +static int +newslot (void); + +/* Register name faking - works in collusion with the linker. */ +register char* stack_ptr asm ("sp"); + +/* following is copied from libc/stdio/local.h to check std streams */ +extern void _EXFUN(__sinit,(struct _reent*)); +#define CHECK_INIT(ptr) \ + do \ + { \ + if ((ptr) && !(ptr)->__sdidinit) \ + __sinit (ptr); \ + } \ + while (0) + +static int monitor_stdin; +static int monitor_stdout; +static int monitor_stderr; + +/* Return a pointer to the structure associated with + the user file descriptor fd. */ +static struct fdent* +findslot (int fd) +{ + CHECK_INIT(_REENT); + + /* User file descriptor is out of range. */ + if ((unsigned int) fd >= MAX_OPEN_FILES) + { + return NULL; + } + + /* User file descriptor is open? */ + if (openfiles[fd].handle == -1) + { + return NULL; + } + + /* Valid. */ + return &openfiles[fd]; +} + +/* Return the next lowest numbered free file + structure, or -1 if we can't find one. */ +static int +newslot (void) +{ + int i; + + for (i = 0; i < MAX_OPEN_FILES; i++) + { + if (openfiles[i].handle == -1) + { + break; + } + } + + if (i == MAX_OPEN_FILES) + { + return -1; + } + + return i; +} + +void +initialise_monitor_handles (void) +{ + int i; + + /* Open the standard file descriptors by opening the special + * teletype device, ":tt", read-only to obtain a descriptor for + * standard input and write-only to obtain a descriptor for standard + * output. Finally, open ":tt" in append mode to obtain a descriptor + * for standard error. Since this is a write mode, most kernels will + * probably return the same value as for standard output, but the + * kernel can differentiate the two using the mode flag and return a + * different descriptor for standard error. + */ + + int volatile block[3]; + + block[0] = (int) ":tt"; + block[2] = 3; /* length of filename */ + block[1] = 0; /* mode "r" */ + monitor_stdin = call_host (SEMIHOSTING_SYS_OPEN, (void*) block); + + block[0] = (int) ":tt"; + block[2] = 3; /* length of filename */ + block[1] = 4; /* mode "w" */ + monitor_stdout = call_host (SEMIHOSTING_SYS_OPEN, (void*) block); + + block[0] = (int) ":tt"; + block[2] = 3; /* length of filename */ + block[1] = 8; /* mode "a" */ + monitor_stderr = call_host (SEMIHOSTING_SYS_OPEN, (void*) block); + + /* If we failed to open stderr, redirect to stdout. */ + if (monitor_stderr == -1) + { + monitor_stderr = monitor_stdout; + } + + for (i = 0; i < MAX_OPEN_FILES; i++) + { + openfiles[i].handle = -1; + } + + openfiles[0].handle = monitor_stdin; + openfiles[0].pos = 0; + openfiles[1].handle = monitor_stdout; + openfiles[1].pos = 0; + openfiles[2].handle = monitor_stderr; + openfiles[2].pos = 0; +} + +static int +get_errno (void) +{ + return call_host (SEMIHOSTING_SYS_ERRNO, NULL); +} + +/* Set errno and return result. */ +static int +error (int result) +{ + errno = get_errno (); + return result; +} + +/* Check the return and set errno appropriately. */ +static int +checkerror (int result) +{ + if (result == -1) + { + return error (-1); + } + + return result; +} + +/* fh, is a valid internal file handle. + ptr, is a null terminated string. + len, is the length in bytes to read. + Returns the number of bytes *not* written. */ +int +_swiread (int fh, char* ptr, int len) +{ + int block[3]; + + block[0] = fh; + block[1] = (int) ptr; + block[2] = len; + + return checkerror (call_host (SEMIHOSTING_SYS_READ, block)); +} + +/* fd, is a valid user file handle. + Translates the return of _swiread into + bytes read. */ +int +_read (int fd, char* ptr, int len) +{ + int res; + struct fdent *pfd; + + pfd = findslot (fd); + if (pfd == NULL) + { + errno = EBADF; + return -1; + } + + res = _swiread (pfd->handle, ptr, len); + + if (res == -1) + { + return res; + } + + pfd->pos += len - res; + + /* res == len is not an error, + at least if we want feof() to work. */ + return len - res; +} + +/* fd, is a user file descriptor. */ +int +_swilseek (int fd, int ptr, int dir) +{ + int res; + struct fdent *pfd; + + /* Valid file descriptor? */ + pfd = findslot (fd); + if (pfd == NULL) + { + errno = EBADF; + return -1; + } + + /* Valid whence? */ + if ((dir != SEEK_CUR) && (dir != SEEK_SET) && (dir != SEEK_END)) + { + errno = EINVAL; + return -1; + } + + /* Convert SEEK_CUR to SEEK_SET */ + if (dir == SEEK_CUR) + { + ptr = pfd->pos + ptr; + /* The resulting file offset would be negative. */ + if (ptr < 0) + { + errno = EINVAL; + if ((pfd->pos > 0) && (ptr > 0)) + { + errno = EOVERFLOW; + } + return -1; + } + dir = SEEK_SET; + } + + int block[2]; + if (dir == SEEK_END) + { + block[0] = pfd->handle; + res = checkerror (call_host (SEMIHOSTING_SYS_FLEN, block)); + if (res == -1) + { + return -1; + } + ptr += res; + } + + /* This code only does absolute seeks. */ + block[0] = pfd->handle; + block[1] = ptr; + res = checkerror (call_host (SEMIHOSTING_SYS_SEEK, block)); + + /* At this point ptr is the current file position. */ + if (res >= 0) + { + pfd->pos = ptr; + return ptr; + } + else + { + return -1; + } +} + +int +_lseek (int fd, int ptr, int dir) +{ + return _swilseek (fd, ptr, dir); +} + +/* fh, is a valid internal file handle. + Returns the number of bytes *not* written. */ +int +_swiwrite (int fh, char* ptr, int len) +{ + int block[3]; + + block[0] = fh; + block[1] = (int) ptr; + block[2] = len; + + return checkerror (call_host (SEMIHOSTING_SYS_WRITE, block)); +} + +/* fd, is a user file descriptor. */ +int +_write (int fd, char* ptr, int len) +{ + int res; + struct fdent *pfd; + + pfd = findslot (fd); + if (pfd == NULL) + { + errno = EBADF; + return -1; + } + + res = _swiwrite (pfd->handle, ptr, len); + + /* Clearly an error. */ + if (res < 0) + { + return -1; + } + + pfd->pos += len - res; + + /* We wrote 0 bytes? + Retrieve errno just in case. */ + if ((len - res) == 0) + { + return error (0); + } + + return (len - res); +} + +int +_swiopen (const char* path, int flags) +{ + int aflags = 0, fh; + uint32_t block[3]; + + int fd = newslot (); + + if (fd == -1) + { + errno = EMFILE; + return -1; + } + + /* It is an error to open a file that already exists. */ + if ((flags & O_CREAT) && (flags & O_EXCL)) + { + struct stat st; + int res; + res = _stat (path, &st); + if (res != -1) + { + errno = EEXIST; + return -1; + } + } + + /* The flags are Unix-style, so we need to convert them. */ +#ifdef O_BINARY + if (flags & O_BINARY) + { + aflags |= 1; + } +#endif + + /* In O_RDONLY we expect aflags == 0. */ + + if (flags & O_RDWR) + { + aflags |= 2; + } + + if ((flags & O_CREAT) || (flags & O_TRUNC) || (flags & O_WRONLY)) + { + aflags |= 4; + } + + if (flags & O_APPEND) + { + /* Can't ask for w AND a; means just 'a'. */ + aflags &= ~4; + aflags |= 8; + } + + block[0] = (uint32_t) path; + block[2] = strlen (path); + block[1] = (uint32_t) aflags; + + fh = call_host (SEMIHOSTING_SYS_OPEN, block); + + /* Return a user file descriptor or an error. */ + if (fh >= 0) + { + openfiles[fd].handle = fh; + openfiles[fd].pos = 0; + return fd; + } + else + { + return error (fh); + } +} + +int +_open (const char* path, int flags, ...) +{ + return _swiopen (path, flags); +} + +/* fh, is a valid internal file handle. */ +int +_swiclose (int fh) +{ + return checkerror (call_host (SEMIHOSTING_SYS_CLOSE, &fh)); +} + +/* fd, is a user file descriptor. */ +int +_close (int fd) +{ + int res; + struct fdent *pfd; + + pfd = findslot (fd); + if (pfd == NULL) + { + errno = EBADF; + return -1; + } + + /* Handle stderr == stdout. */ + if ((fd == 1 || fd == 2) && (openfiles[1].handle == openfiles[2].handle)) + { + pfd->handle = -1; + return 0; + } + + /* Attempt to close the handle. */ + res = _swiclose (pfd->handle); + + /* Reclaim handle? */ + if (res == 0) + { + pfd->handle = -1; + } + + return res; +} + +int __attribute__((weak)) +_getpid (int n __attribute__ ((unused))) +{ + return 1; +} + +int +_swistat (int fd, struct stat* st) +{ + struct fdent *pfd; + int res; + + pfd = findslot (fd); + if (pfd == NULL) + { + errno = EBADF; + return -1; + } + + /* Always assume a character device, + with 1024 byte blocks. */ + st->st_mode |= S_IFCHR; + st->st_blksize = 1024; + res = checkerror (call_host (SEMIHOSTING_SYS_FLEN, &pfd->handle)); + if (res == -1) + { + return -1; + } + + /* Return the file size. */ + st->st_size = res; + return 0; +} + +int __attribute__((weak)) +_fstat (int fd, struct stat* st) +{ + memset (st, 0, sizeof(*st)); + return _swistat (fd, st); +} + +int __attribute__((weak)) +_stat (const char*fname, struct stat *st) +{ + int fd, res; + memset (st, 0, sizeof(*st)); + /* The best we can do is try to open the file readonly. + If it exists, then we can guess a few things about it. */ + if ((fd = _open (fname, O_RDONLY)) == -1) + { + return -1; + } + st->st_mode |= S_IFREG | S_IREAD; + res = _swistat (fd, st); + /* Not interested in the error. */ + _close (fd); + return res; +} + +int __attribute__((weak)) +_link (void) +{ + errno = ENOSYS; + return -1; +} + +int +_unlink (const char* path) +{ + int res; + uint32_t block[2]; + block[0] = (uint32_t) path; + block[1] = strlen (path); + res = call_host (SEMIHOSTING_SYS_REMOVE, block); + + if (res == -1) + { + return error (res); + } + return 0; +} + +int +_gettimeofday (struct timeval* tp, void* tzvp) +{ + struct timezone* tzp = tzvp; + if (tp) + { + /* Ask the host for the seconds since the Unix epoch. */ + tp->tv_sec = call_host (SEMIHOSTING_SYS_TIME, NULL); + tp->tv_usec = 0; + } + + /* Return fixed data for the timezone. */ + if (tzp) + { + tzp->tz_minuteswest = 0; + tzp->tz_dsttime = 0; + } + + return 0; +} + +/* Return a clock that ticks at 100Hz. */ +clock_t +_clock (void) +{ + clock_t timeval; + + timeval = (clock_t) call_host (SEMIHOSTING_SYS_CLOCK, NULL); + return timeval; +} + +/* Return a clock that ticks at 100Hz. */ +clock_t +_times (struct tms* tp) +{ + clock_t timeval = _clock (); + + if (tp) + { + tp->tms_utime = timeval; /* user time */ + tp->tms_stime = 0; /* system time */ + tp->tms_cutime = 0; /* user time, children */ + tp->tms_cstime = 0; /* system time, children */ + } + + return timeval; +} + +int +_isatty (int fd) +{ + struct fdent *pfd; + int tty; + + pfd = findslot (fd); + if (pfd == NULL) + { + errno = EBADF; + return 0; + } + + tty = call_host (SEMIHOSTING_SYS_ISTTY, &pfd->handle); + + if (tty == 1) + { + return 1; + } + + errno = get_errno (); + return 0; +} + +int +_system (const char* s) +{ + uint32_t block[2]; + int e; + + /* Hmmm. The ARM debug interface specification doesn't say whether + SYS_SYSTEM does the right thing with a null argument, or assign any + meaning to its return value. Try to do something reasonable.... */ + if (!s) + { + return 1; /* maybe there is a shell available? we can hope. :-P */ + } + block[0] = (uint32_t) s; + block[1] = strlen (s); + e = checkerror (call_host (SEMIHOSTING_SYS_SYSTEM, block)); + if ((e >= 0) && (e < 256)) + { + /* We have to convert e, an exit status to the encoded status of + the command. To avoid hard coding the exit status, we simply + loop until we find the right position. */ + int exit_code; + + for (exit_code = e; e && WEXITSTATUS (e) != exit_code; e <<= 1) + { + continue; + } + } + return e; +} + +int +_rename (const char* oldpath, const char* newpath) +{ + uint32_t block[4]; + block[0] = (uint32_t) oldpath; + block[1] = strlen (oldpath); + block[2] = (uint32_t) newpath; + block[3] = strlen (newpath); + return checkerror (call_host (SEMIHOSTING_SYS_RENAME, block)) ? -1 : 0; +} + +// ---------------------------------------------------------------------------- +// Required by Google Tests + +int +mkdir (const char *path __attribute__((unused)), + mode_t mode __attribute__((unused))) +{ +#if 0 + // always return true + return 0; +#else + errno = ENOSYS; + return -1; +#endif +} + +char * +getcwd (char *buf, size_t size) +{ + // no cwd available via semihosting, so we use the temporary folder + strncpy (buf, "/tmp", size); + return buf; +} + +#endif // defined OS_USE_SEMIHOSTING + +#endif // __STDC_HOSTED__ == 1 diff --git a/source/system/stm32f4xx/assert.c b/source/system/stm32f4xx/assert.c new file mode 100644 index 0000000..19a48a0 --- /dev/null +++ b/source/system/stm32f4xx/assert.c @@ -0,0 +1,55 @@ +// +// This file is part of the µOS++ III distribution. +// Copyright (c) 2014 Liviu Ionescu. +// + +#include +#include +#include + +//#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) + +// ---------------------------------------------------------------------------- diff --git a/source/system/stm32f4xx/vectors_stm32f407xx.c b/source/system/stm32f4xx/vectors_stm32f407xx.c new file mode 100644 index 0000000..33ac1d4 --- /dev/null +++ b/source/system/stm32f4xx/vectors_stm32f407xx.c @@ -0,0 +1,335 @@ +// +// Copyright (c) 2015 Liviu Ionescu. +// This file was automatically generated by the xPacks scripts. +// + +// The list of external handlers is from the ARM assembly startup files. + +// ---------------------------------------------------------------------------- + +#include "ExceptionHandlers.h" + +// ---------------------------------------------------------------------------- + +void __attribute__((weak)) +Default_Handler(void); + +// Forward declaration of the specific IRQ handlers. These are aliased +// to the Default_Handler, which is a 'forever' loop. When the application +// defines a handler (with the same name), this will automatically take +// precedence over these weak definitions + +void __attribute__ ((weak, alias ("Default_Handler"))) +WWDG_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +PVD_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TAMP_STAMP_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +RTC_WKUP_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +FLASH_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +RCC_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +EXTI0_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +EXTI1_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +EXTI2_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +EXTI3_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +EXTI4_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA1_Stream0_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA1_Stream1_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA1_Stream2_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA1_Stream3_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA1_Stream4_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA1_Stream5_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA1_Stream6_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +ADC_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +CAN1_TX_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +CAN1_RX0_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +CAN1_RX1_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +CAN1_SCE_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +EXTI9_5_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM1_BRK_TIM9_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM1_UP_TIM10_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM1_TRG_COM_TIM11_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM1_CC_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM2_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM3_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM4_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +I2C1_EV_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +I2C1_ER_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +I2C2_EV_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +I2C2_ER_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +SPI1_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +SPI2_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +USART1_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +USART2_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +USART3_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +EXTI15_10_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +RTC_Alarm_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +OTG_FS_WKUP_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM8_BRK_TIM12_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM8_UP_TIM13_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM8_TRG_COM_TIM14_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM8_CC_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA1_Stream7_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +FMC_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +SDIO_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM5_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +SPI3_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +UART4_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +UART5_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM6_DAC_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +TIM7_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA2_Stream0_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA2_Stream1_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA2_Stream2_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA2_Stream3_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA2_Stream4_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +ETH_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +ETH_WKUP_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +CAN2_TX_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +CAN2_RX0_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +CAN2_RX1_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +CAN2_SCE_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +OTG_FS_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA2_Stream5_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA2_Stream6_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DMA2_Stream7_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +USART6_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +I2C3_EV_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +I2C3_ER_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +OTG_HS_EP1_OUT_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +OTG_HS_EP1_IN_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +OTG_HS_WKUP_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +OTG_HS_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +DCMI_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +HASH_RNG_IRQHandler(void); +void __attribute__ ((weak, alias ("Default_Handler"))) +FPU_IRQHandler(void); + +// ---------------------------------------------------------------------------- + +extern unsigned int _estack; + +typedef void +(* const pHandler)(void); + +// ---------------------------------------------------------------------------- + +// The table of interrupt handlers. It has an explicit section name +// and relies on the linker script to place it at the correct location +// in memory. + +__attribute__ ((section(".isr_vector"),used)) +pHandler __isr_vectors[] = + { + // Cortex-M Core Handlers + (pHandler) &_estack, // The initial stack pointer + Reset_Handler, // The reset handler + + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + MemManage_Handler, // The MPU fault handler + BusFault_Handler, // The bus fault handler + UsageFault_Handler, // The usage fault handler +#else + 0, // Reserved + 0, // Reserved + 0, // Reserved +#endif + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + DebugMon_Handler, // Debug monitor handler +#else + 0, // Reserved +#endif + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // ---------------------------------------------------------------------- + // External Interrupts + WWDG_IRQHandler, // Window WatchDog + PVD_IRQHandler, // PVD through EXTI Line detection + TAMP_STAMP_IRQHandler, // Tamper and TimeStamps through the EXTI line + RTC_WKUP_IRQHandler, // RTC Wakeup through the EXTI line + FLASH_IRQHandler, // FLASH + RCC_IRQHandler, // RCC + EXTI0_IRQHandler, // EXTI Line0 + EXTI1_IRQHandler, // EXTI Line1 + EXTI2_IRQHandler, // EXTI Line2 + EXTI3_IRQHandler, // EXTI Line3 + EXTI4_IRQHandler, // EXTI Line4 + DMA1_Stream0_IRQHandler, // DMA1 Stream 0 + DMA1_Stream1_IRQHandler, // DMA1 Stream 1 + DMA1_Stream2_IRQHandler, // DMA1 Stream 2 + DMA1_Stream3_IRQHandler, // DMA1 Stream 3 + DMA1_Stream4_IRQHandler, // DMA1 Stream 4 + DMA1_Stream5_IRQHandler, // DMA1 Stream 5 + DMA1_Stream6_IRQHandler, // DMA1 Stream 6 + ADC_IRQHandler, // ADC1, ADC2 and ADC3s + CAN1_TX_IRQHandler, // CAN1 TX + CAN1_RX0_IRQHandler, // CAN1 RX0 + CAN1_RX1_IRQHandler, // CAN1 RX1 + CAN1_SCE_IRQHandler, // CAN1 SCE + EXTI9_5_IRQHandler, // External Line[9:5]s + TIM1_BRK_TIM9_IRQHandler, // TIM1 Break and TIM9 + TIM1_UP_TIM10_IRQHandler, // TIM1 Update and TIM10 + TIM1_TRG_COM_TIM11_IRQHandler, // TIM1 Trigger and Commutation and TIM11 + TIM1_CC_IRQHandler, // TIM1 Capture Compare + TIM2_IRQHandler, // TIM2 + TIM3_IRQHandler, // TIM3 + TIM4_IRQHandler, // TIM4 + I2C1_EV_IRQHandler, // I2C1 Event + I2C1_ER_IRQHandler, // I2C1 Error + I2C2_EV_IRQHandler, // I2C2 Event + I2C2_ER_IRQHandler, // I2C2 Error + SPI1_IRQHandler, // SPI1 + SPI2_IRQHandler, // SPI2 + USART1_IRQHandler, // USART1 + USART2_IRQHandler, // USART2 + USART3_IRQHandler, // USART3 + EXTI15_10_IRQHandler, // External Line[15:10]s + RTC_Alarm_IRQHandler, // RTC Alarm (A and B) through EXTI Line + OTG_FS_WKUP_IRQHandler, // USB OTG FS Wakeup through EXTI line + TIM8_BRK_TIM12_IRQHandler, // TIM8 Break and TIM12 + TIM8_UP_TIM13_IRQHandler, // TIM8 Update and TIM13 + TIM8_TRG_COM_TIM14_IRQHandler, // TIM8 Trigger and Commutation and TIM14 + TIM8_CC_IRQHandler, // TIM8 Capture Compare + DMA1_Stream7_IRQHandler, // DMA1 Stream7 + FMC_IRQHandler, // FMC + SDIO_IRQHandler, // SDIO + TIM5_IRQHandler, // TIM5 + SPI3_IRQHandler, // SPI3 + UART4_IRQHandler, // UART4 + UART5_IRQHandler, // UART5 + TIM6_DAC_IRQHandler, // TIM6 and DAC1&2 underrun errors + TIM7_IRQHandler, // TIM7 + DMA2_Stream0_IRQHandler, // DMA2 Stream 0 + DMA2_Stream1_IRQHandler, // DMA2 Stream 1 + DMA2_Stream2_IRQHandler, // DMA2 Stream 2 + DMA2_Stream3_IRQHandler, // DMA2 Stream 3 + DMA2_Stream4_IRQHandler, // DMA2 Stream 4 + ETH_IRQHandler, // Ethernet + ETH_WKUP_IRQHandler, // Ethernet Wakeup through EXTI line + CAN2_TX_IRQHandler, // CAN2 TX + CAN2_RX0_IRQHandler, // CAN2 RX0 + CAN2_RX1_IRQHandler, // CAN2 RX1 + CAN2_SCE_IRQHandler, // CAN2 SCE + OTG_FS_IRQHandler, // USB OTG FS + DMA2_Stream5_IRQHandler, // DMA2 Stream 5 + DMA2_Stream6_IRQHandler, // DMA2 Stream 6 + DMA2_Stream7_IRQHandler, // DMA2 Stream 7 + USART6_IRQHandler, // USART6 + I2C3_EV_IRQHandler, // I2C3 event + I2C3_ER_IRQHandler, // I2C3 error + OTG_HS_EP1_OUT_IRQHandler, // USB OTG HS End Point 1 Out + OTG_HS_EP1_IN_IRQHandler, // USB OTG HS End Point 1 In + OTG_HS_WKUP_IRQHandler, // USB OTG HS Wakeup through EXTI + OTG_HS_IRQHandler, // USB OTG HS + DCMI_IRQHandler, // DCMI + 0, // Reserved + HASH_RNG_IRQHandler, // Hash and Rng + FPU_IRQHandler, // FPU +}; + +// ---------------------------------------------------------------------------- + +// Processor ends up here if an unexpected interrupt occurs or a +// specific handler is not present in the application code. +// When in DEBUG, trigger a debug exception to clearly notify +// the user of the exception and help identify the cause. + +void __attribute__ ((section(".after_vectors"))) +Default_Handler(void) +{ +#if defined(DEBUG) +__DEBUG_BKPT(); +#endif +while (1) + { + } +} + +// ---------------------------------------------------------------------------- diff --git a/source/test/firmware/kernel/ringbuffer/Makefile b/source/test/firmware/kernel/ringbuffer/Makefile deleted file mode 100755 index fed86fd..0000000 --- a/source/test/firmware/kernel/ringbuffer/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -include ../../../../../config/make/rules.mk - -TEST_MAINFILE = $(TEST_EXE_DIR)cunit_ringbuffer -TEST_INCLUDES = \ - -I . \ - -I /usr/include \ - -I $(ROOT_DIR)/source/firmware/kernel - -TEST_SOURCES = \ - $(ROOT_DIR)/source/firmware/kernel/ringbuffer.c \ - $(ROOT_DIR)/source/test/firmware/kernel/ringbuffer/cunit_ringbuffer.c - -TEST_OBJECTS = $(TEST_SOURCES:$(SRC_DIR)/%.c=$(TEST_OBJ_DIR)/%.o) -TEST_DEPS = $(TEST_SOURCES:$(SRC_DIR)/%.c=$(TEST_OBJ_DIR)/%.d) - -TEST_CFLAGS = \ - $(CFLAGS) \ - $(TEST_INCLUDES) - -TEST_LDFLAGS = \ - $(LDFLAGS) \ - -lcunit - -all: $(TEST_MAINFILE) - -clean: - -rm -f $(TEST_OBJECTS) \ - $(TEST_DEPS) \ - $(TEST_MAINFILE) - -$(TEST_MAINFILE): $(TEST_OBJECTS) - @$(MKDIR) $(TEST_EXE_DIR) - $(NATIVE_CC) $(TEST_CFLAGS) $(TEST_LDFLAGS) $(TEST_OBJECTS) -o $(TEST_MAINFILE) - -$(TEST_OBJ_DIR)/%.o: $(SRC_DIR)/%.c - @$(MKDIR) $(dir $@) - $(call maketestdep,$<,$@,$(subst .o,.d,$@)) - $(NATIVE_CC) $(TEST_CFLAGS) -c $< -o $@ - -ifneq "$(MAKECMDGOALS)" "clean" --include $(TEST_DEPS) -endif diff --git a/source/test/firmware/kernel/ringbuffer/cpu.h b/source/test/firmware/kernel/ringbuffer/cpu.h deleted file mode 100755 index 6d39253..0000000 --- a/source/test/firmware/kernel/ringbuffer/cpu.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * cpu.h - * - * Created on: Nov 3, 2013 - * Author: tkl - */ - -#ifndef CPU_H_ -#define CPU_H_ - -#define disable_irq() -#define enable_irq() - -#endif /* CPU_H_ */ diff --git a/source/test/firmware/kernel/ringbuffer/cunit_ringbuffer.c b/source/test/firmware/kernel/ringbuffer/cunit_ringbuffer.c deleted file mode 100755 index 703ec6e..0000000 --- a/source/test/firmware/kernel/ringbuffer/cunit_ringbuffer.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include - -#if 0 -#include -#endif - -#include "ringbuffer.h" - -static int init_suite(void) -{ - return 0; -} - -static int clean_suite(void) -{ - return 0; -} - -/* DUT */ -static char mem[10]; -static struct ringbuffer rb = { - mem, - mem, - mem, - sizeof(mem), - 0 -}; - -static void test_ringbuffer_size(void) -{ - char str[] = "0123456789ABCDEFGHI"; - CU_ASSERT(sizeof(mem) == ringbuffer_write(&rb, str, sizeof(str))); -} - -int main(void) -{ - /* test suite section */ - CU_pSuite suite = NULL; - if(CUE_SUCCESS != CU_initialize_registry()) - goto exit_2; - suite = CU_add_suite("list test suite", init_suite, clean_suite); - if(NULL == suite) - goto exit_1; - - /* test case section */ - if( - NULL == CU_add_test(suite, "ringbuffer size", test_ringbuffer_size) - ) - goto exit_1; - - /* basic interface using tests */ - CU_basic_set_mode(CU_BRM_VERBOSE); - CU_basic_run_tests(); - CU_basic_show_failures(CU_get_failure_list()); - -#if 0 - /* automated interface using tests */ - CU_automated_run_tests(); - CU_list_tests_to_file(); -#endif - -exit_1: - CU_cleanup_registry(); -exit_2: - return CU_get_error(); -}