git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1825 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
3bc41906b3
commit
c047b21980
|
@ -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
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__;
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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.<br>
|
||||
* For performance and code size reasons the recommended setting
|
||||
* is to leave this option disabled.<br>
|
||||
* 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 <b>must</b> be recompiled with the GCC option @p
|
||||
* -ffixed-@<reg@>.
|
||||
* @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_ */
|
||||
|
||||
/** @} */
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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_ */
|
||||
|
||||
/** @} */
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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()
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 <b>directly</b> 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");
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -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.<br>
|
||||
* 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_ */
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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 <b>directly</b> 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");
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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_ */
|
||||
|
||||
/** @} */
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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)
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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 <b>directly</b> 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_ */
|
||||
|
||||
/** @} */
|
Loading…
Reference in New Issue