From c047b2198006076a00ebfe9cff9e8537aeb8ca96 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 2 Apr 2010 08:11:05 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1825 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM3-STM32F103-GCC-ALT/Makefile | 204 ------------- demos/ARMCM3-STM32F103-GCC-ALT/ch.ld | 94 ------ demos/ARMCM3-STM32F103-GCC-ALT/chconf.h | 483 ------------------------------ demos/ARMCM3-STM32F103-GCC-ALT/halconf.h | 152 ---------- demos/ARMCM3-STM32F103-GCC-ALT/main.c | 69 ----- demos/ARMCM3-STM32F103-GCC-ALT/mcuconf.h | 92 ------ demos/ARMCM3-STM32F103-GCC-ALT/readme.txt | 28 -- docs/reports/STM32F103-72-ALT.txt | 156 ---------- docs/reports/STM32F103-72.txt | 26 +- os/ports/GCC/ARMCM3/chcore.h | 8 - os/ports/GCC/ARMCMx/LPC11xx/port.mk | 5 +- os/ports/GCC/ARMCMx/STM32F10x/port.mk | 1 + os/ports/GCC/ARMCMx/chcore.c | 155 ---------- os/ports/GCC/ARMCMx/chcore.h | 375 +++-------------------- os/ports/GCC/ARMCMx/chcore_v6m.c | 152 ++++++++++ os/ports/GCC/ARMCMx/chcore_v6m.h | 271 +++++++++++++++++ os/ports/GCC/ARMCMx/chcore_v7m.c | 178 +++++++++++ os/ports/GCC/ARMCMx/chcore_v7m.h | 313 +++++++++++++++++++ 18 files changed, 978 insertions(+), 1784 deletions(-) delete mode 100644 demos/ARMCM3-STM32F103-GCC-ALT/Makefile delete mode 100644 demos/ARMCM3-STM32F103-GCC-ALT/ch.ld delete mode 100644 demos/ARMCM3-STM32F103-GCC-ALT/chconf.h delete mode 100644 demos/ARMCM3-STM32F103-GCC-ALT/halconf.h delete mode 100644 demos/ARMCM3-STM32F103-GCC-ALT/main.c delete mode 100644 demos/ARMCM3-STM32F103-GCC-ALT/mcuconf.h delete mode 100644 demos/ARMCM3-STM32F103-GCC-ALT/readme.txt delete mode 100644 docs/reports/STM32F103-72-ALT.txt create mode 100644 os/ports/GCC/ARMCMx/chcore_v6m.c create mode 100644 os/ports/GCC/ARMCMx/chcore_v6m.h create mode 100644 os/ports/GCC/ARMCMx/chcore_v7m.c create mode 100644 os/ports/GCC/ARMCMx/chcore_v7m.h diff --git a/demos/ARMCM3-STM32F103-GCC-ALT/Makefile b/demos/ARMCM3-STM32F103-GCC-ALT/Makefile deleted file mode 100644 index 347a6f7e0..000000000 --- a/demos/ARMCM3-STM32F103-GCC-ALT/Makefile +++ /dev/null @@ -1,204 +0,0 @@ -############################################################################## -# Build global options -# NOTE: Can be overridden externally. -# - -# Compiler options here. -ifeq ($(USE_OPT),) - USE_OPT = -O2 -ggdb -fomit-frame-pointer -mabi=apcs-gnu -falign-functions=16 -endif - -# C++ specific options here (added to USE_OPT). -ifeq ($(USE_CPPOPT),) - USE_CPPOPT = -fno-rtti -endif - -# Enable this if you want the linker to remove unused code and data -ifeq ($(USE_LINK_GC),) - USE_LINK_GC = yes -endif - -# If enabled, this option allows to compile the application in THUMB mode. -ifeq ($(USE_THUMB),) - USE_THUMB = yes -endif - -# Enable register caching optimization (read documentation). -ifeq ($(USE_CURRP_CACHING),) - USE_CURRP_CACHING = no -endif - -# -# Build global options -############################################################################## - -############################################################################## -# Architecture or project specific options -# - -# Enable this if you really want to use the STM FWLib. -ifeq ($(USE_FWLIB),) - USE_FWLIB = no -endif - -# -# Architecture or project specific options -############################################################################## - -############################################################################## -# Project, sources and paths -# - -# Define project name here -PROJECT = ch - -# Define linker script file here -LDSCRIPT= ch.ld - -# Imported source files -CHIBIOS = ../.. -include $(CHIBIOS)/boards/OLIMEX_STM32_P103/board.mk -include $(CHIBIOS)/os/hal/platforms/STM32/platform.mk -include $(CHIBIOS)/os/hal/hal.mk -include $(CHIBIOS)/os/ports/GCC/ARMCM3/STM32F103/port.mk -include $(CHIBIOS)/os/kernel/kernel.mk -include $(CHIBIOS)/test/test.mk - -# C sources that can be compiled in ARM or THUMB mode depending on the global -# setting. -CSRC = $(PORTSRC) \ - $(KERNSRC) \ - $(TESTSRC) \ - $(HALSRC) \ - $(PLATFORMSRC) \ - $(BOARDSRC) \ - $(CHIBIOS)/os/various/evtimer.c \ - $(CHIBIOS)/os/various/syscalls.c \ - main.c - -# C++ sources that can be compiled in ARM or THUMB mode depending on the global -# setting. -CPPSRC = - -# C sources to be compiled in ARM mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -ACSRC = - -# C++ sources to be compiled in ARM mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -ACPPSRC = - -# C sources to be compiled in THUMB mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -TCSRC = - -# C sources to be compiled in THUMB mode regardless of the global setting. -# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler -# option that results in lower performance and larger code size. -TCPPSRC = - -# List ASM source files here -ASMSRC = $(PORTASM) \ - $(CHIBIOS)/os/ports/GCC/ARMCM3/STM32F103/vectors.s - -INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \ - $(HALINC) $(PLATFORMINC) $(BOARDINC) \ - $(CHIBIOS)/os/various - -# -# Project, sources and paths -############################################################################## - -############################################################################## -# Compiler settings -# - -MCU = cortex-m3 - -TRGT = arm-elf- -CC = $(TRGT)gcc -CPPC = $(TRGT)g++ -# Enable loading with g++ only if you need C++ runtime support. -# NOTE: You can use C++ even without C++ support if you are careful. C++ -# runtime support makes code size explode. -LD = $(TRGT)gcc -#LD = $(TRGT)g++ -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -OD = $(TRGT)objdump -HEX = $(CP) -O ihex -BIN = $(CP) -O binary - -# ARM-specific options here -AOPT = - -# THUMB-specific options here -TOPT = -mthumb -DTHUMB - -# Define C warning options here -CWARN = -Wall -Wextra -Wstrict-prototypes - -# Define C++ warning options here -CPPWARN = -Wall -Wextra - -# -# Compiler settings -############################################################################## - -############################################################################## -# Start of default section -# - -# List all default C defines here, like -D_DEBUG=1 -DDEFS = -DSTM32F10X_MD - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################## - -############################################################################## -# Start of user section -# - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List all user directories here -UINCDIR = - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# -# End of user defines -############################################################################## - -ifeq ($(USE_FWLIB),yes) - include $(CHIBIOS)/ext/stm32lib/stm32lib.mk - CSRC += $(STM32SRC) - INCDIR += $(STM32INC) - USE_OPT += -DUSE_STDPERIPH_DRIVER -endif - -include $(CHIBIOS)/os/ports/GCC/ARM/rules.mk diff --git a/demos/ARMCM3-STM32F103-GCC-ALT/ch.ld b/demos/ARMCM3-STM32F103-GCC-ALT/ch.ld deleted file mode 100644 index 1405765cd..000000000 --- a/demos/ARMCM3-STM32F103-GCC-ALT/ch.ld +++ /dev/null @@ -1,94 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/* - * ST32F103 memory setup. - */ -__main_stack_size__ = 0x0200; -__process_stack_size__ = 0x0400; -__stacks_total_size__ = __main_stack_size__ + __process_stack_size__; - -MEMORY -{ - flash : org = 0x08000000, len = 128k - ram : org = 0x20000000, len = 20k -} - -__ram_start__ = ORIGIN(ram); -__ram_size__ = LENGTH(ram); -__ram_end__ = __ram_start__ + __ram_size__; - -SECTIONS -{ - . = 0; - - .text : ALIGN(16) SUBALIGN(16) - { - _text = .; - KEEP(*(vectors)); - *(.text) - *(.text.*); - *(.rodata); - *(.rodata.*); - *(.glue_7t); - *(.glue_7); - *(.gcc*); - *(.ctors); - *(.dtors); - . = ALIGN(4); - _etext = .; - } > flash - - _textdata = _etext; - - .data : - { - _data = .; - *(.data) - . = ALIGN(4); - *(.data.*) - . = ALIGN(4); - *(.ramtext) - . = ALIGN(4); - _edata = .; - } > ram AT > flash - - .bss : - { - _bss_start = .; - *(.bss) - . = ALIGN(4); - *(.bss.*) - . = ALIGN(4); - *(COMMON) - . = ALIGN(4); - _bss_end = .; - } > ram - - /DISCARD/ : - { - *(.eh_*) - } -} - -PROVIDE(end = .); -_end = .; - -__heap_base__ = _end; -__heap_end__ = __ram_end__ - __stacks_total_size__; diff --git a/demos/ARMCM3-STM32F103-GCC-ALT/chconf.h b/demos/ARMCM3-STM32F103-GCC-ALT/chconf.h deleted file mode 100644 index 046d28300..000000000 --- a/demos/ARMCM3-STM32F103-GCC-ALT/chconf.h +++ /dev/null @@ -1,483 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file templates/chconf.h - * @brief Configuration file template. - * @details A copy of this file must be placed in each project directory, it - * contains the application specific kernel settings. - * - * @addtogroup config - * @details Kernel related settings and hooks. - * @{ - */ - -#ifndef _CHCONF_H_ -#define _CHCONF_H_ - -/*===========================================================================*/ -/* Kernel parameters. */ -/*===========================================================================*/ - -/** - * @brief System tick frequency. - * @details Frequency of the system timer that drives the system ticks. This - * setting also defines the system tick time unit. - */ -#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__) -#define CH_FREQUENCY 1000 -#endif - -/** - * @brief Round robin interval. - * @details This constant is the number of system ticks allowed for the - * threads before preemption occurs. Setting this value to zero - * disables the preemption for threads with equal priority and the - * round robin becomes cooperative. Note that higher priority - * threads can still preempt, the kernel is always preemptive. - * - * @note Disabling the round robin preemption makes the kernel more compact - * and generally faster. - */ -#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__) -#define CH_TIME_QUANTUM 20 -#endif - -/** - * @brief Nested locks. - * @details If enabled then the use of nested @p chSysLock() / @p chSysUnlock() - * operations is allowed.
- * For performance and code size reasons the recommended setting - * is to leave this option disabled.
- * You may use this option if you need to merge ChibiOS/RT with - * external libraries that require nested lock/unlock operations. - * - * @note T he default is @p FALSE. - */ -#if !defined(CH_USE_NESTED_LOCKS) || defined(__DOXYGEN__) -#define CH_USE_NESTED_LOCKS FALSE -#endif - -/** - * @brief Managed RAM size. - * @details Size of the RAM area to be managed by the OS. If set to zero - * then the whole available RAM is used. The core memory is made - * available to the heap allocator and/or can be used directly through - * the simplified core memory allocator. - * - * @note In order to let the OS manage the whole RAM the linker script must - * provide the @p __heap_base__ and @p __heap_end__ symbols. - * @note Requires @p CH_USE_COREMEM. - */ -#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__) -#define CH_MEMCORE_SIZE 0 -#endif - -/*===========================================================================*/ -/* Performance options. */ -/*===========================================================================*/ - -/** - * @brief OS optimization. - * @details If enabled then time efficient rather than space efficient code - * is used when two possible implementations exist. - * - * @note This is not related to the compiler optimization options. - * @note The default is @p TRUE. - */ -#if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__) -#define CH_OPTIMIZE_SPEED TRUE -#endif - -/** - * @brief Exotic optimization. - * @details If defined then a CPU register is used as storage for the global - * @p currp variable. Caching this variable in a register greatly - * improves both space and time OS efficiency. A side effect is that - * one less register has to be saved during the context switch - * resulting in lower RAM usage and faster context switch. - * - * @note This option is only usable with the GCC compiler and is only useful - * on processors with many registers like ARM cores. - * @note If this option is enabled then ALL the libraries linked to the - * ChibiOS/RT code must be recompiled with the GCC option @p - * -ffixed-@. - * @note This option must be enabled in the Makefile, it is listed here for - * documentation only. - */ -#if defined(__DOXYGEN__) -#define CH_CURRP_REGISTER_CACHE "reg" -#endif - -/*===========================================================================*/ -/* Subsystem options. */ -/*===========================================================================*/ - -/** - * @brief Threads registry APIs. - * @details If enabled then the registry APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__) -#define CH_USE_REGISTRY TRUE -#endif - -/** - * @brief Threads synchronization APIs. - * @details If enabled then the @p chThdWait() function is included in - * the kernel. - * - * @note The default is @p TRUE. - */ -#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__) -#define CH_USE_WAITEXIT TRUE -#endif - -/** - * @brief Semaphores APIs. - * @details If enabled then the Semaphores APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__) -#define CH_USE_SEMAPHORES TRUE -#endif - -/** - * @brief Semaphores queuing mode. - * @details If enabled then the threads are enqueued on semaphores by - * priority rather than in FIFO order. - * - * @note The default is @p FALSE. Enable this if you have special requirements. - * @note Requires @p CH_USE_SEMAPHORES. - */ -#if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__) -#define CH_USE_SEMAPHORES_PRIORITY FALSE -#endif - -/** - * @brief Atomic semaphore API. - * @details If enabled then the semaphores the @p chSemSignalWait() API - * is included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_USE_SEMAPHORES. - */ -#if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__) -#define CH_USE_SEMSW TRUE -#endif - -/** - * @brief Mutexes APIs. - * @details If enabled then the mutexes APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__) -#define CH_USE_MUTEXES TRUE -#endif - -/** - * @brief Conditional Variables APIs. - * @details If enabled then the conditional variables APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_USE_MUTEXES. - */ -#if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__) -#define CH_USE_CONDVARS TRUE -#endif - -/** - * @brief Conditional Variables APIs with timeout. - * @details If enabled then the conditional variables APIs with timeout - * specification are included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_USE_CONDVARS. - */ -#if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__) -#define CH_USE_CONDVARS_TIMEOUT TRUE -#endif - -/** - * @brief Events Flags APIs. - * @details If enabled then the event flags APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__) -#define CH_USE_EVENTS TRUE -#endif - -/** - * @brief Events Flags APIs with timeout. - * @details If enabled then the events APIs with timeout specification - * are included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_USE_EVENTS. - */ -#if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__) -#define CH_USE_EVENTS_TIMEOUT TRUE -#endif - -/** - * @brief Synchronous Messages APIs. - * @details If enabled then the synchronous messages APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - */ -#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__) -#define CH_USE_MESSAGES TRUE -#endif - -/** - * @brief Synchronous Messages queuing mode. - * @details If enabled then messages are served by priority rather than in - * FIFO order. - * - * @note The default is @p FALSE. Enable this if you have special requirements. - * @note Requires @p CH_USE_MESSAGES. - */ -#if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__) -#define CH_USE_MESSAGES_PRIORITY FALSE -#endif - -/** - * @brief Mailboxes APIs. - * @details If enabled then the asynchronous messages (mailboxes) APIs are - * included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_USE_SEMAPHORES. - */ -#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__) -#define CH_USE_MAILBOXES TRUE -#endif - -/** - * @brief I/O Queues APIs. - * @details If enabled then the I/O queues APIs are included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_USE_SEMAPHORES. - */ -#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__) -#define CH_USE_QUEUES TRUE -#endif - -/** - * @brief Core Memory Manager APIs. - * @details If enabled then the core memory manager APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - */ -#if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__) -#define CH_USE_MEMCORE TRUE -#endif - -/** - * @brief Heap Allocator APIs. - * @details If enabled then the memory heap allocator APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_USE_COREMEM and either @p CH_USE_MUTEXES or - * @p CH_USE_SEMAPHORES. - * @note Mutexes are recommended. - */ -#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__) -#define CH_USE_HEAP TRUE -#endif - -/** - * @brief C-runtime allocator. - * @details If enabled the the heap allocator APIs just wrap the C-runtime - * @p malloc() and @p free() functions. - * - * @note The default is @p FALSE. - * @note Requires @p CH_USE_HEAP. - * @note The C-runtime may or may not require @p CH_USE_COREMEM, see the - * appropriate documentation. - */ -#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__) -#define CH_USE_MALLOC_HEAP FALSE -#endif - -/** - * @brief Memory Pools Allocator APIs. - * @details If enabled then the memory pools allocator APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - */ -#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__) -#define CH_USE_MEMPOOLS TRUE -#endif - -/** - * @brief Dynamic Threads APIs. - * @details If enabled then the dynamic threads creation APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_USE_WAITEXIT. - * @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS. - */ -#if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__) -#define CH_USE_DYNAMIC TRUE -#endif - -/*===========================================================================*/ -/* Debug options. */ -/*===========================================================================*/ - -/** - * @brief Debug option, parameters checks. - * @details If enabled then the checks on the API functions input - * parameters are activated. - * - * @note The default is @p FALSE. - */ -#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS FALSE -#endif - -/** - * @brief Debug option, consistency checks. - * @details If enabled then all the assertions in the kernel code are - * activated. This includes consistency checks inside the kernel, - * runtime anomalies and port-defined checks. - * - * @note The default is @p FALSE. - */ -#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS FALSE -#endif - -/** - * @brief Debug option, trace buffer. - * @details If enabled then the context switch circular trace buffer is - * activated. - * - * @note The default is @p FALSE. - */ -#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE FALSE -#endif - -/** - * @brief Debug option, stack checks. - * @details If enabled then a runtime stack check is performed. - * - * @note The default is @p FALSE. - * @note The stack check is performed in a architecture/port dependent way. - * It may not be implemented or some ports. - * @note The default failure mode is to halt the system with the global - * @p panic_msg variable set to @p NULL. - */ -#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK FALSE -#endif - -/** - * @brief Debug option, stacks initialization. - * @details If enabled then the threads working area is filled with a byte - * value when a thread is created. This can be useful for the - * runtime measurement of the used stack. - * - * @note The default is @p FALSE. - */ -#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS FALSE -#endif - -/** - * @brief Debug option, threads profiling. - * @details If enabled then a field is added to the @p Thread structure that - * counts the system ticks occurred while executing the thread. - * - * @note The default is @p TRUE. - * @note This debug option is defaulted to TRUE because it is required by - * some test cases into the test suite. - */ -#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__) -#define CH_DBG_THREADS_PROFILING TRUE -#endif - -/*===========================================================================*/ -/* Kernel hooks. */ -/*===========================================================================*/ - -/** - * @brief Threads descriptor structure hook. - * @details User fields added to the end of the @p Thread structure. - */ -#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__) -#define THREAD_EXT_FIELDS \ -struct { \ - /* Add threads custom fields here.*/ \ -}; -#endif - -/** - * @brief Threads initialization hook. - * @details User initialization code added to the @p chThdInit() API. - * - * @note It is invoked from within @p chThdInit() and implicitily from all - * the threads creation APIs. - */ -#if !defined(THREAD_EXT_INIT) || defined(__DOXYGEN__) -#define THREAD_EXT_INIT(tp) { \ - /* Add threads initialization code here.*/ \ -} -#endif - -/** - * @brief Threads finalization hook. - * @details User finalization code added to the @p chThdExit() API. - * - * @note It is inserted into lock zone. - * @note It is also invoked when the threads simply return in order to - * terminate. - */ -#if !defined(THREAD_EXT_EXIT) || defined(__DOXYGEN__) -#define THREAD_EXT_EXIT(tp) { \ - /* Add threads finalization code here.*/ \ -} -#endif - -/** - * @brief Idle Loop hook. - * @details This hook is continuously invoked by the idle thread loop. - */ -#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__) -#define IDLE_LOOP_HOOK() { \ - /* Idle loop code here.*/ \ -} -#endif - -#endif /* _CHCONF_H_ */ - -/** @} */ diff --git a/demos/ARMCM3-STM32F103-GCC-ALT/halconf.h b/demos/ARMCM3-STM32F103-GCC-ALT/halconf.h deleted file mode 100644 index 763b0019a..000000000 --- a/demos/ARMCM3-STM32F103-GCC-ALT/halconf.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file templates/halconf.h - * @brief HAL configuration header. - * @addtogroup HAL_CONF - * @{ - */ - -/* - * HAL configuration file, this file allows to enable or disable the various - * device drivers from your application. You may also use this file in order - * to override the device drivers default settings. - */ - -#ifndef _HALCONF_H_ -#define _HALCONF_H_ - -/* - * Uncomment the following line in order to include a mcu-related - * settings file. This file can be used to include platform specific - * header files or to override the low level drivers settings. - */ -#include "mcuconf.h" - -/*===========================================================================*/ -/* PAL driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables the PAL subsystem. - */ -#if !defined(CH_HAL_USE_PAL) || defined(__DOXYGEN__) -#define CH_HAL_USE_PAL TRUE -#endif - -/*===========================================================================*/ -/* ADC driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables the ADC subsystem. - */ -#if !defined(CH_HAL_USE_ADC) || defined(__DOXYGEN__) -#define CH_HAL_USE_ADC FALSE -#endif - -/*===========================================================================*/ -/* CAN driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables the CAN subsystem. - */ -#if !defined(CH_HAL_USE_CAN) || defined(__DOXYGEN__) -#define CH_HAL_USE_CAN FALSE -#endif - -/*===========================================================================*/ -/* MAC driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables the MAC subsystem. - */ -#if !defined(CH_HAL_USE_MAC) || defined(__DOXYGEN__) -#define CH_HAL_USE_MAC FALSE -#endif - -/*===========================================================================*/ -/* PWM driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables the PWM subsystem. - */ -#if !defined(CH_HAL_USE_PWM) || defined(__DOXYGEN__) -#define CH_HAL_USE_PWM FALSE -#endif - -/*===========================================================================*/ -/* SERIAL driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables the SERIAL subsystem. - */ -#if !defined(CH_HAL_USE_SERIAL) || defined(__DOXYGEN__) -#define CH_HAL_USE_SERIAL TRUE -#endif - -/* - * Default SERIAL settings overrides (uncomment to override). - */ -/*#define SERIAL_DEFAULT_BITRATE 38400*/ -/*#define SERIAL_BUFFERS_SIZE 64*/ - -/*===========================================================================*/ -/* SPI driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables the SPI subsystem. - */ -#if !defined(CH_HAL_USE_SPI) || defined(__DOXYGEN__) -#define CH_HAL_USE_SPI FALSE -#endif - -/* - * Default SPI settings overrides (uncomment to override). - */ -/*#define SPI_USE_MUTUAL_EXCLUSION TRUE*/ - -/*===========================================================================*/ -/* MMC_SPI driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables the MMC_SPI subsystem. - */ -#if !defined(CH_HAL_USE_MMC_SPI) || defined(__DOXYGEN__) -#define CH_HAL_USE_MMC_SPI FALSE -#endif - -/* - * Default MMC_SPI settings overrides (uncomment to override). - */ -/*#define MMC_SECTOR_SIZE 512*/ -/*#define MMC_NICE_WAITING TRUE*/ -/*#define MMC_POLLING_INTERVAL 10*/ -/*#define MMC_POLLING_DELAY 10*/ - -#endif /* _HALCONF_H_ */ - -/** @} */ diff --git a/demos/ARMCM3-STM32F103-GCC-ALT/main.c b/demos/ARMCM3-STM32F103-GCC-ALT/main.c deleted file mode 100644 index 0072f0958..000000000 --- a/demos/ARMCM3-STM32F103-GCC-ALT/main.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "ch.h" -#include "hal.h" -#include "test.h" - -/* - * Red LEDs blinker thread, times are in milliseconds. - */ -static WORKING_AREA(waThread1, 128); -static msg_t Thread1(void *arg) { - - (void)arg; - while (TRUE) { - palClearPad(IOPORT3, GPIOC_LED); - chThdSleepMilliseconds(500); - palSetPad(IOPORT3, GPIOC_LED); - chThdSleepMilliseconds(500); - } - return 0; -} - -/* - * Entry point, note, the main() function is already a thread in the system - * on entry. - */ -int main(int argc, char **argv) { - - (void)argc; - (void)argv; - - /* - * Activates the serial driver 2 using the driver default configuration. - */ - sdStart(&SD2, NULL); - - /* - * Creates the blinker thread. - */ - chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); - - /* - * Normal main() thread activity, in this demo it does nothing except - * sleeping in a loop and check the button state. - */ - while (TRUE) { - if (palReadPad(IOPORT1, GPIOA_BUTTON)) - TestThread(&SD2); - chThdSleepMilliseconds(500); - } - return 0; -} diff --git a/demos/ARMCM3-STM32F103-GCC-ALT/mcuconf.h b/demos/ARMCM3-STM32F103-GCC-ALT/mcuconf.h deleted file mode 100644 index 28ae05e73..000000000 --- a/demos/ARMCM3-STM32F103-GCC-ALT/mcuconf.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/* - * STM32 drivers configuration. - * The following settings override the default settings present in - * the various device driver implementation headers. - * Note that the settings for each driver only have effect if the driver - * is enabled in halconf.h. - * - * IRQ priorities: - * 15...0 Lowest...Highest. - * - * DMA priorities: - * 0...3 Lowest...Highest. - */ - -/* - * HAL driver system settings. - */ -#define STM32_SYSCLK 72 - -/* - * ADC driver system settings. - */ -#define USE_STM32_ADC1 TRUE -#define STM32_ADC1_DMA_PRIORITY 3 -#define STM32_ADC1_IRQ_PRIORITY 5 -#define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt() - -/* - * CAN driver system settings. - */ -#define USE_STM32_CAN1 TRUE -#define STM32_CAN1_IRQ_PRIORITY 11 - -/* - * PWM driver system settings. - */ -#define USE_STM32_PWM1 TRUE -#define USE_STM32_PWM2 FALSE -#define USE_STM32_PWM3 FALSE -#define USE_STM32_PWM4 FALSE -#define STM32_PWM1_IRQ_PRIORITY 7 -#define STM32_PWM2_IRQ_PRIORITY 7 -#define STM32_PWM3_IRQ_PRIORITY 7 -#define STM32_PWM4_IRQ_PRIORITY 7 - -/* - * SERIAL driver system settings. - */ -#define USE_STM32_USART1 FALSE -#define USE_STM32_USART2 TRUE -#define USE_STM32_USART3 FALSE -#if defined(STM32F10X_HD) || defined(STM32F10X_CL) -#define USE_STM32_UART4 FALSE -#define USE_STM32_UART5 FALSE -#endif -#define STM32_USART1_PRIORITY 12 -#define STM32_USART2_PRIORITY 12 -#define STM32_USART3_PRIORITY 12 -#if defined(STM32F10X_HD) || defined(STM32F10X_CL) -#define STM32_UART4_PRIORITY 12 -#define STM32_UART5_PRIORITY 12 -#endif - -/* - * SPI driver system settings. - */ -#define USE_STM32_SPI1 TRUE -#define USE_STM32_SPI2 TRUE -#define STM32_SPI1_DMA_PRIORITY 2 -#define STM32_SPI2_DMA_PRIORITY 2 -#define STM32_SPI1_IRQ_PRIORITY 10 -#define STM32_SPI2_IRQ_PRIORITY 10 -#define STM32_SPI1_DMA_ERROR_HOOK() chSysHalt() diff --git a/demos/ARMCM3-STM32F103-GCC-ALT/readme.txt b/demos/ARMCM3-STM32F103-GCC-ALT/readme.txt deleted file mode 100644 index 353dd2658..000000000 --- a/demos/ARMCM3-STM32F103-GCC-ALT/readme.txt +++ /dev/null @@ -1,28 +0,0 @@ -***************************************************************************** -** ChibiOS/RT port for ARM-Cortex-M3 STM32F103. ** -***************************************************************************** - -** TARGET ** - -The demo will on an Olimex STM32-P103 board. - -** The Demo ** - -The demo flashes the board LED using a thread, by pressing the button located -on the board the test procedure is activated with output on the serial port -COM2 (USART2). - -** Build Procedure ** - -The demo has been tested by using the free Codesourcery GCC-based toolchain, -YAGARTO and an experimental WinARM build including GCC 4.3.0. -Just modify the TRGT line in the makefile in order to use different GCC ports. - -** Notes ** - -Some files used by the demo are not part of ChibiOS/RT but are copyright of -ST Microelectronics and are licensed under a different license. -Also note that not all the files present in the ST library are distribited -with ChibiOS/RT, you can find the whole library on the ST web site: - - http://www.st.com diff --git a/docs/reports/STM32F103-72-ALT.txt b/docs/reports/STM32F103-72-ALT.txt deleted file mode 100644 index 4d3d89417..000000000 --- a/docs/reports/STM32F103-72-ALT.txt +++ /dev/null @@ -1,156 +0,0 @@ -*************************************************************************** -Options: -O2 -fomit-frame-pointer -mabi=apcs-gnu -falign-functions=16 -Settings: SYSCLK=72, ACR=0x12 (2 wait states) -*************************************************************************** - -*** ChibiOS/RT test suite -*** -*** Kernel: 1.5.4unstable -*** GCC Version: 4.4.2 -*** Architecture: ARMv7-M -*** Core Variant: Cortex-M3 -*** Platform: STM32 -*** Test Board: Olimex STM32-P103 - ----------------------------------------------------------------------------- ---- Test Case 1.1 (Threads, enqueuing test #1) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 1.2 (Threads, enqueuing test #2) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 1.3 (Threads, priority change) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 1.4 (Threads, delays) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 2.1 (Semaphores, enqueuing) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 2.2 (Semaphores, timeout) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 2.3 (Semaphores, atomic signal-wait) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 3.1 (Mutexes, priority enqueuing test) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 3.2 (Mutexes, priority inheritance, simple case) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 3.3 (Mutexes, priority inheritance, complex case) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 3.4 (Mutexes, priority return) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 3.5 (Mutexes, status) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 3.6 (CondVar, signal test) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 3.7 (CondVar, broadcast test) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 3.8 (CondVar, boost test) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 4.1 (Messages, loop) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 5.1 (Mailboxes, queuing and timeouts) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 6.1 (Events, registration and dispatch) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 6.2 (Events, wait and broadcast) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 6.3 (Events, timeouts) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 7.1 (Heap, allocation and fragmentation test) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 8.1 (Memory Pools, queue/dequeue) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 9.1 (Dynamic APIs, threads creation from heap) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 9.2 (Dynamic APIs, threads creation from memory pool) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 10.1 (Queues, input queues) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 10.2 (Queues, output queues) ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.1 (Benchmark, messages #1) ---- Score : 226004 msgs/S, 452008 ctxswc/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.2 (Benchmark, messages #2) ---- Score : 188141 msgs/S, 376282 ctxswc/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.3 (Benchmark, messages #3) ---- Score : 188141 msgs/S, 376282 ctxswc/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.4 (Benchmark, context switch) ---- Score : 707232 ctxswc/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.5 (Benchmark, threads, full cycle) ---- Score : 147284 threads/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.6 (Benchmark, threads, create only) ---- Score : 204767 threads/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.7 (Benchmark, mass reschedule, 5 threads) ---- Score : 57135 reschedules/S, 342810 ctxswc/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.8 (Benchmark, round robin context switching) ---- Score : 429720 ctxswc/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.9 (Benchmark, I/O Queues throughput) ---- Score : 475040 bytes/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.10 (Benchmark, virtual timers set/reset) ---- Score : 647548 timers/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.11 (Benchmark, semaphores wait/signal) ---- Score : 833440 wait+signal/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.12 (Benchmark, mutexes lock/unlock) ---- Score : 644680 lock+unlock/S ---- Result: SUCCESS ----------------------------------------------------------------------------- ---- Test Case 11.13 (Benchmark, RAM footprint) ---- System: 332 bytes ---- Thread: 68 bytes ---- Timer : 20 bytes ---- Semaph: 12 bytes ---- EventS: 4 bytes ---- EventL: 12 bytes ---- Mutex : 16 bytes ---- CondV.: 8 bytes ---- Queue : 32 bytes ---- MailB.: 40 bytes ---- Result: SUCCESS ----------------------------------------------------------------------------- - -Final result: SUCCESS diff --git a/docs/reports/STM32F103-72.txt b/docs/reports/STM32F103-72.txt index 81c9a564d..4d3d89417 100644 --- a/docs/reports/STM32F103-72.txt +++ b/docs/reports/STM32F103-72.txt @@ -92,55 +92,55 @@ Settings: SYSCLK=72, ACR=0x12 (2 wait states) --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.1 (Benchmark, messages #1) ---- Score : 252111 msgs/S, 504222 ctxswc/S +--- Score : 226004 msgs/S, 452008 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.2 (Benchmark, messages #2) ---- Score : 200704 msgs/S, 401408 ctxswc/S +--- Score : 188141 msgs/S, 376282 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.3 (Benchmark, messages #3) ---- Score : 200704 msgs/S, 401408 ctxswc/S +--- Score : 188141 msgs/S, 376282 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.4 (Benchmark, context switch) ---- Score : 822344 ctxswc/S +--- Score : 707232 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.5 (Benchmark, threads, full cycle) ---- Score : 156203 threads/S +--- Score : 147284 threads/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.6 (Benchmark, threads, create only) ---- Score : 223839 threads/S +--- Score : 204767 threads/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.7 (Benchmark, mass reschedule, 5 threads) ---- Score : 62866 reschedules/S, 377196 ctxswc/S +--- Score : 57135 reschedules/S, 342810 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.8 (Benchmark, round robin context switching) ---- Score : 491292 ctxswc/S +--- Score : 429720 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.9 (Benchmark, I/O Queues throughput) ---- Score : 471792 bytes/S +--- Score : 475040 bytes/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.10 (Benchmark, virtual timers set/reset) ---- Score : 644466 timers/S +--- Score : 647548 timers/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.11 (Benchmark, semaphores wait/signal) ---- Score : 895484 wait+signal/S +--- Score : 833440 wait+signal/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.12 (Benchmark, mutexes lock/unlock) ---- Score : 694320 lock+unlock/S +--- Score : 644680 lock+unlock/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.13 (Benchmark, RAM footprint) ---- System: 340 bytes +--- System: 332 bytes --- Thread: 68 bytes --- Timer : 20 bytes --- Semaph: 12 bytes diff --git a/os/ports/GCC/ARMCM3/chcore.h b/os/ports/GCC/ARMCM3/chcore.h index b844fbffb..ac8ab021b 100644 --- a/os/ports/GCC/ARMCM3/chcore.h +++ b/os/ports/GCC/ARMCM3/chcore.h @@ -34,13 +34,6 @@ /* Port constants. */ /*===========================================================================*/ -/** - * @brief Port implementing a exception mode context switching. - * @details This macro can be used to differentiate this port from the other - * Cortex-Mx port which defines @p CORTEX_PORT_MODE_EXOSWITCH. - */ -#define CORTEX_PORT_MODE_ENDOSWITCH - #define CORTEX_M0 0 /**< @brief Cortex-M0 variant. */ #define CORTEX_M1 1 /**< @brief Cortex-M1 variant. */ #define CORTEX_M3 3 /**< @brief Cortex-M3 variant. */ @@ -55,7 +48,6 @@ #error "unknown or unsupported Cortex-M model" #endif - /*===========================================================================*/ /* Port derived parameters. */ /*===========================================================================*/ diff --git a/os/ports/GCC/ARMCMx/LPC11xx/port.mk b/os/ports/GCC/ARMCMx/LPC11xx/port.mk index dfbb01b16..3935b9195 100644 --- a/os/ports/GCC/ARMCMx/LPC11xx/port.mk +++ b/os/ports/GCC/ARMCMx/LPC11xx/port.mk @@ -1,7 +1,8 @@ # List of the ChibiOS/RT Cortex-M0 LPC111x port files. PORTSRC = ${CHIBIOS}/os/ports/GCC/ARMCMx/chcore.c \ - ${CHIBIOS}/os/ports/GCC/ARMCMx/nvic.c -# ${CHIBIOS}/os/ports/GCC/ARMCMx/cmsis/core_cm0.c + ${CHIBIOS}/os/ports/GCC/ARMCMx/chcore_v6m.c \ + ${CHIBIOS}/os/ports/GCC/ARMCMx/nvic.c \ + ${CHIBIOS}/os/ports/GCC/ARMCMx/cmsis/core_cm0.c PORTASM = ${CHIBIOS}/os/ports/GCC/ARMCMx/crt0.s diff --git a/os/ports/GCC/ARMCMx/STM32F10x/port.mk b/os/ports/GCC/ARMCMx/STM32F10x/port.mk index 739f031f8..02cbe871a 100644 --- a/os/ports/GCC/ARMCMx/STM32F10x/port.mk +++ b/os/ports/GCC/ARMCMx/STM32F10x/port.mk @@ -1,5 +1,6 @@ # List of the ChibiOS/RT Cortex-M3 STM32 port files. PORTSRC = ${CHIBIOS}/os/ports/GCC/ARMCMx/chcore.c \ + ${CHIBIOS}/os/ports/GCC/ARMCMx/chcore_v7m.c \ ${CHIBIOS}/os/ports/GCC/ARMCMx/nvic.c \ ${CHIBIOS}/os/ports/GCC/ARMCMx/cmsis/core_cm3.c diff --git a/os/ports/GCC/ARMCMx/chcore.c b/os/ports/GCC/ARMCMx/chcore.c index 908f0b5a6..24a9d7f7a 100644 --- a/os/ports/GCC/ARMCMx/chcore.c +++ b/os/ports/GCC/ARMCMx/chcore.c @@ -26,17 +26,6 @@ */ #include "ch.h" -#include "nvic.h" - -/** - * @brief PC register temporary storage. - */ -regarm_t _port_saved_pc; - -/** - * @brief IRQ nesting counter. - */ -unsigned _port_irq_nesting; /** * @brief Halts the system. @@ -53,148 +42,4 @@ void port_halt(void) { } } -/** - * @brief System Timer vector. - * @details This interrupt is used as system tick. - * @note The timer must be initialized in the startup code. - */ -CH_IRQ_HANDLER(SysTickVector) { - - CH_IRQ_PROLOGUE(); - - chSysLockFromIsr(); - chSysTimerHandlerI(); - chSysUnlockFromIsr(); - - CH_IRQ_EPILOGUE(); -} - -/** - * @brief Post-IRQ switch code. - * @details On entry the stack and the registers are restored by the exception - * return, the PC value is stored in @p _port_saved_pc, the interrupts - * are disabled. - */ -#if !defined(__DOXYGEN__) -__attribute__((naked)) -#endif -void _port_switch_from_irq(void) { - /* Note, saves r4 to make space for the PC.*/ -#if defined(CH_ARCHITECTURE_ARM_v6M) - asm volatile ("push {r0, r1, r2, r3, r4} \n\t" \ - "mrs r0, APSR \n\t" \ - "mov r1, r12 \n\t" \ - "push {r0, r1, lr} \n\t" \ - "ldr r0, =_port_saved_pc \n\t" \ - "ldr r0, [r0] \n\t" \ - "add r0, r0, #1 \n\t" \ - "str r0, [sp, #28]"); -#elif defined(CH_ARCHITECTURE_ARM_v7M) - asm volatile ("push {r0, r1, r2, r3, r4} \n\t" \ - "mrs r0, APSR \n\t" \ - "push {r0, r12, lr} \n\t" \ - "ldr r0, =_port_saved_pc \n\t" \ - "ldr r0, [r0] \n\t" \ - "add r0, r0, #1 \n\t" \ - "str r0, [sp, #28]"); -#endif - - chSchDoRescheduleI(); - - /* Note, the last registers are restored alone after re-enabling the - interrupts in order to minimize the (very remote and unlikely) - possibility that the stack is filled by continuous and saturating - interrupts that would not allow that last words to be pulled out of - the stack.*/ -#if defined(CH_ARCHITECTURE_ARM_v6M) - asm volatile ("pop {r0, r1, r2} \n\t" \ - "mov r12, r1 \n\t" \ - "msr APSR, r0 \n\t" \ - "mov lr, r2"); -#elif defined(CH_ARCHITECTURE_ARM_v7M) - asm volatile ("pop {r0, r12, lr} \n\t" \ - "msr APSR, r0"); -#endif -#if CORTEX_USE_BASEPRI - asm volatile ("mov r0, #0 \n\t" \ - "msr BASEPRI, r0"); -#else /* !CORTEX_USE_BASEPRI */ - asm volatile ("cpsie i"); -#endif /* !CORTEX_USE_BASEPRI */ - asm volatile ("pop {r0, r1, r2, r3, pc}"); -} - -#if defined(CH_ARCHITECTURE_ARM_v6M) -#define PUSH_CONTEXT(sp) { \ - asm volatile ("push {r4, r5, r6, r7, lr} \n\t" \ - "mov r4, r8 \n\t" \ - "mov r5, r9 \n\t" \ - "mov r6, r10 \n\t" \ - "mov r7, r11 \n\t" \ - "push {r4, r5, r6, r7}"); \ -} - -#define POP_CONTEXT(sp) { \ - asm volatile ("pop {r4, r5, r6, r7} \n\t" \ - "mov r8, r4 \n\t" \ - "mov r9, r5 \n\t" \ - "mov r10, r6 \n\t" \ - "mov r11, r7 \n\t" \ - "pop {r4, r5, r6, r7, pc}" : : "r" (sp)); \ -} -#elif defined(CH_ARCHITECTURE_ARM_v7M) -#define PUSH_CONTEXT(sp) { \ - asm volatile ("push {r4, r5, r6, r7, r8, r9, r10, r11, lr} \n\t"); \ -} - -#define POP_CONTEXT(sp) { \ - asm volatile ("pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} \n\t" \ - : : "r" (sp)); \ -} -#endif - -/** - * @brief Performs a context switch between two threads. - * @details This is the most critical code in any port, this function - * is responsible for the context switch between 2 threads. - * @note The implementation of this code affects directly the context - * switch performance so optimize here as much as you can. - * - * @param[in] ntp the thread to be switched in - * @param[in] otp the thread to be switched out - */ -#if !defined(__DOXYGEN__) -__attribute__((naked)) -#endif -void port_switch(Thread *ntp, Thread *otp) { - register struct intctx *r13 asm ("r13"); - - /* Stack overflow check, if enabled.*/ -#if CH_DBG_ENABLE_STACK_CHECK - if ((void *)(r13 - 1) < (void *)(otp + 1)) - asm volatile ("movs r0, #0 \n\t" - "b chDbgPanic"); -#endif /* CH_DBG_ENABLE_STACK_CHECK */ - - PUSH_CONTEXT(r13); - - otp->p_ctx.r13 = r13; - r13 = ntp->p_ctx.r13; - - POP_CONTEXT(r13); -} - -/** - * @brief Start a thread by invoking its work function. - * @details If the work function returns @p chThdExit() is automatically - * invoked. - */ -void _port_thread_start(void) { - - port_unlock(); - asm volatile ("mov r0, r5 \n\t" \ - "blx r4 \n\t" \ - "bl chThdExit"); -} - /** @} */ diff --git a/os/ports/GCC/ARMCMx/chcore.h b/os/ports/GCC/ARMCMx/chcore.h index e627fcf8f..5d45b00fd 100644 --- a/os/ports/GCC/ARMCMx/chcore.h +++ b/os/ports/GCC/ARMCMx/chcore.h @@ -34,13 +34,6 @@ /* Port constants. */ /*===========================================================================*/ -/** - * @brief Port implementing a process mode context switching. - * @details This macro can be used to differentiate this port from the other - * Cortex-Mx port which defines @p CORTEX_PORT_MODE_ENDOSWITCH. - */ -#define CORTEX_PORT_MODE_EXOSWITCH - #define CORTEX_M0 0 /**< @brief Cortex-M0 variant. */ #define CORTEX_M1 1 /**< @brief Cortex-M1 variant. */ #define CORTEX_M3 3 /**< @brief Cortex-M3 variant. */ @@ -61,16 +54,6 @@ /* Port statically derived parameters. */ /*===========================================================================*/ -/** - * @brief Priority masking support. - */ -#if (CORTEX_MODEL == CORTEX_M3) || (CORTEX_MODEL == CORTEX_M4) || \ - defined(__DOXYGEN__) -#define CORTEX_SUPPORTS_BASEPRI TRUE -#else -#define CORTEX_SUPPORTS_BASEPRI FALSE -#endif - /** * @brief Total priority levels. */ @@ -89,6 +72,11 @@ */ #define CORTEX_MAXIMUM_PRIORITY 0 +/** + * @brief Disabled value for BASEPRI register. + */ +#define CORTEX_BASEPRI_DISABLED 0 + /*===========================================================================*/ /* Port macros. */ /*===========================================================================*/ @@ -117,8 +105,8 @@ /** * @brief SYSTICK handler priority. - * @note The default priority is calculated as the priority level in - * the middle of the numeric priorities range. + * @note The default SYSTICK handler priority is calculated as the priority + * level in the middle of the numeric priorities range. */ #ifndef CORTEX_PRIORITY_SYSTICK #define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1) @@ -130,44 +118,48 @@ #endif /** - * @brief Priority masking support. - * @details The ARMv7-M architecture is capable to mask only interrupt - * priorities below or equal to a certain specified priority - * mask. If this option is enabled all the priorities above - * @p CORTEX_BASEPRI_KERNEL (lower numeric values) are not - * affected by the kernel locks and can operate with minimum - * latency.
- * This option makes the kernel code a bit larger and slower, if - * your application does not need fast interrups it is recommended - * to keep this option disabled. + * @brief SVCALL handler priority. + * @note The default SVCALL handler priority is calculated as + * @p CORTEX_MAXIMUM_PRIORITY+1, in the ARMv7-M port this reserves + * the @p CORTEX_MAXIMUM_PRIORITY priority level as fast interrupts + * priority level. + * @note The SVCALL vector is only used in the ARMv7-M port, it is available + * to user in the ARMv6-M port. */ -#if CORTEX_SUPPORTS_BASEPRI || defined(__DOXYGEN__) -#if !defined(CORTEX_USE_BASEPRI) || defined(__DOXYGEN__) -#define CORTEX_USE_BASEPRI FALSE -#endif /* !defined(CORTEX_USE_BASEPRI) */ -#else /* !CORTEX_SUPPORTS_BASEPRI */ -#if defined(CORTEX_USE_BASEPRI) && CORTEX_USE_BASEPRI -#error "BASEPRI priority masking register not supported in this architecture" +#ifndef CORTEX_PRIORITY_SVCALL +#define CORTEX_PRIORITY_SVCALL (CORTEX_MAXIMUM_PRIORITY + 1) +#else +/* If it is externally redefined then better perform a validity check on it.*/ +#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SVCALL) +#error "invalid priority level specified for CORTEX_PRIORITY_SVCALL" +#endif +#endif + +/** + * @brief PENDSV handler priority. + * @note The default PENDSV handler priority is set at the + * @p CORTEX_MINIMUM_PRIORITY priority level. + * @note In the ARMv7-M port this value should be not changed from the + * minimum priority level. + * @note The PENDSV vector is only used in the ARMv7-M port, it is available + * to user in the ARMv6-M port. + */ +#ifndef CORTEX_PRIORITY_PENDSV +#define CORTEX_PRIORITY_PENDSV CORTEX_MINIMUM_PRIORITY +#else +/* If it is externally redefined then better perform a validity check on it.*/ +#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_PENDSV) +#error "invalid priority level specified for CORTEX_PRIORITY_PENDSV" +#endif #endif -#define CORTEX_USE_BASEPRI FALSE -#endif /* !CORTEX_SUPPORTS_BASEPRI */ -#if CORTEX_USE_BASEPRI || defined(__DOXYGEN__) /** * @brief BASEPRI level within kernel lock. - * @details Priority levels higher than this one (lower numeric values) are - * unaffected by kernel locks and can be classified as fast - * interrupt sources, see @ref interrupt_classes. - * @note This constant is defined only if the @p CORTEX_USE_BASEPRI port - * option is enabled. - * @note The default setting reserves just the highest priority level - * (@p CORTEX_MAXIMUM_PRIORITY) for fast interrupts, you may redefine - * this setting in order to reserve more levels. + * @note This value must not mask the SVCALL priority level. */ #ifndef CORTEX_BASEPRI_KERNEL -#define CORTEX_BASEPRI_KERNEL CORTEX_PRIORITY_MASK(CORTEX_MAXIMUM_PRIORITY+1) +#define CORTEX_BASEPRI_KERNEL CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1) #endif -#endif /* CORTEX_USE_BASEPRI */ /*===========================================================================*/ /* Port exported info. */ @@ -225,294 +217,21 @@ typedef uint32_t stkalign_t; */ typedef void *regarm_t; -/** - * @brief Cortex-Mx exception context. - */ -struct cmxctx { - regarm_t r0; - regarm_t r1; - regarm_t r2; - regarm_t r3; - regarm_t r12; - regarm_t lr_thd; - regarm_t pc; - regarm_t xpsr; -}; - -#if !defined(__DOXYGEN__) -/** - * @brief Interrupt saved context. - * @details This structure represents the stack frame saved during a - * preemption-capable interrupt handler. - */ -struct extctx { - regarm_t xpsr; - regarm_t r12; - regarm_t lr; - regarm_t r0; - regarm_t r1; - regarm_t r2; - regarm_t r3; - regarm_t pc; -}; -#endif - -#if !defined(__DOXYGEN__) -/** - * @brief System saved context. - * @details This structure represents the inner stack frame during a context - * switching. - */ -#if defined(CH_ARCHITECTURE_ARM_v6M) -struct intctx { - regarm_t r8; - regarm_t r9; - regarm_t r10; - regarm_t r11; - regarm_t r4; - regarm_t r5; - regarm_t r6; - regarm_t r7; - regarm_t lr; -}; -#elif defined(CH_ARCHITECTURE_ARM_v7M) -struct intctx { - regarm_t r4; - regarm_t r5; - regarm_t r6; - regarm_t r7; - regarm_t r8; - regarm_t r9; - regarm_t r10; - regarm_t r11; - regarm_t lr; -}; -#endif -#endif - #if !defined(__DOXYGEN__) /** * @brief Platform dependent part of the @p Thread structure. - * @details In the Cortex-Mx port this structure just holds a pointer to the - * @p intctx structure representing the stack pointer at the time - * of the context switch. + * @details In this port the structure just holds a pointer to the @p intctx + * structure representing the stack pointer at context switch time. */ struct context { struct intctx *r13; }; #endif -/** - * @brief Platform dependent part of the @p chThdInit() API. - * @details This code usually setup the context switching frame represented - * by an @p intctx structure. - */ -#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \ - tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \ - wsize - \ - sizeof(struct intctx)); \ - tp->p_ctx.r13->r4 = pf; \ - tp->p_ctx.r13->r5 = arg; \ - tp->p_ctx.r13->lr = _port_thread_start; \ -} - -/** - * @brief Stack size for the system idle thread. - * @details This size depends on the idle thread implementation, usually - * the idle thread should take no more space than those reserved - * by @p INT_REQUIRED_STACK. - * @note In this port it is set to 4 because the idle thread does have - * a stack frame when compiling without optimizations. - */ -#ifndef IDLE_THREAD_STACK_SIZE -#define IDLE_THREAD_STACK_SIZE 4 -#endif - -/** - * @brief Per-thread stack overhead for interrupts servicing. - * @details This constant is used in the calculation of the correct working - * area size. - * This value can be zero on those architecture where there is a - * separate interrupt stack and the stack space between @p intctx and - * @p extctx is known to be zero. - * @note This port requires some extra stack space for interrupt handling - * representing the frame of the function @p chSchDoRescheduleI(). - */ -#ifndef INT_REQUIRED_STACK -#define INT_REQUIRED_STACK 8 -#endif - -/** - * @brief Enforces a correct alignment for a stack area size value. - */ -#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1) - -/** - * @brief Computes the thread working area global size. - */ -#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \ - sizeof(struct intctx) + \ - sizeof(struct extctx) + \ - (n) + (INT_REQUIRED_STACK)) - -/** - * @brief Static working area allocation. - * @details This macro is used to allocate a static thread working area - * aligned as both position and size. - */ -#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]; - -/** - * @brief IRQ prologue code. - * @details This macro must be inserted at the start of all IRQ handlers - * enabled to invoke system APIs. - */ -#define PORT_IRQ_PROLOGUE() { \ - chSysLockFromIsr(); \ - _port_irq_nesting++; \ - chSysUnlockFromIsr(); \ -} - -/** - * @brief IRQ epilogue code. - * @details This macro must be inserted at the end of all IRQ handlers - * enabled to invoke system APIs. - */ -#define PORT_IRQ_EPILOGUE() { \ - chSysLockFromIsr(); \ - if ((--_port_irq_nesting == 0) && chSchIsRescRequiredExI()) { \ - register struct cmxctx *ctxp; \ - \ - asm volatile ("mrs %0, PSP" : "=r" (ctxp) : ); \ - _port_saved_pc = ctxp->pc; \ - ctxp->pc = _port_switch_from_irq; \ - return; \ - } \ - chSysUnlockFromIsr(); \ -} - -/** - * @brief IRQ handler function declaration. - * @note @p id can be a function name or a vector number depending on the - * port implementation. - */ -#define PORT_IRQ_HANDLER(id) void id(void) - -/** - * @brief Port-related initialization code. - */ -#define port_init() { \ - _port_irq_nesting = 0; \ - SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \ - NVICSetSystemHandlerPriority(HANDLER_SYSTICK, \ - CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \ -} - -/** - * @brief Kernel-lock action. - * @details Usually this function just disables interrupts but may perform - * more actions. - */ -#if CORTEX_USE_BASEPRI -#define port_lock() { \ - register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; \ - asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); \ -} -#else /* !CORTEX_USE_BASEPRI */ -#define port_lock() asm volatile ("cpsid i") -#endif /* !CORTEX_USE_BASEPRI */ - -/** - * @brief Kernel-unlock action. - * @details Usually this function just disables interrupts but may perform - * more actions. - */ -#if CORTEX_USE_BASEPRI -#define port_unlock() { \ - register uint32_t tmp asm ("r3") = 0; \ - asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); \ -} -#else /* !CORTEX_USE_BASEPRI */ -#define port_unlock() asm volatile ("cpsie i") -#endif /* !CORTEX_USE_BASEPRI */ - -/** - * @brief Kernel-lock action from an interrupt handler. - * @details This function is invoked before invoking I-class APIs from - * interrupt handlers. The implementation is architecture dependent, - * in its simplest form it is void. - * @note Same as @p port_lock() in this port. - */ -#define port_lock_from_isr() port_lock() - -/** - * @brief Kernel-unlock action from an interrupt handler. - * @details This function is invoked after invoking I-class APIs from interrupt - * handlers. The implementation is architecture dependent, in its - * simplest form it is void. - * @note Same as @p port_lock() in this port. - */ -#define port_unlock_from_isr() port_unlock() - -/** - * @brief Disables all the interrupt sources. - */ -#define port_disable() asm volatile ("cpsid i") - -/** - * @brief Disables the interrupt sources below kernel-level priority. - */ -#if CORTEX_USE_BASEPRI -#define port_suspend() { \ - register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; \ - asm volatile ("msr BASEPRI, %0 \n\t" \ - "cpsie i" : : "r" (tmp)); \ -} -#else /* !CORTEX_USE_BASEPRI */ -#define port_suspend() asm volatile ("cpsid i") -#endif /* !CORTEX_USE_BASEPRI */ - -/** - * @brief Enables all the interrupt sources. - */ -#if CORTEX_USE_BASEPRI -#define port_enable() { \ - register uint32_t tmp asm ("r3") = 0; \ - asm volatile ("msr BASEPRI, %0 \n\t" \ - "cpsie i" : : "r" (tmp)); \ -} -#else /* !CORTEX_USE_BASEPRI */ -#define port_enable() asm volatile ("cpsie i") -#endif /* !CORTEX_USE_BASEPRI */ - -/** - * @brief Enters an architecture-dependent IRQ-waiting mode. - * @details The function is meant to return when an interrupt becomes pending. - * The simplest implementation is an empty function or macro but this - * would not take advantage of architecture-specific power saving - * modes. - * @note Implemented as an inlined @p WFI instruction. - */ -#if CORTEX_ENABLE_WFI_IDLE || defined(__DOXYGEN__) -#define port_wait_for_interrupt() asm volatile ("wfi") -#else -#define port_wait_for_interrupt() -#endif - -#if !defined(__DOXYGEN__) -extern regarm_t _port_saved_pc; -extern unsigned _port_irq_nesting; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void port_halt(void); - void port_switch(Thread *ntp, Thread *otp); - void _port_switch_from_irq(void); - void _port_thread_start(void); -#ifdef __cplusplus -} +#if defined(CH_ARCHITECTURE_ARM_v6M) +#include "chcore_v6m.h" +#elif defined(CH_ARCHITECTURE_ARM_v7M) +#include "chcore_v7m.h" #endif #endif /* _CHCORE_H_ */ diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.c b/os/ports/GCC/ARMCMx/chcore_v6m.c new file mode 100644 index 000000000..8f8a0a100 --- /dev/null +++ b/os/ports/GCC/ARMCMx/chcore_v6m.c @@ -0,0 +1,152 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file ARMCMx/chcore_v6m.c + * @brief ARMv6-M architecture port code. + * + * @addtogroup ARMCMx_V6M_CORE + * @{ + */ + +#include "ch.h" + +/** + * @brief PC register temporary storage. + */ +regarm_t _port_saved_pc; + +/** + * @brief IRQ nesting counter. + */ +unsigned _port_irq_nesting; + +/** + * @brief System Timer vector. + * @details This interrupt is used as system tick. + * @note The timer must be initialized in the startup code. + */ +CH_IRQ_HANDLER(SysTickVector) { + + CH_IRQ_PROLOGUE(); + + chSysLockFromIsr(); + chSysTimerHandlerI(); + chSysUnlockFromIsr(); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief Post-IRQ switch code. + * @details On entry the stack and the registers are restored by the exception + * return, the PC value is stored in @p _port_saved_pc, the interrupts + * are disabled. + */ +#if !defined(__DOXYGEN__) +__attribute__((naked)) +#endif +void _port_switch_from_irq(void) { + /* Note, saves r4 to make space for the PC.*/ + asm volatile ("push {r0, r1, r2, r3, r4} \n\t" \ + "mrs r0, APSR \n\t" \ + "mov r1, r12 \n\t" \ + "push {r0, r1, lr} \n\t" \ + "ldr r0, =_port_saved_pc \n\t" \ + "ldr r0, [r0] \n\t" \ + "add r0, r0, #1 \n\t" \ + "str r0, [sp, #28]"); + + chSchDoRescheduleI(); + + /* Note, the last registers are restored alone after re-enabling the + interrupts in order to minimize the (very remote and unlikely) + possibility that the stack is filled by continuous and saturating + interrupts that would not allow that last words to be pulled out of + the stack.*/ + asm volatile ("pop {r0, r1, r2} \n\t" \ + "mov r12, r1 \n\t" \ + "msr APSR, r0 \n\t" \ + "mov lr, r2 \n\t" \ + "pop {r0, r1, r2, r3, pc}"); +} + +#define PUSH_CONTEXT(sp) { \ + asm volatile ("push {r4, r5, r6, r7, lr} \n\t" \ + "mov r4, r8 \n\t" \ + "mov r5, r9 \n\t" \ + "mov r6, r10 \n\t" \ + "mov r7, r11 \n\t" \ + "push {r4, r5, r6, r7}"); \ +} + +#define POP_CONTEXT(sp) { \ + asm volatile ("pop {r4, r5, r6, r7} \n\t" \ + "mov r8, r4 \n\t" \ + "mov r9, r5 \n\t" \ + "mov r10, r6 \n\t" \ + "mov r11, r7 \n\t" \ + "pop {r4, r5, r6, r7, pc}" : : "r" (sp)); \ +} + +/** + * @brief Performs a context switch between two threads. + * @details This is the most critical code in any port, this function + * is responsible for the context switch between 2 threads. + * @note The implementation of this code affects directly the context + * switch performance so optimize here as much as you can. + * + * @param[in] ntp the thread to be switched in + * @param[in] otp the thread to be switched out + */ +#if !defined(__DOXYGEN__) +__attribute__((naked)) +#endif +void port_switch(Thread *ntp, Thread *otp) { + register struct intctx *r13 asm ("r13"); + + /* Stack overflow check, if enabled.*/ +#if CH_DBG_ENABLE_STACK_CHECK + if ((void *)(r13 - 1) < (void *)(otp + 1)) + asm volatile ("movs r0, #0 \n\t" + "b chDbgPanic"); +#endif /* CH_DBG_ENABLE_STACK_CHECK */ + + PUSH_CONTEXT(r13); + + otp->p_ctx.r13 = r13; + r13 = ntp->p_ctx.r13; + + POP_CONTEXT(r13); +} + +/** + * @brief Start a thread by invoking its work function. + * @details If the work function returns @p chThdExit() is automatically + * invoked. + */ +void _port_thread_start(void) { + + port_unlock(); + asm volatile ("mov r0, r5 \n\t" \ + "blx r4 \n\t" \ + "bl chThdExit"); +} + +/** @} */ diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h new file mode 100644 index 000000000..7aff774bc --- /dev/null +++ b/os/ports/GCC/ARMCMx/chcore_v6m.h @@ -0,0 +1,271 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file ARMCMx/chcore_v6m.h + * @brief ARMv6-M architecture port macros and structures. + * + * @addtogroup ARMCMx_V6M_CORE + * @{ + */ + +#ifndef _CHCORE_V6M_H_ +#define _CHCORE_V6M_H_ + +/*===========================================================================*/ +/* Port implementation part. */ +/*===========================================================================*/ + +/** + * @brief Cortex-Mx exception context. + */ +struct cmxctx { + regarm_t r0; + regarm_t r1; + regarm_t r2; + regarm_t r3; + regarm_t r12; + regarm_t lr_thd; + regarm_t pc; + regarm_t xpsr; +}; + +#if !defined(__DOXYGEN__) +/** + * @brief Interrupt saved context. + * @details This structure represents the stack frame saved during a + * preemption-capable interrupt handler. + */ +struct extctx { + regarm_t xpsr; + regarm_t r12; + regarm_t lr; + regarm_t r0; + regarm_t r1; + regarm_t r2; + regarm_t r3; + regarm_t pc; +}; +#endif + +#if !defined(__DOXYGEN__) +/** + * @brief System saved context. + * @details This structure represents the inner stack frame during a context + * switching. + */ +struct intctx { + regarm_t r8; + regarm_t r9; + regarm_t r10; + regarm_t r11; + regarm_t r4; + regarm_t r5; + regarm_t r6; + regarm_t r7; + regarm_t lr; +}; +#endif + +/** + * @brief Platform dependent part of the @p chThdInit() API. + * @details This code usually setup the context switching frame represented + * by an @p intctx structure. + */ +#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \ + tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \ + wsize - \ + sizeof(struct intctx)); \ + tp->p_ctx.r13->r4 = pf; \ + tp->p_ctx.r13->r5 = arg; \ + tp->p_ctx.r13->lr = _port_thread_start; \ +} + +/** + * @brief Stack size for the system idle thread. + * @details This size depends on the idle thread implementation, usually + * the idle thread should take no more space than those reserved + * by @p INT_REQUIRED_STACK. + * @note In this port it is set to 4 because the idle thread does have + * a stack frame when compiling without optimizations. + */ +#ifndef IDLE_THREAD_STACK_SIZE +#define IDLE_THREAD_STACK_SIZE 4 +#endif + +/** + * @brief Per-thread stack overhead for interrupts servicing. + * @details This constant is used in the calculation of the correct working + * area size. + * This value can be zero on those architecture where there is a + * separate interrupt stack and the stack space between @p intctx and + * @p extctx is known to be zero. + * @note This port requires some extra stack space for interrupt handling + * representing the frame of the function @p chSchDoRescheduleI(). + */ +#ifndef INT_REQUIRED_STACK +#define INT_REQUIRED_STACK 8 +#endif + +/** + * @brief Enforces a correct alignment for a stack area size value. + */ +#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1) + +/** + * @brief Computes the thread working area global size. + */ +#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \ + sizeof(struct intctx) + \ + sizeof(struct extctx) + \ + (n) + (INT_REQUIRED_STACK)) + +/** + * @brief Static working area allocation. + * @details This macro is used to allocate a static thread working area + * aligned as both position and size. + */ +#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]; + +/** + * @brief IRQ prologue code. + * @details This macro must be inserted at the start of all IRQ handlers + * enabled to invoke system APIs. + */ +#define PORT_IRQ_PROLOGUE() { \ + chSysLockFromIsr(); \ + _port_irq_nesting++; \ + chSysUnlockFromIsr(); \ +} + +/** + * @brief IRQ epilogue code. + * @details This macro must be inserted at the end of all IRQ handlers + * enabled to invoke system APIs. + */ +#define PORT_IRQ_EPILOGUE() { \ + chSysLockFromIsr(); \ + if ((--_port_irq_nesting == 0) && chSchIsRescRequiredExI()) { \ + register struct cmxctx *ctxp; \ + \ + asm volatile ("mrs %0, PSP" : "=r" (ctxp) : ); \ + _port_saved_pc = ctxp->pc; \ + ctxp->pc = _port_switch_from_irq; \ + return; \ + } \ + chSysUnlockFromIsr(); \ +} + +/** + * @brief IRQ handler function declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + */ +#define PORT_IRQ_HANDLER(id) void id(void) + +/** + * @brief Port-related initialization code. + */ +#define port_init() { \ + _port_irq_nesting = 0; \ + SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \ + NVICSetSystemHandlerPriority(HANDLER_SYSTICK, \ + CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \ +} + +/** + * @brief Kernel-lock action. + * @details Usually this function just disables interrupts but may perform + * more actions. + */ +#define port_lock() asm volatile ("cpsid i") + +/** + * @brief Kernel-unlock action. + * @details Usually this function just disables interrupts but may perform + * more actions. + */ +#define port_unlock() asm volatile ("cpsie i") + +/** + * @brief Kernel-lock action from an interrupt handler. + * @details This function is invoked before invoking I-class APIs from + * interrupt handlers. The implementation is architecture dependent, + * in its simplest form it is void. + * @note Same as @p port_lock() in this port. + */ +#define port_lock_from_isr() port_lock() + +/** + * @brief Kernel-unlock action from an interrupt handler. + * @details This function is invoked after invoking I-class APIs from interrupt + * handlers. The implementation is architecture dependent, in its + * simplest form it is void. + * @note Same as @p port_lock() in this port. + */ +#define port_unlock_from_isr() port_unlock() + +/** + * @brief Disables all the interrupt sources. + */ +#define port_disable() asm volatile ("cpsid i") + +/** + * @brief Disables the interrupt sources below kernel-level priority. + */ +#define port_suspend() asm volatile ("cpsid i") + +/** + * @brief Enables all the interrupt sources. + */ +#define port_enable() asm volatile ("cpsie i") + +/** + * @brief Enters an architecture-dependent IRQ-waiting mode. + * @details The function is meant to return when an interrupt becomes pending. + * The simplest implementation is an empty function or macro but this + * would not take advantage of architecture-specific power saving + * modes. + * @note Implemented as an inlined @p WFI instruction. + */ +#if CORTEX_ENABLE_WFI_IDLE || defined(__DOXYGEN__) +#define port_wait_for_interrupt() asm volatile ("wfi") +#else +#define port_wait_for_interrupt() +#endif + +#if !defined(__DOXYGEN__) +extern regarm_t _port_saved_pc; +extern unsigned _port_irq_nesting; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void port_halt(void); + void port_switch(Thread *ntp, Thread *otp); + void _port_switch_from_irq(void); + void _port_thread_start(void); +#ifdef __cplusplus +} +#endif + +#endif /* _CHCORE_V6M_H_ */ + +/** @} */ diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.c b/os/ports/GCC/ARMCMx/chcore_v7m.c new file mode 100644 index 000000000..e5df0d296 --- /dev/null +++ b/os/ports/GCC/ARMCMx/chcore_v7m.c @@ -0,0 +1,178 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file ARMCMx/chcore_v7m.c + * @brief ARMv7-M architecture port code. + * + * @addtogroup ARMCMx_V7M_CORE + * @{ + */ + +#include "ch.h" + +#if !CH_OPTIMIZE_SPEED +void _port_lock(void) { + register uint32_t tmp asm ("r3") = BASEPRI_KERNEL; + asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); +} + +void _port_unlock(void) { + register uint32_t tmp asm ("r3") = BASEPRI_USER; + asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); +} +#endif + +/** + * @brief System Timer vector. + * @details This interrupt is used as system tick. + * @note The timer must be initialized in the startup code. + */ +void SysTickVector(void) { + + chSysLockFromIsr(); + chSysTimerHandlerI(); + if (chSchIsRescRequiredExI()) + SCB_ICSR = ICSR_PENDSVSET; + chSysUnlockFromIsr(); +} + +#if CORTEX_MODEL == CORTEX_M0 +#define PUSH_CONTEXT(sp, prio) { \ + asm volatile ("mrs %0, PSP \n\t" \ + "sub %0, %0, #40 \n\t" \ + "stmia %0!, {r3-r7} \n\t" \ + "sub %0, %0, #20 \n\t" \ + "mov r3, r8 \n\t" \ + "str r3, [%0, #20] \n\t" \ + "mov r3, r9 \n\t" \ + "str r3, [%0, #24] \n\t" \ + "mov r3, r10 \n\t" \ + "str r3, [%0, #28] \n\t" \ + "mov r3, r11 \n\t" \ + "str r3, [%0, #32] \n\t" \ + "mov r3, lr \n\t" \ + "str r3, [%0, #36] \n\t" \ + : "=r" (sp) : "r" (sp), "r" (prio)); \ +} + +#define POP_CONTEXT(sp) { \ + asm volatile ("ldr r3, [%0, #20] \n\t" \ + "mov r8, r3 \n\t" \ + "ldr r3, [%0, #24] \n\t" \ + "mov r9, r3 \n\t" \ + "ldr r3, [%0, #28] \n\t" \ + "mov r10, r3 \n\t" \ + "ldr r3, [%0, #32] \n\t" \ + "mov r11, r3 \n\t" \ + "ldr r3, [%0, #36] \n\t" \ + "mov lr, r3 \n\t" \ + "ldmia %0!, {r3-r7} \n\t" \ + "add %0, %0, #20 \n\t" \ + "msr PSP, %0 \n\t" \ + "msr BASEPRI, r3 \n\t" \ + "bx lr" : "=r" (sp) : "r" (sp)); \ +} +#else /* CORTEX_MODEL != CORTEX_M0 */ +#if !defined(CH_CURRP_REGISTER_CACHE) +#define PUSH_CONTEXT(sp, prio) { \ + asm volatile ("mrs %0, PSP \n\t" \ + "stmdb %0!, {r3-r11,lr}" : \ + "=r" (sp) : "r" (sp), "r" (prio)); \ +} + +#define POP_CONTEXT(sp) { \ + asm volatile ("ldmia %0!, {r3-r11, lr} \n\t" \ + "msr PSP, %0 \n\t" \ + "msr BASEPRI, r3 \n\t" \ + "bx lr" : "=r" (sp) : "r" (sp)); \ +} +#else /* defined(CH_CURRP_REGISTER_CACHE) */ +#define PUSH_CONTEXT(sp, prio) { \ + asm volatile ("mrs %0, PSP \n\t" \ + "stmdb %0!, {r3-r6,r8-r11, lr}" : \ + "=r" (sp) : "r" (sp), "r" (prio)); \ +} + +#define POP_CONTEXT(sp) { \ + asm volatile ("ldmia %0!, {r3-r6,r8-r11, lr} \n\t" \ + "msr PSP, %0 \n\t" \ + "msr BASEPRI, r3 \n\t" \ + "bx lr" : "=r" (sp) : "r" (sp)); \ +} +#endif /* defined(CH_CURRP_REGISTER_CACHE) */ +#endif /* CORTEX_MODEL != CORTEX_M0 */ + +/** + * @brief SVC vector. + * @details The SVC vector is used for commanded context switch. Structures + * @p intctx are saved and restored from the process stacks of the + * switched threads. + * + * @param[in] ntp the thread to be switched it + * @param[in] otp the thread to be switched out + */ +#if !defined(__DOXYGEN__) +__attribute__((naked)) +#endif +void SVCallVector(Thread *ntp, Thread *otp) { + register struct intctx *sp_thd asm("r2"); + register uint32_t prio asm ("r3"); + + asm volatile ("mrs r3, BASEPRI" : "=r" (prio) : ); + PUSH_CONTEXT(sp_thd, prio) + + otp->p_ctx.r13 = sp_thd; + sp_thd = ntp->p_ctx.r13; + + POP_CONTEXT(sp_thd) +} + +/** + * @brief Preemption code. + */ +#if !defined(__DOXYGEN__) +__attribute__((naked)) +#endif +void PendSVVector(void) { + register struct intctx *sp_thd asm("r2"); + register uint32_t prio asm ("r3"); + Thread *otp, *ntp; + + chSysLockFromIsr(); + + prio = CORTEX_BASEPRI_DISABLED; + PUSH_CONTEXT(sp_thd, prio) + + (otp = currp)->p_ctx.r13 = sp_thd; + ntp = fifo_remove(&rlist.r_queue); + setcurrp(ntp); + ntp->p_state = THD_STATE_CURRENT; + chSchReadyI(otp); +#if CH_TIME_QUANTUM > 0 + /* Set the round-robin time quantum.*/ + rlist.r_preempt = CH_TIME_QUANTUM; +#endif + chDbgTrace(otp); + sp_thd = ntp->p_ctx.r13; + + POP_CONTEXT(sp_thd) +} + +/** @} */ diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.h b/os/ports/GCC/ARMCMx/chcore_v7m.h new file mode 100644 index 000000000..804f6357e --- /dev/null +++ b/os/ports/GCC/ARMCMx/chcore_v7m.h @@ -0,0 +1,313 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file ARMCMx/chcore_v7m.h + * @brief ARMv7-M architecture port macros and structures. + * + * @addtogroup ARMCMx_V7M_CORE + * @{ + */ + +#ifndef _CHCORE_V7M_H_ +#define _CHCORE_V7M_H_ + +/*===========================================================================*/ +/* Port implementation part. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +/** + * @brief Interrupt saved context. + * @details This structure represents the stack frame saved during a + * preemption-capable interrupt handler. + * @note This structure is empty in this port. + */ +struct extctx { +}; +#endif + +#if !defined(__DOXYGEN__) +/** + * @brief System saved context. + * @details This structure represents the inner stack frame during a context + * switching. + */ +struct intctx { + regarm_t basepri; + regarm_t r4; + regarm_t r5; + regarm_t r6; +#ifndef CH_CURRP_REGISTER_CACHE + regarm_t r7; +#endif + regarm_t r8; + regarm_t r9; + regarm_t r10; + regarm_t r11; + regarm_t lr_exc; + /* Start of the hardware saved frame.*/ + regarm_t r0; + regarm_t r1; + regarm_t r2; + regarm_t r3; + regarm_t r12; + regarm_t lr_thd; + regarm_t pc; + regarm_t xpsr; +}; +#endif + +/** + * @brief Platform dependent part of the @p chThdInit() API. + * @details This code usually setup the context switching frame represented + * by an @p intctx structure. + */ +#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \ + tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \ + wsize - \ + sizeof(struct intctx)); \ + tp->p_ctx.r13->basepri = CORTEX_BASEPRI_DISABLED; \ + tp->p_ctx.r13->lr_exc = (regarm_t)0xFFFFFFFD; \ + tp->p_ctx.r13->r0 = arg; \ + tp->p_ctx.r13->lr_thd = chThdExit; \ + tp->p_ctx.r13->pc = pf; \ + tp->p_ctx.r13->xpsr = (regarm_t)0x01000000; \ +} + +/** + * @brief Stack size for the system idle thread. + * @details This size depends on the idle thread implementation, usually + * the idle thread should take no more space than those reserved + * by @p INT_REQUIRED_STACK. + * @note In this port it is set to 4 because the idle thread does have + * a stack frame when compiling without optimizations. + */ +#ifndef IDLE_THREAD_STACK_SIZE +#define IDLE_THREAD_STACK_SIZE 4 +#endif + +/** + * @brief Per-thread stack overhead for interrupts servicing. + * @details This constant is used in the calculation of the correct working + * area size. + * This value can be zero on those architecture where there is a + * separate interrupt stack and the stack space between @p intctx and + * @p extctx is known to be zero. + * @note This port requires no extra stack space for interrupt handling. + */ +#ifndef INT_REQUIRED_STACK +#define INT_REQUIRED_STACK 0 +#endif + +/** + * @brief Enforces a correct alignment for a stack area size value. + */ +#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1) + +/** + * @brief Computes the thread working area global size. + */ +#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \ + sizeof(struct intctx) + \ + sizeof(struct extctx) + \ + (n) + (INT_REQUIRED_STACK)) + +/** + * @brief Static working area allocation. + * @details This macro is used to allocate a static thread working area + * aligned as both position and size. + */ +#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]; + +/** + * @brief IRQ prologue code. + * @details This macro must be inserted at the start of all IRQ handlers + * enabled to invoke system APIs. + */ +#define PORT_IRQ_PROLOGUE() + +/** + * @brief IRQ epilogue code. + * @details This macro must be inserted at the end of all IRQ handlers + * enabled to invoke system APIs. + */ +#define PORT_IRQ_EPILOGUE() { \ + chSysLockFromIsr(); \ + if (chSchIsRescRequiredI()) \ + SCB_ICSR = ICSR_PENDSVSET; \ + chSysUnlockFromIsr(); \ +} + +/** + * @brief IRQ handler function declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + */ +#define PORT_IRQ_HANDLER(id) void id(void) + +/** + * @brief Port-related initialization code. + */ +#define port_init() { \ + SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \ + NVICSetSystemHandlerPriority(HANDLER_SVCALL, \ + CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL)); \ + NVICSetSystemHandlerPriority(HANDLER_PENDSV, \ + CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); \ + NVICSetSystemHandlerPriority(HANDLER_SYSTICK, \ + CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \ +} + +/** + * @brief Kernel-lock action. + * @details Usually this function just disables interrupts but may perform + * more actions. + * @note In this port this it raises the base priority to kernel level. + */ +#if CH_OPTIMIZE_SPEED +#define port_lock() { \ + register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; \ + asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); \ +} +#else +#define port_lock() { \ + asm volatile ("bl _port_lock" : : : "r3", "lr"); \ +} +#endif + +/** + * @brief Kernel-unlock action. + * @details Usually this function just disables interrupts but may perform + * more actions. + * @note In this port this it lowers the base priority to kernel level. + */ +#if CH_OPTIMIZE_SPEED +#define port_unlock() { \ + register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_DISABLED; \ + asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); \ +} +#else +#define port_unlock() { \ + asm volatile ("bl _port_unlock" : : : "r3", "lr"); \ +} +#endif + +/** + * @brief Kernel-lock action from an interrupt handler. + * @details This function is invoked before invoking I-class APIs from + * interrupt handlers. The implementation is architecture dependent, + * in its simplest form it is void. + * @note Same as @p port_lock() in this port. + */ +#define port_lock_from_isr() port_lock() + +/** + * @brief Kernel-unlock action from an interrupt handler. + * @details This function is invoked after invoking I-class APIs from interrupt + * handlers. The implementation is architecture dependent, in its + * simplest form it is void. + * @note Same as @p port_unlock() in this port. + */ +#define port_unlock_from_isr() port_unlock() + +/** + * @brief Disables all the interrupt sources. + * @note Of course non maskable interrupt sources are not included. + * @note In this port it disables all the interrupt sources by raising + * the priority mask to level 0. + */ +#define port_disable() asm volatile ("cpsid i") + +/** + * @brief Disables the interrupt sources below kernel-level priority. + * @note Interrupt sources above kernel level remains enabled. + * @note In this port it raises/lowers the base priority to kernel level. + */ +#define port_suspend() { \ + register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; \ + asm volatile ("msr BASEPRI, %0 \n\t" \ + "cpsie i" : : "r" (tmp)); \ +} + +/** + * @brief Enables all the interrupt sources. + * @note In this port it lowers the base priority to user level. + */ +#define port_enable() { \ + register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_DISABLED; \ + asm volatile ("msr BASEPRI, %0 \n\t" \ + "cpsie i" : : "r" (tmp)); \ +} + +/** + * @brief Enters an architecture-dependent IRQ-waiting mode. + * @details The function is meant to return when an interrupt becomes pending. + * The simplest implementation is an empty function or macro but this + * would not take advantage of architecture-specific power saving + * modes. + * @note Implemented as an inlined @p WFI instruction. + */ +#if CORTEX_ENABLE_WFI_IDLE || defined(__DOXYGEN__) +#define port_wait_for_interrupt() { \ + asm volatile ("wfi"); \ +} +#else +#define port_wait_for_interrupt() +#endif + +/** + * @brief Performs a context switch between two threads. + * @details This is the most critical code in any port, this function + * is responsible for the context switch between 2 threads. + * @note The implementation of this code affects directly the context + * switch performance so optimize here as much as you can. + * @note Implemented as inlined code for performance reasons. + * + * @param[in] ntp the thread to be switched in + * @param[in] otp the thread to be switched out + */ +static INLINE Thread *port_switch(Thread *ntp, Thread *otp) { + register Thread *_ntp asm ("r0") = (ntp); + register Thread *_otp asm ("r1") = (otp); +#if CH_DBG_ENABLE_STACK_CHECK + register char *sp asm ("sp"); + if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) + asm volatile ("movs r0, #0 \n\t" + "b chDbgPanic"); +#endif /* CH_DBG_ENABLE_STACK_CHECK */ + asm volatile ("svc #0" : : "r" (_otp), "r" (_ntp) : "memory"); + return _otp; +} + +#ifdef __cplusplus +extern "C" { +#endif + void port_halt(void); +#if !CH_OPTIMIZE_SPEED + void _port_lock(void); + void _port_unlock(void); +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _CHCORE_V7M_H_ */ + +/** @} */ -- cgit v1.2.3