From 641f2c372605cf405f0dda8536b45a78e0e5e2e2 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 16 Feb 2016 09:59:21 +0000 Subject: [PATCH] Tree reorganization. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8899 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/common/ext/readme.txt | 7 +- os/common/oslib/include/chbsem.h | 311 ++++++++++ os/common/oslib/include/chdynamic.h | 94 +++ os/common/oslib/include/chheap.h | 164 +++++ os/common/oslib/include/chmboxes.h | 207 +++++++ os/common/oslib/include/chmemcore.h | 130 ++++ os/common/oslib/include/chmempools.h | 168 ++++++ os/common/oslib/readme.txt | 3 + os/common/oslib/src/chdynamic.c | 150 +++++ os/common/oslib/src/chheap.c | 383 ++++++++++++ os/common/oslib/src/chmboxes.c | 435 ++++++++++++++ os/common/oslib/src/chmemcore.c | 166 ++++++ os/common/oslib/src/chmempools.c | 203 +++++++ .../nilcore.c => common/ports/ARM/chcore.c} | 8 +- os/common/ports/ARM/chcore.h | 564 ++++++++++++++++++ .../ports/ARM/chcore_timer.h} | 30 +- os/common/ports/ARM/compilers/GCC/chcoreasm.s | 303 ++++++++++ .../ports/ARM/compilers/GCC/chtypes.h} | 50 +- .../ARM/compilers/GCC/mk/port_generic.mk | 7 + .../ports/ARMCMx/chcore.c} | 4 +- .../ports/ARMCMx/chcore.h} | 35 +- .../ports/ARMCMx/chcore_timer.h} | 8 +- .../ports/ARMCMx/chcore_v6m.c} | 6 +- .../ports/ARMCMx/chcore_v6m.h} | 70 ++- .../ports/ARMCMx/chcore_v7m.c} | 13 +- .../ports/ARMCMx/chcore_v7m.h} | 194 ++++-- os/common/ports/ARMCMx/cmsis_os/cmsis_os.c | 554 +++++++++++++++++ os/common/ports/ARMCMx/cmsis_os/cmsis_os.h | 520 ++++++++++++++++ os/common/ports/ARMCMx/cmsis_os/cmsis_os.mk | 4 + .../ARMCMx/compilers/GCC/chcoreasm_v6m.s} | 46 +- .../ARMCMx/compilers/GCC/chcoreasm_v7m.s} | 54 +- .../ports/ARMCMx/compilers/GCC/chtypes.h} | 51 +- .../ports/ARMCMx/compilers/GCC/mk/port_v6m.mk | 8 + .../ports/ARMCMx/compilers/GCC/mk/port_v7m.mk | 8 + .../ARMCMx/compilers/IAR/chcoreasm_v6m.s | 142 +++++ .../ARMCMx/compilers/IAR/chcoreasm_v7m.s | 150 +++++ .../ports/ARMCMx/compilers/IAR/chtypes.h | 98 +++ .../ARMCMx/compilers/RVCT/chcoreasm_v6m.s | 139 +++++ .../ARMCMx/compilers/RVCT/chcoreasm_v7m.s | 148 +++++ .../ports/ARMCMx/compilers/RVCT/chtypes.h | 98 +++ os/common/ports/ARMCMx/mpu.h | 208 +++++++ .../nilcore.c => common/ports/AVR/chcore.c} | 33 +- .../nilcore.h => common/ports/AVR/chcore.h} | 270 ++++++--- .../ports/AVR/chcore_timer.h} | 8 +- .../ports/AVR/compilers/GCC/chtypes.h} | 53 +- os/common/ports/AVR/compilers/GCC/mk/port.mk | 7 + os/common/ports/SIMIA32/chcore.c | 120 ++++ os/common/ports/SIMIA32/chcore.h | 382 ++++++++++++ .../ports/SIMIA32/compilers/GCC/chtypes.h | 110 ++++ os/common/ports/SIMIA32/compilers/GCC/port.mk | 7 + os/common/ports/e200/chcore.c | 54 ++ .../nilcore.h => common/ports/e200/chcore.h} | 150 +++-- os/common/ports/e200/compilers/CW/chcoreasm.s | 124 ++++ os/common/ports/e200/compilers/CW/chtypes.h | 93 +++ os/common/ports/e200/compilers/CW/ivor.s | 204 +++++++ .../ports/e200/compilers/GCC/chcoreasm.s | 114 ++++ .../ports/e200/compilers/GCC/chtypes.h} | 51 +- .../ports/e200/compilers/GCC/ivor.s | 34 +- os/common/ports/e200/compilers/GCC/mk/port.mk | 8 + os/common/ports/readme.txt | 3 + .../ports/templates/chcore.c} | 68 +-- .../ports/templates/chcore.h} | 191 ++++-- os/common/ports/templates/chtypes.h | 107 ++++ .../ARM/compilers/GCC/mk/startup_lpc214x.mk | 10 +- os/common/startup/ARM/compilers/GCC/rules.ld | 1 + .../ARMCMx/compilers/GCC/mk/startup_k20x.mk | 16 +- .../ARMCMx/compilers/GCC/mk/startup_kl2x.mk | 16 +- .../compilers/GCC/mk/startup_stm32f0xx.mk | 16 +- .../compilers/GCC/mk/startup_stm32f1xx.mk | 16 +- .../compilers/GCC/mk/startup_stm32f2xx.mk | 16 +- .../compilers/GCC/mk/startup_stm32f3xx.mk | 16 +- .../compilers/GCC/mk/startup_stm32f4xx.mk | 16 +- .../compilers/GCC/mk/startup_stm32f7xx.mk | 16 +- .../compilers/GCC/mk/startup_stm32l0xx.mk | 16 +- .../compilers/GCC/mk/startup_stm32l1xx.mk | 16 +- .../compilers/GCC/mk/startup_stm32l4xx.mk | 16 +- .../compilers/GCC/mk/startup_spc560bcxx.mk | 12 +- .../compilers/GCC/mk/startup_spc560bxx.mk | 12 +- .../compilers/GCC/mk/startup_spc560dxx.mk | 12 +- .../compilers/GCC/mk/startup_spc560pxx.mk | 12 +- .../compilers/GCC/mk/startup_spc563mxx.mk | 12 +- .../compilers/GCC/mk/startup_spc564axx.mk | 12 +- .../compilers/GCC/mk/startup_spc56ecxx.mk | 12 +- .../compilers/GCC/mk/startup_spc56elxx.mk | 12 +- os/nil/include/{nil.h => ch.h} | 0 .../ports/ARMCMx/compilers/GCC/mk/port_v6m.mk | 8 - .../ports/ARMCMx/compilers/GCC/mk/port_v7m.mk | 8 - os/nil/ports/AVR/compilers/GCC/mk/port.mk | 7 - .../e200/compilers/GCC/mk/port_spc560bcxx.mk | 14 - .../e200/compilers/GCC/mk/port_spc560bxx.mk | 14 - .../e200/compilers/GCC/mk/port_spc560dxx.mk | 14 - .../e200/compilers/GCC/mk/port_spc560pxx.mk | 14 - .../e200/compilers/GCC/mk/port_spc563mxx.mk | 14 - .../e200/compilers/GCC/mk/port_spc564axx.mk | 14 - .../e200/compilers/GCC/mk/port_spc56ecxx.mk | 14 - .../e200/compilers/GCC/mk/port_spc56elxx.mk | 14 - .../e200/compilers/GCC/mk/port_spc57emxx.mk | 14 - os/nil/src/{nil.c => ch.c} | 0 os/nil/templates/{nilconf.h => chconf.h} | 139 ++++- 99 files changed, 7937 insertions(+), 766 deletions(-) create mode 100644 os/common/oslib/include/chbsem.h create mode 100644 os/common/oslib/include/chdynamic.h create mode 100644 os/common/oslib/include/chheap.h create mode 100644 os/common/oslib/include/chmboxes.h create mode 100644 os/common/oslib/include/chmemcore.h create mode 100644 os/common/oslib/include/chmempools.h create mode 100644 os/common/oslib/readme.txt create mode 100644 os/common/oslib/src/chdynamic.c create mode 100644 os/common/oslib/src/chheap.c create mode 100644 os/common/oslib/src/chmboxes.c create mode 100644 os/common/oslib/src/chmemcore.c create mode 100644 os/common/oslib/src/chmempools.c rename os/{nil/templates/nilcore.c => common/ports/ARM/chcore.c} (93%) create mode 100644 os/common/ports/ARM/chcore.h rename os/{nil/templates/nilcore_timer.h => common/ports/ARM/chcore_timer.h} (81%) create mode 100644 os/common/ports/ARM/compilers/GCC/chcoreasm.s rename os/{nil/templates/niltypes.h => common/ports/ARM/compilers/GCC/chtypes.h} (52%) create mode 100644 os/common/ports/ARM/compilers/GCC/mk/port_generic.mk rename os/{nil/ports/ARMCMx/nilcore.c => common/ports/ARMCMx/chcore.c} (95%) rename os/{nil/ports/ARMCMx/nilcore.h => common/ports/ARMCMx/chcore.h} (87%) rename os/{nil/ports/ARMCMx/nilcore_timer.h => common/ports/ARMCMx/chcore_timer.h} (93%) rename os/{nil/ports/ARMCMx/nilcore_v6m.c => common/ports/ARMCMx/chcore_v6m.c} (95%) rename os/{nil/ports/ARMCMx/nilcore_v6m.h => common/ports/ARMCMx/chcore_v6m.h} (82%) rename os/{nil/ports/ARMCMx/nilcore_v7m.c => common/ports/ARMCMx/chcore_v7m.c} (94%) rename os/{nil/ports/ARMCMx/nilcore_v7m.h => common/ports/ARMCMx/chcore_v7m.h} (70%) create mode 100644 os/common/ports/ARMCMx/cmsis_os/cmsis_os.c create mode 100644 os/common/ports/ARMCMx/cmsis_os/cmsis_os.h create mode 100644 os/common/ports/ARMCMx/cmsis_os/cmsis_os.mk rename os/{nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v6m.s => common/ports/ARMCMx/compilers/GCC/chcoreasm_v6m.s} (77%) rename os/{nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v7m.s => common/ports/ARMCMx/compilers/GCC/chcoreasm_v7m.s} (75%) rename os/{nil/ports/ARMCMx/compilers/GCC/niltypes.h => common/ports/ARMCMx/compilers/GCC/chtypes.h} (52%) create mode 100644 os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk create mode 100644 os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk create mode 100644 os/common/ports/ARMCMx/compilers/IAR/chcoreasm_v6m.s create mode 100644 os/common/ports/ARMCMx/compilers/IAR/chcoreasm_v7m.s create mode 100644 os/common/ports/ARMCMx/compilers/IAR/chtypes.h create mode 100644 os/common/ports/ARMCMx/compilers/RVCT/chcoreasm_v6m.s create mode 100644 os/common/ports/ARMCMx/compilers/RVCT/chcoreasm_v7m.s create mode 100644 os/common/ports/ARMCMx/compilers/RVCT/chtypes.h create mode 100644 os/common/ports/ARMCMx/mpu.h rename os/{nil/ports/AVR/nilcore.c => common/ports/AVR/chcore.c} (83%) rename os/{nil/ports/AVR/nilcore.h => common/ports/AVR/chcore.h} (55%) rename os/{nil/ports/AVR/nilcore_timer.h => common/ports/AVR/chcore_timer.h} (93%) rename os/{nil/ports/AVR/compilers/GCC/niltypes.h => common/ports/AVR/compilers/GCC/chtypes.h} (50%) create mode 100644 os/common/ports/AVR/compilers/GCC/mk/port.mk create mode 100644 os/common/ports/SIMIA32/chcore.c create mode 100644 os/common/ports/SIMIA32/chcore.h create mode 100644 os/common/ports/SIMIA32/compilers/GCC/chtypes.h create mode 100644 os/common/ports/SIMIA32/compilers/GCC/port.mk create mode 100644 os/common/ports/e200/chcore.c rename os/{nil/ports/e200/nilcore.h => common/ports/e200/chcore.h} (75%) create mode 100644 os/common/ports/e200/compilers/CW/chcoreasm.s create mode 100644 os/common/ports/e200/compilers/CW/chtypes.h create mode 100644 os/common/ports/e200/compilers/CW/ivor.s create mode 100644 os/common/ports/e200/compilers/GCC/chcoreasm.s rename os/{nil/ports/e200/compilers/GCC/niltypes.h => common/ports/e200/compilers/GCC/chtypes.h} (53%) rename os/{nil => common}/ports/e200/compilers/GCC/ivor.s (88%) create mode 100644 os/common/ports/e200/compilers/GCC/mk/port.mk create mode 100644 os/common/ports/readme.txt rename os/{nil/ports/e200/nilcore.c => common/ports/templates/chcore.c} (58%) rename os/{nil/templates/nilcore.h => common/ports/templates/chcore.h} (62%) create mode 100644 os/common/ports/templates/chtypes.h rename os/nil/include/{nil.h => ch.h} (100%) delete mode 100644 os/nil/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk delete mode 100644 os/nil/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk delete mode 100644 os/nil/ports/AVR/compilers/GCC/mk/port.mk delete mode 100644 os/nil/ports/e200/compilers/GCC/mk/port_spc560bcxx.mk delete mode 100644 os/nil/ports/e200/compilers/GCC/mk/port_spc560bxx.mk delete mode 100644 os/nil/ports/e200/compilers/GCC/mk/port_spc560dxx.mk delete mode 100644 os/nil/ports/e200/compilers/GCC/mk/port_spc560pxx.mk delete mode 100644 os/nil/ports/e200/compilers/GCC/mk/port_spc563mxx.mk delete mode 100644 os/nil/ports/e200/compilers/GCC/mk/port_spc564axx.mk delete mode 100644 os/nil/ports/e200/compilers/GCC/mk/port_spc56ecxx.mk delete mode 100644 os/nil/ports/e200/compilers/GCC/mk/port_spc56elxx.mk delete mode 100644 os/nil/ports/e200/compilers/GCC/mk/port_spc57emxx.mk rename os/nil/src/{nil.c => ch.c} (100%) rename os/nil/templates/{nilconf.h => chconf.h} (51%) diff --git a/os/common/ext/readme.txt b/os/common/ext/readme.txt index 24c7070ee..38d5d4423 100644 --- a/os/common/ext/readme.txt +++ b/os/common/ext/readme.txt @@ -1,6 +1,7 @@ -All the code contained under ./os/ext is not part of the ChibiOS project and -supplied as-is without any additional warranty by ChibiOS. For ownership and -copyright statements see the license details inside the code. +All the code contained under ./os/common/ext is not part of the ChibiOS +project and supplied as-is without any additional warranty by ChibiOS. +For ownership and copyright statements see the license details inside the +code. Some modules may contain changes from the ChibiOS team in order to increase compatibility or usability with ChibiOS itself. diff --git a/os/common/oslib/include/chbsem.h b/os/common/oslib/include/chbsem.h new file mode 100644 index 000000000..ac2b37e9c --- /dev/null +++ b/os/common/oslib/include/chbsem.h @@ -0,0 +1,311 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chbsem.h + * @brief Binary semaphores structures and macros. + * + * @addtogroup binary_semaphores + * @details Binary semaphores related APIs and services. + *

Operation mode

+ * Binary semaphores are implemented as a set of inline functions + * that use the existing counting semaphores primitives. The + * difference between counting and binary semaphores is that the + * counter of binary semaphores is not allowed to grow above the + * value 1. Repeated signal operation are ignored. A binary + * semaphore can thus have only two defined states: + * - Taken, when its counter has a value of zero or lower + * than zero. A negative number represent the number of threads + * queued on the binary semaphore. + * - Not taken, when its counter has a value of one. + * . + * Binary semaphores are different from mutexes because there is no + * concept of ownership, a binary semaphore can be taken by a + * thread and signaled by another thread or an interrupt handler, + * mutexes can only be taken and released by the same thread. Another + * difference is that binary semaphores, unlike mutexes, do not + * implement the priority inheritance protocol.
+ * In order to use the binary semaphores APIs the + * @p CH_CFG_USE_SEMAPHORES option must be enabled in @p chconf.h. + * @{ + */ + +#ifndef _CHBSEM_H_ +#define _CHBSEM_H_ + +#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @extends semaphore_t + * + * @brief Binary semaphore type. + */ +typedef struct { + semaphore_t sem; +} binary_semaphore_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Data part of a static semaphore initializer. + * @details This macro should be used when statically initializing a semaphore + * that is part of a bigger structure. + * + * @param[in] name the name of the semaphore variable + * @param[in] taken the semaphore initial state + */ +#define _BSEMAPHORE_DATA(name, taken) \ + {_SEMAPHORE_DATA(name.sem, ((taken) ? 0 : 1))} + +/** + * @brief Static semaphore initializer. + * @details Statically initialized semaphores require no explicit + * initialization using @p chBSemInit(). + * + * @param[in] name the name of the semaphore variable + * @param[in] taken the semaphore initial state + */ +#define BSEMAPHORE_DECL(name, taken) \ + binary_semaphore_t name = _BSEMAPHORE_DATA(name, taken) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes a binary semaphore. + * + * @param[out] bsp pointer to a @p binary_semaphore_t structure + * @param[in] taken initial state of the binary semaphore: + * - @a false, the initial state is not taken. + * - @a true, the initial state is taken. + * . + * + * @init + */ +static inline void chBSemObjectInit(binary_semaphore_t *bsp, bool taken) { + + chSemObjectInit(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1); +} + +/** + * @brief Wait operation on the binary semaphore. + * + * @param[in] bsp pointer to a @p binary_semaphore_t structure + * @return A message specifying how the invoking thread has been + * released from the semaphore. + * @retval MSG_OK if the binary semaphore has been successfully taken. + * @retval MSG_RESET if the binary semaphore has been reset using + * @p bsemReset(). + * + * @api + */ +static inline msg_t chBSemWait(binary_semaphore_t *bsp) { + + return chSemWait(&bsp->sem); +} + +/** + * @brief Wait operation on the binary semaphore. + * + * @param[in] bsp pointer to a @p binary_semaphore_t structure + * @return A message specifying how the invoking thread has been + * released from the semaphore. + * @retval MSG_OK if the binary semaphore has been successfully taken. + * @retval MSG_RESET if the binary semaphore has been reset using + * @p bsemReset(). + * + * @sclass + */ +static inline msg_t chBSemWaitS(binary_semaphore_t *bsp) { + + chDbgCheckClassS(); + + return chSemWaitS(&bsp->sem); +} + +/** + * @brief Wait operation on the binary semaphore. + * + * @param[in] bsp pointer to a @p binary_semaphore_t structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return A message specifying how the invoking thread has been + * released from the semaphore. + * @retval MSG_OK if the binary semaphore has been successfully taken. + * @retval MSG_RESET if the binary semaphore has been reset using + * @p bsemReset(). + * @retval MSG_TIMEOUT if the binary semaphore has not been signaled or reset + * within the specified timeout. + * + * @sclass + */ +static inline msg_t chBSemWaitTimeoutS(binary_semaphore_t *bsp, + systime_t time) { + + chDbgCheckClassS(); + + return chSemWaitTimeoutS(&bsp->sem, time); +} + +/** + * @brief Wait operation on the binary semaphore. + * + * @param[in] bsp pointer to a @p binary_semaphore_t structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return A message specifying how the invoking thread has been + * released from the semaphore. + * @retval MSG_OK if the binary semaphore has been successfully taken. + * @retval MSG_RESET if the binary semaphore has been reset using + * @p bsemReset(). + * @retval MSG_TIMEOUT if the binary semaphore has not been signaled or reset + * within the specified timeout. + * + * @api + */ +static inline msg_t chBSemWaitTimeout(binary_semaphore_t *bsp, + systime_t time) { + + return chSemWaitTimeout(&bsp->sem, time); +} + +/** + * @brief Reset operation on the binary semaphore. + * @note The released threads can recognize they were waked up by a reset + * rather than a signal because the @p bsemWait() will return + * @p MSG_RESET instead of @p MSG_OK. + * @note This function does not reschedule. + * + * @param[in] bsp pointer to a @p binary_semaphore_t structure + * @param[in] taken new state of the binary semaphore + * - @a false, the new state is not taken. + * - @a true, the new state is taken. + * . + * + * @iclass + */ +static inline void chBSemResetI(binary_semaphore_t *bsp, bool taken) { + + chDbgCheckClassI(); + + chSemResetI(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1); +} + +/** + * @brief Reset operation on the binary semaphore. + * @note The released threads can recognize they were waked up by a reset + * rather than a signal because the @p bsemWait() will return + * @p MSG_RESET instead of @p MSG_OK. + * + * @param[in] bsp pointer to a @p binary_semaphore_t structure + * @param[in] taken new state of the binary semaphore + * - @a false, the new state is not taken. + * - @a true, the new state is taken. + * . + * + * @api + */ +static inline void chBSemReset(binary_semaphore_t *bsp, bool taken) { + + chSemReset(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1); +} + +/** + * @brief Performs a signal operation on a binary semaphore. + * @note This function does not reschedule. + * + * @param[in] bsp pointer to a @p binary_semaphore_t structure + * + * @iclass + */ +static inline void chBSemSignalI(binary_semaphore_t *bsp) { + + chDbgCheckClassI(); + + if (bsp->sem.cnt < (cnt_t)1) { + chSemSignalI(&bsp->sem); + } +} + +/** + * @brief Performs a signal operation on a binary semaphore. + * + * @param[in] bsp pointer to a @p binary_semaphore_t structure + * + * @api + */ +static inline void chBSemSignal(binary_semaphore_t *bsp) { + + chSysLock(); + chBSemSignalI(bsp); + chSchRescheduleS(); + chSysUnlock(); +} + +/** + * @brief Returns the binary semaphore current state. + * + * @param[in] bsp pointer to a @p binary_semaphore_t structure + * @return The binary semaphore current state. + * @retval false if the binary semaphore is not taken. + * @retval true if the binary semaphore is taken. + * + * @iclass + */ +static inline bool chBSemGetStateI(binary_semaphore_t *bsp) { + + chDbgCheckClassI(); + + return (bsp->sem.cnt > (cnt_t)0) ? false : true; +} + +#endif /* CH_CFG_USE_SEMAPHORES == TRUE */ + +#endif /* _CHBSEM_H_ */ + +/** @} */ diff --git a/os/common/oslib/include/chdynamic.h b/os/common/oslib/include/chdynamic.h new file mode 100644 index 000000000..fa00bd83e --- /dev/null +++ b/os/common/oslib/include/chdynamic.h @@ -0,0 +1,94 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chdynamic.h + * @brief Dynamic threads macros and structures. + * + * @addtogroup dynamic_threads + * @{ + */ + +#ifndef _CHDYNAMIC_H_ +#define _CHDYNAMIC_H_ + +#if (CH_CFG_USE_DYNAMIC == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Module dependencies check. + */ +#if CH_CFG_USE_WAITEXIT == FALSE +#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_WAITEXIT" +#endif + +#if (CH_CFG_USE_HEAP == FALSE) && (CH_CFG_USE_MEMPOOLS == FALSE) +#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_HEAP and/or CH_CFG_USE_MEMPOOLS" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* + * Dynamic threads APIs. + */ +#ifdef __cplusplus +extern "C" { +#endif +#if CH_CFG_USE_HEAP == TRUE + thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size, + tprio_t prio, tfunc_t pf, void *arg); +#endif +#if CH_CFG_USE_MEMPOOLS == TRUE + thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, tprio_t prio, + tfunc_t pf, void *arg); +#endif +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CH_CFG_USE_DYNAMIC == TRUE */ + +#endif /* _CHDYNAMIC_H_ */ + +/** @} */ diff --git a/os/common/oslib/include/chheap.h b/os/common/oslib/include/chheap.h new file mode 100644 index 000000000..25b1c1ade --- /dev/null +++ b/os/common/oslib/include/chheap.h @@ -0,0 +1,164 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chheap.h + * @brief Heaps macros and structures. + * + * @addtogroup heaps + * @{ + */ + +#ifndef _CHHEAP_H_ +#define _CHHEAP_H_ + +#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/** + * @brief Minimum alignment used for heap. + */ +#define CH_HEAP_ALIGNMENT sizeof (heap_header_t) + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if CH_CFG_USE_MEMCORE == FALSE +#error "CH_CFG_USE_HEAP requires CH_CFG_USE_MEMCORE" +#endif + +#if (CH_CFG_USE_MUTEXES == FALSE) && (CH_CFG_USE_SEMAPHORES == FALSE) +#error "CH_CFG_USE_HEAP requires CH_CFG_USE_MUTEXES and/or CH_CFG_USE_SEMAPHORES" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a memory heap. + */ +typedef struct memory_heap memory_heap_t; + +/** + * @brief Type of a memory heap header. + */ +typedef union heap_header heap_header_t; + +/** + * @brief Memory heap block header. + */ +union heap_header { + stkalign_t align; + struct { + heap_header_t *next; /**< @brief Next block in free list. */ + size_t pages; /**< @brief Size of the area in pages. */ + } free; + struct { + memory_heap_t *heap; /**< @brief Block owner heap. */ + size_t size; /**< @brief Size of the area in bytes. */ + } used; +}; + +/** + * @brief Structure describing a memory heap. + */ +struct memory_heap { + memgetfunc_t provider; /**< @brief Memory blocks provider for + this heap. */ + heap_header_t header; /**< @brief Free blocks list header. */ +#if CH_CFG_USE_MUTEXES == TRUE + mutex_t mtx; /**< @brief Heap access mutex. */ +#else + semaphore_t sem; /**< @brief Heap access semaphore. */ +#endif +}; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void _heap_init(void); + void chHeapObjectInit(memory_heap_t *heapp, void *buf, size_t size); + void *chHeapAllocAligned(memory_heap_t *heapp, size_t size, unsigned align); + void chHeapFree(void *p); + size_t chHeapStatus(memory_heap_t *heapp, size_t *totalp, size_t *largestp); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Allocates a block of memory from the heap by using the first-fit + * algorithm. + * @details The allocated block is guaranteed to be properly aligned for a + * pointer data type. + * + * @param[in] heapp pointer to a heap descriptor or @p NULL in order to + * access the default heap. + * @param[in] size the size of the block to be allocated. Note that the + * allocated block may be a bit bigger than the requested + * size for alignment and fragmentation reasons. + * @return A pointer to the allocated block. + * @retval NULL if the block cannot be allocated. + * + * @api + */ +static inline void *chHeapAlloc(memory_heap_t *heapp, size_t size) { + + return chHeapAllocAligned(heapp, size, CH_HEAP_ALIGNMENT); +} + +/** + * @brief Returns the size of an allocated block. + * @note The returned value is the requested size, the real size is the + * same value aligned to the next @p CH_HEAP_ALIGNMENT multiple. + * + * @param[in] p pointer to the memory block + * + * @api + */ +static inline size_t chHeapGetSize(const void *p) { + + return ((heap_header_t *)p)->used.size; +} + +#endif /* CH_CFG_USE_HEAP == TRUE */ + +#endif /* _CHHEAP_H_ */ + +/** @} */ diff --git a/os/common/oslib/include/chmboxes.h b/os/common/oslib/include/chmboxes.h new file mode 100644 index 000000000..44d6f9904 --- /dev/null +++ b/os/common/oslib/include/chmboxes.h @@ -0,0 +1,207 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chmboxes.h + * @brief Mailboxes macros and structures. + * + * @addtogroup mailboxes + * @{ + */ + +#ifndef _CHMBOXES_H_ +#define _CHMBOXES_H_ + +#if (CH_CFG_USE_MAILBOXES == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if CH_CFG_USE_SEMAPHORES == FALSE +#error "CH_CFG_USE_MAILBOXES requires CH_CFG_USE_SEMAPHORES" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Structure representing a mailbox object. + */ +typedef struct { + msg_t *buffer; /**< @brief Pointer to the mailbox + buffer. */ + msg_t *top; /**< @brief Pointer to the location + after the buffer. */ + msg_t *wrptr; /**< @brief Write pointer. */ + msg_t *rdptr; /**< @brief Read pointer. */ + semaphore_t fullsem; /**< @brief Full counter + @p semaphore_t. */ + semaphore_t emptysem; /**< @brief Empty counter + @p semaphore_t. */ +} mailbox_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Data part of a static mailbox initializer. + * @details This macro should be used when statically initializing a + * mailbox that is part of a bigger structure. + * + * @param[in] name the name of the mailbox variable + * @param[in] buffer pointer to the mailbox buffer area + * @param[in] size size of the mailbox buffer area + */ +#define _MAILBOX_DATA(name, buffer, size) { \ + (msg_t *)(buffer), \ + (msg_t *)(buffer) + size, \ + (msg_t *)(buffer), \ + (msg_t *)(buffer), \ + _SEMAPHORE_DATA(name.fullsem, 0), \ + _SEMAPHORE_DATA(name.emptysem, size), \ +} + +/** + * @brief Static mailbox initializer. + * @details Statically initialized mailboxes require no explicit + * initialization using @p chMBInit(). + * + * @param[in] name the name of the mailbox variable + * @param[in] buffer pointer to the mailbox buffer area + * @param[in] size size of the mailbox buffer area + */ +#define MAILBOX_DECL(name, buffer, size) \ + mailbox_t name = _MAILBOX_DATA(name, buffer, size) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void chMBObjectInit(mailbox_t *mbp, msg_t *buf, cnt_t n); + void chMBReset(mailbox_t *mbp); + void chMBResetI(mailbox_t *mbp); + msg_t chMBPost(mailbox_t *mbp, msg_t msg, systime_t timeout); + msg_t chMBPostS(mailbox_t *mbp, msg_t msg, systime_t timeout); + msg_t chMBPostI(mailbox_t *mbp, msg_t msg); + msg_t chMBPostAhead(mailbox_t *mbp, msg_t msg, systime_t timeout); + msg_t chMBPostAheadS(mailbox_t *mbp, msg_t msg, systime_t timeout); + msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg); + msg_t chMBFetch(mailbox_t *mbp, msg_t *msgp, systime_t timeout); + msg_t chMBFetchS(mailbox_t *mbp, msg_t *msgp, systime_t timeout); + msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Returns the mailbox buffer size. + * + * @param[in] mbp the pointer to an initialized mailbox_t object + * @return The size of the mailbox. + * + * @iclass + */ +static inline size_t chMBGetSizeI(mailbox_t *mbp) { + + /*lint -save -e9033 [10.8] Perfectly safe pointers + arithmetic.*/ + return (size_t)(mbp->top - mbp->buffer); + /*lint -restore*/ +} + +/** + * @brief Returns the number of free message slots into a mailbox. + * @note Can be invoked in any system state but if invoked out of a locked + * state then the returned value may change after reading. + * @note The returned value can be less than zero when there are waiting + * threads on the internal semaphore. + * + * @param[in] mbp the pointer to an initialized mailbox_t object + * @return The number of empty message slots. + * + * @iclass + */ +static inline cnt_t chMBGetFreeCountI(mailbox_t *mbp) { + + chDbgCheckClassI(); + + return chSemGetCounterI(&mbp->emptysem); +} + +/** + * @brief Returns the number of used message slots into a mailbox. + * @note Can be invoked in any system state but if invoked out of a locked + * state then the returned value may change after reading. + * @note The returned value can be less than zero when there are waiting + * threads on the internal semaphore. + * + * @param[in] mbp the pointer to an initialized mailbox_t object + * @return The number of queued messages. + * + * @iclass + */ +static inline cnt_t chMBGetUsedCountI(mailbox_t *mbp) { + + chDbgCheckClassI(); + + return chSemGetCounterI(&mbp->fullsem); +} + +/** + * @brief Returns the next message in the queue without removing it. + * @pre A message must be waiting in the queue for this function to work + * or it would return garbage. The correct way to use this macro is + * to use @p chMBGetFullCountI() and then use this macro, all within + * a lock state. + * + * @param[in] mbp the pointer to an initialized mailbox_t object + * @return The next message in queue. + * + * @iclass + */ +static inline msg_t chMBPeekI(mailbox_t *mbp) { + + chDbgCheckClassI(); + + return *mbp->rdptr; +} + +#endif /* CH_CFG_USE_MAILBOXES == TRUE */ + +#endif /* _CHMBOXES_H_ */ + +/** @} */ diff --git a/os/common/oslib/include/chmemcore.h b/os/common/oslib/include/chmemcore.h new file mode 100644 index 000000000..f877f0607 --- /dev/null +++ b/os/common/oslib/include/chmemcore.h @@ -0,0 +1,130 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chmemcore.h + * @brief Core memory manager macros and structures. + * + * @addtogroup memcore + * @{ + */ + +#ifndef _CHMEMCORE_H_ +#define _CHMEMCORE_H_ + +#if (CH_CFG_USE_MEMCORE == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @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_CFG_USE_MEMCORE. + */ +#define CH_CFG_MEMCORE_SIZE 0 + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if CH_CFG_MEMCORE_SIZE < 0 +#error "invalid CH_CFG_MEMCORE_SIZE value specified" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Memory get function. + */ +typedef void *(*memgetfunc_t)(size_t size, unsigned align); + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void _core_init(void); + void *chCoreAllocAlignedI(size_t size, unsigned align); + void *chCoreAllocAligned(size_t size, unsigned align); + size_t chCoreGetStatusX(void); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Allocates a memory block. + * @details The allocated block is guaranteed to be properly aligned for a + * pointer data type. + * + * @param[in] size the size of the block to be allocated. + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. + * + * @iclass + */ +static inline void *chCoreAllocI(size_t size) { + + return chCoreAllocAlignedI(size, PORT_NATURAL_ALIGN); +} + +/** + * @brief Allocates a memory block. + * @details The allocated block is guaranteed to be properly aligned for a + * pointer data type. + * + * @param[in] size the size of the block to be allocated. + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. + * + * @api + */ +static inline void *chCoreAlloc(size_t size) { + + return chCoreAllocAligned(size, PORT_NATURAL_ALIGN); +} + +#endif /* CH_CFG_USE_MEMCORE == TRUE */ + +#endif /* _CHMEMCORE_H_ */ + +/** @} */ diff --git a/os/common/oslib/include/chmempools.h b/os/common/oslib/include/chmempools.h new file mode 100644 index 000000000..2d582f48a --- /dev/null +++ b/os/common/oslib/include/chmempools.h @@ -0,0 +1,168 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chmempools.h + * @brief Memory Pools macros and structures. + * + * @addtogroup pools + * @{ + */ + +#ifndef _CHMEMPOOLS_H_ +#define _CHMEMPOOLS_H_ + +#if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if CH_CFG_USE_MEMCORE == FALSE +#error "CH_CFG_USE_MEMPOOLS requires CH_CFG_USE_MEMCORE" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Memory pool free object header. + */ +struct pool_header { + struct pool_header *next; /**< @brief Pointer to the next pool + header in the list. */ +}; + +/** + * @brief Memory pool descriptor. + */ +typedef struct { + struct pool_header *next; /**< @brief Pointer to the header. */ + size_t object_size; /**< @brief Memory pool objects + size. */ + memgetfunc_t provider; /**< @brief Memory blocks provider + for this pool. */ +} memory_pool_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Data part of a static memory pool initializer. + * @details This macro should be used when statically initializing a + * memory pool that is part of a bigger structure. + * + * @param[in] name the name of the memory pool variable + * @param[in] size size of the memory pool contained objects + * @param[in] provider memory provider function for the memory pool + */ +#define _MEMORYPOOL_DATA(name, size, provider) \ + {NULL, size, provider} + +/** + * @brief Static memory pool initializer in hungry mode. + * @details Statically initialized memory pools require no explicit + * initialization using @p chPoolInit(). + * + * @param[in] name the name of the memory pool variable + * @param[in] size size of the memory pool contained objects + * @param[in] provider memory provider function for the memory pool or @p NULL + * if the pool is not allowed to grow automatically + */ +#define MEMORYPOOL_DECL(name, size, provider) \ + memory_pool_t name = _MEMORYPOOL_DATA(name, size, provider) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void chPoolObjectInit(memory_pool_t *mp, size_t size, memgetfunc_t provider); + void chPoolLoadArray(memory_pool_t *mp, void *p, size_t n); + void *chPoolAllocI(memory_pool_t *mp); + void *chPoolAlloc(memory_pool_t *mp); + void chPoolFreeI(memory_pool_t *mp, void *objp); + void chPoolFree(memory_pool_t *mp, void *objp); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Adds an object to a memory pool. + * @pre The memory pool must be already been initialized. + * @pre The added object must be of the right size for the specified + * memory pool. + * @pre The added object must be memory aligned to the size of + * @p stkalign_t type. + * @note This function is just an alias for @p chPoolFree() and has been + * added for clarity. + * + * @param[in] mp pointer to a @p memory_pool_t structure + * @param[in] objp the pointer to the object to be added + * + * @api + */ +static inline void chPoolAdd(memory_pool_t *mp, void *objp) { + + chPoolFree(mp, objp); +} + +/** + * @brief Adds an object to a memory pool. + * @pre The memory pool must be already been initialized. + * @pre The added object must be of the right size for the specified + * memory pool. + * @pre The added object must be memory aligned to the size of + * @p stkalign_t type. + * @note This function is just an alias for @p chPoolFree() and has been + * added for clarity. + * + * @param[in] mp pointer to a @p memory_pool_t structure + * @param[in] objp the pointer to the object to be added + * + * @iclass + */ +static inline void chPoolAddI(memory_pool_t *mp, void *objp) { + + chDbgCheckClassI(); + + chPoolFreeI(mp, objp); +} + +#endif /* CH_CFG_USE_MEMPOOLS == TRUE */ + +#endif /* _CHMEMPOOLS_H_ */ + +/** @} */ diff --git a/os/common/oslib/readme.txt b/os/common/oslib/readme.txt new file mode 100644 index 000000000..e1c274da4 --- /dev/null +++ b/os/common/oslib/readme.txt @@ -0,0 +1,3 @@ +All the code contained under ./os/common/oslib are optional RTOS modules +compatible with both RT and NIL. The code is placed under ./os/common in +order to prevent code duplication and disalignments. diff --git a/os/common/oslib/src/chdynamic.c b/os/common/oslib/src/chdynamic.c new file mode 100644 index 000000000..7d8b609be --- /dev/null +++ b/os/common/oslib/src/chdynamic.c @@ -0,0 +1,150 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chdynamic.c + * @brief Dynamic threads code. + * + * @addtogroup dynamic_threads + * @details Dynamic threads related APIs and services. + * @note Compatible with RT only. + * @{ + */ + +#include "ch.h" + +#if (CH_CFG_USE_DYNAMIC == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__) +/** + * @brief Creates a new thread allocating the memory from the heap. + * @pre The configuration options @p CH_CFG_USE_DYNAMIC and + * @p CH_CFG_USE_HEAP must be enabled in order to use this function. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note The memory allocated for the thread is not released automatically, + * it is responsibility of the creator thread to call @p chThdWait() + * and then release the allocated memory. + * + * @param[in] heapp heap from which allocate the memory or @p NULL for the + * default heap + * @param[in] size size of the working area to be allocated + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p thread_t structure allocated for + * the thread into the working space area. + * @retval NULL if the memory cannot be allocated. + * + * @api + */ +thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size, + tprio_t prio, tfunc_t pf, void *arg) { + void *wsp; + + wsp = chHeapAllocAligned(heapp, size, PORT_WORKING_AREA_ALIGN); + if (wsp == NULL) { + return NULL; + } + +#if CH_DBG_FILL_THREADS == TRUE + _thread_memfill((uint8_t *)wsp, + (uint8_t *)wsp + size, + CH_DBG_STACK_FILL_VALUE); +#endif + + return chThdCreateStatic(wsp, size, prio, pf, arg); +} +#endif /* CH_CFG_USE_HEAP == TRUE */ + +#if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__) +/** + * @brief Creates a new thread allocating the memory from the specified + * memory pool. + * @pre The configuration options @p CH_CFG_USE_DYNAMIC and + * @p CH_CFG_USE_MEMPOOLS must be enabled in order to use this + * function. + * @pre The pool must be initialized to contain only objects with + * alignment @p PORT_WORKING_AREA_ALIGN. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note The memory allocated for the thread is not released automatically, + * it is responsibility of the creator thread to call @p chThdWait() + * and then release the allocated memory. + * + * @param[in] mp pointer to the memory pool object + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p thread_t structure allocated for + * the thread into the working space area. + * @retval NULL if the memory pool is empty. + * + * @api + */ +thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, tprio_t prio, + tfunc_t pf, void *arg) { + void *wsp; + + chDbgCheck(mp != NULL); + + wsp = chPoolAlloc(mp); + if (wsp == NULL) { + return NULL; + } + +#if CH_DBG_FILL_THREADS == TRUE + _thread_memfill((uint8_t *)wsp, + (uint8_t *)wsp + mp->object_size, + CH_DBG_STACK_FILL_VALUE); +#endif + + return chThdCreateStatic(wsp, mp->object_size, prio, pf, arg); +} +#endif /* CH_CFG_USE_MEMPOOLS == TRUE */ + +#endif /* CH_CFG_USE_DYNAMIC == TRUE */ + +/** @} */ diff --git a/os/common/oslib/src/chheap.c b/os/common/oslib/src/chheap.c new file mode 100644 index 000000000..a35b646ba --- /dev/null +++ b/os/common/oslib/src/chheap.c @@ -0,0 +1,383 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chheap.c + * @brief Heaps code. + * + * @addtogroup heaps + * @details Heap Allocator related APIs. + *

Operation mode

+ * The heap allocator implements a first-fit strategy and its APIs + * are functionally equivalent to the usual @p malloc() and @p free() + * library functions. The main difference is that the OS heap APIs + * are guaranteed to be thread safe and there is the ability to + * return memory blocks aligned to arbitrary powers of two.
+ * @pre In order to use the heap APIs the @p CH_CFG_USE_HEAP option must + * be enabled in @p chconf.h. + * @note Compatible with RT and NIL. + * @{ + */ + +#include "ch.h" + +#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/* + * Defaults on the best synchronization mechanism available. + */ +#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) +#define H_LOCK(h) chMtxLock(&(h)->mtx) +#define H_UNLOCK(h) chMtxUnlock(&(h)->mtx) +#else +#define H_LOCK(h) (void) chSemWait(&(h)->sem) +#define H_UNLOCK(h) chSemSignal(&(h)->sem) +#endif + +#define H_BLOCK(hp) ((hp) + 1U) + +#define H_LIMIT(hp) (H_BLOCK(hp) + H_PAGES(hp)) + +#define H_NEXT(hp) ((hp)->free.next) + +#define H_PAGES(hp) ((hp)->free.pages) + +#define H_HEAP(hp) ((hp)->used.heap) + +#define H_SIZE(hp) ((hp)->used.size) + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/** + * @brief Default heap descriptor. + */ +static memory_heap_t default_heap; + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the default heap. + * + * @notapi + */ +void _heap_init(void) { + + default_heap.provider = chCoreAllocAligned; + H_NEXT(&default_heap.header) = NULL; + H_PAGES(&default_heap.header) = 0; +#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) + chMtxObjectInit(&default_heap.mtx); +#else + chSemObjectInit(&default_heap.sem, (cnt_t)1); +#endif +} + +/** + * @brief Initializes a memory heap from a static memory area. + * @pre Both the heap buffer base and the heap size must be aligned to + * the @p heap_header_t type size. + * + * @param[out] heapp pointer to the memory heap descriptor to be initialized + * @param[in] buf heap buffer base + * @param[in] size heap size + * + * @init + */ +void chHeapObjectInit(memory_heap_t *heapp, void *buf, size_t size) { + heap_header_t *hp = buf; + + chDbgCheck((heapp != NULL) && (size > 0U) && + MEM_IS_ALIGNED(buf, CH_HEAP_ALIGNMENT) && + MEM_IS_ALIGNED(size, CH_HEAP_ALIGNMENT)); + + heapp->provider = NULL; + H_NEXT(&heapp->header) = hp; + H_PAGES(&heapp->header) = 0; + H_NEXT(hp) = NULL; + H_PAGES(hp) = (size - sizeof (heap_header_t)) / CH_HEAP_ALIGNMENT; +#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) + chMtxObjectInit(&heapp->mtx); +#else + chSemObjectInit(&heapp->sem, (cnt_t)1); +#endif +} + +/** + * @brief Allocates a block of memory from the heap by using the first-fit + * algorithm. + * @details The allocated block is guaranteed to be properly aligned to the + * specified alignment. + * + * @param[in] heapp pointer to a heap descriptor or @p NULL in order to + * access the default heap. + * @param[in] size the size of the block to be allocated. Note that the + * allocated block may be a bit bigger than the requested + * size for alignment and fragmentation reasons. + * @param[in] align desired memory alignment + * @return A pointer to the aligned allocated block. + * @retval NULL if the block cannot be allocated. + * + * @api + */ +void *chHeapAllocAligned(memory_heap_t *heapp, size_t size, unsigned align) { + heap_header_t *qp, *hp; + size_t pages; + + chDbgCheck((size > 0U) && MEM_IS_VALID_ALIGNMENT(align)); + + /* If an heap is not specified then the default system header is used.*/ + if (heapp == NULL) { + heapp = &default_heap; + } + + /* Minimum alignment is constrained by the heap header structure size.*/ + if (align < CH_HEAP_ALIGNMENT) { + align = CH_HEAP_ALIGNMENT; + } + + /* Size is converted in number of elementary allocation units.*/ + pages = MEM_ALIGN_NEXT(size, CH_HEAP_ALIGNMENT) / CH_HEAP_ALIGNMENT; + + /* Taking heap mutex/semaphore.*/ + H_LOCK(heapp); + + /* Start of the free blocks list.*/ + qp = &heapp->header; + while (H_NEXT(qp) != NULL) { + heap_header_t *ahp; + + /* Next free block.*/ + hp = H_NEXT(qp); + + /* Pointer aligned to the requested alignment.*/ + ahp = (heap_header_t *)MEM_ALIGN_NEXT(H_BLOCK(hp), align) - 1U; + + if ((ahp < H_LIMIT(hp)) && (pages <= (size_t)(H_LIMIT(hp) - 1U - ahp))) { + /* The block is large enough to contain a correctly aligned area + of sufficient size.*/ + + if (ahp > hp) { + /* The block is not properly aligned, must split it.*/ + size_t bpages; + + bpages = H_LIMIT(hp) - H_BLOCK(ahp); + H_PAGES(hp) = ahp - H_BLOCK(hp); + if (bpages > pages) { + /* The block is bigger than required, must split the excess.*/ + heap_header_t *fp; + + /* Creating the excess block.*/ + fp = H_BLOCK(ahp) + pages; + H_PAGES(fp) = bpages - pages - 1U; + + /* Linking the excess block.*/ + H_NEXT(fp) = H_NEXT(hp); + H_NEXT(hp) = fp; + } + + hp = ahp; + } + else { + /* The block is already properly aligned.*/ + + if (H_PAGES(hp) == pages) { + /* Exact size, getting the whole block.*/ + H_NEXT(qp) = H_NEXT(hp); + } + else { + /* The block is bigger than required, must split the excess.*/ + heap_header_t *fp; + + fp = H_BLOCK(hp) + pages; + H_NEXT(fp) = H_NEXT(hp); + H_PAGES(fp) = H_LIMIT(hp) - H_BLOCK(fp); + H_NEXT(qp) = fp; + } + } + + /* Setting in the block owner heap and size.*/ + H_SIZE(hp) = size; + H_HEAP(hp) = heapp; + + /* Releasing heap mutex/semaphore.*/ + H_UNLOCK(heapp); + + /*lint -save -e9087 [11.3] Safe cast.*/ + return (void *)H_BLOCK(hp); + /*lint -restore*/ + } + + /* Next in the free blocks list.*/ + qp = hp; + } + + /* Releasing heap mutex/semaphore.*/ + H_UNLOCK(heapp); + + /* More memory is required, tries to get it from the associated provider + else fails.*/ + if (heapp->provider != NULL) { + hp = heapp->provider((pages + 1U) * CH_HEAP_ALIGNMENT, align); + if (hp != NULL) { + H_HEAP(hp) = heapp; + H_SIZE(hp) = size; + + /*lint -save -e9087 [11.3] Safe cast.*/ + return (void *)H_BLOCK(hp); + /*lint -restore*/ + } + } + + return NULL; +} + +/** + * @brief Frees a previously allocated memory block. + * + * @param[in] p pointer to the memory block to be freed + * + * @api + */ +void chHeapFree(void *p) { + heap_header_t *qp, *hp; + memory_heap_t *heapp; + + chDbgCheck((p != NULL) && MEM_IS_ALIGNED(p, CH_HEAP_ALIGNMENT)); + + /*lint -save -e9087 [11.3] Safe cast.*/ + hp = (heap_header_t *)p - 1U; + /*lint -restore*/ + heapp = H_HEAP(hp); + qp = &heapp->header; + + /* Size is converted in number of elementary allocation units.*/ + H_PAGES(hp) = MEM_ALIGN_NEXT(H_SIZE(hp), + CH_HEAP_ALIGNMENT) / CH_HEAP_ALIGNMENT; + + /* Taking heap mutex/semaphore.*/ + H_LOCK(heapp); + + while (true) { + chDbgAssert((hp < qp) || (hp >= H_LIMIT(qp)), "within free block"); + + if (((qp == &heapp->header) || (hp > qp)) && + ((H_NEXT(qp) == NULL) || (hp < H_NEXT(qp)))) { + /* Insertion after qp.*/ + H_NEXT(hp) = H_NEXT(qp); + H_NEXT(qp) = hp; + /* Verifies if the newly inserted block should be merged.*/ + if (H_LIMIT(hp) == H_NEXT(hp)) { + /* Merge with the next block.*/ + H_PAGES(hp) += H_PAGES(H_NEXT(hp)) + 1U; + H_NEXT(hp) = H_NEXT(H_NEXT(hp)); + } + if ((H_LIMIT(qp) == hp)) { + /* Merge with the previous block.*/ + H_PAGES(qp) += H_PAGES(hp) + 1U; + H_NEXT(qp) = H_NEXT(hp); + } + break; + } + qp = H_NEXT(qp); + } + + /* Releasing heap mutex/semaphore.*/ + H_UNLOCK(heapp); + + return; +} + +/** + * @brief Reports the heap status. + * @note This function is meant to be used in the test suite, it should + * not be really useful for the application code. + * + * @param[in] heapp pointer to a heap descriptor or @p NULL in order to + * access the default heap. + * @param[in] totalp pointer to a variable that will receive the total + * fragmented free space or @ NULL + * @param[in] largestp pointer to a variable that will receive the largest + * free free block found space or @ NULL + * @return The number of fragments in the heap. + * + * @api + */ +size_t chHeapStatus(memory_heap_t *heapp, size_t *totalp, size_t *largestp) { + heap_header_t *qp; + size_t n, tpages, lpages; + + if (heapp == NULL) { + heapp = &default_heap; + } + + H_LOCK(heapp); + tpages = 0U; + lpages = 0U; + n = 0U; + qp = &heapp->header; + while (H_NEXT(qp) != NULL) { + size_t pages = H_PAGES(H_NEXT(qp)); + + /* Updating counters.*/ + n++; + tpages += pages; + if (pages > lpages) { + lpages = pages; + } + + qp = H_NEXT(qp); + } + + /* Writing out fragmented free memory.*/ + if (totalp != NULL) { + *totalp = tpages * CH_HEAP_ALIGNMENT; + } + + /* Writing out unfragmented free memory.*/ + if (largestp != NULL) { + *largestp = lpages * CH_HEAP_ALIGNMENT; + } + H_UNLOCK(heapp); + + return n; +} + +#endif /* CH_CFG_USE_HEAP == TRUE */ + +/** @} */ diff --git a/os/common/oslib/src/chmboxes.c b/os/common/oslib/src/chmboxes.c new file mode 100644 index 000000000..bb75fee6c --- /dev/null +++ b/os/common/oslib/src/chmboxes.c @@ -0,0 +1,435 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chmboxes.c + * @brief Mailboxes code. + * + * @addtogroup mailboxes + * @details Asynchronous messages. + *

Operation mode

+ * A mailbox is an asynchronous communication mechanism.
+ * Operations defined for mailboxes: + * - Post: Posts a message on the mailbox in FIFO order. + * - Post Ahead: Posts a message on the mailbox with urgent + * priority. + * - Fetch: A message is fetched from the mailbox and removed + * from the queue. + * - Reset: The mailbox is emptied and all the stored messages + * are lost. + * . + * A message is a variable of type msg_t that is guaranteed to have + * the same size of and be compatible with (data) pointers (anyway an + * explicit cast is needed). + * If larger messages need to be exchanged then a pointer to a + * structure can be posted in the mailbox but the posting side has + * no predefined way to know when the message has been processed. A + * possible approach is to allocate memory (from a memory pool for + * example) from the posting side and free it on the fetching side. + * Another approach is to set a "done" flag into the structure pointed + * by the message. + * @pre In order to use the mailboxes APIs the @p CH_CFG_USE_MAILBOXES + * option must be enabled in @p chconf.h. + * @note Compatible with RT and NIL. + * @{ + */ + +#include "ch.h" + +#if (CH_CFG_USE_MAILBOXES == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes a @p mailbox_t object. + * + * @param[out] mbp the pointer to the @p mailbox_t structure to be + * initialized + * @param[in] buf pointer to the messages buffer as an array of @p msg_t + * @param[in] n number of elements in the buffer array + * + * @init + */ +void chMBObjectInit(mailbox_t *mbp, msg_t *buf, cnt_t n) { + + chDbgCheck((mbp != NULL) && (buf != NULL) && (n > (cnt_t)0)); + + mbp->buffer = buf; + mbp->rdptr = buf; + mbp->wrptr = buf; + mbp->top = &buf[n]; + chSemObjectInit(&mbp->emptysem, n); + chSemObjectInit(&mbp->fullsem, (cnt_t)0); +} + +/** + * @brief Resets a @p mailbox_t object. + * @details All the waiting threads are resumed with status @p MSG_RESET and + * the queued messages are lost. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * + * @api + */ +void chMBReset(mailbox_t *mbp) { + + chSysLock(); + chMBResetI(mbp); + chSchRescheduleS(); + chSysUnlock(); +} + +/** + * @brief Resets a @p mailbox_t object. + * @details All the waiting threads are resumed with status @p MSG_RESET and + * the queued messages are lost. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * + * @api + */ +void chMBResetI(mailbox_t *mbp) { + + chDbgCheckClassI(); + chDbgCheck(mbp != NULL); + + mbp->wrptr = mbp->buffer; + mbp->rdptr = mbp->buffer; + chSemResetI(&mbp->emptysem, (cnt_t)(mbp->top - mbp->buffer)); + chSemResetI(&mbp->fullsem, (cnt_t)0); +} + +/** + * @brief Posts a message into a mailbox. + * @details The invoking thread waits until a empty slot in the mailbox becomes + * available or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * @param[in] msg the message to be posted on the mailbox + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval MSG_OK if a message has been correctly posted. + * @retval MSG_RESET if the mailbox has been reset while waiting. + * @retval MSG_TIMEOUT if the operation has timed out. + * + * @api + */ +msg_t chMBPost(mailbox_t *mbp, msg_t msg, systime_t timeout) { + msg_t rdymsg; + + chSysLock(); + rdymsg = chMBPostS(mbp, msg, timeout); + chSysUnlock(); + + return rdymsg; +} + +/** + * @brief Posts a message into a mailbox. + * @details The invoking thread waits until a empty slot in the mailbox becomes + * available or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * @param[in] msg the message to be posted on the mailbox + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval MSG_OK if a message has been correctly posted. + * @retval MSG_RESET if the mailbox has been reset while waiting. + * @retval MSG_TIMEOUT if the operation has timed out. + * + * @sclass + */ +msg_t chMBPostS(mailbox_t *mbp, msg_t msg, systime_t timeout) { + msg_t rdymsg; + + chDbgCheckClassS(); + chDbgCheck(mbp != NULL); + + rdymsg = chSemWaitTimeoutS(&mbp->emptysem, timeout); + if (rdymsg == MSG_OK) { + *mbp->wrptr++ = msg; + if (mbp->wrptr >= mbp->top) { + mbp->wrptr = mbp->buffer; + } + chSemSignalI(&mbp->fullsem); + chSchRescheduleS(); + } + + return rdymsg; +} + +/** + * @brief Posts a message into a mailbox. + * @details This variant is non-blocking, the function returns a timeout + * condition if the queue is full. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * @param[in] msg the message to be posted on the mailbox + * @return The operation status. + * @retval MSG_OK if a message has been correctly posted. + * @retval MSG_TIMEOUT if the mailbox is full and the message cannot be + * posted. + * + * @iclass + */ +msg_t chMBPostI(mailbox_t *mbp, msg_t msg) { + + chDbgCheckClassI(); + chDbgCheck(mbp != NULL); + + if (chSemGetCounterI(&mbp->emptysem) <= (cnt_t)0) { + return MSG_TIMEOUT; + } + + chSemFastWaitI(&mbp->emptysem); + *mbp->wrptr++ = msg; + if (mbp->wrptr >= mbp->top) { + mbp->wrptr = mbp->buffer; + } + chSemSignalI(&mbp->fullsem); + + return MSG_OK; +} + +/** + * @brief Posts an high priority message into a mailbox. + * @details The invoking thread waits until a empty slot in the mailbox becomes + * available or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * @param[in] msg the message to be posted on the mailbox + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval MSG_OK if a message has been correctly posted. + * @retval MSG_RESET if the mailbox has been reset while waiting. + * @retval MSG_TIMEOUT if the operation has timed out. + * + * @api + */ +msg_t chMBPostAhead(mailbox_t *mbp, msg_t msg, systime_t timeout) { + msg_t rdymsg; + + chSysLock(); + rdymsg = chMBPostAheadS(mbp, msg, timeout); + chSysUnlock(); + + return rdymsg; +} + +/** + * @brief Posts an high priority message into a mailbox. + * @details The invoking thread waits until a empty slot in the mailbox becomes + * available or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * @param[in] msg the message to be posted on the mailbox + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval MSG_OK if a message has been correctly posted. + * @retval MSG_RESET if the mailbox has been reset while waiting. + * @retval MSG_TIMEOUT if the operation has timed out. + * + * @sclass + */ +msg_t chMBPostAheadS(mailbox_t *mbp, msg_t msg, systime_t timeout) { + msg_t rdymsg; + + chDbgCheckClassS(); + chDbgCheck(mbp != NULL); + + rdymsg = chSemWaitTimeoutS(&mbp->emptysem, timeout); + if (rdymsg == MSG_OK) { + if (--mbp->rdptr < mbp->buffer) { + mbp->rdptr = mbp->top - 1; + } + *mbp->rdptr = msg; + chSemSignalI(&mbp->fullsem); + chSchRescheduleS(); + } + + return rdymsg; +} + +/** + * @brief Posts an high priority message into a mailbox. + * @details This variant is non-blocking, the function returns a timeout + * condition if the queue is full. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * @param[in] msg the message to be posted on the mailbox + * @return The operation status. + * @retval MSG_OK if a message has been correctly posted. + * @retval MSG_TIMEOUT if the mailbox is full and the message cannot be + * posted. + * + * @iclass + */ +msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg) { + + chDbgCheckClassI(); + chDbgCheck(mbp != NULL); + + if (chSemGetCounterI(&mbp->emptysem) <= (cnt_t)0) { + return MSG_TIMEOUT; + } + chSemFastWaitI(&mbp->emptysem); + if (--mbp->rdptr < mbp->buffer) { + mbp->rdptr = mbp->top - 1; + } + *mbp->rdptr = msg; + chSemSignalI(&mbp->fullsem); + + return MSG_OK; +} + +/** + * @brief Retrieves a message from a mailbox. + * @details The invoking thread waits until a message is posted in the mailbox + * or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * @param[out] msgp pointer to a message variable for the received message + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval MSG_OK if a message has been correctly fetched. + * @retval MSG_RESET if the mailbox has been reset while waiting. + * @retval MSG_TIMEOUT if the operation has timed out. + * + * @api + */ +msg_t chMBFetch(mailbox_t *mbp, msg_t *msgp, systime_t timeout) { + msg_t rdymsg; + + chSysLock(); + rdymsg = chMBFetchS(mbp, msgp, timeout); + chSysUnlock(); + + return rdymsg; +} + +/** + * @brief Retrieves a message from a mailbox. + * @details The invoking thread waits until a message is posted in the mailbox + * or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * @param[out] msgp pointer to a message variable for the received message + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval MSG_OK if a message has been correctly fetched. + * @retval MSG_RESET if the mailbox has been reset while waiting. + * @retval MSG_TIMEOUT if the operation has timed out. + * + * @sclass + */ +msg_t chMBFetchS(mailbox_t *mbp, msg_t *msgp, systime_t timeout) { + msg_t rdymsg; + + chDbgCheckClassS(); + chDbgCheck((mbp != NULL) && (msgp != NULL)); + + rdymsg = chSemWaitTimeoutS(&mbp->fullsem, timeout); + if (rdymsg == MSG_OK) { + *msgp = *mbp->rdptr++; + if (mbp->rdptr >= mbp->top) { + mbp->rdptr = mbp->buffer; + } + chSemSignalI(&mbp->emptysem); + chSchRescheduleS(); + } + + return rdymsg; +} + +/** + * @brief Retrieves a message from a mailbox. + * @details This variant is non-blocking, the function returns a timeout + * condition if the queue is empty. + * + * @param[in] mbp the pointer to an initialized @p mailbox_t object + * @param[out] msgp pointer to a message variable for the received message + * @return The operation status. + * @retval MSG_OK if a message has been correctly fetched. + * @retval MSG_TIMEOUT if the mailbox is empty and a message cannot be + * fetched. + * + * @iclass + */ +msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp) { + + chDbgCheckClassI(); + chDbgCheck((mbp != NULL) && (msgp != NULL)); + + if (chSemGetCounterI(&mbp->fullsem) <= (cnt_t)0) { + return MSG_TIMEOUT; + } + chSemFastWaitI(&mbp->fullsem); + *msgp = *mbp->rdptr++; + if (mbp->rdptr >= mbp->top) { + mbp->rdptr = mbp->buffer; + } + chSemSignalI(&mbp->emptysem); + + return MSG_OK; +} +#endif /* CH_CFG_USE_MAILBOXES == TRUE */ + +/** @} */ diff --git a/os/common/oslib/src/chmemcore.c b/os/common/oslib/src/chmemcore.c new file mode 100644 index 000000000..a665b07b2 --- /dev/null +++ b/os/common/oslib/src/chmemcore.c @@ -0,0 +1,166 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chmemcore.c + * @brief Core memory manager code. + * + * @addtogroup memcore + * @details Core Memory Manager related APIs and services. + *

Operation mode

+ * The core memory manager is a simplified allocator that only + * allows to allocate memory blocks without the possibility to + * free them.
+ * This allocator is meant as a memory blocks provider for the + * other allocators such as: + * - C-Runtime allocator (through a compiler specific adapter module). + * - Heap allocator (see @ref heaps). + * - Memory pools allocator (see @ref pools). + * . + * By having a centralized memory provider the various allocators + * can coexist and share the main memory.
+ * This allocator, alone, is also useful for very simple + * applications that just require a simple way to get memory + * blocks. + * @pre In order to use the core memory manager APIs the @p CH_CFG_USE_MEMCORE + * option must be enabled in @p chconf.h. + * @note Compatible with RT and NIL. + * @{ + */ + +#include "ch.h" + +#if (CH_CFG_USE_MEMCORE == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +static uint8_t *nextmem; +static uint8_t *endmem; + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level memory manager initialization. + * + * @notapi + */ +void _core_init(void) { +#if CH_CFG_MEMCORE_SIZE == 0 + extern uint8_t __heap_base__[]; + extern uint8_t __heap_end__[]; + + /*lint -save -e9033 [10.8] Required cast operations.*/ + nextmem = (uint8_t *)MEM_ALIGN_NEXT(__heap_base__, PORT_NATURAL_ALIGN); + endmem = (uint8_t *)MEM_ALIGN_PREV(__heap_end__, PORT_NATURAL_ALIGN); + /*lint restore*/ +#else + static stkalign_t buffer[MEM_ALIGN_NEXT(CH_CFG_MEMCORE_SIZE) / + PORT_NATURAL_ALIGN]; + + nextmem = (uint8_t *)&buffer[0]; + endmem = (uint8_t *)&buffer[MEM_ALIGN_NEXT(CH_CFG_MEMCORE_SIZE) / + PORT_NATURAL_ALIGN]; +#endif +} + +/** + * @brief Allocates a memory block. + * @details The allocated block is guaranteed to be properly aligned to the + * specified alignment. + * + * @param[in] size the size of the block to be allocated. + * @param[in] align desired memory alignment + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. + * + * @iclass + */ +void *chCoreAllocAlignedI(size_t size, unsigned align) { + uint8_t *p; + + chDbgCheckClassI(); + chDbgCheck(MEM_IS_VALID_ALIGNMENT(align)); + + size = MEM_ALIGN_NEXT(size, align); + p = (uint8_t *)MEM_ALIGN_NEXT(nextmem, align); + + /* ---????? lint -save -e9033 [10.8] The cast is safe.*/ + if ((size_t)(endmem - p) < size) { + /* ---????? lint -restore*/ + return NULL; + } + nextmem = p + size; + + return p; +} + +/** + * @brief Allocates a memory block. + * @details The allocated block is guaranteed to be properly aligned to the + * specified alignment. + * + * @param[in] size the size of the block to be allocated + * @param[in] align desired memory alignment + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. + * + * @api + */ +void *chCoreAllocAligned(size_t size, unsigned align) { + void *p; + + chSysLock(); + p = chCoreAllocAlignedI(size, align); + chSysUnlock(); + + return p; +} + +/** + * @brief Core memory status. + * + * @return The size, in bytes, of the free core memory. + * + * @xclass + */ +size_t chCoreGetStatusX(void) { + + /*lint -save -e9033 [10.8] The cast is safe.*/ + return (size_t)(endmem - nextmem); + /*lint -restore*/ +} +#endif /* CH_CFG_USE_MEMCORE == TRUE */ + +/** @} */ diff --git a/os/common/oslib/src/chmempools.c b/os/common/oslib/src/chmempools.c new file mode 100644 index 000000000..c29fde8f4 --- /dev/null +++ b/os/common/oslib/src/chmempools.c @@ -0,0 +1,203 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chmempools.c + * @brief Memory Pools code. + * + * @addtogroup pools + * @details Memory Pools related APIs and services. + *

Operation mode

+ * The Memory Pools APIs allow to allocate/free fixed size objects in + * constant time and reliably without memory fragmentation + * problems.
+ * Memory Pools do not enforce any alignment constraint on the + * contained object however the objects must be properly aligned + * to contain a pointer to void. + * @pre In order to use the memory pools APIs the @p CH_CFG_USE_MEMPOOLS option + * must be enabled in @p chconf.h. + * @note Compatible with RT and NIL. + * @{ + */ + +#include "ch.h" + +#if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes an empty memory pool. + * + * @param[out] mp pointer to a @p memory_pool_t structure + * @param[in] size the size of the objects contained in this memory pool, + * the minimum accepted size is the size of a pointer to + * void. + * @param[in] provider memory provider function for the memory pool or + * @p NULL if the pool is not allowed to grow + * automatically + * + * @init + */ +void chPoolObjectInit(memory_pool_t *mp, size_t size, memgetfunc_t provider) { + + chDbgCheck((mp != NULL) && (size >= sizeof(void *))); + + mp->next = NULL; + mp->object_size = size; + mp->provider = provider; +} + +/** + * @brief Loads a memory pool with an array of static objects. + * @pre The memory pool must be already been initialized. + * @pre The array elements must be of the right size for the specified + * memory pool. + * @post The memory pool contains the elements of the input array. + * + * @param[in] mp pointer to a @p memory_pool_t structure + * @param[in] p pointer to the array first element + * @param[in] n number of elements in the array + * + * @api + */ +void chPoolLoadArray(memory_pool_t *mp, void *p, size_t n) { + + chDbgCheck((mp != NULL) && (n != 0U)); + + while (n != 0U) { + chPoolAdd(mp, p); + /*lint -save -e9087 [11.3] Safe cast.*/ + p = (void *)(((uint8_t *)p) + mp->object_size); + /*lint -restore*/ + n--; + } +} + +/** + * @brief Allocates an object from a memory pool. + * @pre The memory pool must be already been initialized. + * + * @param[in] mp pointer to a @p memory_pool_t structure + * @return The pointer to the allocated object. + * @retval NULL if pool is empty. + * + * @iclass + */ +void *chPoolAllocI(memory_pool_t *mp) { + void *objp; + + chDbgCheckClassI(); + chDbgCheck(mp != NULL); + + objp = mp->next; + /*lint -save -e9013 [15.7] There is no else because it is not needed.*/ + if (objp != NULL) { + mp->next = mp->next->next; + } + else if (mp->provider != NULL) { + objp = mp->provider(mp->object_size, PORT_NATURAL_ALIGN); /* TODO: Alignment is not properly handled */ + } + /*lint -restore*/ + + return objp; +} + +/** + * @brief Allocates an object from a memory pool. + * @pre The memory pool must be already been initialized. + * + * @param[in] mp pointer to a @p memory_pool_t structure + * @return The pointer to the allocated object. + * @retval NULL if pool is empty. + * + * @api + */ +void *chPoolAlloc(memory_pool_t *mp) { + void *objp; + + chSysLock(); + objp = chPoolAllocI(mp); + chSysUnlock(); + + return objp; +} + +/** + * @brief Releases an object into a memory pool. + * @pre The memory pool must be already been initialized. + * @pre The freed object must be of the right size for the specified + * memory pool. + * @pre The object must be properly aligned to contain a pointer to void. + * + * @param[in] mp pointer to a @p memory_pool_t structure + * @param[in] objp the pointer to the object to be released + * + * @iclass + */ +void chPoolFreeI(memory_pool_t *mp, void *objp) { + struct pool_header *php = objp; + + chDbgCheckClassI(); + chDbgCheck((mp != NULL) && (objp != NULL)); + + php->next = mp->next; + mp->next = php; +} + +/** + * @brief Releases an object into a memory pool. + * @pre The memory pool must be already been initialized. + * @pre The freed object must be of the right size for the specified + * memory pool. + * @pre The object must be properly aligned to contain a pointer to void. + * + * @param[in] mp pointer to a @p memory_pool_t structure + * @param[in] objp the pointer to the object to be released + * + * @api + */ +void chPoolFree(memory_pool_t *mp, void *objp) { + + chSysLock(); + chPoolFreeI(mp, objp); + chSysUnlock(); +} + +#endif /* CH_CFG_USE_MEMPOOLS == TRUE */ + +/** @} */ diff --git a/os/nil/templates/nilcore.c b/os/common/ports/ARM/chcore.c similarity index 93% rename from os/nil/templates/nilcore.c rename to os/common/ports/ARM/chcore.c index 7bbb020fa..ae495ae2c 100644 --- a/os/nil/templates/nilcore.c +++ b/os/common/ports/ARM/chcore.c @@ -18,14 +18,14 @@ */ /** - * @file templates/nilcore.c - * @brief Port code. + * @file ARM/chcore.c + * @brief ARM port code. * - * @addtogroup NIL_CORE + * @addtogroup ARM_CORE * @{ */ -#include "nil.h" +#include "ch.h" /*===========================================================================*/ /* Module local definitions. */ diff --git a/os/common/ports/ARM/chcore.h b/os/common/ports/ARM/chcore.h new file mode 100644 index 000000000..c83d19e23 --- /dev/null +++ b/os/common/ports/ARM/chcore.h @@ -0,0 +1,564 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file ARM/chcore.h + * @brief ARM7/9 architecture port macros and structures. + * + * @addtogroup ARM_CORE + * @{ + */ + +#ifndef _CHCORE_H_ +#define _CHCORE_H_ + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/** + * @name Port Capabilities and Constants + * @{ + */ +/** + * @brief This port supports a realtime counter. + */ +#define PORT_SUPPORTS_RT FALSE + +/** + * @brief Natural alignment constant. + * @note It is the minimum alignment for pointer-size variables. + */ +#define PORT_NATURAL_ALIGN sizeof (void *) + +/** + * @brief Stack alignment constant. + * @note It is the alignement required for the stack pointer. + */ +#define PORT_STACK_ALIGN sizeof (stkalign_t) + +/** + * @brief Working Areas alignment constant. + * @note It is the alignment to be enforced for thread working areas. + */ +#define PORT_WORKING_AREA_ALIGN sizeof (stkalign_t) +/** @} */ + +/** + * @name Architecture and Compiler + * @{ + */ +/** + * @brief Macro defining a generic ARM architecture. + */ +#define PORT_ARCHITECTURE_ARM + +/* The following code is not processed when the file is included from an + asm module because those intrinsic macros are not necessarily defined + by the assembler too.*/ +#if !defined(_FROM_ASM_) + +/** + * @brief Compiler name and version. + */ +#if defined(__GNUC__) || defined(__DOXYGEN__) +#define PORT_COMPILER_NAME "GCC " __VERSION__ + +#else +#error "unsupported compiler" +#endif + +#endif /* !defined(_FROM_ASM_) */ +/** @} */ + +/** + * @name ARM variants + * @{ + */ +#define ARM_CORE_ARM7TDMI 7 +#define ARM_CORE_ARM9 9 +#define ARM_CORE_CORTEX_A8 108 +#define ARM_CORE_CORTEX_A9 109 +/** @} */ + +/* Inclusion of the ARM implementation specific parameters.*/ +#include "armparams.h" + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief Enables an alternative timer implementation. + * @details Usually the port uses a timer interface defined in the file + * @p chcore_timer.h, if this option is enabled then the file + * @p chcore_timer_alt.h is included instead. + */ +#if !defined(PORT_USE_ALT_TIMER) +#define PORT_USE_ALT_TIMER FALSE +#endif + +/** + * @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 PORT_INT_REQUIRED_STACK. + * @note In this port it is set to 32 because the idle thread does have + * a stack frame when compiling without optimizations. You may + * reduce this value to zero when compiling with optimizations. + */ +#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__) +#define PORT_IDLE_THREAD_STACK_SIZE 32 +#endif + +/** + * @brief Per-thread stack overhead for interrupts servicing. + * @details This constant is used in the calculation of the correct working + * area size. + */ +#if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__) +#define PORT_INT_REQUIRED_STACK 32 +#endif + +/** + * @brief If enabled allows the idle thread to enter a low power mode. + */ +#ifndef ARM_ENABLE_WFI_IDLE +#define ARM_ENABLE_WFI_IDLE FALSE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* The following code is not processed when the file is included from an + asm module.*/ +#if !defined(_FROM_ASM_) + +/* ARM core check.*/ +#if (ARM_CORE == ARM_CORE_ARM7TDMI) || defined(__DOXYGEN__) +#define PORT_ARCHITECTURE_ARM_ARM7 +#define PORT_ARCHITECTURE_NAME "ARMv4T" +#define PORT_CORE_VARIANT_NAME "ARM7" + +#elif ARM_CORE == ARM_CORE_ARM9 +#define PORT_ARCHITECTURE_ARM_ARM9 +#define PORT_ARCHITECTURE_NAME "ARMv5T" +#define PORT_CORE_VARIANT_NAME "ARM9" + +#elif ARM_CORE == ARM_CORE_CORTEX_A8 +#define PORT_ARCHITECTURE_ARM_CORTEXA8 +#define PORT_ARCHITECTURE_NAME "ARMv7" +#define PORT_CORE_VARIANT_NAME "ARM Cortex-A8" + +#elif ARM_CORE == ARM_CORE_CORTEX_A9 +#define PORT_ARCHITECTURE_ARM_CORTEXA9 +#define PORT_ARCHITECTURE_NAME "ARMv7" +#define PORT_CORE_VARIANT_NAME "ARM Cortex-A9" + +#else +#error "unknown or unsupported ARM core" +#endif + +#if defined(THUMB_PRESENT) +#if defined(THUMB_NO_INTERWORKING) +#define PORT_INFO "Pure THUMB mode" +#else +#define PORT_INFO "Interworking mode" +#endif +#else +#define PORT_INFO "Pure ARM mode" +#endif + +#endif /* !defined(_FROM_ASM_) */ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/* The following code is not processed when the file is included from an + asm module.*/ +#if !defined(_FROM_ASM_) + +/** + * @brief Type of stack and memory alignment enforcement. + * @note In this architecture the stack alignment is enforced to 64 bits. + */ +typedef uint64_t stkalign_t; + +/** + * @brief Generic ARM register. + */ +typedef void *regarm_t; + +/** + * @brief Interrupt saved context. + * @details This structure represents the stack frame saved during an + * interrupt handler. + */ +struct port_extctx { + regarm_t spsr_irq; + regarm_t lr_irq; + regarm_t r0; + regarm_t r1; + regarm_t r2; + regarm_t r3; + regarm_t r12; + regarm_t lr_usr; +}; + +/** + * @brief System saved context. + * @details This structure represents the inner stack frame during a context + * switch. + */ +struct port_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; +}; + +/** + * @brief Platform dependent part of the @p thread_t structure. + * @details In this port the structure just holds a pointer to the + * @p port_intctx structure representing the stack pointer + * at context switch time. + */ +struct port_context { + struct port_intctx *r13; +}; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Platform dependent part of the @p chThdCreateI() API. + * @details This code usually setup the context switching frame represented + * by an @p port_intctx structure. + */ +#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \ + (tp)->ctx.r13 = (struct port_intctx *)((uint8_t *)(wtop) - \ + sizeof (struct port_intctx)); \ + (tp)->ctx.r13->r4 = (regarm_t)(pf); \ + (tp)->ctx.r13->r5 = (regarm_t)(arg); \ + (tp)->ctx.r13->lr = (regarm_t)(_port_thread_start); \ +} + +/** + * @brief Computes the thread working area global size. + * @note There is no need to perform alignments in this macro. + */ +#define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \ + sizeof(struct port_extctx) + \ + ((size_t)(n)) + ((size_t)(PORT_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. + * + * @param[in] s the name to be assigned to the stack array + * @param[in] n the stack size to be assigned to the thread + */ +#define PORT_WORKING_AREA(s, n) \ + stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)] + +/** + * @brief Priority level verification macro. + * @todo Add the required parameters to armparams.h. + */ +#define PORT_IRQ_IS_VALID_PRIORITY(n) false + +/** + * @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() return chSchIsPreemptionRequired() + +/** + * @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) bool id(void) + +/** + * @brief Fast IRQ handler function declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + */ +#define PORT_FAST_IRQ_HANDLER(id) \ + __attribute__((interrupt("FIQ"))) void id(void) + +/** + * @brief Performs a context switch between two threads. + * @details This is the most critical code in any port, this function + * is responsible for the context switch between 2 threads. + * @note The implementation of this code affects directly the context + * switch performance so optimize here as much as you can. + * @note Implemented as inlined code for performance reasons. + * + * @param[in] ntp the thread to be switched in + * @param[in] otp the thread to be switched out + */ +#if defined(THUMB) + +#if CH_DBG_ENABLE_STACK_CHECK == TRUE +#define port_switch(ntp, otp) { \ + register struct port_intctx *r13 asm ("r13"); \ + if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \ + chSysHalt("stack overflow"); \ + _port_switch_thumb(ntp, otp); \ +} +#else +#define port_switch(ntp, otp) _port_switch_thumb(ntp, otp) +#endif + +#else /* !defined(THUMB) */ + +#if CH_DBG_ENABLE_STACK_CHECK == TRUE +#define port_switch(ntp, otp) { \ + register struct port_intctx *r13 asm ("r13"); \ + if ((stkalign_t *)(r13 - 1) < otp->stklimit) \ + chSysHalt("stack overflow"); \ + _port_switch_arm(ntp, otp); \ +} +#else +#define port_switch(ntp, otp) _port_switch_arm(ntp, otp) +#endif + +#endif /* !defined(THUMB) */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +#if defined(THUMB_PRESENT) + syssts_t _port_get_cpsr(void); +#endif +#if defined(THUMB) + void _port_switch_thumb(thread_t *ntp, thread_t *otp); +#else + void _port_switch_arm(thread_t *ntp, thread_t *otp); +#endif + void _port_thread_start(void); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Port-related initialization code. + */ +static inline void port_init(void) { + +} + +/** + * @brief Returns a word encoding the current interrupts status. + * + * @return The interrupts status. + */ +static inline syssts_t port_get_irq_status(void) { + syssts_t sts; + +#if defined(THUMB) + sts = _port_get_cpsr(); +#else + __asm volatile ("mrs %[p0], CPSR" : [p0] "=r" (sts) :); +#endif + /*lint -save -e530 [9.1] Asm instruction not seen by lint.*/ + return sts; + /*lint -restore*/ +} + +/** + * @brief Checks the interrupt status. + * + * @param[in] sts the interrupt status word + * + * @return The interrupt status. + * @retval false the word specified a disabled interrupts status. + * @retval true the word specified an enabled interrupts status. + */ +static inline bool port_irq_enabled(syssts_t sts) { + + return (sts & (syssts_t)0x80) == (syssts_t)0; +} + +/** + * @brief Determines the current execution context. + * + * @return The execution context. + * @retval false not running in ISR mode. + * @retval true running in ISR mode. + */ +static inline bool port_is_isr_context(void) { + syssts_t sts; + +#if defined(THUMB) + sts = _port_get_cpsr(); +#else + __asm volatile ("mrs %[p0], CPSR" : [p0] "=r" (sts) :); +#endif + + /*lint -save -e530 [9.1] Asm instruction not seen by lint.*/ + return (sts & (syssts_t)0x1F) == (syssts_t)0x12; + /*lint -restore*/ +} + +/** + * @brief Kernel-lock action. + * @details In this port it disables the IRQ sources and keeps FIQ sources + * enabled. + */ +static inline void port_lock(void) { + +#if defined(THUMB) + __asm volatile ("bl _port_lock_thumb" : : : "r3", "lr", "memory"); +#else + __asm volatile ("msr CPSR_c, #0x9F" : : : "memory"); +#endif +} + +/** + * @brief Kernel-unlock action. + * @details In this port it enables both the IRQ and FIQ sources. + */ +static inline void port_unlock(void) { + +#if defined(THUMB) + __asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr", "memory"); +#else + __asm volatile ("msr CPSR_c, #0x1F" : : : "memory"); +#endif +} + +/** + * @brief Kernel-lock action from an interrupt handler. + * @note Empty in this port. + */ +static inline void port_lock_from_isr(void) { + +} + +/** + * @brief Kernel-unlock action from an interrupt handler. + * @note Empty in this port. + */ +static inline void port_unlock_from_isr(void) { + +} + +/** + * @brief Disables all the interrupt sources. + * @details In this port it disables both the IRQ and FIQ sources. + * @note Implements a workaround for spurious interrupts taken from the NXP + * LPC214x datasheet. + */ +static inline void port_disable(void) { + +#if defined(THUMB) + __asm volatile ("bl _port_disable_thumb" : : : "r3", "lr", "memory"); +#else + __asm volatile ("mrs r3, CPSR \n\t" + "orr r3, #0x80 \n\t" + "msr CPSR_c, r3 \n\t" + "orr r3, #0x40 \n\t" + "msr CPSR_c, r3" : : : "r3", "memory"); +#endif +} + +/** + * @brief Disables the interrupt sources below kernel-level priority. + * @note Interrupt sources above kernel level remains enabled. + * @note In this port it disables the IRQ sources and enables the + * FIQ sources. + */ +static inline void port_suspend(void) { + +#if defined(THUMB) + __asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr", "memory"); +#else + __asm volatile ("msr CPSR_c, #0x9F" : : : "memory"); +#endif +} + +/** + * @brief Enables all the interrupt sources. + * @note In this port it enables both the IRQ and FIQ sources. + */ +static inline void port_enable(void) { + +#if defined(THUMB) + __asm volatile ("bl _port_enable_thumb" : : : "r3", "lr", "memory"); +#else + __asm volatile ("msr CPSR_c, #0x1F" : : : "memory"); +#endif +} + +/** + * @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. + */ +static inline void port_wait_for_interrupt(void) { + +#if ARM_ENABLE_WFI_IDLE == TRUE + ARM_WFI_IMPL; +#endif +} + +#if CH_CFG_ST_TIMEDELTA > 0 +#if PORT_USE_ALT_TIMER == FALSE +#include "chcore_timer.h" +#else /* PORT_USE_ALT_TIMER */ +#include "chcore_timer_alt.h" +#endif /* PORT_USE_ALT_TIMER */ +#endif /* CH_CFG_ST_TIMEDELTA > 0 */ + +#endif /* !defined(_FROM_ASM_) */ + +#endif /* _CHCORE_H_ */ + +/** @} */ diff --git a/os/nil/templates/nilcore_timer.h b/os/common/ports/ARM/chcore_timer.h similarity index 81% rename from os/nil/templates/nilcore_timer.h rename to os/common/ports/ARM/chcore_timer.h index 6eab4dd40..07f6e09a0 100644 --- a/os/nil/templates/nilcore_timer.h +++ b/os/common/ports/ARM/chcore_timer.h @@ -18,15 +18,18 @@ */ /** - * @file templates/nilcore_timer.h + * @file chcore_timer.h * @brief System timer header file. * - * @addtogroup NIL_TIMER + * @addtogroup ARM_TIMER * @{ */ -#ifndef _NILCORE_TIMER_H_ -#define _NILCORE_TIMER_H_ +#ifndef _CHCORE_TIMER_H_ +#define _CHCORE_TIMER_H_ + +/* This is the only header in the HAL designed to be include-able alone.*/ +#include "st.h" /*===========================================================================*/ /* Module constants. */ @@ -61,13 +64,13 @@ * @note Makes sure that no spurious alarms are triggered after * this call. * - * @param[in] abstime the time to be set for the first alarm + * @param[in] time the time to be set for the first alarm * * @notapi */ -static inline void port_timer_start_alarm(systime_t abstime) { +static inline void port_timer_start_alarm(systime_t time) { - (void)abstime; + stStartAlarm(time); } /** @@ -77,18 +80,19 @@ static inline void port_timer_start_alarm(systime_t abstime) { */ static inline void port_timer_stop_alarm(void) { + stStopAlarm(); } /** * @brief Sets the alarm time. * - * @param[in] abstime the time to be set for the next alarm + * @param[in] time the time to be set for the next alarm * * @notapi */ -static inline void port_timer_set_alarm(systime_t abstime) { +static inline void port_timer_set_alarm(systime_t time) { - (void)abstime; + stSetAlarm(time); } /** @@ -100,7 +104,7 @@ static inline void port_timer_set_alarm(systime_t abstime) { */ static inline systime_t port_timer_get_time(void) { - return (systime_t)0; + return stGetCounter(); } /** @@ -112,9 +116,9 @@ static inline systime_t port_timer_get_time(void) { */ static inline systime_t port_timer_get_alarm(void) { - return (systime_t)0; + return stGetAlarm(); } -#endif /* _NILCORE_TIMER_H_ */ +#endif /* _CHCORE_TIMER_H_ */ /** @} */ diff --git a/os/common/ports/ARM/compilers/GCC/chcoreasm.s b/os/common/ports/ARM/compilers/GCC/chcoreasm.s new file mode 100644 index 000000000..f4cc740c8 --- /dev/null +++ b/os/common/ports/ARM/compilers/GCC/chcoreasm.s @@ -0,0 +1,303 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file ARM/compilers/GCC/chcoreasm.s + * @brief ARM architecture port low level code. + * + * @addtogroup ARM_CORE + * @{ + */ + +#define _FROM_ASM_ +#include "chconf.h" +#include "armparams.h" + +#define FALSE 0 +#define TRUE 1 + +#if !defined(__DOXYGEN__) + +/* + * RTOS-specific context offset. + */ +#if defined(_CHIBIOS_RT_CONF_) +#define CONTEXT_OFFSET 12 +#elif defined(_CHIBIOS_NIL_CONF_) +#define CONTEXT_OFFSET 0 +#else +#error "invalid chconf.h" +#endif + + .set MODE_USR, 0x10 + .set MODE_FIQ, 0x11 + .set MODE_IRQ, 0x12 + .set MODE_SVC, 0x13 + .set MODE_ABT, 0x17 + .set MODE_UND, 0x1B + .set MODE_SYS, 0x1F + + .equ I_BIT, 0x80 + .equ F_BIT, 0x40 + + .text + +/* + * The following functions are only present if there is THUMB code in + * the system. + */ +#if defined(THUMB_PRESENT) + .balign 16 + .code 16 + .thumb_func + .global _port_get_cpsr +_port_get_cpsr: + mov r0, pc + bx r0 +.code 32 + mrs r0, CPSR + bx lr + + .balign 16 + .code 16 + .thumb_func + .global _port_disable_thumb +_port_disable_thumb: + mov r3, pc + bx r3 +.code 32 + mrs r3, CPSR + orr r3, #I_BIT + msr CPSR_c, r3 + orr r3, #F_BIT + msr CPSR_c, r3 + bx lr + + .balign 16 + .code 16 + .thumb_func + .global _port_suspend_thumb +_port_suspend_thumb: + // Goes into _port_unlock_thumb + + .code 16 + .global _port_lock_thumb +_port_lock_thumb: + mov r3, pc + bx r3 + .code 32 + msr CPSR_c, #MODE_SYS | I_BIT + bx lr + + .balign 16 + .code 16 + .thumb_func + .global _port_enable_thumb +_port_enable_thumb: + // Goes into _port_unlock_thumb + + .code 16 + .global _port_unlock_thumb +_port_unlock_thumb: + mov r3, pc + bx r3 + .code 32 + msr CPSR_c, #MODE_SYS + bx lr +#endif /* defined(THUMB_PRESENT) */ + + .balign 16 +#if defined(THUMB_PRESENT) + .code 16 + .thumb_func + .global _port_switch_thumb +_port_switch_thumb: + mov r2, pc + bx r2 + // Goes into _port_switch_arm in ARM mode +#endif /* defined(THUMB_PRESENT) */ + + .code 32 + .global _port_switch_arm +_port_switch_arm: + stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr} + str sp, [r1, #12] + ldr sp, [r0, #12] +#if defined(THUMB_PRESENT) + ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr} + bx lr +#else /* !defined(THUMB_PRESENT)T */ + ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc} +#endif /* !defined(THUMB_PRESENT) */ + +/* + * Common IRQ code. It expects a macro ARM_IRQ_VECTOR_REG with the address + * of a register holding the address of the ISR to be invoked, the ISR + * then returns in the common epilogue code where the context switch will + * be performed, if required. + * System stack frame structure after a context switch in the + * interrupt handler: + * + * High +------------+ + * | LR_USR | -+ + * | r12 | | + * | r3 | | + * | r2 | | External context: IRQ handler frame + * | r1 | | + * | r0 | | + * | LR_IRQ | | (user code return address) + * | PSR_USR | -+ (user code status) + * | .... | <- chSchDoReschedule() stack frame, optimize it for space + * | LR | -+ (system code return address) + * | r11 | | + * | r10 | | + * | r9 | | + * | r8 | | Internal context: chSysSwitch() frame + * | r7 | | + * | r6 | | + * | r5 | | + * SP-> | r4 | -+ + * Low +------------+ + */ + .balign 16 + .code 32 + .global Irq_Handler +Irq_Handler: + stmfd sp!, {r0-r3, r12, lr} + ldr r0, =ARM_IRQ_VECTOR_REG + ldr r0, [r0] +#if !defined(THUMB_NO_INTERWORKING) + ldr lr, =_irq_ret_arm // ISR return point. + bx r0 // Calling the ISR. +_irq_ret_arm: +#else /* defined(THUMB_NO_INTERWORKING) */ + add r1, pc, #1 + bx r1 + .code 16 + bl _bxr0 // Calling the ISR. + mov lr, pc + bx lr + .code 32 +#endif /* defined(THUMB_NO_INTERWORKING) */ + cmp r0, #0 + ldmfd sp!, {r0-r3, r12, lr} + subeqs pc, lr, #4 // No reschedule, returns. + + // Now the frame is created in the system stack, the IRQ + // stack is empty. + msr CPSR_c, #MODE_SYS | I_BIT + stmfd sp!, {r0-r3, r12, lr} + msr CPSR_c, #MODE_IRQ | I_BIT + mrs r0, SPSR + mov r1, lr + msr CPSR_c, #MODE_SYS | I_BIT + stmfd sp!, {r0, r1} // Push R0=SPSR, R1=LR_IRQ. + + // Context switch. +#if defined(THUMB_NO_INTERWORKING) + add r0, pc, #1 + bx r0 + .code 16 +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_lock +#endif + bl chSchDoReschedule +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif + mov lr, pc + bx lr + .code 32 +#else /* !defined(THUMB_NO_INTERWORKING) */ +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_lock +#endif + bl chSchDoReschedule +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#endif /* !defined(THUMB_NO_INTERWORKING) */ + + // Re-establish the IRQ conditions again. + ldmfd sp!, {r0, r1} // Pop R0=SPSR, R1=LR_IRQ. + msr CPSR_c, #MODE_IRQ | I_BIT + msr SPSR_fsxc, r0 + mov lr, r1 + msr CPSR_c, #MODE_SYS | I_BIT + ldmfd sp!, {r0-r3, r12, lr} + msr CPSR_c, #MODE_IRQ | I_BIT + subs pc, lr, #4 +#if defined(THUMB_NO_INTERWORKING) + .code 16 +_bxr0: bx r0 +#endif + +/* + * Threads trampoline code. + * NOTE: The threads always start in ARM mode and then switches to the + * thread-function mode. + */ + .balign 16 + .code 32 + .globl _port_thread_start +_port_thread_start: +#if defined(THUMB_NO_INTERWORKING) + add r0, pc, #1 + bx r0 + .code 16 +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif + bl _port_unlock_thumb + mov r0, r5 + bl _bxr4 +#if defined(_CHIBIOS_RT_CONF_) + mov r0, #0 /* MSG_OK */ + bl chThdExit +_zombies: b _zombies +#endif +#if defined(_CHIBIOS_NIL_CONF_) + mov r0, #0 + bl chSysHalt +#endif +_bxr4: bx r4 + +#else /* !defined(THUMB_NO_INTERWORKING) */ +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif + msr CPSR_c, #MODE_SYS + mov r0, r5 + mov lr, pc + bx r4 +#if defined(_CHIBIOS_RT_CONF_) + mov r0, #0 /* MSG_OK */ + bl chThdExit +_zombies: b _zombies +#endif +#if defined(_CHIBIOS_NIL_CONF_) + mov r0, #0 + bl chSysHalt +#endif + +#endif /* !defined(THUMB_NO_INTERWORKING) */ + +#endif /* !defined(__DOXYGEN__) */ + +/** @} */ diff --git a/os/nil/templates/niltypes.h b/os/common/ports/ARM/compilers/GCC/chtypes.h similarity index 52% rename from os/nil/templates/niltypes.h rename to os/common/ports/ARM/compilers/GCC/chtypes.h index 16043831b..5ea352765 100644 --- a/os/nil/templates/niltypes.h +++ b/os/common/ports/ARM/compilers/GCC/chtypes.h @@ -18,15 +18,15 @@ */ /** - * @file templates/niltypes.h - * @brief Port system types. + * @file ARM/compilers/GCC/chtypes.h + * @brief ARM port system types. * - * @addtogroup NIL_TYPES + * @addtogroup ARM_GCC_CORE * @{ */ -#ifndef _NILTYPES_H_ -#define _NILTYPES_H_ +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ #include #include @@ -39,33 +39,36 @@ * @brief Generic 'false' boolean constant. */ #if !defined(FALSE) || defined(__DOXYGEN__) -#define FALSE 0 +#define FALSE 0 #endif /** * @brief Generic 'true' boolean constant. */ #if !defined(TRUE) || defined(__DOXYGEN__) -#define TRUE 1 +#define TRUE 1 #endif /** @} */ -typedef uint32_t syssts_t; /**< System status word. */ -typedef uint32_t rtcnt_t; /**< Realtime counter. */ -typedef uint8_t tstate_t; /**< Thread state. */ -typedef int32_t msg_t; /**< Inter-thread message. */ -typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ -typedef int32_t cnt_t; /**< Generic signed counter. */ -typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ - /** - * @brief Type of system time. + * @name Kernel types + * @{ */ -#if (NIL_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__) -typedef uint32_t systime_t; -#else -typedef uint16_t systime_t; -#endif +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint32_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint32_t tprio_t; /**< Thread priority. */ +typedef int32_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint32_t eventflags_t; /**< Mask of event flags. */ +typedef int32_t cnt_t; /**< Generic signed counter. */ +typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ /** * @brief ROM constant modifier. @@ -83,14 +86,13 @@ typedef uint16_t systime_t; /** * @brief Optimized thread function declaration macro. */ -#define PORT_THD_FUNCTION(tname, arg) \ - __attribute__((noreturn)) void tname(void *arg) +#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg) /** * @brief Packed variable specifier. */ #define PACKED_VAR __attribute__((packed)) -#endif /* _NILTYPES_H_ */ +#endif /* _CHTYPES_H_ */ /** @} */ diff --git a/os/common/ports/ARM/compilers/GCC/mk/port_generic.mk b/os/common/ports/ARM/compilers/GCC/mk/port_generic.mk new file mode 100644 index 000000000..5762f96a0 --- /dev/null +++ b/os/common/ports/ARM/compilers/GCC/mk/port_generic.mk @@ -0,0 +1,7 @@ +# List of the ChibiOS/RT ARM generic port files. +PORTSRC = ${CHIBIOS}/os/common/ports/ARM/chcore.c + +PORTASM = $(CHIBIOS)/os/common/ports/ARM/compilers/GCC/chcoreasm.s + +PORTINC = ${CHIBIOS}/os/common/ports/ARM \ + ${CHIBIOS}/os/common/ports/ARM/compilers/GCC diff --git a/os/nil/ports/ARMCMx/nilcore.c b/os/common/ports/ARMCMx/chcore.c similarity index 95% rename from os/nil/ports/ARMCMx/nilcore.c rename to os/common/ports/ARMCMx/chcore.c index 7d7738029..81c61c505 100644 --- a/os/nil/ports/ARMCMx/nilcore.c +++ b/os/common/ports/ARMCMx/chcore.c @@ -18,14 +18,14 @@ */ /** - * @file ARMCMx/nilcore.c + * @file ARMCMx/chcore.c * @brief ARM Cortex-Mx port code. * * @addtogroup ARMCMx_CORE * @{ */ -#include "nil.h" +#include "ch.h" /*===========================================================================*/ /* Module local definitions. */ diff --git a/os/nil/ports/ARMCMx/nilcore.h b/os/common/ports/ARMCMx/chcore.h similarity index 87% rename from os/nil/ports/ARMCMx/nilcore.h rename to os/common/ports/ARMCMx/chcore.h index 21b5a0535..16743bbdf 100644 --- a/os/nil/ports/ARMCMx/nilcore.h +++ b/os/common/ports/ARMCMx/chcore.h @@ -18,15 +18,15 @@ */ /** - * @file ARMCMx/nilcore.h + * @file ARMCMx/chcore.h * @brief ARM Cortex-Mx port macros and structures. * * @addtogroup ARMCMx_CORE * @{ */ -#ifndef _NILCORE_H_ -#define _NILCORE_H_ +#ifndef _CHCORE_H_ +#define _CHCORE_H_ /*===========================================================================*/ /* Module constants. */ @@ -76,8 +76,8 @@ /** * @brief Enables an alternative timer implementation. * @details Usually the port uses a timer interface defined in the file - * @p nilcore_timer.h, if this option is enabled then the file - * @p nilcore_timer_alt.h is included instead. + * @p chcore_timer.h, if this option is enabled then the file + * @p chcore_timer_alt.h is included instead. */ #if !defined(PORT_USE_ALT_TIMER) #define PORT_USE_ALT_TIMER FALSE @@ -128,6 +128,16 @@ struct port_extctx {}; struct port_intctx {}; #endif /* defined(__DOXYGEN__) */ +/** + * @brief Platform dependent part of the @p thread_t structure. + * @details In this port the structure just holds a pointer to the + * @p port_intctx structure representing the stack pointer + * at context switch time. + */ +struct port_context { + struct port_intctx *r13; +}; + #endif /* !defined(_FROM_ASM_) */ /*===========================================================================*/ @@ -180,25 +190,26 @@ struct port_intctx {}; /* Includes the sub-architecture-specific part.*/ #if (CORTEX_MODEL == 0) || (CORTEX_MODEL == 1) -#include "nilcore_v6m.h" +#include "chcore_v6m.h" #elif (CORTEX_MODEL == 3) || (CORTEX_MODEL == 4) || (CORTEX_MODEL == 7) -#include "nilcore_v7m.h" +#include "mpu.h" +#include "chcore_v7m.h" #else #error "unknown Cortex-M variant" #endif #if !defined(_FROM_ASM_) -#if NIL_CFG_ST_TIMEDELTA > 0 +#if CH_CFG_ST_TIMEDELTA > 0 #if PORT_USE_ALT_TIMER == FALSE -#include "nilcore_timer.h" +#include "chcore_timer.h" #else /* PORT_USE_ALT_TIMER != FALSE */ -#include "nilcore_timer_alt.h" +#include "chcore_timer_alt.h" #endif /* PORT_USE_ALT_TIMER != FALSE */ -#endif /* NIL_CFG_ST_TIMEDELTA > 0 */ +#endif /* CH_CFG_ST_TIMEDELTA > 0 */ #endif /* !defined(_FROM_ASM_) */ -#endif /* _NILCORE_H_ */ +#endif /* _CHCORE_H_ */ /** @} */ diff --git a/os/nil/ports/ARMCMx/nilcore_timer.h b/os/common/ports/ARMCMx/chcore_timer.h similarity index 93% rename from os/nil/ports/ARMCMx/nilcore_timer.h rename to os/common/ports/ARMCMx/chcore_timer.h index 2c7c98cf6..7d607a096 100644 --- a/os/nil/ports/ARMCMx/nilcore_timer.h +++ b/os/common/ports/ARMCMx/chcore_timer.h @@ -18,15 +18,15 @@ */ /** - * @file ARMCMx/nilcore_timer.h + * @file chcore_timer.h * @brief System timer header file. * * @addtogroup ARMCMx_TIMER * @{ */ -#ifndef _NILCORE_TIMER_H_ -#define _NILCORE_TIMER_H_ +#ifndef _CHCORE_TIMER_H_ +#define _CHCORE_TIMER_H_ /* This is the only header in the HAL designed to be include-able alone.*/ #include "st.h" @@ -119,6 +119,6 @@ static inline systime_t port_timer_get_alarm(void) { return stGetAlarm(); } -#endif /* _NILCORE_TIMER_H_ */ +#endif /* _CHCORE_TIMER_H_ */ /** @} */ diff --git a/os/nil/ports/ARMCMx/nilcore_v6m.c b/os/common/ports/ARMCMx/chcore_v6m.c similarity index 95% rename from os/nil/ports/ARMCMx/nilcore_v6m.c rename to os/common/ports/ARMCMx/chcore_v6m.c index 791062db3..b799a8724 100644 --- a/os/nil/ports/ARMCMx/nilcore_v6m.c +++ b/os/common/ports/ARMCMx/chcore_v6m.c @@ -18,14 +18,14 @@ */ /** - * @file nilcore_v6m.c + * @file chcore_v6m.c * @brief ARMv6-M architecture port code. * * @addtogroup ARMCMx_V6M_CORE * @{ */ -#include "nil.h" +#include "ch.h" /*===========================================================================*/ /* Module local definitions. */ @@ -129,7 +129,7 @@ void _port_irq_epilogue(regarm_t lr) { /* The exit sequence is different depending on if a preemption is required or not.*/ - if (chSchIsRescRequiredI()) { + if (chSchIsPreemptionRequired()) { /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; } diff --git a/os/nil/ports/ARMCMx/nilcore_v6m.h b/os/common/ports/ARMCMx/chcore_v6m.h similarity index 82% rename from os/nil/ports/ARMCMx/nilcore_v6m.h rename to os/common/ports/ARMCMx/chcore_v6m.h index 3a500d2b0..0ff3288b6 100644 --- a/os/nil/ports/ARMCMx/nilcore_v6m.h +++ b/os/common/ports/ARMCMx/chcore_v6m.h @@ -33,10 +33,33 @@ /*===========================================================================*/ /** - * @brief This port does not support a realtime counter. + * @name Port Capabilities and Constants + * @{ + */ +/** + * @brief This port supports a realtime counter. */ #define PORT_SUPPORTS_RT FALSE +/** + * @brief Natural alignment constant. + * @note It is the minimum alignment for pointer-size variables. + */ +#define PORT_NATURAL_ALIGN sizeof (void *) + +/** + * @brief Stack alignment constant. + * @note It is the alignement required for the stack pointer. + */ +#define PORT_STACK_ALIGN sizeof (stkalign_t) + +/** + * @brief Working Areas alignment constant. + * @note It is the alignment to be enforced for thread working areas. + */ +#define PORT_WORKING_AREA_ALIGN PORT_STACK_ALIGN +/** @} */ + /** * @brief PendSV priority level. * @note This priority is enforced to be equal to @p 0, @@ -66,13 +89,13 @@ * @brief Per-thread stack overhead for interrupts servicing. * @details This constant is used in the calculation of the correct working * area size. - * @note In this port this value is conservatively set to 32 because the + * @note In this port this value is conservatively set to 64 because the * function @p chSchDoReschedule() can have a stack frame, especially * with compiler optimizations disabled. The value can be reduced * when compiler optimizations are enabled. */ #if !defined(PORT_INT_REQUIRED_STACK) -#define PORT_INT_REQUIRED_STACK 32 +#define PORT_INT_REQUIRED_STACK 64 #endif /** @@ -179,26 +202,37 @@ struct port_intctx { /*===========================================================================*/ /** - * @brief Platform dependent thread stack setup. + * @brief Platform dependent part of the @p chThdCreateI() API. * @details This code usually setup the context switching frame represented * by an @p port_intctx structure. */ -#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \ - (tp)->ctxp = (struct port_intctx *)((uint8_t *)(wend) - \ - sizeof(struct port_intctx)); \ - (tp)->ctxp->r4 = (regarm_t)(pf); \ - (tp)->ctxp->r5 = (regarm_t)(arg); \ - (tp)->ctxp->lr = (regarm_t)_port_thread_start; \ +#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \ + (tp)->ctx.r13 = (struct port_intctx *)((uint8_t *)(wtop) - \ + sizeof (struct port_intctx)); \ + (tp)->ctx.r13->r4 = (regarm_t)(pf); \ + (tp)->ctx.r13->r5 = (regarm_t)(arg); \ + (tp)->ctx.r13->lr = (regarm_t)_port_thread_start; \ } /** * @brief Computes the thread working area global size. * @note There is no need to perform alignments in this macro. */ -#define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \ - sizeof(struct port_extctx) + \ +#define PORT_WA_SIZE(n) (sizeof (struct port_intctx) + \ + sizeof (struct port_extctx) + \ ((size_t)(n)) + ((size_t)(PORT_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. + * + * @param[in] s the name to be assigned to the stack array + * @param[in] n the stack size to be assigned to the thread + */ +#define PORT_WORKING_AREA(s, n) \ + stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)] + /** * @brief IRQ prologue code. * @details This macro must be inserted at the start of all IRQ handlers @@ -246,12 +280,12 @@ struct port_intctx { * @param[in] ntp the thread to be switched in * @param[in] otp the thread to be switched out */ -#if (NIL_CFG_ENABLE_STACK_CHECK == FALSE) || defined(__DOXYGEN__) +#if (CH_DBG_ENABLE_STACK_CHECK == FALSE) || defined(__DOXYGEN__) #define port_switch(ntp, otp) _port_switch(ntp, otp) #else #define port_switch(ntp, otp) { \ struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \ - if ((stkalign_t *)(r13 - 1) < (otp)->stklim) { \ + if ((stkalign_t *)(r13 - 1) < (otp)->stklimit) { \ chSysHalt("stack overflow"); \ } \ _port_switch(ntp, otp); \ @@ -266,10 +300,10 @@ struct port_intctx { extern "C" { #endif void _port_irq_epilogue(regarm_t lr); - void _port_switch_from_isr(void); - void _port_exit_from_isr(void); void _port_switch(thread_t *ntp, thread_t *otp); void _port_thread_start(void); + void _port_switch_from_isr(void); + void _port_exit_from_isr(void); #ifdef __cplusplus } #endif @@ -302,8 +336,8 @@ static inline syssts_t port_get_irq_status(void) { * @param[in] sts the interrupt status word * * @return The interrupt status. - * @retvel false the word specified a disabled interrupts status. - * @retvel true the word specified an enabled interrupts status. + * @retval false the word specified a disabled interrupts status. + * @retval true the word specified an enabled interrupts status. */ static inline bool port_irq_enabled(syssts_t sts) { diff --git a/os/nil/ports/ARMCMx/nilcore_v7m.c b/os/common/ports/ARMCMx/chcore_v7m.c similarity index 94% rename from os/nil/ports/ARMCMx/nilcore_v7m.c rename to os/common/ports/ARMCMx/chcore_v7m.c index c381fc3ef..82cbb1c32 100644 --- a/os/nil/ports/ARMCMx/nilcore_v7m.c +++ b/os/common/ports/ARMCMx/chcore_v7m.c @@ -18,14 +18,14 @@ */ /** - * @file nilcore_v7m.c + * @file chcore_v7m.c * @brief ARMv7-M architecture port code. * * @addtogroup ARMCMx_V7M_CORE * @{ */ -#include "nil.h" +#include "ch.h" /*===========================================================================*/ /* Module local definitions. */ @@ -63,7 +63,7 @@ void SVC_Handler(void) { /*lint -restore*/ struct port_extctx *ctxp; -#if CORTEX_USE_FPU == TRUE +#if CORTEX_USE_FPU /* Enforcing unstacking of the FP part of the context.*/ FPU->FPCCR &= ~FPU_FPCCR_LSPACT_Msk; #endif @@ -95,7 +95,7 @@ void PendSV_Handler(void) { /*lint -restore*/ struct port_extctx *ctxp; -#if CORTEX_USE_FPU == TRUE +#if CORTEX_USE_FPU /* Enforcing unstacking of the FP part of the context.*/ FPU->FPCCR &= ~FPU_FPCCR_LSPACT_Msk; #endif @@ -139,13 +139,16 @@ void _port_irq_epilogue(void) { /* Setting up a fake XPSR register value.*/ ctxp->xpsr = (regarm_t)0x01000000; +#if CORTEX_USE_FPU == TRUE + ctxp->fpscr = (regarm_t)FPU->FPDSCR; +#endif /* Writing back the modified PSP value.*/ __set_PSP((uint32_t)ctxp); /* The exit sequence is different depending on if a preemption is required or not.*/ - if (chSchIsRescRequiredI()) { + if (chSchIsPreemptionRequired()) { /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; } diff --git a/os/nil/ports/ARMCMx/nilcore_v7m.h b/os/common/ports/ARMCMx/chcore_v7m.h similarity index 70% rename from os/nil/ports/ARMCMx/nilcore_v7m.h rename to os/common/ports/ARMCMx/chcore_v7m.h index c9ffe87b8..3c0dfc4a1 100644 --- a/os/nil/ports/ARMCMx/nilcore_v7m.h +++ b/os/common/ports/ARMCMx/chcore_v7m.h @@ -25,18 +25,42 @@ * @{ */ -#ifndef _NILCORE_V7M_H_ -#define _NILCORE_V7M_H_ +#ifndef _CHCORE_V7M_H_ +#define _CHCORE_V7M_H_ /*===========================================================================*/ /* Module constants. */ /*===========================================================================*/ +/** + * @name Port Capabilities and Constants + * @{ + */ /** * @brief This port supports a realtime counter. */ #define PORT_SUPPORTS_RT TRUE +/** + * @brief Natural alignment constant. + * @note It is the minimum alignment for pointer-size variables. + */ +#define PORT_NATURAL_ALIGN sizeof (void *) + +/** + * @brief Stack alignment constant. + * @note It is the alignement required for the stack pointer. + */ +#define PORT_STACK_ALIGN sizeof (stkalign_t) + +/** + * @brief Working Areas alignment constant. + * @note It is the alignment to be enforced for thread working areas. + */ +#define PORT_WORKING_AREA_ALIGN (PORT_ENABLE_GUARD_PAGES == TRUE ? \ + 32U : PORT_STACK_ALIGN) +/** @} */ + /** * @brief Disabled value for BASEPRI register. */ @@ -46,6 +70,17 @@ /* Module pre-compile time settings. */ /*===========================================================================*/ +/** + * @brief Enables stack overflow guard pages using MPU. + * @note This option can only be enabled if also option + * @p CH_DBG_ENABLE_STACK_CHECK is enabled. + * @note The use of this option has an overhead of 32 bytes for each + * thread. + */ +#if !defined(PORT_ENABLE_GUARD_PAGES) || defined(__DOXYGEN__) +#define PORT_ENABLE_GUARD_PAGES FALSE +#endif + /** * @brief Stack size for the system idle thread. * @details This size depends on the idle thread implementation, usually @@ -63,13 +98,13 @@ * @brief Per-thread stack overhead for interrupts servicing. * @details This constant is used in the calculation of the correct working * area size. - * @note In this port this value is conservatively set to 32 because the + * @note In this port this value is conservatively set to 64 because the * function @p chSchDoReschedule() can have a stack frame, especially * with compiler optimizations disabled. The value can be reduced * when compiler optimizations are enabled. */ #if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__) -#define PORT_INT_REQUIRED_STACK 32 +#define PORT_INT_REQUIRED_STACK 64 #endif /** @@ -135,6 +170,23 @@ /* Derived constants and error checks. */ /*===========================================================================*/ +#if !defined(_FROM_ASM_) +/** + * @brief MPU guard page size. + */ +#if (PORT_ENABLE_GUARD_PAGES == TRUE) || defined(__DOXYGEN__) + #if CH_DBG_ENABLE_STACK_CHECK == FALSE + #error "PORT_ENABLE_GUARD_PAGES requires CH_DBG_ENABLE_STACK_CHECK" + #endif + #if __MPU_PRESENT == 0 + #error "MPU not present in current device" + #endif + #define PORT_GUARD_PAGE_SIZE 32U +#else + #define PORT_GUARD_PAGE_SIZE 0U +#endif +#endif /* !defined(_FROM_ASM_) */ + /** * @name Architecture and Compiler * @{ @@ -153,25 +205,45 @@ /** * @brief Name of the architecture variant. */ -#define PORT_CORE_VARIANT_NAME "Cortex-M3" +#if (PORT_ENABLE_GUARD_PAGES == FALSE) || defined(__DOXYGEN__) + #define PORT_CORE_VARIANT_NAME "Cortex-M3" +#else + #define PORT_CORE_VARIANT_NAME "Cortex-M3 (MPU)" +#endif #elif (CORTEX_MODEL == 4) -#define PORT_ARCHITECTURE_ARM_v7ME -#define PORT_ARCHITECTURE_NAME "ARMv7E-M" -#if CORTEX_USE_FPU -#define PORT_CORE_VARIANT_NAME "Cortex-M4F" -#else -#define PORT_CORE_VARIANT_NAME "Cortex-M4" -#endif + #define PORT_ARCHITECTURE_ARM_v7ME + #define PORT_ARCHITECTURE_NAME "ARMv7E-M" + #if CORTEX_USE_FPU + #if PORT_ENABLE_GUARD_PAGES == FALSE + #define PORT_CORE_VARIANT_NAME "Cortex-M4F" + #else + #define PORT_CORE_VARIANT_NAME "Cortex-M4F (MPU)" + #endif + #else + #if PORT_ENABLE_GUARD_PAGES == FALSE + #define PORT_CORE_VARIANT_NAME "Cortex-M4" + #else + #define PORT_CORE_VARIANT_NAME "Cortex-M4 (MPU)" + #endif + #endif #elif (CORTEX_MODEL == 7) -#define PORT_ARCHITECTURE_ARM_v7ME -#define PORT_ARCHITECTURE_NAME "ARMv7E-M" -#if CORTEX_USE_FPU -#define PORT_CORE_VARIANT_NAME "Cortex-M7F" -#else -#define PORT_CORE_VARIANT_NAME "Cortex-M7" -#endif + #define PORT_ARCHITECTURE_ARM_v7ME + #define PORT_ARCHITECTURE_NAME "ARMv7E-M" + #if CORTEX_USE_FPU + #if PORT_ENABLE_GUARD_PAGES == FALSE + #define PORT_CORE_VARIANT_NAME "Cortex-M7F" + #else + #define PORT_CORE_VARIANT_NAME "Cortex-M7F (MPU)" + #endif + #else + #if PORT_ENABLE_GUARD_PAGES == FALSE + #define PORT_CORE_VARIANT_NAME "Cortex-M7" + #else + #define PORT_CORE_VARIANT_NAME "Cortex-M7 (MPU)" + #endif + #endif #endif /** @@ -290,21 +362,39 @@ struct port_intctx { * @details This code usually setup the context switching frame represented * by an @p port_intctx structure. */ -#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \ - (tp)->ctxp = (struct port_intctx *)((uint8_t *)(wend) - \ - sizeof(struct port_intctx)); \ - (tp)->ctxp->r4 = (regarm_t)(pf); \ - (tp)->ctxp->r5 = (regarm_t)(arg); \ - (tp)->ctxp->lr = (regarm_t)_port_thread_start; \ +#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \ + (tp)->ctx.r13 = (struct port_intctx *)((uint8_t *)(wtop) - \ + sizeof (struct port_intctx)); \ + (tp)->ctx.r13->r4 = (regarm_t)(pf); \ + (tp)->ctx.r13->r5 = (regarm_t)(arg); \ + (tp)->ctx.r13->lr = (regarm_t)_port_thread_start; \ } /** * @brief Computes the thread working area global size. * @note There is no need to perform alignments in this macro. */ -#define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \ - sizeof(struct port_extctx) + \ - ((size_t)(n)) + ((size_t)(PORT_INT_REQUIRED_STACK))) +#define PORT_WA_SIZE(n) ((size_t)PORT_GUARD_PAGE_SIZE + \ + sizeof (struct port_intctx) + \ + sizeof (struct port_extctx) + \ + (size_t)(n) + \ + (size_t)PORT_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. + * + * @param[in] s the name to be assigned to the stack array + * @param[in] n the stack size to be assigned to the thread + */ +#if (PORT_ENABLE_GUARD_PAGES == FALSE) || defined(__DOXYGEN__) +#define PORT_WORKING_AREA(s, n) \ + stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)] +#else +#define PORT_WORKING_AREA(s, n) \ + ALIGNED_VAR(32) stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)] +#endif /** * @brief IRQ prologue code. @@ -344,16 +434,30 @@ struct port_intctx { * @param[in] ntp the thread to be switched in * @param[in] otp the thread to be switched out */ -#if (NIL_CFG_ENABLE_STACK_CHECK == FALSE) || defined(__DOXYGEN__) +#if (CH_DBG_ENABLE_STACK_CHECK == FALSE) || defined(__DOXYGEN__) #define port_switch(ntp, otp) _port_switch(ntp, otp) #else +#if PORT_ENABLE_GUARD_PAGES == FALSE #define port_switch(ntp, otp) { \ struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \ - if ((stkalign_t *)(r13 - 1) < (otp)->stklim) { \ + if ((stkalign_t *)(r13 - 1) < (otp)->stklimit) { \ chSysHalt("stack overflow"); \ } \ _port_switch(ntp, otp); \ } +#else +#define port_switch(ntp, otp) { \ + _port_switch(ntp, otp); \ + \ + /* Setting up the guard page for the switched-in thread.*/ \ + mpuConfigureRegion(MPU_REGION_0, \ + chThdGetSelfX()->stklimit, \ + MPU_RASR_ATTR_AP_NA_NA | \ + MPU_RASR_ATTR_NON_CACHEABLE | \ + MPU_RASR_SIZE_32 | \ + MPU_RASR_ENABLE); \ +} +#endif #endif /*===========================================================================*/ @@ -387,7 +491,7 @@ static inline void port_init(void) { /* Initializing priority grouping.*/ NVIC_SetPriorityGrouping(CORTEX_PRIGROUP_INIT); - /* DWT cycle counter enable.*/ + /* DWT cycle counter enable, note, the M7 requires DWT unlocking.*/ CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; #if CORTEX_MODEL == 7 DWT->LAR = 0xC5ACCE55U; @@ -399,6 +503,24 @@ static inline void port_init(void) { NVIC_SetPriority(SVCall_IRQn, CORTEX_PRIORITY_SVCALL); #endif NVIC_SetPriority(PendSV_IRQn, CORTEX_PRIORITY_PENDSV); + +#if PORT_ENABLE_GUARD_PAGES == TRUE + { + extern stkalign_t __main_thread_stack_base__; + + /* Setting up the guard page on the main() function stack base + initially.*/ + mpuConfigureRegion(MPU_REGION_0, + &__main_thread_stack_base__, + MPU_RASR_ATTR_AP_NA_NA | + MPU_RASR_ATTR_NON_CACHEABLE | + MPU_RASR_SIZE_32 | + MPU_RASR_ENABLE); + + /* MPU is enabled.*/ + mpuEnable(MPU_CTRL_PRIVDEFENA); + } +#endif } /** @@ -423,8 +545,8 @@ static inline syssts_t port_get_irq_status(void) { * @param[in] sts the interrupt status word * * @return The interrupt status. - * @retvel false the word specified a disabled interrupts status. - * @retvel true the word specified an enabled interrupts status. + * @retval false the word specified a disabled interrupts status. + * @retval true the word specified an enabled interrupts status. */ static inline bool port_irq_enabled(syssts_t sts) { @@ -456,13 +578,13 @@ static inline void port_lock(void) { #if CORTEX_SIMPLIFIED_PRIORITY == FALSE #if defined(__CM7_REV) -#if __CM7_REV == 0 +#if __CM7_REV <= 1 __disable_irq(); #endif #endif __set_BASEPRI(CORTEX_BASEPRI_KERNEL); #if defined(__CM7_REV) -#if __CM7_REV == 0 +#if __CM7_REV <= 1 __enable_irq(); #endif #endif @@ -571,6 +693,6 @@ static inline rtcnt_t port_rt_get_counter_value(void) { #endif /* !defined(_FROM_ASM_) */ -#endif /* _NILCORE_V7M_H_ */ +#endif /* _CHCORE_V7M_H_ */ /** @} */ diff --git a/os/common/ports/ARMCMx/cmsis_os/cmsis_os.c b/os/common/ports/ARMCMx/cmsis_os/cmsis_os.c new file mode 100644 index 000000000..df4b6ba31 --- /dev/null +++ b/os/common/ports/ARMCMx/cmsis_os/cmsis_os.c @@ -0,0 +1,554 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 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 . +*/ +/* + Concepts and parts of this file have been contributed by Andre R. + */ + +/** + * @file cmsis_os.c + * @brief CMSIS RTOS module code. + * + * @addtogroup CMSIS_OS + * @{ + */ + +#include "cmsis_os.h" +#include + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +int32_t cmsis_os_started; + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +static memory_pool_t sempool; +static semaphore_t semaphores[CMSIS_CFG_NUM_SEMAPHORES]; + +static memory_pool_t timpool; +static struct os_timer_cb timers[CMSIS_CFG_NUM_TIMERS]; + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/** + * @brief Virtual timers common callback. + */ +static void timer_cb(void const *arg) { + + osTimerId timer_id = (osTimerId)arg; + timer_id->ptimer(timer_id->argument); + if (timer_id->type == osTimerPeriodic) { + chSysLockFromISR(); + chVTDoSetI(&timer_id->vt, MS2ST(timer_id->millisec), + (vtfunc_t)timer_cb, timer_id); + chSysUnlockFromISR(); + } +} + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Kernel initialization. + */ +osStatus osKernelInitialize(void) { + + cmsis_os_started = 0; + + chSysInit(); + chThdSetPriority(HIGHPRIO); + + chPoolObjectInit(&sempool, sizeof(semaphore_t), chCoreAlloc); + chPoolLoadArray(&sempool, semaphores, CMSIS_CFG_NUM_SEMAPHORES); + + chPoolObjectInit(&timpool, sizeof(virtual_timer_t), chCoreAlloc); + chPoolLoadArray(&timpool, timers, CMSIS_CFG_NUM_TIMERS); + + return osOK; +} + +/** + * @brief Kernel start. + */ +osStatus osKernelStart(void) { + + cmsis_os_started = 1; + + chThdSetPriority(NORMALPRIO); + + return osOK; +} + +/** + * @brief Creates a thread. + */ +osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument) { + size_t size; + + size = thread_def->stacksize == 0 ? CMSIS_CFG_DEFAULT_STACK : + thread_def->stacksize; + return (osThreadId)chThdCreateFromHeap(0, + THD_WORKING_AREA_SIZE(size), + NORMALPRIO+thread_def->tpriority, + (tfunc_t)thread_def->pthread, + argument); +} + +/** + * @brief Thread termination. + * @note The thread is not really terminated but asked to terminate which + * is not compliant. + */ +osStatus osThreadTerminate(osThreadId thread_id) { + + if (thread_id == osThreadGetId()) { + /* Note, no memory will be recovered unless a cleaner thread is + implemented using the registry.*/ + chThdExit(0); + } + chThdTerminate(thread_id); + chThdWait((thread_t *)thread_id); + + return osOK; +} + +/** + * @brief Change thread priority. + * @note This can interfere with the priority inheritance mechanism. + */ +osStatus osThreadSetPriority(osThreadId thread_id, osPriority newprio) { + osPriority oldprio; + thread_t * tp = (thread_t *)thread_id; + + chSysLock(); + + /* Changing priority.*/ +#if CH_CFG_USE_MUTEXES + oldprio = (osPriority)tp->p_realprio; + if ((tp->p_prio == tp->p_realprio) || ((tprio_t)newprio > tp->p_prio)) + tp->p_prio = (tprio_t)newprio; + tp->p_realprio = (tprio_t)newprio; +#else + oldprio = tp->p_prio; + tp->p_prio = (tprio_t)newprio; +#endif + + /* The following states need priority queues reordering.*/ + switch (tp->p_state) { +#if CH_CFG_USE_MUTEXES | \ + CH_CFG_USE_CONDVARS | \ + (CH_CFG_USE_SEMAPHORES && CH_CFG_USE_SEMAPHORES_PRIORITY) | \ + (CH_CFG_USE_MESSAGES && CH_CFG_USE_MESSAGES_PRIORITY) +#if CH_CFG_USE_MUTEXES + case CH_STATE_WTMTX: +#endif +#if CH_CFG_USE_CONDVARS + case CH_STATE_WTCOND: +#endif +#if CH_CFG_USE_SEMAPHORES && CH_CFG_USE_SEMAPHORES_PRIORITY + case CH_STATE_WTSEM: +#endif +#if CH_CFG_USE_MESSAGES && CH_CFG_USE_MESSAGES_PRIORITY + case CH_STATE_SNDMSGQ: +#endif + /* Re-enqueues tp with its new priority on the queue.*/ + queue_prio_insert(queue_dequeue(tp), + (threads_queue_t *)tp->p_u.wtobjp); + break; +#endif + case CH_STATE_READY: +#if CH_DBG_ENABLE_ASSERTS + /* Prevents an assertion in chSchReadyI().*/ + tp->p_state = CH_STATE_CURRENT; +#endif + /* Re-enqueues tp with its new priority on the ready list.*/ + chSchReadyI(queue_dequeue(tp)); + break; + } + + /* Rescheduling.*/ + chSchRescheduleS(); + + chSysUnlock(); + + return oldprio; +} + +/** + * @brief Create a timer. + */ +osTimerId osTimerCreate(const osTimerDef_t *timer_def, + os_timer_type type, + void *argument) { + + osTimerId timer = chPoolAlloc(&timpool); + chVTObjectInit(&timer->vt); + timer->ptimer = timer_def->ptimer; + timer->type = type; + timer->argument = argument; + return timer; +} + +/** + * @brief Start a timer. + */ +osStatus osTimerStart(osTimerId timer_id, uint32_t millisec) { + + if ((millisec == 0) || (millisec == osWaitForever)) + return osErrorValue; + + timer_id->millisec = millisec; + chVTSet(&timer_id->vt, MS2ST(millisec), (vtfunc_t)timer_cb, timer_id); + + return osOK; +} + +/** + * @brief Stop a timer. + */ +osStatus osTimerStop(osTimerId timer_id) { + + chVTReset(&timer_id->vt); + + return osOK; +} + +/** + * @brief Delete a timer. + */ +osStatus osTimerDelete(osTimerId timer_id) { + + chVTReset(&timer_id->vt); + chPoolFree(&timpool, (void *)timer_id); + + return osOK; +} + +/** + * @brief Send signals. + */ +int32_t osSignalSet(osThreadId thread_id, int32_t signals) { + int32_t oldsignals; + + syssts_t sts = chSysGetStatusAndLockX(); + oldsignals = (int32_t)thread_id->p_epending; + chEvtSignalI((thread_t *)thread_id, (eventmask_t)signals); + chSysRestoreStatusX(sts); + + return oldsignals; +} + +/** + * @brief Clear signals. + */ +int32_t osSignalClear(osThreadId thread_id, int32_t signals) { + eventmask_t m; + + chSysLock(); + + m = thread_id->p_epending & (eventmask_t)signals; + thread_id->p_epending &= ~(eventmask_t)signals; + + chSysUnlock(); + + return (int32_t)m; +} + +/** + * @brief Wait for signals. + */ +osEvent osSignalWait(int32_t signals, uint32_t millisec) { + osEvent event; + systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ? + TIME_INFINITE : MS2ST(millisec); + + if (signals == 0) + event.value.signals = (uint32_t)chEvtWaitAnyTimeout(ALL_EVENTS, timeout); + else + event.value.signals = (uint32_t)chEvtWaitAllTimeout((eventmask_t)signals, + timeout); + + /* Type of event.*/ + if (event.value.signals == 0) + event.status = osEventTimeout; + else + event.status = osEventSignal; + + return event; +} + +/** + * @brief Create a semaphore. + * @note @p semaphore_def is not used. + * @note Can involve memory allocation. + */ +osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def, + int32_t count) { + + (void)semaphore_def; + + semaphore_t *sem = chPoolAlloc(&sempool); + chSemObjectInit(sem, (cnt_t)count); + return sem; +} + +/** + * @brief Wait on a semaphore. + */ +int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec) { + systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ? + TIME_INFINITE : MS2ST(millisec); + + msg_t msg = chSemWaitTimeout((semaphore_t *)semaphore_id, timeout); + switch (msg) { + case MSG_OK: + return osOK; + case MSG_TIMEOUT: + return osErrorTimeoutResource; + } + return osErrorResource; +} + +/** + * @brief Release a semaphore. + */ +osStatus osSemaphoreRelease(osSemaphoreId semaphore_id) { + + syssts_t sts = chSysGetStatusAndLockX(); + chSemSignalI((semaphore_t *)semaphore_id); + chSysRestoreStatusX(sts); + + return osOK; +} + +/** + * @brief Deletes a semaphore. + * @note After deletion there could be references in the system to a + * non-existent semaphore. + */ +osStatus osSemaphoreDelete(osSemaphoreId semaphore_id) { + + chSemReset((semaphore_t *)semaphore_id, 0); + chPoolFree(&sempool, (void *)semaphore_id); + + return osOK; +} + +/** + * @brief Create a mutex. + * @note @p mutex_def is not used. + * @note Can involve memory allocation. + */ +osMutexId osMutexCreate(const osMutexDef_t *mutex_def) { + + (void)mutex_def; + + binary_semaphore_t *mtx = chPoolAlloc(&sempool); + chBSemObjectInit(mtx, false); + return mtx; +} + +/** + * @brief Wait on a mutex. + */ +osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec) { + systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ? + TIME_INFINITE : MS2ST(millisec); + + msg_t msg = chBSemWaitTimeout((binary_semaphore_t *)mutex_id, timeout); + switch (msg) { + case MSG_OK: + return osOK; + case MSG_TIMEOUT: + return osErrorTimeoutResource; + } + return osErrorResource; +} + +/** + * @brief Release a mutex. + */ +osStatus osMutexRelease(osMutexId mutex_id) { + + syssts_t sts = chSysGetStatusAndLockX(); + chBSemSignalI((binary_semaphore_t *)mutex_id); + chSysRestoreStatusX(sts); + + return osOK; +} + +/** + * @brief Deletes a mutex. + * @note After deletion there could be references in the system to a + * non-existent semaphore. + */ +osStatus osMutexDelete(osMutexId mutex_id) { + + chSemReset((semaphore_t *)mutex_id, 0); + chPoolFree(&sempool, (void *)mutex_id); + + return osOK; +} + +/** + * @brief Create a memory pool. + * @note The pool is not really created because it is allocated statically, + * this function just re-initializes it. + */ +osPoolId osPoolCreate(const osPoolDef_t *pool_def) { + + chPoolObjectInit(pool_def->pool, (size_t)pool_def->item_sz, NULL); + chPoolLoadArray(pool_def->pool, pool_def->items, (size_t)pool_def->pool_sz); + + return (osPoolId)pool_def->pool; +} + +/** + * @brief Allocate an object. + */ +void *osPoolAlloc(osPoolId pool_id) { + void *object; + + syssts_t sts = chSysGetStatusAndLockX(); + object = chPoolAllocI((memory_pool_t *)pool_id); + chSysRestoreStatusX(sts); + + return object; +} + +/** + * @brief Allocate an object clearing it. + */ +void *osPoolCAlloc(osPoolId pool_id) { + void *object; + + object = chPoolAllocI((memory_pool_t *)pool_id); + memset(object, 0, pool_id->mp_object_size); + return object; +} + +/** + * @brief Free an object. + */ +osStatus osPoolFree(osPoolId pool_id, void *block) { + + syssts_t sts = chSysGetStatusAndLockX(); + chPoolFreeI((memory_pool_t *)pool_id, block); + chSysRestoreStatusX(sts); + + return osOK; +} + +/** + * @brief Create a message queue. + * @note The queue is not really created because it is allocated statically, + * this function just re-initializes it. + */ +osMessageQId osMessageCreate(const osMessageQDef_t *queue_def, + osThreadId thread_id) { + + /* Ignoring this parameter for now.*/ + (void)thread_id; + + if (queue_def->item_sz > sizeof (msg_t)) + return NULL; + + chMBObjectInit(queue_def->mailbox, + queue_def->items, + (size_t)queue_def->queue_sz); + + return (osMessageQId) queue_def->mailbox; +} + +/** + * @brief Put a message in the queue. + */ +osStatus osMessagePut(osMessageQId queue_id, + uint32_t info, + uint32_t millisec) { + msg_t msg; + systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ? + TIME_INFINITE : MS2ST(millisec); + + if (port_is_isr_context()) { + + /* Waiting makes no sense in ISRs so any value except "immediate" + makes no sense.*/ + if (millisec != 0) + return osErrorValue; + + chSysLockFromISR(); + msg = chMBPostI((mailbox_t *)queue_id, (msg_t)info); + chSysUnlockFromISR(); + } + else + msg = chMBPost((mailbox_t *)queue_id, (msg_t)info, timeout); + + return msg == MSG_OK ? osOK : osEventTimeout; +} + +/** + * @brief Get a message from the queue. + */ +osEvent osMessageGet(osMessageQId queue_id, + uint32_t millisec) { + msg_t msg; + osEvent event; + systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ? + TIME_INFINITE : MS2ST(millisec); + + event.def.message_id = queue_id; + + if (port_is_isr_context()) { + + /* Waiting makes no sense in ISRs so any value except "immediate" + makes no sense.*/ + if (millisec != 0) { + event.status = osErrorValue; + return event; + } + + chSysLockFromISR(); + msg = chMBFetchI((mailbox_t *)queue_id, (msg_t*)&event.value.v); + chSysUnlockFromISR(); + } + else { + msg = chMBFetch((mailbox_t *)queue_id, (msg_t*)&event.value.v, timeout); + } + + /* Returned event type.*/ + event.status = msg == MSG_OK ? osEventMessage : osEventTimeout; + return event; +} + +/** @} */ diff --git a/os/common/ports/ARMCMx/cmsis_os/cmsis_os.h b/os/common/ports/ARMCMx/cmsis_os/cmsis_os.h new file mode 100644 index 000000000..23f12a0b6 --- /dev/null +++ b/os/common/ports/ARMCMx/cmsis_os/cmsis_os.h @@ -0,0 +1,520 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 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 . +*/ +/* + Concepts and parts of this file have been contributed by Andre R. + */ + +/** + * @file cmsis_os.h + * @brief CMSIS RTOS module macros and structures. + * + * @addtogroup CMSIS_OS + * @{ + */ + +#ifndef _CMSIS_OS_H_ +#define _CMSIS_OS_H_ + +#include "ch.h" + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/** + * @brief API version. + */ +#define osCMSIS 0x10002 + +/** + * @brief Kernel version. + */ +#define osKernelSystemId "KERNEL V1.00" + +/** + * @brief ChibiOS/RT version encoded for CMSIS. + */ +#define osCMSIS_KERNEL ((CH_KERNEL_MAJOR << 16) | \ + (CH_KERNEL_MINOR << 8) | \ + (CH_KERNEL_PATCH)) + +/** + * @name CMSIS Capabilities + * @{ + */ +#define osFeature_MainThread 1 +#define osFeature_Pool 1 +#define osFeature_MailQ 0 +#define osFeature_MessageQ 1 +#define osFeature_Signals 24 +#define osFeature_Semaphore ((1U << 31) - 1U) +#define osFeature_Wait 0 +#define osFeature_SysTick 1 +/**< @} */ + +/** + * @brief Wait forever specification for timeouts. + */ +#define osWaitForever TIME_INFINITE + +/** + * @brief System tick frequency. + */ +#define osKernelSysTickFrequency CH_CFG_FREQUENCY + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief Number of pre-allocated static semaphores/mutexes. + */ +#if !defined(CMSIS_CFG_DEFAULT_STACK) +#define CMSIS_CFG_DEFAULT_STACK 256 +#endif + +/** + * @brief Number of pre-allocated static semaphores/mutexes. + */ +#if !defined(CMSIS_CFG_NUM_SEMAPHORES) +#define CMSIS_CFG_NUM_SEMAPHORES 4 +#endif + +/** + * @brief Number of pre-allocated static timers. + */ +#if !defined(CMSIS_CFG_NUM_TIMERS) +#define CMSIS_CFG_NUM_TIMERS 4 +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !CH_CFG_USE_MEMPOOLS +#error "CMSIS RTOS requires CH_CFG_USE_MEMPOOLS" +#endif + +#if !CH_CFG_USE_EVENTS +#error "CMSIS RTOS requires CH_CFG_USE_EVENTS" +#endif + +#if !CH_CFG_USE_EVENTS_TIMEOUT +#error "CMSIS RTOS requires CH_CFG_USE_EVENTS_TIMEOUT" +#endif + +#if !CH_CFG_USE_SEMAPHORES +#error "CMSIS RTOS requires CH_CFG_USE_SEMAPHORES" +#endif + +#if !CH_CFG_USE_DYNAMIC +#error "CMSIS RTOS requires CH_CFG_USE_DYNAMIC" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of priority levels. + */ +typedef enum { + osPriorityIdle = -3, + osPriorityLow = -2, + osPriorityBelowNormal = -1, + osPriorityNormal = 0, + osPriorityAboveNormal = +1, + osPriorityHigh = +2, + osPriorityRealtime = +3, + osPriorityError = 0x84 +} osPriority; + +/** + * @brief Type of error codes. + */ +typedef enum { + osOK = 0, + osEventSignal = 0x08, + osEventMessage = 0x10, + osEventMail = 0x20, + osEventTimeout = 0x40, + osErrorParameter = 0x80, + osErrorResource = 0x81, + osErrorTimeoutResource = 0xC1, + osErrorISR = 0x82, + osErrorISRRecursive = 0x83, + osErrorPriority = 0x84, + osErrorNoMemory = 0x85, + osErrorValue = 0x86, + osErrorOS = 0xFF, + os_status_reserved = 0x7FFFFFFF +} osStatus; + +/** + * @brief Type of a timer mode. + */ +typedef enum { + osTimerOnce = 0, + osTimerPeriodic = 1 +} os_timer_type; + +/** + * @brief Type of thread functions. + */ +typedef void (*os_pthread) (void const *argument); + +/** + * @brief Type of timer callback. + */ +typedef void (*os_ptimer) (void const *argument); + +/** + * @brief Type of pointer to thread control block. + */ +typedef thread_t *osThreadId; + +/** + * @brief Type of pointer to timer control block. + */ +typedef struct os_timer_cb { + virtual_timer_t vt; + os_timer_type type; + os_ptimer ptimer; + void *argument; + uint32_t millisec; +} *osTimerId; + +/** + * @brief Type of pointer to mutex control block. + */ +typedef binary_semaphore_t *osMutexId; + +/** + * @brief Type of pointer to semaphore control block. + */ +typedef semaphore_t *osSemaphoreId; + +/** + * @brief Type of pointer to memory pool control block. + */ +typedef memory_pool_t *osPoolId; + +/** + * @brief Type of pointer to message queue control block. + */ +typedef struct mailbox *osMessageQId; + +/** + * @brief Type of an event. + */ +typedef struct { + osStatus status; + union { + uint32_t v; + void *p; + int32_t signals; + } value; + union { +/* osMailQId mail_id;*/ + osMessageQId message_id; + } def; +} osEvent; + +/** + * @brief Type of a thread definition block. + */ +typedef struct os_thread_def { + os_pthread pthread; + osPriority tpriority; + uint32_t stacksize; +} osThreadDef_t; + +/** + * @brief Type of a timer definition block. + */ +typedef struct os_timer_def { + os_ptimer ptimer; +} osTimerDef_t; + +/** + * @brief Type of a mutex definition block. + */ +typedef struct os_mutex_def { + uint32_t dummy; +} osMutexDef_t; + +/** + * @brief Type of a semaphore definition block. + */ +typedef struct os_semaphore_def { + uint32_t dummy; +} osSemaphoreDef_t; + +/** + * @brief Type of a memory pool definition block. + */ +typedef struct os_pool_def { + uint32_t pool_sz; + uint32_t item_sz; + memory_pool_t *pool; + void *items; +} osPoolDef_t; + +/** + * @brief Type of a message queue definition block. + */ +typedef struct os_messageQ_def { + uint32_t queue_sz; + uint32_t item_sz; + mailbox_t *mailbox; + void *items; +} osMessageQDef_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Convert a microseconds value to a RTOS kernel system timer value. + */ +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * \ + (osKernelSysTickFrequency)) / \ + 1000000) + +/** + * @brief Create a Thread definition. + */ +#if defined(osObjectsExternal) +#define osThreadDef(name, priority, instances, stacksz) \ + extern const osThreadDef_t os_thread_def_##name +#else +#define osThreadDef(name, priority, stacksz) \ +const osThreadDef_t os_thread_def_##name = { \ + (name), \ + (priority), \ + (stacksz) \ +} +#endif + +/** + * @brief Access a Thread definition. + */ +#define osThread(name) &os_thread_def_##name + +/** + * @brief Define a Timer object. + */ +#if defined(osObjectsExternal) +#define osTimerDef(name, function) \ + extern const osTimerDef_t os_timer_def_##name +#else +#define osTimerDef(name, function) \ +const osTimerDef_t os_timer_def_##name = { \ + (function) \ +} +#endif + +/** + * @brief Access a Timer definition. + */ +#define osTimer(name) &os_timer_def_##name + +/** + * @brief Define a Mutex. + */ +#if defined(osObjectsExternal) +#define osMutexDef(name) extern const osMutexDef_t os_mutex_def_##name +#else +#define osMutexDef(name) const osMutexDef_t os_mutex_def_##name = {0} +#endif + +/** + * @brief Access a Mutex definition. + */ +#define osMutex(name) &os_mutex_def_##name + +/** + * @brief Define a Semaphore. + */ +#if defined(osObjectsExternal) +#define osSemaphoreDef(name) \ + extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ + const osSemaphoreDef_t os_semaphore_def_##name = {0} +#endif + +/** + * @brief Access a Semaphore definition. + */ +#define osSemaphore(name) &os_semaphore_def_##name + +/** + * @brief Define a Memory Pool. + */ +#if defined(osObjectsExternal) +#define osPoolDef(name, no, type) \ + extern const osPoolDef_t os_pool_def_##name +#else +#define osPoolDef(name, no, type) \ +static const type os_pool_buf_##name[no]; \ +static memory_pool_t os_pool_obj_##name; \ +const osPoolDef_t os_pool_def_##name = { \ + (no), \ + sizeof (type), \ + (void *)&os_pool_obj_##name, \ + (void *)&os_pool_buf_##name[0] \ +} +#endif + +/** + * @brief Access a Memory Pool definition. + */ +#define osPool(name) &os_pool_def_##name + +/** + * @brief Define a Message Queue. + */ +#if defined(osObjectsExternal) +#define osMessageQDef(name, queue_sz, type) \ + extern const osMessageQDef_t os_messageQ_def_##name +#else +#define osMessageQDef(name, queue_sz, type) \ +static const msg_t os_messageQ_buf_##name[queue_sz]; \ +static mailbox_t os_messageQ_obj_##name; \ +const osMessageQDef_t os_messageQ_def_##name = { \ + (queue_sz), \ + sizeof (type) \ + (void *)&os_messageQ_obj_##name, \ + (void *)&os_messageQ_buf_##name[0] \ +} +#endif + +/** + * @brief Access a Message Queue definition. + */ +#define osMessageQ(name) &os_messageQ_def_##name + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +extern int32_t cmsis_os_started; + +#ifdef __cplusplus +extern "C" { +#endif + osStatus osKernelInitialize(void); + osStatus osKernelStart(void); + osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument); + osStatus osThreadTerminate(osThreadId thread_id); + osStatus osThreadSetPriority(osThreadId thread_id, osPriority newprio); + /*osEvent osWait(uint32_t millisec);*/ + osTimerId osTimerCreate(const osTimerDef_t *timer_def, + os_timer_type type, + void *argument); + osStatus osTimerStart(osTimerId timer_id, uint32_t millisec); + osStatus osTimerStop(osTimerId timer_id); + osStatus osTimerDelete(osTimerId timer_id); + int32_t osSignalSet(osThreadId thread_id, int32_t signals); + int32_t osSignalClear(osThreadId thread_id, int32_t signals); + osEvent osSignalWait(int32_t signals, uint32_t millisec); + osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def, + int32_t count); + int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec); + osStatus osSemaphoreRelease(osSemaphoreId semaphore_id); + osStatus osSemaphoreDelete(osSemaphoreId semaphore_id); + osMutexId osMutexCreate(const osMutexDef_t *mutex_def); + osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec); + osStatus osMutexRelease(osMutexId mutex_id); + osStatus osMutexDelete(osMutexId mutex_id); + osPoolId osPoolCreate(const osPoolDef_t *pool_def); + void *osPoolAlloc(osPoolId pool_id); + void *osPoolCAlloc(osPoolId pool_id); + osStatus osPoolFree(osPoolId pool_id, void *block); + osMessageQId osMessageCreate(const osMessageQDef_t *queue_def, + osThreadId thread_id); + osStatus osMessagePut(osMessageQId queue_id, + uint32_t info, + uint32_t millisec); + osEvent osMessageGet(osMessageQId queue_id, + uint32_t millisec); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief To be or not to be. + */ +static inline int32_t osKernelRunning(void) { + + return cmsis_os_started; +} + +/** + * @brief System ticks since start. + */ +static inline uint32_t osKernelSysTick(void) { + + return (uint32_t)chVTGetSystemTimeX(); +} + +/** + * @brief Returns the current thread. + */ +static inline osThreadId osThreadGetId(void) { + + return (osThreadId)chThdGetSelfX(); +} + +/** + * @brief Thread time slice yield. + */ +static inline osStatus osThreadYield(void) { + + chThdYield(); + + return osOK; +} + +/** + * @brief Returns priority of a thread. + */ +static inline osPriority osThreadGetPriority(osThreadId thread_id) { + + return thread_id->p_prio; +} + +/** + * @brief Thread delay in milliseconds. + */ +static inline osStatus osDelay(uint32_t millisec) { + + chThdSleepMilliseconds(millisec); + + return osOK; +} + +#endif /* _CMSIS_OS_H_ */ + +/** @} */ diff --git a/os/common/ports/ARMCMx/cmsis_os/cmsis_os.mk b/os/common/ports/ARMCMx/cmsis_os/cmsis_os.mk new file mode 100644 index 000000000..d679622ad --- /dev/null +++ b/os/common/ports/ARMCMx/cmsis_os/cmsis_os.mk @@ -0,0 +1,4 @@ +# List of the ChibiOS/RT CMSIS RTOS wrapper. +CMSISRTOSSRC = ${CHIBIOS}/os/rt/ports/ARMCMx/cmsis_os/cmsis_os.c + +CMSISRTOSINC = ${CHIBIOS}/os/rt/ports/ARMCMx/cmsis_os diff --git a/os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v6m.s b/os/common/ports/ARMCMx/compilers/GCC/chcoreasm_v6m.s similarity index 77% rename from os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v6m.s rename to os/common/ports/ARMCMx/compilers/GCC/chcoreasm_v6m.s index 68862f96e..935c7630f 100644 --- a/os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v6m.s +++ b/os/common/ports/ARMCMx/compilers/GCC/chcoreasm_v6m.s @@ -18,7 +18,7 @@ */ /** - * @file ARMCMx/compilers/GCC/nilcoreasm_v6m.s + * @file compilers/GCC/chcoreasm_v6m.s * @brief ARMv6-M architecture port low level code. * * @addtogroup ARMCMx_GCC_CORE @@ -34,12 +34,22 @@ #endif #define _FROM_ASM_ -#include "nilconf.h" -#include "nilcore.h" +#include "chconf.h" +#include "chcore.h" #if !defined(__DOXYGEN__) - .set CONTEXT_OFFSET, 0 +/* + * RTOS-specific context offset. + */ +#if defined(_CHIBIOS_RT_CONF_) +#define CONTEXT_OFFSET 12 +#elif defined(_CHIBIOS_NIL_CONF_) +#define CONTEXT_OFFSET 0 +#else +#error "invalid chconf.h" +#endif + .set SCB_ICSR, 0xE000ED04 .set ICSR_PENDSVSET, 0x10000000 .set ICSR_NMIPENDSET, 0x80000000 @@ -62,12 +72,12 @@ _port_switch: mov r6, r10 mov r7, r11 push {r4, r5, r6, r7} - + mov r3, sp str r3, [r1, #CONTEXT_OFFSET] ldr r3, [r0, #CONTEXT_OFFSET] mov sp, r3 - + pop {r4, r5, r6, r7} mov r8, r4 mov r9, r5 @@ -86,11 +96,17 @@ _port_switch: .thumb_func .globl _port_thread_start _port_thread_start: +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif cpsie i mov r0, r5 blx r4 - mov r3, #0 - bl chSysHalt + movs r0, #0 /* MSG_OK */ + bl chThdExit /*--------------------------------------------------------------------------* * Post-IRQ switch code. @@ -100,7 +116,19 @@ _port_thread_start: .thumb_func .globl _port_switch_from_isr _port_switch_from_isr: - bl chSchRescheduleS +#if CH_DBG_STATISTICS + bl _stats_start_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_lock +#endif + bl chSchDoReschedule +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif .globl _port_exit_from_isr _port_exit_from_isr: ldr r2, .L2 diff --git a/os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v7m.s b/os/common/ports/ARMCMx/compilers/GCC/chcoreasm_v7m.s similarity index 75% rename from os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v7m.s rename to os/common/ports/ARMCMx/compilers/GCC/chcoreasm_v7m.s index a98802798..7a77ba406 100644 --- a/os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v7m.s +++ b/os/common/ports/ARMCMx/compilers/GCC/chcoreasm_v7m.s @@ -18,7 +18,7 @@ */ /** - * @file ARMCMx/compilers/GCC/nilcoreasm_v7m.s + * @file compilers/GCC/chcoreasm_v7m.s * @brief ARMv7-M architecture port low level code. * * @addtogroup ARMCMx_GCC_CORE @@ -34,12 +34,22 @@ #endif #define _FROM_ASM_ -#include "nilconf.h" -#include "nilcore.h" +#include "chconf.h" +#include "chcore.h" #if !defined(__DOXYGEN__) - .set CONTEXT_OFFSET, 0 +/* + * RTOS-specific context offset. + */ +#if defined(_CHIBIOS_RT_CONF_) +#define CONTEXT_OFFSET 12 +#elif defined(_CHIBIOS_NIL_CONF_) +#define CONTEXT_OFFSET 0 +#else +#error "invalid chconf.h" +#endif + .set SCB_ICSR, 0xE000ED04 .set ICSR_PENDSVSET, 0x10000000 @@ -92,16 +102,28 @@ _port_switch: .thumb_func .globl _port_thread_start _port_thread_start: -#if !CORTEX_SIMPLIFIED_PRIORITY - movs r3, #0 - msr BASEPRI, r3 -#else /* CORTEX_SIMPLIFIED_PRIORITY */ +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif +#if CORTEX_SIMPLIFIED_PRIORITY cpsie i -#endif /* CORTEX_SIMPLIFIED_PRIORITY */ +#else + movs r3, #0 /* CORTEX_BASEPRI_DISABLED */ + msr BASEPRI, r3 +#endif mov r0, r5 blx r4 +#if defined(_CHIBIOS_RT_CONF_) + movs r0, #0 /* MSG_OK */ + bl chThdExit +#endif +#if defined(_CHIBIOS_NIL_CONF_) mov r3, #0 bl chSysHalt +#endif /*--------------------------------------------------------------------------* * Post-IRQ switch code. @@ -111,7 +133,19 @@ _port_thread_start: .thumb_func .globl _port_switch_from_isr _port_switch_from_isr: - bl chSchRescheduleS +#if CH_DBG_STATISTICS + bl _stats_start_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_lock +#endif + bl chSchDoReschedule +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif .globl _port_exit_from_isr _port_exit_from_isr: #if CORTEX_SIMPLIFIED_PRIORITY diff --git a/os/nil/ports/ARMCMx/compilers/GCC/niltypes.h b/os/common/ports/ARMCMx/compilers/GCC/chtypes.h similarity index 52% rename from os/nil/ports/ARMCMx/compilers/GCC/niltypes.h rename to os/common/ports/ARMCMx/compilers/GCC/chtypes.h index 402110096..15ab05a62 100644 --- a/os/nil/ports/ARMCMx/compilers/GCC/niltypes.h +++ b/os/common/ports/ARMCMx/compilers/GCC/chtypes.h @@ -18,15 +18,15 @@ */ /** - * @file ARMCMx/compilers/GCC/niltypes.h + * @file ARMCMx/compilers/GCC/chtypes.h * @brief ARM Cortex-Mx port system types. * * @addtogroup ARMCMx_GCC_CORE * @{ */ -#ifndef _NILTYPES_H_ -#define _NILTYPES_H_ +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ #include #include @@ -39,33 +39,36 @@ * @brief Generic 'false' boolean constant. */ #if !defined(FALSE) || defined(__DOXYGEN__) -#define FALSE 0 +#define FALSE 0 #endif /** * @brief Generic 'true' boolean constant. */ #if !defined(TRUE) || defined(__DOXYGEN__) -#define TRUE 1 +#define TRUE 1 #endif /** @} */ -typedef uint32_t syssts_t; /**< System status word. */ -typedef uint32_t rtcnt_t; /**< Realtime counter. */ -typedef uint8_t tstate_t; /**< Thread state. */ -typedef int32_t msg_t; /**< Inter-thread message. */ -typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ -typedef int32_t cnt_t; /**< Generic signed counter. */ -typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ - /** - * @brief Type of system time. + * @name Kernel types + * @{ */ -#if (NIL_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__) -typedef uint32_t systime_t; -#else -typedef uint16_t systime_t; -#endif +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint32_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint32_t tprio_t; /**< Thread priority. */ +typedef int32_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint32_t eventflags_t; /**< Mask of event flags. */ +typedef int32_t cnt_t; /**< Generic signed counter. */ +typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ /** * @brief ROM constant modifier. @@ -83,14 +86,18 @@ typedef uint16_t systime_t; /** * @brief Optimized thread function declaration macro. */ -#define PORT_THD_FUNCTION(tname, arg) \ - __attribute__((noreturn)) void tname(void *arg) +#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg) /** * @brief Packed variable specifier. */ #define PACKED_VAR __attribute__((packed)) -#endif /* _NILTYPES_H_ */ +/** + * @brief Memory alignment enforcement for variables. + */ +#define ALIGNED_VAR(n) __attribute__((aligned(n))) + +#endif /* _CHTYPES_H_ */ /** @} */ diff --git a/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk b/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk new file mode 100644 index 000000000..383457de6 --- /dev/null +++ b/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk @@ -0,0 +1,8 @@ +# List of the ChibiOS/RT Cortex-M0 STM32F0xx port files. +PORTSRC = $(CHIBIOS)/os/common/ports/ARMCMx/chcore.c \ + $(CHIBIOS)/os/common/ports/ARMCMx/chcore_v6m.c + +PORTASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/chcoreasm_v6m.s + +PORTINC = $(CHIBIOS)/os/common/ports/ARMCMx \ + $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC diff --git a/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk b/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk new file mode 100644 index 000000000..86bf45e7b --- /dev/null +++ b/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk @@ -0,0 +1,8 @@ +# List of the ChibiOS/RT ARMv7M generic port files. +PORTSRC = $(CHIBIOS)/os/common/ports/ARMCMx/chcore.c \ + $(CHIBIOS)/os/common/ports/ARMCMx/chcore_v7m.c + +PORTASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/chcoreasm_v7m.s + +PORTINC = $(CHIBIOS)/os/common/ports/ARMCMx \ + $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC diff --git a/os/common/ports/ARMCMx/compilers/IAR/chcoreasm_v6m.s b/os/common/ports/ARMCMx/compilers/IAR/chcoreasm_v6m.s new file mode 100644 index 000000000..ad2820dfa --- /dev/null +++ b/os/common/ports/ARMCMx/compilers/IAR/chcoreasm_v6m.s @@ -0,0 +1,142 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file compilers/IAR/chcoreasm_v6m.s + * @brief ARMv6-M architecture port low level code. + * + * @addtogroup ARMCMx_IAR_CORE + * @{ + */ + +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE 1 +#endif + +#define _FROM_ASM_ +#include "chconf.h" +#include "chcore.h" + +#if !defined(__DOXYGEN__) + + MODULE ?chcoreasm_v6m + + AAPCS INTERWORK, VFP_COMPATIBLE + PRESERVE8 + +CONTEXT_OFFSET SET 12 +SCB_ICSR SET 0xE000ED04 + + SECTION .text:CODE:NOROOT(2) + + EXTERN chThdExit + EXTERN chSchDoReschedule +#if CH_DBG_STATISTICS + EXTERN _stats_start_measure_crit_thd + EXTERN _stats_stop_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + EXTERN _dbg_check_unlock + EXTERN _dbg_check_lock +#endif + + THUMB + +/* + * Performs a context switch between two threads. + */ + PUBLIC _port_switch +_port_switch: + push {r4, r5, r6, r7, lr} + mov r4, r8 + mov r5, r9 + mov r6, r10 + mov r7, r11 + push {r4, r5, r6, r7} + mov r3, sp + str r3, [r1, #CONTEXT_OFFSET] + ldr r3, [r0, #CONTEXT_OFFSET] + mov sp, r3 + pop {r4, r5, r6, r7} + mov r8, r4 + mov r9, r5 + mov r10, r6 + mov r11, r7 + pop {r4, r5, r6, r7, pc} + +/* + * Start a thread by invoking its work function. + * If the work function returns @p chThdExit() is automatically invoked. + */ + PUBLIC _port_thread_start +_port_thread_start: +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif + cpsie i + mov r0, r5 + blx r4 + bl chThdExit + +/* + * Post-IRQ switch code. + * Exception handlers return here for context switching. + */ + PUBLIC _port_switch_from_isr + PUBLIC _port_exit_from_isr +_port_switch_from_isr: +#if CH_DBG_STATISTICS + bl _stats_start_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_lock +#endif + bl chSchDoReschedule +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif +_port_exit_from_isr: + ldr r2, =SCB_ICSR + movs r3, #128 +#if CORTEX_ALTERNATE_SWITCH + lsls r3, r3, #21 + str r3, [r2, #0] + cpsie i +#else + lsls r3, r3, #24 + str r3, [r2, #0] +#endif +waithere: + b waithere + + END + +#endif /* !defined(__DOXYGEN__) */ + +/** @} */ diff --git a/os/common/ports/ARMCMx/compilers/IAR/chcoreasm_v7m.s b/os/common/ports/ARMCMx/compilers/IAR/chcoreasm_v7m.s new file mode 100644 index 000000000..2f58a73aa --- /dev/null +++ b/os/common/ports/ARMCMx/compilers/IAR/chcoreasm_v7m.s @@ -0,0 +1,150 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file compilers/IAR/chcoreasm_v7m.s + * @brief ARMv7-M architecture port low level code. + * + * @addtogroup ARMCMx_IAR_CORE + * @{ + */ + +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE 1 +#endif + +#define _FROM_ASM_ +#include "chconf.h" +#include "chcore.h" + +#if !defined(__DOXYGEN__) + + MODULE ?chcoreasm_v7m + + AAPCS INTERWORK, VFP_COMPATIBLE + PRESERVE8 + +CONTEXT_OFFSET SET 12 +SCB_ICSR SET 0xE000ED04 +ICSR_PENDSVSET SET 0x10000000 + + SECTION .text:CODE:NOROOT(2) + + EXTERN chThdExit + EXTERN chSchDoReschedule +#if CH_DBG_STATISTICS + EXTERN _stats_start_measure_crit_thd + EXTERN _stats_stop_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + EXTERN _dbg_check_unlock + EXTERN _dbg_check_lock +#endif + + THUMB + +/* + * Performs a context switch between two threads. + */ + PUBLIC _port_switch +_port_switch: + push {r4, r5, r6, r7, r8, r9, r10, r11, lr} +#if CORTEX_USE_FPU + vpush {s16-s31} +#endif + + str sp, [r1, #CONTEXT_OFFSET] +#if (CORTEX_SIMPLIFIED_PRIORITY == FALSE) && \ + ((CORTEX_MODEL == 3) || (CORTEX_MODEL == 4)) + /* Workaround for ARM errata 752419, only applied if + condition exists for it to be triggered.*/ + ldr r3, [r0, #CONTEXT_OFFSET] + mov sp, r3 +#else + ldr sp, [r0, #CONTEXT_OFFSET] +#endif + +#if CORTEX_USE_FPU + vpop {s16-s31} +#endif + pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} + +/* + * Start a thread by invoking its work function. + * If the work function returns @p chThdExit() is automatically invoked. + */ + PUBLIC _port_thread_start +_port_thread_start: +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif +#if CORTEX_SIMPLIFIED_PRIORITY + cpsie i +#else + movs r3, #0 /* CORTEX_BASEPRI_DISABLED */ + msr BASEPRI, r3 +#endif + mov r0, r5 + blx r4 + bl chThdExit + +/* + * Post-IRQ switch code. + * Exception handlers return here for context switching. + */ + PUBLIC _port_switch_from_isr + PUBLIC _port_exit_from_isr +_port_switch_from_isr: +#if CH_DBG_STATISTICS + bl _stats_start_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_lock +#endif + bl chSchDoReschedule +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif +_port_exit_from_isr: +#if CORTEX_SIMPLIFIED_PRIORITY + mov r3, #LWRD SCB_ICSR + movt r3, #HWRD SCB_ICSR + mov r2, #ICSR_PENDSVSET + str r2, [r3] + cpsie i +#else + svc #0 +#endif +.L3: b .L3 + + END + +#endif /* !defined(__DOXYGEN__) */ + +/** @} */ diff --git a/os/common/ports/ARMCMx/compilers/IAR/chtypes.h b/os/common/ports/ARMCMx/compilers/IAR/chtypes.h new file mode 100644 index 000000000..2078217da --- /dev/null +++ b/os/common/ports/ARMCMx/compilers/IAR/chtypes.h @@ -0,0 +1,98 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file ARMCMx/compilers/IAR/chtypes.h + * @brief ARM Cortex-Mx port system types. + * + * @addtogroup ARMCMx_IAR_CORE + * @{ + */ + +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ + +#include +#include +#include + +/** + * @name Common constants + */ +/** + * @brief Generic 'false' boolean constant. + */ +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +/** + * @brief Generic 'true' boolean constant. + */ +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE (!FALSE) +#endif +/** @} */ + +/** + * @name Kernel types + * @{ + */ +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint32_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint32_t tprio_t; /**< Thread priority. */ +typedef int32_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint32_t eventflags_t; /**< Mask of event flags. */ +typedef int32_t cnt_t; /**< Generic signed counter. */ +typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ + +/** + * @brief ROM constant modifier. + * @note It is set to use the "const" keyword in this port. + */ +#define ROMCONST const + +/** + * @brief Makes functions not inlineable. + * @note If the compiler does not support such attribute then the + * realtime counter precision could be degraded. + */ +#define NOINLINE + +/** + * @brief Optimized thread function declaration macro. + */ +#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg) + +/** + * @brief Packed variable specifier. + */ +#define PACKED_VAR __packed + +#endif /* _CHTYPES_H_ */ + +/** @} */ diff --git a/os/common/ports/ARMCMx/compilers/RVCT/chcoreasm_v6m.s b/os/common/ports/ARMCMx/compilers/RVCT/chcoreasm_v6m.s new file mode 100644 index 000000000..e61662f38 --- /dev/null +++ b/os/common/ports/ARMCMx/compilers/RVCT/chcoreasm_v6m.s @@ -0,0 +1,139 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file compilers/RVCT/chcoreasm_v6m.s + * @brief ARMv6-M architecture port low level code. + * + * @addtogroup ARMCMx_RVCT_CORE + * @{ + */ + +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE 1 +#endif + +#define _FROM_ASM_ +#include "chconf.h" +#include "chcore.h" + +#if !defined(__DOXYGEN__) + +CONTEXT_OFFSET EQU 12 +SCB_ICSR EQU 0xE000ED04 + + PRESERVE8 + THUMB + AREA |.text|, CODE, READONLY + + IMPORT chThdExit + IMPORT chSchDoReschedule +#if CH_DBG_STATISTICS + IMPORT _stats_start_measure_crit_thd + IMPORT _stats_stop_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + IMPORT _dbg_check_unlock + IMPORT _dbg_check_lock +#endif + +/* + * Performs a context switch between two threads. + */ + EXPORT _port_switch +_port_switch PROC + push {r4, r5, r6, r7, lr} + mov r4, r8 + mov r5, r9 + mov r6, r10 + mov r7, r11 + push {r4, r5, r6, r7} + mov r3, sp + str r3, [r1, #CONTEXT_OFFSET] + ldr r3, [r0, #CONTEXT_OFFSET] + mov sp, r3 + pop {r4, r5, r6, r7} + mov r8, r4 + mov r9, r5 + mov r10, r6 + mov r11, r7 + pop {r4, r5, r6, r7, pc} + ENDP + +/* + * Start a thread by invoking its work function. + * If the work function returns @p chThdExit() is automatically invoked. + */ + EXPORT _port_thread_start +_port_thread_start PROC +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif + cpsie i + mov r0, r5 + blx r4 + bl chThdExit + ENDP + +/* + * Post-IRQ switch code. + * Exception handlers return here for context switching. + */ + EXPORT _port_switch_from_isr + EXPORT _port_exit_from_isr +_port_switch_from_isr PROC +#if CH_DBG_STATISTICS + bl _stats_start_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_lock +#endif + bl chSchDoReschedule +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif +_port_exit_from_isr + ldr r2, =SCB_ICSR + movs r3, #128 +#if CORTEX_ALTERNATE_SWITCH + lsls r3, r3, #21 + str r3, [r2, #0] + cpsie i +#else + lsls r3, r3, #24 + str r3, [r2, #0] +#endif +waithere b waithere + ENDP + + END + +#endif /* !defined(__DOXYGEN__) */ + +/** @} */ diff --git a/os/common/ports/ARMCMx/compilers/RVCT/chcoreasm_v7m.s b/os/common/ports/ARMCMx/compilers/RVCT/chcoreasm_v7m.s new file mode 100644 index 000000000..69bfaa59c --- /dev/null +++ b/os/common/ports/ARMCMx/compilers/RVCT/chcoreasm_v7m.s @@ -0,0 +1,148 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file compilers/RVCT/chcoreasm_v7m.s + * @brief ARMv7-M architecture port low level code. + * + * @addtogroup ARMCMx_RVCT_CORE + * @{ + */ + +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE 1 +#endif + +#define _FROM_ASM_ +#include "chconf.h" +#include "chcore.h" + +#if !defined(__DOXYGEN__) + +CONTEXT_OFFSET EQU 12 +SCB_ICSR EQU 0xE000ED04 +ICSR_PENDSVSET EQU 0x10000000 + + PRESERVE8 + THUMB + AREA |.text|, CODE, READONLY + + IMPORT chThdExit + IMPORT chSchDoReschedule +#if CH_DBG_STATISTICS + IMPORT _stats_start_measure_crit_thd + IMPORT _stats_stop_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + IMPORT _dbg_check_unlock + IMPORT _dbg_check_lock +#endif + +/* + * Performs a context switch between two threads. + */ + EXPORT _port_switch +_port_switch PROC + push {r4, r5, r6, r7, r8, r9, r10, r11, lr} +#if CORTEX_USE_FPU + vpush {s16-s31} +#endif + + str sp, [r1, #CONTEXT_OFFSET] +#if (CORTEX_SIMPLIFIED_PRIORITY == FALSE) && \ + ((CORTEX_MODEL == 3) || (CORTEX_MODEL == 4)) + /* Workaround for ARM errata 752419, only applied if + condition exists for it to be triggered.*/ + ldr r3, [r0, #CONTEXT_OFFSET] + mov sp, r3 +#else + ldr sp, [r0, #CONTEXT_OFFSET] +#endif + +#if CORTEX_USE_FPU + vpop {s16-s31} +#endif + pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} + ENDP + +/* + * Start a thread by invoking its work function. + * If the work function returns @p chThdExit() is automatically invoked. + */ + EXPORT _port_thread_start +_port_thread_start PROC +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif +#if CORTEX_SIMPLIFIED_PRIORITY + cpsie i +#else + movs r3, #0 /* CORTEX_BASEPRI_DISABLED */ + msr BASEPRI, r3 +#endif + mov r0, r5 + blx r4 + bl chThdExit + ENDP + +/* + * Post-IRQ switch code. + * Exception handlers return here for context switching. + */ + EXPORT _port_switch_from_isr + EXPORT _port_exit_from_isr +_port_switch_from_isr PROC +#if CH_DBG_STATISTICS + bl _stats_start_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_lock +#endif + bl chSchDoReschedule +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif +_port_exit_from_isr +#if CORTEX_SIMPLIFIED_PRIORITY + mov r3, #SCB_ICSR :AND: 0xFFFF + movt r3, #SCB_ICSR :SHR: 16 + mov r2, #ICSR_PENDSVSET + str r2, [r3, #0] + cpsie i +#else + svc #0 +#endif +waithere b waithere + ENDP + + END + +#endif /* !defined(__DOXYGEN__) */ + +/** @} */ diff --git a/os/common/ports/ARMCMx/compilers/RVCT/chtypes.h b/os/common/ports/ARMCMx/compilers/RVCT/chtypes.h new file mode 100644 index 000000000..ce846a912 --- /dev/null +++ b/os/common/ports/ARMCMx/compilers/RVCT/chtypes.h @@ -0,0 +1,98 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file ARMCMx/compilers/RVCT/chtypes.h + * @brief ARM Cortex-Mx port system types. + * + * @addtogroup ARMCMx_RVCT_CORE + * @{ + */ + +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ + +#include +#include +#include + +/** + * @name Common constants + */ +/** + * @brief Generic 'false' boolean constant. + */ +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +/** + * @brief Generic 'true' boolean constant. + */ +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE (!FALSE) +#endif +/** @} */ + +/** + * @name Kernel types + * @{ + */ +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint32_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint32_t tprio_t; /**< Thread priority. */ +typedef int32_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint32_t eventflags_t; /**< Mask of event flags. */ +typedef int32_t cnt_t; /**< Generic signed counter. */ +typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ + +/** + * @brief ROM constant modifier. + * @note It is set to use the "const" keyword in this port. + */ +#define ROMCONST const + +/** + * @brief Makes functions not inlineable. + * @note If the compiler does not support such attribute then the + * realtime counter precision could be degraded. + */ +#define NOINLINE + +/** + * @brief Optimized thread function declaration macro. + */ +#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg) + +/** + * @brief Packed variable specifier. + */ +#define PACKED_VAR __packed + +#endif /* _CHTYPES_H_ */ + +/** @} */ diff --git a/os/common/ports/ARMCMx/mpu.h b/os/common/ports/ARMCMx/mpu.h new file mode 100644 index 000000000..ec025e112 --- /dev/null +++ b/os/common/ports/ARMCMx/mpu.h @@ -0,0 +1,208 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file common/ARMCMx/mpu.h + * @brief Cortex-Mx MPU support macros and structures. + * + * @addtogroup COMMON_ARMCMx_MPU + * @{ + */ + +#ifndef _MPU_H_ +#define _MPU_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name MPU registers definitions + * @{ + */ +#define MPU_TYPE_SEPARATED (1U << 0U) +#define MPU_TYPE_DREGION(n) (((n) >> 8U) & 255U) +#define MPU_TYPE_IREGION(n) (((n) >> 16U) & 255U) + +#define MPU_CTRL_ENABLE (1U << 0U) +#define MPU_CTRL_HFNMIENA (1U << 1U) +#define MPU_CTRL_PRIVDEFENA (1U << 2U) + +#define MPU_RNR_REGION_MASK (255U << 0U) +#define MPU_RNR_REGION(n) ((n) << 0U) + +#define MPU_RBAR_REGION_MASK (15U << 0U) +#define MPU_RBAR_REGION(n) ((n) << 0U) +#define MPU_RBAR_VALID (1U << 4U) +#define MPU_RBAR_ADDR_MASK 0xFFFFFFE0U +#define MPU_RBAR_ADDR(n) ((n) << 5U) + +#define MPU_RASR_ENABLE (1U << 0U) +#define MPU_RASR_SIZE_MASK (31U << 1U) +#define MPU_RASR_SIZE(n) ((n) << 1U) +#define MPU_RASR_SIZE_32 MPU_RASR_SIZE(4U) +#define MPU_RASR_SIZE_64 MPU_RASR_SIZE(5U) +#define MPU_RASR_SIZE_128 MPU_RASR_SIZE(6U) +#define MPU_RASR_SIZE_256 MPU_RASR_SIZE(7U) +#define MPU_RASR_SIZE_512 MPU_RASR_SIZE(8U) +#define MPU_RASR_SIZE_1K MPU_RASR_SIZE(9U) +#define MPU_RASR_SIZE_2K MPU_RASR_SIZE(10U) +#define MPU_RASR_SIZE_4K MPU_RASR_SIZE(11U) +#define MPU_RASR_SIZE_8K MPU_RASR_SIZE(12U) +#define MPU_RASR_SIZE_16K MPU_RASR_SIZE(13U) +#define MPU_RASR_SIZE_32K MPU_RASR_SIZE(14U) +#define MPU_RASR_SIZE_64K MPU_RASR_SIZE(15U) +#define MPU_RASR_SIZE_128K MPU_RASR_SIZE(16U) +#define MPU_RASR_SIZE_256K MPU_RASR_SIZE(17U) +#define MPU_RASR_SIZE_512K MPU_RASR_SIZE(18U) +#define MPU_RASR_SIZE_1M MPU_RASR_SIZE(19U) +#define MPU_RASR_SIZE_2M MPU_RASR_SIZE(20U) +#define MPU_RASR_SIZE_4M MPU_RASR_SIZE(21U) +#define MPU_RASR_SIZE_8M MPU_RASR_SIZE(22U) +#define MPU_RASR_SIZE_16M MPU_RASR_SIZE(23U) +#define MPU_RASR_SIZE_32M MPU_RASR_SIZE(24U) +#define MPU_RASR_SIZE_64M MPU_RASR_SIZE(25U) +#define MPU_RASR_SIZE_128M MPU_RASR_SIZE(26U) +#define MPU_RASR_SIZE_256M MPU_RASR_SIZE(27U) +#define MPU_RASR_SIZE_512M MPU_RASR_SIZE(28U) +#define MPU_RASR_SIZE_1G MPU_RASR_SIZE(29U) +#define MPU_RASR_SIZE_2G MPU_RASR_SIZE(30U) +#define MPU_RASR_SIZE_4G MPU_RASR_SIZE(31U) +#define MPU_RASR_SRD_MASK (255U << 8U) +#define MPU_RASR_SRD(n) ((n) << 8U) +#define MPU_RASR_SRD_ALL (0U << 8U) +#define MPU_RASR_SRD_DISABLE_SUB0 (1U << 8U) +#define MPU_RASR_SRD_DISABLE_SUB1 (2U << 8U) +#define MPU_RASR_SRD_DISABLE_SUB2 (4U << 8U) +#define MPU_RASR_SRD_DISABLE_SUB3 (8U << 8U) +#define MPU_RASR_SRD_DISABLE_SUB4 (16U << 8U) +#define MPU_RASR_SRD_DISABLE_SUB5 (32U << 8U) +#define MPU_RASR_SRD_DISABLE_SUB6 (64U << 8U) +#define MPU_RASR_SRD_DISABLE_SUB7 (128U << 8U) +#define MPU_RASR_ATTR_B (1U << 16U) +#define MPU_RASR_ATTR_C (1U << 17U) +#define MPU_RASR_ATTR_S (1U << 18U) +#define MPU_RASR_ATTR_TEX_MASK (7U << 19U) +#define MPU_RASR_ATTR_TEX(n) ((n) << 19U) +#define MPU_RASR_ATTR_AP_MASK (7U << 24U) +#define MPU_RASR_ATTR_AP(n) ((n) << 24U) +#define MPU_RASR_ATTR_AP_NA_NA (0U << 24U) +#define MPU_RASR_ATTR_AP_RW_NA (1U << 24U) +#define MPU_RASR_ATTR_AP_RW_RO (2U << 24U) +#define MPU_RASR_ATTR_AP_RW_RW (3U << 24U) +#define MPU_RASR_ATTR_AP_RO_NA (5U << 24U) +#define MPU_RASR_ATTR_AP_RO_RO (6U << 24U) +#define MPU_RASR_ATTR_XN (1U << 28U) +/** @} */ + +/** + * @name Region attributes + * @{ + */ +#define MPU_RASR_ATTR_STRONGLY_ORDERED (MPU_RASR_ATTR_TEX(0)) +#define MPU_RASR_ATTR_SHARED_DEVICE (MPU_RASR_ATTR_TEX(0) | MPU_RASR_ATTR_B) +#define MPU_RASR_ATTR_CACHEABLE_WT_NWA (MPU_RASR_ATTR_TEX(0) | MPU_RASR_ATTR_C) +#define MPU_RASR_ATTR_CACHEABLE_WB_NWA (MPU_RASR_ATTR_TEX(0) | MPU_RASR_ATTR_B | MPU_RASR_ATTR_C) +#define MPU_RASR_ATTR_NON_CACHEABLE (MPU_RASR_ATTR_TEX(1)) +#define MPU_RASR_ATTR_CACHEABLE_WB_WA (MPU_RASR_ATTR_TEX(1) | MPU_RASR_ATTR_B | MPU_RASR_ATTR_C) +#define MPU_RASR_ATTR_NON_SHARED_DEVICE (MPU_RASR_ATTR_TEX(2)) +/** @} */ + +/** + * @name Region identifiers + * @{ + */ +#define MPU_REGION_0 0U +#define MPU_REGION_1 1U +#define MPU_REGION_2 2U +#define MPU_REGION_3 3U +#define MPU_REGION_4 4U +#define MPU_REGION_5 5U +#define MPU_REGION_6 6U +#define MPU_REGION_7 7U +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Enables the MPU. + * @note MEMFAULENA is enabled in SCB_SHCSR. + * + * @param[in] ctrl MPU control modes as defined in @p MPU_CTRL register, + * the enable bit is enforced + * + * @api + */ +#define mpuEnable(ctrl) { \ + MPU->CTRL = ((uint32_t)ctrl) | MPU_CTRL_ENABLE; \ + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; \ +} + +/** + * @brief Disables the MPU. + * @note MEMFAULENA is disabled in SCB_SHCSR. + * + * @api + */ +#define mpuDisable() { \ + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; \ + MPU->CTRL = 0; \ +} + +/** + * @brief Configures an MPU region. + * + * @param[in] region the region number + * @param[in] address start address of the region, note, there are alignment + * constraints + * @param[in] attribs attributes mask as defined in @p MPU_RASR register + * + * @api + */ +#define mpuConfigureRegion(region, addr, attribs) { \ + MPU->RNR = ((uint32_t)region); \ + MPU->RBAR = ((uint32_t)addr); \ + MPU->RASR = ((uint32_t)attribs); \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _MPU_H_ */ + +/** @} */ diff --git a/os/nil/ports/AVR/nilcore.c b/os/common/ports/AVR/chcore.c similarity index 83% rename from os/nil/ports/AVR/nilcore.c rename to os/common/ports/AVR/chcore.c index 83fe441df..25a6e9c75 100644 --- a/os/nil/ports/AVR/nilcore.c +++ b/os/common/ports/AVR/chcore.c @@ -18,14 +18,14 @@ */ /** - * @file AVR/nilcore.c - * @brief AVR port code. + * @file AVR/chcore.c + * @brief AVR architecture port code. * * @addtogroup AVR_CORE * @{ */ -#include "nil.h" +#include "ch.h" /*===========================================================================*/ /* Module local definitions. */ @@ -35,6 +35,9 @@ /* Module exported variables. */ /*===========================================================================*/ +/* Executing-in-ISR global flag.*/ +bool __avr_in_isr; + /*===========================================================================*/ /* Module local types. */ /*===========================================================================*/ @@ -57,16 +60,16 @@ * is responsible for the context switch between 2 threads. * @note The implementation of this code affects directly the context * switch performance so optimize here as much as you can. - * @note The function is declared as a weak symbol, it is possible to - * redefine it in your application code. * * @param[in] ntp the thread to be switched in * @param[in] otp the thread to be switched out + * + * @todo Put into an asm module, use of naked attribute is problematic. */ #if !defined(__DOXYGEN__) __attribute__((naked, weak)) #endif -void _port_switch(thread_t *ntp, thread_t *otp) { +void port_switch(thread_t *ntp, thread_t *otp) { asm volatile ("push r2"); asm volatile ("push r3"); @@ -87,6 +90,21 @@ void _port_switch(thread_t *ntp, thread_t *otp) { asm volatile ("push r28"); asm volatile ("push r29"); +#if defined(_CHIBIOS_RT_) + asm volatile ("movw r30, r22"); + asm volatile ("in r0, 0x3d"); + asm volatile ("std Z+5, r0"); + asm volatile ("in r0, 0x3e"); + asm volatile ("std Z+6, r0"); + + asm volatile ("movw r30, r24"); + asm volatile ("ldd r0, Z+5"); + asm volatile ("out 0x3d, r0"); + asm volatile ("ldd r0, Z+6"); + asm volatile ("out 0x3e, r0"); +#endif + +#if defined(_CHIBIOS_NIL_) asm volatile ("movw r30, r22"); asm volatile ("in r0, 0x3d"); asm volatile ("std Z+0, r0"); @@ -98,6 +116,7 @@ void _port_switch(thread_t *ntp, thread_t *otp) { asm volatile ("out 0x3d, r0"); asm volatile ("ldd r0, Z+1"); asm volatile ("out 0x3e, r0"); +#endif asm volatile ("pop r29"); asm volatile ("pop r28"); @@ -131,7 +150,7 @@ void _port_thread_start(void) { asm volatile ("movw r24, r4"); asm volatile ("movw r30, r2"); asm volatile ("icall"); - chSysHalt(0); + asm volatile ("call chThdExit"); } /** @} */ diff --git a/os/nil/ports/AVR/nilcore.h b/os/common/ports/AVR/chcore.h similarity index 55% rename from os/nil/ports/AVR/nilcore.h rename to os/common/ports/AVR/chcore.h index 4d3122c22..8f7715b92 100644 --- a/os/nil/ports/AVR/nilcore.h +++ b/os/common/ports/AVR/chcore.h @@ -18,41 +18,68 @@ */ /** - * @file AVR/nilcore.h - * @brief AVR port macros and structures. + * @file templates/chcore.h + * @brief Port related template macros and structures. + * @details This file is a template of the system driver macros provided by + * a port. * - * @addtogroup AVR_CORE + * @addtogroup core * @{ */ -#ifndef _NILCORE_H_ -#define _NILCORE_H_ - -#include -#include +#ifndef _CHCORE_H_ +#define _CHCORE_H_ /*===========================================================================*/ /* Module constants. */ /*===========================================================================*/ +/** + * @name Port Capabilities and Constants + * @{ + */ +/** + * @brief This port supports a realtime counter. + */ +#define PORT_SUPPORTS_RT FALSE + +/** + * @brief Natural alignment constant. + * @note It is the minimum alignment for pointer-size variables. + */ +#define PORT_NATURAL_ALIGN 1U + +/** + * @brief Stack alignment constant. + * @note It is the alignement required for the stack pointer. + */ +#define PORT_STACK_ALIGN 1U + +/** + * @brief Working Areas alignment constant. + * @note It is the alignment to be enforced for thread working areas. + */ +#define PORT_WORKING_AREA_ALIGN 1U +/** @} */ + /** * @name Architecture and Compiler * @{ */ /** - * @brief Macro defining the port architecture. + * @brief Macro defining an AVR architecture. */ #define PORT_ARCHITECTURE_AVR /** - * @brief Name of the implemented architecture. + * @brief Macro defining the specific AVR architecture. */ -#define PORT_ARCHITECTURE_NAME "AVR" +#define PORT_ARCHITECTURE_AVR_MEGAAVR /** - * @brief Name of the architecture variant. + * @brief Name of the implemented architecture. */ -#define PORT_CORE_VARIANT_NAME "MegaAVR" +#define PORT_ARCHITECTURE_NAME "MegaAVR" /** * @brief Compiler name and version. @@ -67,12 +94,7 @@ /** * @brief Port-specific information string. */ -#define PORT_INFO "16 bits code addressing" - -/** - * @brief This port supports a realtime counter. - */ -#define PORT_SUPPORTS_RT FALSE +#define PORT_INFO "None" /** @} */ /*===========================================================================*/ @@ -84,7 +106,6 @@ * @details This size depends on the idle thread implementation, usually * the idle thread should take no more space than those reserved * by @p PORT_INT_REQUIRED_STACK. - * @note In this port it is set to 8. */ #if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__) #define PORT_IDLE_THREAD_STACK_SIZE 8 @@ -94,7 +115,6 @@ * @brief Per-thread stack overhead for interrupts servicing. * @details This constant is used in the calculation of the correct working * area size. - * @note In this port the default is 32 bytes per thread. */ #if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__) #define PORT_INT_REQUIRED_STACK 32 @@ -103,13 +123,26 @@ /** * @brief Enables an alternative timer implementation. * @details Usually the port uses a timer interface defined in the file - * @p nilcore_timer.h, if this option is enabled then the file - * @p nilcore_timer_alt.h is included instead. + * @p chcore_timer.h, if this option is enabled then the file + * @p chcore_timer_alt.h is included instead. */ -#if !defined(PORT_USE_ALT_TIMER) +#if !defined(PORT_USE_ALT_TIMER) || defined(__DOXYGEN__) #define PORT_USE_ALT_TIMER FALSE #endif +/** + * @brief Activate for devices with extended code addressing. + */ +#if !defined(PORT_AVR_3BYTES_PC) || defined(__DOXYGEN__) +#define PORT_AVR_3BYTES_PC FALSE +#endif +/** + * @brief Enables a "wait for interrupt" instruction in the idle loop. + */ +#if !defined(PORT_AVR_WFI_SLEEP_IDLE) || defined(__DOXYGEN__) +#define PORT_AVR_WFI_SLEEP_IDLE FALSE +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -124,13 +157,48 @@ /** * @brief Type of stack and memory alignment enforcement. + * @note In this architecture the stack alignment is enforced to 8 bits. */ typedef uint8_t stkalign_t; +/** + * @brief Interrupt saved context. + * @details This structure represents the stack frame saved during a + * preemption-capable interrupt handler. + * @note R2 and R13 are not saved because those are assumed to be immutable + * during the system life cycle. + */ +struct port_extctx { + uint8_t _next; + uint8_t r31; + uint8_t r30; + uint8_t r27; + uint8_t r26; + uint8_t r25; + uint8_t r24; + uint8_t r23; + uint8_t r22; + uint8_t r21; + uint8_t r20; + uint8_t r19; + uint8_t r18; + uint8_t sr; + uint8_t r1; + uint8_t r0; +#if PORT_AVR_3BYTES_PC + uint8_t pcx; +#endif + uint16_t pc; +}; + /** * @brief System saved context. * @details This structure represents the inner stack frame during a context * switching. + * @note R2 and R13 are not saved because those are assumed to be immutable + * during the system life cycle. + * @note LR is stored in the caller context so it is not present in this + * structure. */ struct port_intctx { uint8_t _next; @@ -152,13 +220,22 @@ struct port_intctx { uint8_t r4; uint8_t r3; uint8_t r2; -#ifdef __AVR_3_BYTE_PC__ +#if PORT_AVR_3BYTES_PC uint8_t pcx; #endif uint8_t pcl; uint8_t pch; }; +/** + * @brief Platform dependent part of the @p thread_t structure. + * @details This structure usually contains just the saved stack pointer + * defined as a pointer to a @p port_intctx structure. + */ +struct port_context { + struct port_intctx *sp; +}; + #endif /* !defined(_FROM_ASM_) */ /*===========================================================================*/ @@ -166,40 +243,64 @@ struct port_intctx { /*===========================================================================*/ /** - * @brief Platform dependent thread stack setup. + * @brief Platform dependent part of the @p chThdCreateI() API. * @details This code usually setup the context switching frame represented * by an @p port_intctx structure. */ -#ifdef __AVR_3_BYTE_PC__ -#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \ - (tp)->ctxp = (struct port_intctx*)(((uint8_t *)(wend)) - \ - sizeof(struct port_intctx)); \ - (tp)->ctxp->r2 = (int)pf; \ - (tp)->ctxp->r3 = (int)pf >> 8; \ - (tp)->ctxp->r4 = (int)arg; \ - (tp)->ctxp->r5 = (int)arg >> 8; \ - (tp)->ctxp->pcx = (int)0; \ - (tp)->ctxp->pcl = (int)_port_thread_start >> 8; \ - (tp)->ctxp->pch = (int)_port_thread_start; \ +#if PORT_AVR_3BYTES_PC || defined(__DOXYGEN__) +#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \ + tp->ctx.sp = (struct port_intctx *)((uint8_t *)(wtop) - \ + sizeof(struct port_intctx)); \ + tp->ctx.sp->r2 = (uint8_t)(pf); \ + tp->ctx.sp->r3 = (uint8_t)((pf) >> 8); \ + tp->ctx.sp->r4 = (uint8_t)(arg); \ + tp->ctx.sp->r5 = (uint8_t)((arg) >> 8); \ + tp->ctx.sp->pcx = (uint8_t)0; \ + tp->ctx.sp->pcl = (uint8_t)_port_thread_start >> 8; \ + tp->ctx.sp->pch = (uint8_t)_port_thread_start; \ } -#else /* __AVR_3_BYTE_PC__ */ -#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \ - (tp)->ctxp = (struct port_intctx*)(((uint8_t *)(wend)) - \ - sizeof(struct port_intctx)); \ - (tp)->ctxp->r2 = (int)pf; \ - (tp)->ctxp->r3 = (int)pf >> 8; \ - (tp)->ctxp->r4 = (int)arg; \ - (tp)->ctxp->r5 = (int)arg >> 8; \ - (tp)->ctxp->pcl = (int)_port_thread_start >> 8; \ - (tp)->ctxp->pch = (int)_port_thread_start; \ +#else /* !PORT_AVR_3BYTES_PC */ +#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \ + tp->ctx.sp = (struct port_intctx *)((uint8_t *)(wtop) - \ + sizeof(struct port_intctx)); \ + tp->ctx.sp->r2 = (uint8_t)(pf); \ + tp->ctx.sp->r3 = (uint8_t)((pf) >> 8); \ + tp->ctx.sp->r4 = (uint8_t)(arg); \ + tp->ctx.sp->r5 = (uint8_t)((arg) >> 8); \ + tp->ctx.sp->pcl = (uint8_t)_port_thread_start >> 8; \ + tp->ctx.sp->pch = (uint8_t)_port_thread_start; \ } -#endif /* __AVR_3_BYTE_PC__ */ +} +#endif /* !PORT_AVR_3BYTES_PC */ + /** * @brief Computes the thread working area global size. * @note There is no need to perform alignments in this macro. */ -#define PORT_WA_SIZE(n) ((sizeof(struct port_intctx) - 1) + \ - (n) + (PORT_INT_REQUIRED_STACK)) +#define PORT_WA_SIZE(n) ((sizeof(struct port_intctx) - 1) + \ + (sizeof(struct port_extctx) - 1) + \ + ((size_t)(n)) + ((size_t)(PORT_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. + * + * @param[in] s the name to be assigned to the stack array + * @param[in] n the stack size to be assigned to the thread + */ +#define PORT_WORKING_AREA(s, n) \ + stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)] + +/** + * @brief Priority level verification macro. + */ +#define PORT_IRQ_IS_VALID_PRIORITY(n) false + +/** + * @brief Priority level verification macro. + */ +#define PORT_IRQ_IS_VALID_KERNEL_PRIORITY(n) false /** * @brief IRQ prologue code. @@ -211,6 +312,7 @@ struct port_intctx { #define PORT_IRQ_PROLOGUE() { \ asm ("" : : : "r18", "r19", "r20", "r21", "r22", "r23", "r24", \ "r25", "r26", "r27", "r30", "r31"); \ + __avr_in_isr = true; \ } /** @@ -218,7 +320,13 @@ struct port_intctx { * @details This macro must be inserted at the end of all IRQ handlers * enabled to invoke system APIs. */ -#define PORT_IRQ_EPILOGUE() chSchRescheduleS() +#define PORT_IRQ_EPILOGUE() { \ + __avr_in_isr == false; \ + _dbg_check_lock(); \ + if (chSchIsPreemptionRequired()) \ + chSchDoReschedule(); \ + _dbg_check_unlock(); \ +} /** * @brief IRQ handler function declaration. @@ -235,16 +343,12 @@ struct port_intctx { #define PORT_FAST_IRQ_HANDLER(id) ISR(id) /** - * @brief Performs a context switch between two threads. - * @details This is the most critical code in any port, this function - * is responsible for the context switch between 2 threads. - * @note The implementation of this code affects directly the context - * switch performance so optimize here as much as you can. - * - * @param[in] ntp the thread to be switched in - * @param[in] otp the thread to be switched out + * @brief Port-related initialization code. + * @note This function is empty in this port. */ -#define port_switch(ntp, otp) _port_switch(ntp, otp) +#define port_init() { \ + __avr_in_isr = true; \ +} /*===========================================================================*/ /* External declarations. */ @@ -257,8 +361,7 @@ struct port_intctx { #ifdef __cplusplus extern "C" { #endif - void _port_irq_epilogue(void); - void _port_switch(thread_t *ntp, thread_t *otp); + void port_switch(thread_t *ntp, thread_t *otp); void _port_thread_start(void); #ifdef __cplusplus } @@ -274,13 +377,6 @@ extern "C" { asm module.*/ #if !defined(_FROM_ASM_) -/** - * @brief Port-related initialization code. - */ -static inline void port_init(void) { - -} - /** * @brief Returns a word encoding the current interrupts status. * @@ -288,7 +384,7 @@ static inline void port_init(void) { */ static inline syssts_t port_get_irq_status(void) { - return 0; + return SREG; } /** @@ -297,12 +393,12 @@ static inline syssts_t port_get_irq_status(void) { * @param[in] sts the interrupt status word * * @return The interrupt status. - * @retvel false the word specified a disabled interrupts status. - * @retvel true the word specified an enabled interrupts status. + * @retval false the word specified a disabled interrupts status. + * @retval true the word specified an enabled interrupts status. */ static inline bool port_irq_enabled(syssts_t sts) { - return false; + return (bool)((sts & 0x80) != 0); } /** @@ -314,11 +410,13 @@ static inline bool port_irq_enabled(syssts_t sts) { */ static inline bool port_is_isr_context(void) { - return false; + return __avr_in_isr; } /** * @brief Kernel-lock action. + * @details Usually this function just disables interrupts but may perform more + * actions. */ static inline void port_lock(void) { @@ -327,6 +425,8 @@ static inline void port_lock(void) { /** * @brief Kernel-unlock action. + * @details Usually this function just enables interrupts but may perform more + * actions. */ static inline void port_unlock(void) { @@ -335,6 +435,9 @@ static inline void port_unlock(void) { /** * @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 This function is empty in this port. */ static inline void port_lock_from_isr(void) { @@ -343,6 +446,9 @@ static inline void port_lock_from_isr(void) { /** * @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 This function is empty in this port. */ static inline void port_unlock_from_isr(void) { @@ -351,6 +457,7 @@ static inline void port_unlock_from_isr(void) { /** * @brief Disables all the interrupt sources. + * @note Of course non-maskable interrupt sources are not included. */ static inline void port_disable(void) { @@ -359,6 +466,7 @@ static inline void port_disable(void) { /** * @brief Disables the interrupt sources below kernel-level priority. + * @note Interrupt sources above kernel level remains enabled. */ static inline void port_suspend(void) { @@ -382,7 +490,9 @@ static inline void port_enable(void) { */ static inline void port_wait_for_interrupt(void) { +#if PORT_AVR_WFI_SLEEP_IDLE asm volatile ("sleep" : : : "memory"); +#endif } /** @@ -401,18 +511,20 @@ static inline rtcnt_t port_rt_get_counter_value(void) { /* Module late inclusions. */ /*===========================================================================*/ +/* The following code is not processed when the file is included from an + asm module.*/ #if !defined(_FROM_ASM_) -#if NIL_CFG_ST_TIMEDELTA > 0 +#if CH_CFG_ST_TIMEDELTA > 0 #if !PORT_USE_ALT_TIMER -#include "nilcore_timer.h" +#include "chcore_timer.h" #else /* PORT_USE_ALT_TIMER */ -#include "nilcore_timer_alt.h" +#include "chcore_timer_alt.h" #endif /* PORT_USE_ALT_TIMER */ -#endif /* NIL_CFG_ST_TIMEDELTA > 0 */ +#endif /* CH_CFG_ST_TIMEDELTA > 0 */ #endif /* !defined(_FROM_ASM_) */ -#endif /* _NILCORE_H_ */ +#endif /* _CHCORE_H_ */ /** @} */ diff --git a/os/nil/ports/AVR/nilcore_timer.h b/os/common/ports/AVR/chcore_timer.h similarity index 93% rename from os/nil/ports/AVR/nilcore_timer.h rename to os/common/ports/AVR/chcore_timer.h index fc00cf50f..58b01a19e 100644 --- a/os/nil/ports/AVR/nilcore_timer.h +++ b/os/common/ports/AVR/chcore_timer.h @@ -18,15 +18,15 @@ */ /** - * @file AVR/nilcore_timer.h + * @file AVR/chcore_timer.h * @brief System timer header file. * * @addtogroup AVR_TIMER * @{ */ -#ifndef _NILCORE_TIMER_H_ -#define _NILCORE_TIMER_H_ +#ifndef _CHCORE_TIMER_H_ +#define _CHCORE_TIMER_H_ /* This is the only header in the HAL designed to be include-able alone.*/ #include "st.h" @@ -119,6 +119,6 @@ static inline systime_t port_timer_get_alarm(void) { return stGetAlarm(); } -#endif /* _NILCORE_TIMER_H_ */ +#endif /* _CHCORE_TIMER_H_ */ /** @} */ diff --git a/os/nil/ports/AVR/compilers/GCC/niltypes.h b/os/common/ports/AVR/compilers/GCC/chtypes.h similarity index 50% rename from os/nil/ports/AVR/compilers/GCC/niltypes.h rename to os/common/ports/AVR/compilers/GCC/chtypes.h index 3e2e941fa..1dbab59d4 100644 --- a/os/nil/ports/AVR/compilers/GCC/niltypes.h +++ b/os/common/ports/AVR/compilers/GCC/chtypes.h @@ -18,15 +18,15 @@ */ /** - * @file AVR/compilers/GCC/niltypes.h - * @brief AVR port system types. + * @file AVR/compilers/GCC/chtypes.h + * @brief AVR architecture port system types. * * @addtogroup AVR_CORE * @{ */ -#ifndef _NILTYPES_H_ -#define _NILTYPES_H_ +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ #include #include @@ -39,33 +39,36 @@ * @brief Generic 'false' boolean constant. */ #if !defined(FALSE) || defined(__DOXYGEN__) -#define FALSE 0 +#define FALSE 0 #endif /** * @brief Generic 'true' boolean constant. */ #if !defined(TRUE) || defined(__DOXYGEN__) -#define TRUE (!FALSE) +#define TRUE (!FALSE) #endif /** @} */ -typedef uint8_t syssts_t; /**< System status word. */ -typedef uint16_t rtcnt_t; /**< Realtime counter. */ -typedef uint8_t tstate_t; /**< Thread state. */ -typedef int16_t msg_t; /**< Inter-thread message. */ -typedef uint8_t eventmask_t; /**< Mask of event identifiers. */ -typedef int8_t cnt_t; /**< Generic signed counter. */ -typedef uint8_t ucnt_t; /**< Generic unsigned counter. */ - /** - * @brief Type of system time. + * @name Kernel types + * @{ */ -#if (NIL_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__) -typedef uint32_t systime_t; -#else -typedef uint16_t systime_t; -#endif +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint8_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint8_t tprio_t; /**< Thread priority. */ +typedef int16_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint8_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint8_t eventflags_t; /**< Mask of event flags. */ +typedef uint8_t cnt_t; /**< Generic signed counter. */ +typedef uint8_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ /** * @brief ROM constant modifier. @@ -83,14 +86,18 @@ typedef uint16_t systime_t; /** * @brief Optimized thread function declaration macro. */ -#define PORT_THD_FUNCTION(tname, arg) \ - __attribute__((noreturn)) void tname(void *arg) +#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg) /** * @brief Packed variable specifier. */ #define PACKED_VAR __attribute__((packed)) -#endif /* _NILTYPES_H_ */ +/** + * @brief Memory alignment enforcement for variables. + */ +#define ALIGNED_VAR(n) __attribute__((aligned(n))) + +#endif /* _CHTYPES_H_ */ /** @} */ diff --git a/os/common/ports/AVR/compilers/GCC/mk/port.mk b/os/common/ports/AVR/compilers/GCC/mk/port.mk new file mode 100644 index 000000000..ff129b8e0 --- /dev/null +++ b/os/common/ports/AVR/compilers/GCC/mk/port.mk @@ -0,0 +1,7 @@ +# List of the ChibiOS/RT AVR port files. +PORTSRC = ${CHIBIOS}/os/rt/ports/AVR/chcore.c + +PORTASM = + +PORTINC = ${CHIBIOS}/os/rt/ports/AVR \ + ${CHIBIOS}/os/rt/ports/AVR/compilers/GCC diff --git a/os/common/ports/SIMIA32/chcore.c b/os/common/ports/SIMIA32/chcore.c new file mode 100644 index 000000000..92d0fed7f --- /dev/null +++ b/os/common/ports/SIMIA32/chcore.c @@ -0,0 +1,120 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file SIMIA32/chcore.c + * @brief Simulator on IA32 port code. + * + * @addtogroup SIMIA32_GCC_CORE + * @{ + */ + +#include + +#include "ch.h" + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +bool port_isr_context_flag; +syssts_t port_irq_sts; + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * Performs a context switch between two threads. + * @param otp the thread to be switched out + * @param ntp the thread to be switched in + */ +__attribute__((used)) +static void __dummy(thread_t *ntp, thread_t *otp) { + (void)ntp; (void)otp; + + asm volatile ( +#if defined(WIN32) + ".globl @port_switch@8 \n\t" + "@port_switch@8:" +#elif defined(__APPLE__) + ".globl _port_switch \n\t" + "_port_switch:" +#else + ".globl port_switch \n\t" + "port_switch:" +#endif + "push %ebp \n\t" + "push %esi \n\t" + "push %edi \n\t" + "push %ebx \n\t" + "movl %esp, 12(%edx) \n\t" + "movl 12(%ecx), %esp \n\t" + "pop %ebx \n\t" + "pop %edi \n\t" + "pop %esi \n\t" + "pop %ebp \n\t" + "ret"); +} + +/** + * @brief Start a thread by invoking its work function. + * @details If the work function returns @p chThdExit() is automatically + * invoked. + */ +__attribute__((cdecl, noreturn)) +void _port_thread_start(msg_t (*pf)(void *), void *p) { + + chSysUnlock(); + pf(p); + chThdExit(0); + while(1); +} + + +/** + * @brief Returns the current value of the realtime counter. + * + * @return The realtime counter value. + */ +rtcnt_t port_rt_get_counter_value(void) { + LARGE_INTEGER n; + + QueryPerformanceCounter(&n); + + return (rtcnt_t)(n.QuadPart / 1000LL); +} + +/** @} */ diff --git a/os/common/ports/SIMIA32/chcore.h b/os/common/ports/SIMIA32/chcore.h new file mode 100644 index 000000000..c9b9d6861 --- /dev/null +++ b/os/common/ports/SIMIA32/chcore.h @@ -0,0 +1,382 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file SIMIA32/chcore.h + * @brief Simulator on IA32 port macros and structures. + * + * @addtogroup SIMIA32_GCC_CORE + * @{ + */ + +#ifndef _CHCORE_H_ +#define _CHCORE_H_ + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/** + * Macro defining the a simulated architecture into x86. + */ +#define PORT_ARCHITECTURE_SIMIA32 + +/** + * Name of the implemented architecture. + */ +#define PORT_ARCHITECTURE_NAME "Simulator" + +/** + * @brief Name of the architecture variant (optional). + */ +#define PORT_CORE_VARIANT_NAME "x86 (integer only)" + +/** + * @brief Name of the compiler supported by this port. + */ +#define PORT_COMPILER_NAME "GCC " __VERSION__ + +/** + * @brief Port-specific information string. + */ +#define PORT_INFO "No preemption" + +/** + * @brief This port supports a realtime counter. + */ +#define PORT_SUPPORTS_RT TRUE + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @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 PORT_INT_REQUIRED_STACK. + */ +#ifndef PORT_IDLE_THREAD_STACK_SIZE +#define PORT_IDLE_THREAD_STACK_SIZE 256 +#endif + +/** + * @brief Per-thread stack overhead for interrupts servicing. + * @details This constant is used in the calculation of the correct working + * area size. + */ +#ifndef PORT_INT_REQUIRED_STACK +#define PORT_INT_REQUIRED_STACK 16384 +#endif + +/** + * @brief Enables an alternative timer implementation. + * @details Usually the port uses a timer interface defined in the file + * @p chcore_timer.h, if this option is enabled then the file + * @p chcore_timer_alt.h is included instead. + */ +#if !defined(PORT_USE_ALT_TIMER) +#define PORT_USE_ALT_TIMER FALSE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if CH_DBG_ENABLE_STACK_CHECK +#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief 16 bytes stack and memory alignment enforcement. + */ +typedef struct { + uint8_t a[16]; +} stkalign_t __attribute__((aligned(16))); + +/** + * @brief Type of a generic x86 register. + */ +typedef void *regx86; + +/** + * @brief Interrupt saved context. + * @details This structure represents the stack frame saved during a + * preemption-capable interrupt handler. + */ +struct port_extctx { +}; + +/** + * @brief System saved context. + * @details This structure represents the inner stack frame during a context + * switch. + */ +struct port_intctx { + regx86 ebx; + regx86 edi; + regx86 esi; + regx86 ebp; + regx86 eip; +}; + +/** + * @brief Platform dependent part of the @p thread_t structure. + * @details In this port the structure just holds a pointer to the + * @p port_intctx structure representing the stack pointer + * at context switch time. + */ +struct context { + struct port_intctx *esp; +}; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +#define APUSH(p, a) do { \ + (p) -= sizeof(void *); \ + *(void **)(p) = (void*)(a); \ +} while (false) + +/* Darwin requires the stack to be aligned to a 16-byte boundary at + * the time of a call instruction (in case the called function needs + * to save MMX registers). This aligns to 'mod' module 16, so that we'll end + * up with the right alignment after pushing the args. */ +#define AALIGN(p, mask, mod) \ + p = (void *)((((uint32_t)(p) - (uint32_t)(mod)) & ~(uint32_t)(mask)) + (uint32_t)(mod)) \ + +/** + * @brief Platform dependent part of the @p chThdCreateI() API. + * @details This code usually setup the context switching frame represented + * by an @p port_intctx structure. + */ +#define PORT_SETUP_CONTEXT(tp, workspace, wsize, pf, arg) { \ + /*lint -save -e611 -e9033 -e9074 -e9087 [10.8, 11.1, 11.3] Valid casts.*/ \ + uint8_t *esp = (uint8_t *)workspace + wsize; \ + APUSH(esp, 0); \ + uint8_t *savebp = esp; \ + AALIGN(esp, 15, 8); \ + APUSH(esp, arg); \ + APUSH(esp, pf); \ + APUSH(esp, 0); \ + esp -= sizeof(struct port_intctx); \ + ((struct port_intctx *)esp)->eip = (void *)_port_thread_start; \ + ((struct port_intctx *)esp)->ebx = NULL; \ + ((struct port_intctx *)esp)->edi = NULL; \ + ((struct port_intctx *)esp)->esi = NULL; \ + ((struct port_intctx *)esp)->ebp = (void *)savebp; \ + (tp)->p_ctx.esp = (struct port_intctx *)esp; \ + /*lint -restore*/ \ +} + + /** + * @brief Computes the thread working area global size. + * @note There is no need to perform alignments in this macro. + */ +#define PORT_WA_SIZE(n) ((sizeof(void *) * 4U) + \ + sizeof(struct port_intctx) + \ + ((size_t)(n)) + \ + ((size_t)(PORT_INT_REQUIRED_STACK))) + +/** + * @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() { \ + port_isr_context_flag = true; \ +} + +/** + * @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() { \ + port_isr_context_flag = false; \ +} + + +/** + * @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 Fast IRQ handler function declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + */ +#define PORT_FAST_IRQ_HANDLER(id) void id(void) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +extern bool port_isr_context_flag; +extern syssts_t port_irq_sts; + +#ifdef __cplusplus +extern "C" { +#endif + /*lint -save -e950 [Dir-2.1] Non-ANSI keywords are fine in the port layer.*/ + __attribute__((fastcall)) void port_switch(thread_t *ntp, thread_t *otp); + __attribute__((cdecl, noreturn)) void _port_thread_start(msg_t (*pf)(void *p), + void *p); + /*lint -restore*/ + rtcnt_t port_rt_get_counter_value(void); + void _sim_check_for_interrupts(void); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Port-related initialization code. + */ +static inline void port_init(void) { + + port_irq_sts = (syssts_t)0; + port_isr_context_flag = false; +} + +/** + * @brief Returns a word encoding the current interrupts status. + * + * @return The interrupts status. + */ +static inline syssts_t port_get_irq_status(void) { + + return port_irq_sts; +} + +/** + * @brief Checks the interrupt status. + * + * @param[in] sts the interrupt status word + * + * @return The interrupt status. + * @retval false the word specified a disabled interrupts status. + * @retval true the word specified an enabled interrupts status. + */ +static inline bool port_irq_enabled(syssts_t sts) { + + return sts == (syssts_t)0; +} + +/** + * @brief Determines the current execution context. + * + * @return The execution context. + * @retval false not running in ISR mode. + * @retval true running in ISR mode. + */ +static inline bool port_is_isr_context(void) { + + return port_isr_context_flag; +} + +/** + * @brief Kernel-lock action. + * @details In this port this function disables interrupts globally. + */ +static inline void port_lock(void) { + + port_irq_sts = (syssts_t)1; +} + +/** + * @brief Kernel-unlock action. + * @details In this port this function enables interrupts globally. + */ +static inline void port_unlock(void) { + + port_irq_sts = (syssts_t)0; +} + +/** + * @brief Kernel-lock action from an interrupt handler. + * @details In this port this function disables interrupts globally. + * @note Same as @p port_lock() in this port. + */ +static inline void port_lock_from_isr(void) { + + port_irq_sts = (syssts_t)1; +} + +/** + * @brief Kernel-unlock action from an interrupt handler. + * @details In this port this function enables interrupts globally. + * @note Same as @p port_lock() in this port. + */ +static inline void port_unlock_from_isr(void) { + + port_irq_sts = (syssts_t)0; +} + +/** + * @brief Disables all the interrupt sources. + */ +static inline void port_disable(void) { + + port_irq_sts = (syssts_t)1; +} + +/** + * @brief Disables the interrupt sources below kernel-level priority. + */ +static inline void port_suspend(void) { + + port_irq_sts = (syssts_t)1; +} + +/** + * @brief Enables all the interrupt sources. + */ +static inline void port_enable(void) { + + port_irq_sts = (syssts_t)0; +} + +/** + * @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. + */ +static inline void port_wait_for_interrupt(void) { + + _sim_check_for_interrupts(); +} + +#endif /* _CHCORE_H_ */ + +/** @} */ diff --git a/os/common/ports/SIMIA32/compilers/GCC/chtypes.h b/os/common/ports/SIMIA32/compilers/GCC/chtypes.h new file mode 100644 index 000000000..175a44287 --- /dev/null +++ b/os/common/ports/SIMIA32/compilers/GCC/chtypes.h @@ -0,0 +1,110 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file SIMIA32/compilers/GCC/chtypes.h + * @brief Simulator on IA32 port system types. + * + * @addtogroup SIMIA32_GCC_CORE + * @{ + */ + +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ + +#include +#include +#include + +/** + * @name Common constants + */ +/** + * @brief Generic 'false' boolean constant. + */ +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +/** + * @brief Generic 'true' boolean constant. + */ +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE 1 +#endif +/** @} */ + +/** + * @name Derived generic types + * @{ + */ +typedef volatile int8_t vint8_t; /**< Volatile signed 8 bits. */ +typedef volatile uint8_t vuint8_t; /**< Volatile unsigned 8 bits. */ +typedef volatile int16_t vint16_t; /**< Volatile signed 16 bits. */ +typedef volatile uint16_t vuint16_t; /**< Volatile unsigned 16 bits. */ +typedef volatile int32_t vint32_t; /**< Volatile signed 32 bits. */ +typedef volatile uint32_t vuint32_t; /**< Volatile unsigned 32 bits. */ +/** @} */ + +/** + * @name Kernel types + * @{ + */ +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint32_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint32_t tprio_t; /**< Thread priority. */ +typedef int32_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint32_t eventflags_t; /**< Mask of event flags. */ +typedef int32_t cnt_t; /**< Generic signed counter. */ +typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ + +/** + * @brief ROM constant modifier. + * @note It is set to use the "const" keyword in this port. + */ +#define ROMCONST const + +/** + * @brief Makes functions not inlineable. + * @note If the compiler does not support such attribute then the + * realtime counter precision could be degraded. + */ +#define NOINLINE __attribute__((noinline)) + +/** + * @brief Optimized thread function declaration macro. + */ +#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg) + +/** + * @brief Packed variable specifier. + */ +#define PACKED_VAR __attribute__((packed)) + +#endif /* _CHTYPES_H_ */ + +/** @} */ diff --git a/os/common/ports/SIMIA32/compilers/GCC/port.mk b/os/common/ports/SIMIA32/compilers/GCC/port.mk new file mode 100644 index 000000000..0d5f0903d --- /dev/null +++ b/os/common/ports/SIMIA32/compilers/GCC/port.mk @@ -0,0 +1,7 @@ +# List of the ChibiOS/RT SIMIA32 port files. +PORTSRC = ${CHIBIOS}/os/rt/ports/SIMIA32/chcore.c + +PORTASM = + +PORTINC = ${CHIBIOS}/os/rt/ports/SIMIA32/compilers/GCC \ + ${CHIBIOS}/os/rt/ports/SIMIA32 diff --git a/os/common/ports/e200/chcore.c b/os/common/ports/e200/chcore.c new file mode 100644 index 000000000..5f410b88f --- /dev/null +++ b/os/common/ports/e200/chcore.c @@ -0,0 +1,54 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file e200/chcore.c + * @brief Power e200 port code. + * + * @addtogroup PPC_CORE + * @{ + */ + +#include "ch.h" + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/nil/ports/e200/nilcore.h b/os/common/ports/e200/chcore.h similarity index 75% rename from os/nil/ports/e200/nilcore.h rename to os/common/ports/e200/chcore.h index ac5a32433..43e8bb151 100644 --- a/os/nil/ports/e200/nilcore.h +++ b/os/common/ports/e200/chcore.h @@ -18,15 +18,15 @@ */ /** - * @file templates/nilcore.h - * @brief Port macros and structures. + * @file PPC/chcore.h + * @brief Power e200 port macros and structures. * - * @addtogroup NIL_CORE + * @addtogroup PPC_CORE * @{ */ -#ifndef _NILCORE_H_ -#define _NILCORE_H_ +#ifndef _CHCORE_H_ +#define _CHCORE_H_ #include "intc.h" @@ -34,6 +34,34 @@ /* Module constants. */ /*===========================================================================*/ +/** + * @name Port Capabilities and Constants + * @{ + */ +/** + * @brief This port supports a realtime counter. + */ +#define PORT_SUPPORTS_RT FALSE + +/** + * @brief Natural alignment constant. + * @note It is the minimum alignment for pointer-size variables. + */ +#define PORT_NATURAL_ALIGN sizeof (void *) + +/** + * @brief Stack alignment constant. + * @note It is the alignement required for the stack pointer. + */ +#define PORT_STACK_ALIGN sizeof (stkalign_t) + +/** + * @brief Working Areas alignment constant. + * @note It is the alignment to be enforced for thread working areas. + */ +#define PORT_WORKING_AREA_ALIGN sizeof (stkalign_t) +/** @} */ + /** * @name Architecture and Compiler * @{ @@ -59,14 +87,12 @@ #if defined(__GNUC__) || defined(__DOXYGEN__) #define PORT_COMPILER_NAME "GCC " __VERSION__ +#elif defined(__MWERKS__) +#define PORT_COMPILER_NAME "CW" + #else #error "unsupported compiler" #endif - -/** - * @brief This port supports a realtime counter. - */ -#define PORT_SUPPORTS_RT FALSE /** @} */ /** @@ -87,10 +113,25 @@ /* Module pre-compile time settings. */ /*===========================================================================*/ +/** + * @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 PORT_INT_REQUIRED_STACK. + * @note In this port it is set to 32 because the idle thread does have + * a stack frame when compiling without optimizations. You may + * reduce this value to zero when compiling with optimizations. + */ +#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__) +#define PORT_IDLE_THREAD_STACK_SIZE 32 +#endif + /** * @brief Per-thread stack overhead for interrupts servicing. * @details This constant is used in the calculation of the correct working * area size. + * @note In this port this value is conservatively is set to 256 because + * there is no separate interrupts stack (yet). */ #if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__) #define PORT_INT_REQUIRED_STACK 256 @@ -99,8 +140,8 @@ /** * @brief Enables an alternative timer implementation. * @details Usually the port uses a timer interface defined in the file - * @p nilcore_timer.h, if this option is enabled then the file - * @p nilcore_timer_alt.h is included instead. + * @p chcore_timer.h, if this option is enabled then the file + * @p chcore_timer_alt.h is included instead. */ #if !defined(PORT_USE_ALT_TIMER) || defined(__DOXYGEN__) #define PORT_USE_ALT_TIMER FALSE @@ -167,6 +208,7 @@ /** * @brief Type of stack and memory alignment enforcement. + * @note In this architecture the stack alignment is enforced to 64 bits. */ typedef uint64_t stkalign_t; @@ -213,7 +255,7 @@ struct port_extctx { regppc_t r11; regppc_t r12; regppc_t padding; - }; +}; /** * @brief System saved context. @@ -247,6 +289,15 @@ struct port_intctx { regppc_t padding; }; +/** + * @brief Platform dependent part of the @p thread_t structure. + * @details This structure usually contains just the saved stack pointer + * defined as a pointer to a @p port_intctx structure. + */ +struct port_context { + struct port_intctx *sp; +}; + #endif /* !defined(_FROM_ASM_) */ /*===========================================================================*/ @@ -254,18 +305,17 @@ struct port_intctx { /*===========================================================================*/ /** - * @brief Platform dependent thread stack setup. + * @brief Platform dependent part of the @p chThdCreateI() API. * @details This code usually setup the context switching frame represented * by an @p port_intctx structure. */ -#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \ - uint8_t *sp = (uint8_t *)(wend) - \ - sizeof(struct port_eabi_frame); \ +#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \ + uint8_t *sp = (uint8_t *)(wtop) - sizeof(struct port_eabi_frame); \ ((struct port_eabi_frame *)sp)->slink = 0; \ ((struct port_eabi_frame *)sp)->shole = (uint32_t)_port_thread_start; \ - (tp)->ctxp = (struct port_intctx *)(sp - sizeof(struct port_intctx)); \ - (tp)->ctxp->r31 = (regppc_t)(arg); \ - (tp)->ctxp->r30 = (regppc_t)(pf); \ + (tp)->ctx.sp = (struct port_intctx *)(sp - sizeof(struct port_intctx)); \ + (tp)->ctx.sp->r31 = (regppc_t)(arg); \ + (tp)->ctx.sp->r30 = (regppc_t)(pf); \ } /** @@ -274,7 +324,18 @@ struct port_intctx { */ #define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \ sizeof(struct port_extctx) + \ - (n) + (PORT_INT_REQUIRED_STACK)) + ((size_t)(n)) + ((size_t)(PORT_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. + * + * @param[in] s the name to be assigned to the stack array + * @param[in] n the stack size to be assigned to the thread + */ +#define PORT_WORKING_AREA(s, n) \ + stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)] /** * @brief IRQ prologue code. @@ -326,12 +387,12 @@ struct port_intctx { * @param[in] ntp the thread to be switched in * @param[in] otp the thread to be switched out */ -#if !NIL_CFG_ENABLE_STACK_CHECK || defined(__DOXYGEN__) +#if !CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__) #define port_switch(ntp, otp) _port_switch(ntp, otp) #else #define port_switch(ntp, otp) { \ register struct port_intctx *sp asm ("%r1"); \ - if ((stkalign_t *)(sp - 1) < otp->stklim) \ + if ((stkalign_t *)(sp - 1) < otp->stklimit) \ chSysHalt("stack overflow"); \ _port_switch(ntp, otp); \ } @@ -383,7 +444,8 @@ extern "C" { #if !defined(_FROM_ASM_) /** - * @brief Port-related initialization code. + * @brief Kernel port layer initialization. + * @details IVOR4 and IVOR10 initialization. */ static inline void port_init(void) { uint32_t n; @@ -395,12 +457,17 @@ static inline void port_init(void) { port_write_spr(272, n); #if PPC_SUPPORTS_IVORS - /* The CPU supports IVOR registers, the kernel requires IVOR4 and IVOR10 - and the initialization is performed here.*/ - asm volatile ("li %%r3, _IVOR4@l \t\n" - "mtIVOR4 %%r3 \t\n" - "li %%r3, _IVOR10@l \t\n" - "mtIVOR10 %%r3" : : : "r3", "memory"); + { + /* The CPU supports IVOR registers, the kernel requires IVOR4 and IVOR10 + and the initialization is performed here.*/ + extern void _IVOR4(void); + port_write_spr(404, _IVOR4); + +#if PPC_SUPPORTS_DECREMENTER + extern void _IVOR10(void); + port_write_spr(410, _IVOR10); +#endif + } #endif /* INTC initialization, software vector mode, 4 bytes vectors, starting @@ -430,8 +497,8 @@ static inline syssts_t port_get_irq_status(void) { * @param[in] sts the interrupt status word * * @return The interrupt status. - * @retvel false the word specified a disabled interrupts status. - * @retvel true the word specified an enabled interrupts status. + * @retval false the word specified a disabled interrupts status. + * @retval true the word specified an enabled interrupts status. */ static inline bool port_irq_enabled(syssts_t sts) { @@ -456,6 +523,7 @@ static inline bool port_is_isr_context(void) { /** * @brief Kernel-lock action. + * @note Implemented as global interrupt disable. */ static inline void port_lock(void) { @@ -464,6 +532,7 @@ static inline void port_lock(void) { /** * @brief Kernel-unlock action. + * @note Implemented as global interrupt enable. */ static inline void port_unlock(void) { @@ -472,6 +541,7 @@ static inline void port_unlock(void) { /** * @brief Kernel-lock action from an interrupt handler. + * @note Implementation not needed. */ static inline void port_lock_from_isr(void) { @@ -479,6 +549,7 @@ static inline void port_lock_from_isr(void) { /** * @brief Kernel-unlock action from an interrupt handler. + * @note Implementation not needed. */ static inline void port_unlock_from_isr(void) { @@ -486,6 +557,7 @@ static inline void port_unlock_from_isr(void) { /** * @brief Disables all the interrupt sources. + * @note Implemented as global interrupt disable. */ static inline void port_disable(void) { @@ -494,6 +566,8 @@ static inline void port_disable(void) { /** * @brief Disables the interrupt sources below kernel-level priority. + * @note Same as @p port_disable() in this port, there is no difference + * between the two states. */ static inline void port_suspend(void) { @@ -502,6 +576,7 @@ static inline void port_suspend(void) { /** * @brief Enables all the interrupt sources. + * @note Implemented as global interrupt enable. */ static inline void port_enable(void) { @@ -514,6 +589,7 @@ static inline void port_enable(void) { * 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 wait instruction. */ static inline void port_wait_for_interrupt(void) { @@ -540,16 +616,16 @@ static inline rtcnt_t port_rt_get_counter_value(void) { #if !defined(_FROM_ASM_) -#if NIL_CFG_ST_TIMEDELTA > 0 +#if CH_CFG_ST_TIMEDELTA > 0 #if !PORT_USE_ALT_TIMER -#include "nilcore_timer.h" +#include "chcore_timer.h" #else /* PORT_USE_ALT_TIMER */ -#include "nilcore_timer_alt.h" +#include "chcore_timer_alt.h" #endif /* PORT_USE_ALT_TIMER */ -#endif /* NIL_CFG_ST_TIMEDELTA > 0 */ +#endif /* CH_CFG_ST_TIMEDELTA > 0 */ #endif /* !defined(_FROM_ASM_) */ -#endif /* _NILCORE_H_ */ +#endif /* _CHCORE_H_ */ /** @} */ diff --git a/os/common/ports/e200/compilers/CW/chcoreasm.s b/os/common/ports/e200/compilers/CW/chcoreasm.s new file mode 100644 index 000000000..85da7221f --- /dev/null +++ b/os/common/ports/e200/compilers/CW/chcoreasm.s @@ -0,0 +1,124 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file e200/compilers/GCC/chcoreasm.s + * @brief Power Architecture port low level code. + * + * @addtogroup PPC_GCC_CORE + * @{ + */ + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE 1 +#endif + +/*===========================================================================*/ +/* Code section. */ +/*===========================================================================*/ + +/* + * Imports the PPC configuration headers. + */ +#define _FROM_ASM_ +#include "chconf.h" +#include "chcore.h" + +#if !defined(__DOXYGEN__) + +/* + * RTOS-specific context offset. + */ +#if defined(_CHIBIOS_RT_CONF_) +#define CONTEXT_OFFSET 12 +#elif defined(_CHIBIOS_NIL_CONF_) +#define CONTEXT_OFFSET 0 +#else +#error "invalid chconf.h" +#endif + +#if defined(_CHIBIOS_RT_CONF_) + .extern chThdExit +#endif + +#if PPC_USE_VLE == TRUE + .section .text_vle, 16 + + .align 2 + .globl _port_switch + .type _port_switch, @function +_port_switch: + e_subi r1, r1, 80 + se_mflr r0 + e_stw r0, 84(r1) + mfcr r0 + se_stw r0, 0(r1) + e_stmw r14, 4(r1) + + se_stw r1, 12(r4) + se_lwz r1, 12(r3) + + e_lmw r14, 4(r1) + se_lwz r0, 0(r1) + mtcr r0 + e_lwz r0, 84(r1) + se_mtlr r0 + e_addi r1, r1, 80 + se_blr + + .align 2 + .globl _port_thread_start + .type _port_thread_start, @function +_port_thread_start: +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif + wrteei 1 + mr r3, r31 + mtctr r30 + se_bctrl +#if defined(_CHIBIOS_RT_CONF_) + se_li r0, 0 + e_bl chThdExit +#endif +#if defined(_CHIBIOS_NIL_CONF_) + se_li r0, 0 + e_bl chSysHalt +#endif + +#else /* PPC_USE_VLE == FALSE */ + +#error "non-VLE mode not yet implemented" + +#endif /* PPC_USE_VLE == FALSE */ + +#endif /* !defined(__DOXYGEN__) */ + +/** @} */ diff --git a/os/common/ports/e200/compilers/CW/chtypes.h b/os/common/ports/e200/compilers/CW/chtypes.h new file mode 100644 index 000000000..e0fa7f6b3 --- /dev/null +++ b/os/common/ports/e200/compilers/CW/chtypes.h @@ -0,0 +1,93 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file e200/compilers/CW/chtypes.h + * @brief Power e200 port system types. + * + * @addtogroup PPC_CW_CORE + * @{ + */ + +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ + +#include +#include +#include + +/** + * @name Common constants + */ +/** + * @brief Generic 'false' boolean constant. + */ +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +/** + * @brief Generic 'true' boolean constant. + */ +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE 1 +#endif +/** @} */ + +/** + * @name Kernel types + * @{ + */ +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint32_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint32_t tprio_t; /**< Thread priority. */ +typedef int32_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint32_t eventflags_t; /**< Mask of event flags. */ +typedef int32_t cnt_t; /**< Generic signed counter. */ +typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ + +/** + * @brief ROM constant modifier. + * @note It is set to use the "const" keyword in this port. + */ +#define ROMCONST const + +/** + * @brief Makes functions not inlineable. + * @note If the compiler does not support such attribute then the + * realtime counter precision could be degraded. + */ +#define NOINLINE __attribute__((noinline)) + +/** + * @brief Optimized thread function declaration macro. + */ +#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg) + +#endif /* _CHTYPES_H_ */ + +/** @} */ diff --git a/os/common/ports/e200/compilers/CW/ivor.s b/os/common/ports/e200/compilers/CW/ivor.s new file mode 100644 index 000000000..d8bbcad65 --- /dev/null +++ b/os/common/ports/e200/compilers/CW/ivor.s @@ -0,0 +1,204 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file ivor.s + * @brief Kernel ISRs. + * + * @addtogroup PPC_CORE + * @{ + */ + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE 1 +#endif + +/*===========================================================================*/ +/* Code section. */ +/*===========================================================================*/ + +/* + * Imports the PPC configuration headers. + */ +#define _FROM_ASM_ +#include "chconf.h" +#include "chcore.h" + +#if !defined(__DOXYGEN__) + + .extern _stats_start_measure_crit_thd + .extern _stats_stop_measure_crit_thd + .extern _dbg_check_lock + .extern _dbg_check_unlock + .extern chSchIsPreemptionRequired + .extern chSchDoReschedule + .extern chSysTimerHandlerI + + .section .handlers, text_vle + +#if PPC_USE_VLE == TRUE + +#if PPC_SUPPORTS_DECREMENTER + /* + * _IVOR10 handler (Book-E decrementer). + */ + .align 16 + .globl _IVOR10 + .type _IVOR10, @function +_IVOR10: + /* Saving the external context (port_extctx structure).*/ + e_stwu r1, -80(r1) + e_stmvsrrw 8(r1) /* Saves PC, MSR. */ + e_stmvsprw 16(r1) /* Saves CR, LR, CTR, XER. */ + e_stmvgprw 32(r1) /* Saves GPR0, GPR3...GPR12. */ + + /* Increasing the SPGR0 register.*/ + mfspr r0, 272 + se_addi r0, 1 + mtspr 272, r0 + + /* Reset DIE bit in TSR register.*/ + e_lis r3, 0x0800 /* DIS bit mask. */ + mtspr 336, r3 /* TSR register. */ + + /* Restoring pre-IRQ MSR register value.*/ + mfSRR1 r0 +#if !PPC_USE_IRQ_PREEMPTION + /* No preemption, keeping EE disabled.*/ + se_bclri r0, 16 /* EE = bit 16. */ +#endif + mtMSR r0 + +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_enter_isr + bl _dbg_check_lock_from_isr +#endif + /* System tick handler invocation.*/ + e_bl chSysTimerHandlerI +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock_from_isr + bl _dbg_check_leave_isr +#endif + +#if PPC_USE_IRQ_PREEMPTION + /* Prevents preemption again.*/ + wrteei 0 +#endif + + /* Jumps to the common IVOR epilogue code.*/ + se_b _ivor_exit +#endif /* PPC_SUPPORTS_DECREMENTER */ + + /* + * _IVOR4 handler (Book-E external interrupt). + */ + .align 16 + .globl _IVOR4 + .type _IVOR4, @function +_IVOR4: + /* Saving the external context (port_extctx structure).*/ + e_stwu r1, -80(r1) + e_stmvsrrw 8(r1) /* Saves PC, MSR. */ + e_stmvsprw 16(r1) /* Saves CR, LR, CTR, XER. */ + e_stmvgprw 32(r1) /* Saves GPR0, GPR3...GPR12. */ + + /* Increasing the SPGR0 register.*/ + mfspr r0, 272 + se_addi r0, 1 + mtspr 272, r0 + + /* Software vector address from the INTC register.*/ + e_lis r3, INTC_IACKR_ADDR@h + e_or2i r3, INTC_IACKR_ADDR@l /* IACKR register address. */ + se_lwz r3, 0(r3) /* IACKR register value. */ + se_lwz r3, 0(r3) + mtCTR r3 /* Software handler address. */ + + /* Restoring pre-IRQ MSR register value.*/ + mfSRR1 r0 +#if !PPC_USE_IRQ_PREEMPTION + /* No preemption, keeping EE disabled.*/ + se_bclri r0, 16 /* EE = bit 16. */ +#endif + mtMSR r0 + + /* Exectes the software handler.*/ + se_bctrl + +#if PPC_USE_IRQ_PREEMPTION + /* Prevents preemption again.*/ + wrteei 0 +#endif + + /* Informs the INTC that the interrupt has been served.*/ + mbar 0 + e_lis r3, INTC_EOIR_ADDR@h + e_or2i r3, INTC_EOIR_ADDR@l + se_stw r3, 0(r3) /* Writing any value should do. */ + + /* Common IVOR epilogue code, context restore.*/ + .globl _ivor_exit +_ivor_exit: + /* Decreasing the SPGR0 register.*/ + mfspr r0, 272 + se_subi r0, 1 + mtspr 272, r0 + +#if CH_DBG_STATISTICS + e_bl _stats_start_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + e_bl _dbg_check_lock +#endif + e_bl chSchIsPreemptionRequired + e_cmpli cr0, r3, 0 + se_beq .noresch + e_bl chSchDoReschedule +.noresch: +#if CH_DBG_SYSTEM_STATE_CHECK + e_bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + e_bl _stats_stop_measure_crit_thd +#endif + + /* Restoring the external context.*/ + e_lmvgprw 32(r1) /* Restores GPR0, GPR3...GPR12. */ + e_lmvsprw 16(r1) /* Restores CR, LR, CTR, XER. */ + e_lmvsrrw 8(r1) /* Restores PC, MSR. */ + e_addi r1, r1, 80 /* Back to the previous frame. */ + se_rfi + +#else /* PPC_USE_VLE == FALSE */ + +#error "non-VLE mode not yet implemented" + +#endif /* PPC_USE_VLE == FALSE */ + +#endif /* !defined(__DOXYGEN__) */ + +/** @} */ diff --git a/os/common/ports/e200/compilers/GCC/chcoreasm.s b/os/common/ports/e200/compilers/GCC/chcoreasm.s new file mode 100644 index 000000000..5d915247c --- /dev/null +++ b/os/common/ports/e200/compilers/GCC/chcoreasm.s @@ -0,0 +1,114 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file e200/compilers/GCC/chcoreasm.s + * @brief Power Architecture port low level code. + * + * @addtogroup PPC_GCC_CORE + * @{ + */ + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE 1 +#endif + +/*===========================================================================*/ +/* Code section. */ +/*===========================================================================*/ + +#define _FROM_ASM_ +#include "chconf.h" +#include "chcore.h" + +#if !defined(__DOXYGEN__) + +/* + * RTOS-specific context offset. + */ +#if defined(_CHIBIOS_RT_CONF_) +#define CONTEXT_OFFSET 12 +#elif defined(_CHIBIOS_NIL_CONF_) +#define CONTEXT_OFFSET 0 +#else +#error "invalid chconf.h" +#endif + +#if PPC_USE_VLE == TRUE + .section .text_vle, "ax" +#else + .section .text, "ax" +#endif + + .align 2 + .globl _port_switch + .type _port_switch, @function +_port_switch: + subi %sp, %sp, 80 + mflr %r0 + stw %r0, 84(%sp) + mfcr %r0 + stw %r0, 0(%sp) + stmw %r14, 4(%sp) + + stw %sp, 12(%r4) + lwz %sp, 12(%r3) + + lmw %r14, 4(%sp) + lwz %r0, 0(%sp) + mtcr %r0 + lwz %r0, 84(%sp) + mtlr %r0 + addi %sp, %sp, 80 + blr + + .align 2 + .globl _port_thread_start + .type _port_thread_start, @function +_port_thread_start: +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif + wrteei 1 + mr %r3, %r31 + mtctr %r30 + bctrl +#if defined(_CHIBIOS_RT_CONF_) + li %r0, 0 + bl chThdExit +#endif +#if defined(_CHIBIOS_NIL_CONF_) + se_li %r0, 0 + e_bl chSysHalt +#endif + +#endif /* !defined(__DOXYGEN__) */ + +/** @} */ diff --git a/os/nil/ports/e200/compilers/GCC/niltypes.h b/os/common/ports/e200/compilers/GCC/chtypes.h similarity index 53% rename from os/nil/ports/e200/compilers/GCC/niltypes.h rename to os/common/ports/e200/compilers/GCC/chtypes.h index 587beb26e..38d4fd59e 100644 --- a/os/nil/ports/e200/compilers/GCC/niltypes.h +++ b/os/common/ports/e200/compilers/GCC/chtypes.h @@ -18,15 +18,15 @@ */ /** - * @file e200/compilers/GCC/niltypes.h + * @file e200/compilers/GCC/chtypes.h * @brief Power e200 port system types. * * @addtogroup PPC_GCC_CORE * @{ */ -#ifndef _NILTYPES_H_ -#define _NILTYPES_H_ +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ #include #include @@ -39,33 +39,36 @@ * @brief Generic 'false' boolean constant. */ #if !defined(FALSE) || defined(__DOXYGEN__) -#define FALSE 0 +#define FALSE 0 #endif /** * @brief Generic 'true' boolean constant. */ #if !defined(TRUE) || defined(__DOXYGEN__) -#define TRUE (!FALSE) +#define TRUE 1 #endif /** @} */ -typedef uint32_t syssts_t; /**< System status word. */ -typedef uint32_t rtcnt_t; /**< Realtime counter. */ -typedef uint8_t tstate_t; /**< Thread state. */ -typedef int32_t msg_t; /**< Inter-thread message. */ -typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ -typedef int32_t cnt_t; /**< Generic signed counter. */ -typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ - /** - * @brief Type of system time. + * @name Kernel types + * @{ */ -#if (NIL_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__) -typedef uint32_t systime_t; -#else -typedef uint16_t systime_t; -#endif +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint32_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint32_t tprio_t; /**< Thread priority. */ +typedef int32_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint32_t eventflags_t; /**< Mask of event flags. */ +typedef int32_t cnt_t; /**< Generic signed counter. */ +typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ /** * @brief ROM constant modifier. @@ -83,14 +86,8 @@ typedef uint16_t systime_t; /** * @brief Optimized thread function declaration macro. */ -#define PORT_THD_FUNCTION(tname, arg) \ - __attribute__((noreturn)) void tname(void *arg) +#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg) -/** - * @brief Packed variable specifier. - */ -#define PACKED_VAR __attribute__((packed)) - -#endif /* _NILTYPES_H_ */ +#endif /* _CHTYPES_H_ */ /** @} */ diff --git a/os/nil/ports/e200/compilers/GCC/ivor.s b/os/common/ports/e200/compilers/GCC/ivor.s similarity index 88% rename from os/nil/ports/e200/compilers/GCC/ivor.s rename to os/common/ports/e200/compilers/GCC/ivor.s index 8bd687c0a..4b1c95dd6 100644 --- a/os/nil/ports/e200/compilers/GCC/ivor.s +++ b/os/common/ports/e200/compilers/GCC/ivor.s @@ -21,7 +21,7 @@ * @file ivor.s * @brief Kernel ISRs. * - * @addtogroup PPC_GCC_CORE + * @addtogroup PPC_CORE * @{ */ @@ -37,8 +37,8 @@ * Imports the PPC configuration headers. */ #define _FROM_ASM_ -#include "nilconf.h" -#include "nilcore.h" +#include "chconf.h" +#include "chcore.h" #if !defined(__DOXYGEN__) @@ -101,8 +101,16 @@ _IVOR10: #endif mtMSR %r0 +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_enter_isr + bl _dbg_check_lock_from_isr +#endif /* System tick handler invocation.*/ bl chSysTimerHandlerI +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock_from_isr + bl _dbg_check_leave_isr +#endif #if PPC_USE_IRQ_PREEMPTION /* Prevents preemption again.*/ @@ -159,7 +167,7 @@ _IVOR4: /* Software vector address from the INTC register.*/ lis %r3, INTC_IACKR_ADDR@h - ori %r3, %r3, INTC_IACKR_ADDR@l + ori %r3, %r3, INTC_IACKR_ADDR@l /* IACKR register address. */ lwz %r3, 0(%r3) /* IACKR register value. */ lwz %r3, 0(%r3) mtCTR %r3 /* Software handler address. */ @@ -194,7 +202,23 @@ _ivor_exit: eaddi %r0, %r0, -1 mtspr 272, %r0 - bl chSchRescheduleS +#if CH_DBG_STATISTICS + bl _stats_start_measure_crit_thd +#endif +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_lock +#endif + bl chSchIsPreemptionRequired + cmpli cr0, %r3, 0 + beq cr0, .noresch + bl chSchDoReschedule +.noresch: +#if CH_DBG_SYSTEM_STATE_CHECK + bl _dbg_check_unlock +#endif +#if CH_DBG_STATISTICS + bl _stats_stop_measure_crit_thd +#endif /* Restoring the external context.*/ #if PPC_USE_VLE && PPC_SUPPORTS_VLE_MULTI diff --git a/os/common/ports/e200/compilers/GCC/mk/port.mk b/os/common/ports/e200/compilers/GCC/mk/port.mk new file mode 100644 index 000000000..d22a30c97 --- /dev/null +++ b/os/common/ports/e200/compilers/GCC/mk/port.mk @@ -0,0 +1,8 @@ +# List of the ChibiOS/RT e200 generic port files. +PORTSRC = $(CHIBIOS)/os/common/ports/e200/chcore.c + +PORTASM = $(CHIBIOS)/os/common/ports/e200/compilers/GCC/ivor.s \ + $(CHIBIOS)/os/common/ports/e200/compilers/GCC/chcoreasm.s + +PORTINC = $(CHIBIOS)/os/common/ports/e200 \ + $(CHIBIOS)/os/common/ports/e200/compilers/GCC diff --git a/os/common/ports/readme.txt b/os/common/ports/readme.txt new file mode 100644 index 000000000..71e7249e6 --- /dev/null +++ b/os/common/ports/readme.txt @@ -0,0 +1,3 @@ +All the code contained under ./os/common/ports are RTOS ports compatible +with both RT and NIL. The code is placed under ./os/common in order to +prevent code duplication and disalignments. diff --git a/os/nil/ports/e200/nilcore.c b/os/common/ports/templates/chcore.c similarity index 58% rename from os/nil/ports/e200/nilcore.c rename to os/common/ports/templates/chcore.c index 4e4510bab..ef24978a7 100644 --- a/os/nil/ports/e200/nilcore.c +++ b/os/common/ports/templates/chcore.c @@ -18,14 +18,19 @@ */ /** - * @file templates/nilcore.c - * @brief Port code. + * @file templates/chcore.c + * @brief Port related template code. + * @details This file is a template of the system driver functions provided by + * a port. Some of the following functions may be implemented as + * macros in chcore.h if the implementer decides that there is an + * advantage in doing so, for example because performance concerns. * - * @addtogroup NIL_CORE + * @addtogroup core + * @details Non portable code templates. * @{ */ -#include "nil.h" +#include "ch.h" /*===========================================================================*/ /* Module local definitions. */ @@ -51,57 +56,24 @@ /* Module exported functions. */ /*===========================================================================*/ +/** + * @brief Port-related initialization code. + * @note This function is usually empty. + */ +void _port_init(void) { +} + /** * @brief Performs a context switch between two threads. * @details This is the most critical code in any port, this function * is responsible for the context switch between 2 threads. * @note The implementation of this code affects directly the context * switch performance so optimize here as much as you can. + * + * @param[in] ntp the thread to be switched in + * @param[in] otp the thread to be switched out */ -#if !defined(__DOXYGEN__) -__attribute__((naked)) -#endif -void port_dummy1(void) { - - asm (".global _port_switch"); - asm ("_port_switch:"); - asm ("subi %sp, %sp, 80"); /* Size of the intctx structure. */ - asm ("mflr %r0"); - asm ("stw %r0, 84(%sp)"); /* LR into the caller frame. */ - asm ("mfcr %r0"); - asm ("stw %r0, 0(%sp)"); /* CR. */ - asm ("stmw %r14, 4(%sp)"); /* GPR14...GPR31. */ - - asm ("stw %sp, 0(%r4)"); /* Store swapped-out stack. */ - asm ("lwz %sp, 0(%r3)"); /* Load swapped-in stack. */ - - asm ("lmw %r14, 4(%sp)"); /* GPR14...GPR31. */ - asm ("lwz %r0, 0(%sp)"); /* CR. */ - asm ("mtcr %r0"); - asm ("lwz %r0, 84(%sp)"); /* LR from the caller frame. */ - asm ("mtlr %r0"); - asm ("addi %sp, %sp, 80"); /* Size of the intctx structure. */ - asm ("blr"); -} - -/** - * @brief Start a thread by invoking its work function. - * @details If the work function returns @p chThdExit() is automatically - * invoked. - */ -#if !defined(__DOXYGEN__) -__attribute__((naked)) -#endif -void port_dummy2(void) { - - asm (".global _port_thread_start"); - asm ("_port_thread_start:"); - chSysUnlock(); - asm ("mr %r3, %r31"); /* Thread parameter. */ - asm ("mtctr %r30"); - asm ("bctrl"); /* Invoke thread function. */ - asm ("li %r0, 0"); - asm ("bl chSysHalt"); /* Thread termination on exit. */ +void _port_switch(thread_t *ntp, thread_t *otp) { } /** @} */ diff --git a/os/nil/templates/nilcore.h b/os/common/ports/templates/chcore.h similarity index 62% rename from os/nil/templates/nilcore.h rename to os/common/ports/templates/chcore.h index 1aad42ddc..dc4cdb45f 100644 --- a/os/nil/templates/nilcore.h +++ b/os/common/ports/templates/chcore.h @@ -18,38 +18,68 @@ */ /** - * @file templates/nilcore.h - * @brief Port macros and structures. + * @file templates/chcore.h + * @brief Port related template macros and structures. + * @details This file is a template of the system driver macros provided by + * a port. * - * @addtogroup NIL_CORE + * @addtogroup core * @{ */ -#ifndef _NILCORE_H_ -#define _NILCORE_H_ +#ifndef _CHCORE_H_ +#define _CHCORE_H_ /*===========================================================================*/ /* Module constants. */ /*===========================================================================*/ +/** + * @name Port Capabilities and Constants + * @{ + */ +/** + * @brief This port supports a realtime counter. + */ +#define PORT_SUPPORTS_RT FALSE + +/** + * @brief Natural alignment constant. + * @note It is the minimum alignment for pointer-size variables. + */ +#define PORT_NATURAL_ALIGN sizeof (void *) + +/** + * @brief Stack alignment constant. + * @note It is the alignement required for the stack pointer. + */ +#define PORT_STACK_ALIGN sizeof (stkalign_t) + +/** + * @brief Working Areas alignment constant. + * @note It is the alignment to be enforced for thread working areas. + */ +#define PORT_WORKING_AREA_ALIGN sizeof (stkalign_t) +/** @} */ + /** * @name Architecture and Compiler * @{ */ /** - * @brief Macro defining the port architecture. + * @brief Macro defining an XXX architecture. */ #define PORT_ARCHITECTURE_XXX /** - * @brief Name of the implemented architecture. + * @brief Macro defining the specific XXX architecture. */ -#define PORT_ARCHITECTURE_NAME "XXX" +#define PORT_ARCHITECTURE_XXX_YYY /** - * @brief Name of the architecture variant. + * @brief Name of the implemented architecture. */ -#define PORT_CORE_VARIANT_NAME "XXXX-Y" +#define PORT_ARCHITECTURE_NAME "XXX Architecture" /** * @brief Compiler name and version. @@ -64,37 +94,49 @@ /** * @brief Port-specific information string. */ -#define PORT_INFO "port description" - -/** - * @brief This port supports a realtime counter. - */ -#define PORT_SUPPORTS_RT FALSE +#define PORT_INFO "no info" /** @} */ /*===========================================================================*/ /* Module pre-compile time settings. */ /*===========================================================================*/ +/** + * @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 PORT_INT_REQUIRED_STACK. + */ +#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__) +#define PORT_IDLE_THREAD_STACK_SIZE 32 +#endif + /** * @brief Per-thread stack overhead for interrupts servicing. * @details This constant is used in the calculation of the correct working * area size. */ #if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__) -#define PORT_INT_REQUIRED_STACK 32 +#define PORT_INT_REQUIRED_STACK 256 #endif /** * @brief Enables an alternative timer implementation. * @details Usually the port uses a timer interface defined in the file - * @p nilcore_timer.h, if this option is enabled then the file - * @p nilcore_timer_alt.h is included instead. + * @p chcore_timer.h, if this option is enabled then the file + * @p chcore_timer_alt.h is included instead. */ -#if !defined(PORT_USE_ALT_TIMER) +#if !defined(PORT_USE_ALT_TIMER) || defined(__DOXYGEN__) #define PORT_USE_ALT_TIMER FALSE #endif +/** + * @brief Enables a "wait for interrupt" instruction in the idle loop. + */ +#if !defined(PORT_XXX_WFI_SLEEP_IDLE) || defined(__DOXYGEN__) +#define PORT_XXX_ENABLE_WFI_IDLE FALSE +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -109,6 +151,7 @@ /** * @brief Type of stack and memory alignment enforcement. + * @note In this architecture the stack alignment is enforced to 64 bits. */ typedef uint64_t stkalign_t; @@ -116,20 +159,31 @@ typedef uint64_t stkalign_t; * @brief Interrupt saved context. * @details This structure represents the stack frame saved during a * preemption-capable interrupt handler. + * @note R2 and R13 are not saved because those are assumed to be immutable + * during the system life cycle. */ struct port_extctx { - uint32_t reg1; - uint32_t reg2; }; /** * @brief System saved context. * @details This structure represents the inner stack frame during a context - * switch. + * switching. + * @note R2 and R13 are not saved because those are assumed to be immutable + * during the system life cycle. + * @note LR is stored in the caller context so it is not present in this + * structure. */ struct port_intctx { - uint32_t reg3; - uint32_t reg4; +}; + +/** + * @brief Platform dependent part of the @p thread_t structure. + * @details This structure usually contains just the saved stack pointer + * defined as a pointer to a @p port_intctx structure. + */ +struct port_context { + struct port_intctx *sp; }; #endif /* !defined(_FROM_ASM_) */ @@ -139,16 +193,12 @@ struct port_intctx { /*===========================================================================*/ /** - * @brief Platform dependent thread stack setup. + * @brief Platform dependent part of the @p chThdCreateI() API. * @details This code usually setup the context switching frame represented * by an @p port_intctx structure. */ -#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) do { \ - (void)(tp); \ - (void)(wend); \ - (void)(pf); \ - (void)(arg); \ -} while (false) +#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \ +} /** * @brief Computes the thread working area global size. @@ -156,8 +206,18 @@ struct port_intctx { */ #define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \ sizeof(struct port_extctx) + \ - (size_t)(n) + \ - (size_t)(PORT_INT_REQUIRED_STACK)) + ((size_t)(n)) + ((size_t)(PORT_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. + * + * @param[in] s the name to be assigned to the stack array + * @param[in] n the stack size to be assigned to the thread + */ +#define PORT_WORKING_AREA(s, n) \ + stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)] /** * @brief Priority level verification macro. @@ -181,7 +241,7 @@ struct port_intctx { * @details This macro must be inserted at the end of all IRQ handlers * enabled to invoke system APIs. */ -#define PORT_IRQ_EPILOGUE() _port_irq_epilogue() +#define PORT_IRQ_EPILOGUE() /** * @brief IRQ handler function declaration. @@ -207,11 +267,16 @@ struct port_intctx { * @param[in] ntp the thread to be switched in * @param[in] otp the thread to be switched out */ -#define port_switch(ntp, otp) do { \ - (void)ntp; \ - (void)otp; \ - /*_port_switch(ntp, otp)*/ \ -} while (false) +#if !CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__) +#define port_switch(ntp, otp) _port_switch(ntp, otp) +#else +#define port_switch(ntp, otp) { \ + register struct port_intctx *sp asm ("%r1"); \ + if ((stkalign_t *)(sp - 1) < otp->stklimit) \ + chSysHalt("stack overflow"); \ + _port_switch(ntp, otp); \ +} +#endif /*===========================================================================*/ /* External declarations. */ @@ -224,9 +289,8 @@ struct port_intctx { #ifdef __cplusplus extern "C" { #endif - void _port_irq_epilogue(void); + void _port_init(void); void _port_switch(thread_t *ntp, thread_t *otp); - void _port_thread_start(void); #ifdef __cplusplus } #endif @@ -241,13 +305,6 @@ extern "C" { asm module.*/ #if !defined(_FROM_ASM_) -/** - * @brief Port-related initialization code. - */ -static inline void port_init(void) { - -} - /** * @brief Returns a word encoding the current interrupts status. * @@ -255,7 +312,7 @@ static inline void port_init(void) { */ static inline syssts_t port_get_irq_status(void) { - return (syssts_t)0; + return 0; } /** @@ -288,6 +345,8 @@ static inline bool port_is_isr_context(void) { /** * @brief Kernel-lock action. + * @details Usually this function just disables interrupts but may perform more + * actions. */ static inline void port_lock(void) { @@ -295,6 +354,8 @@ static inline void port_lock(void) { /** * @brief Kernel-unlock action. + * @details Usually this function just enables interrupts but may perform more + * actions. */ static inline void port_unlock(void) { @@ -302,6 +363,9 @@ static inline void port_unlock(void) { /** * @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. */ static inline void port_lock_from_isr(void) { @@ -309,6 +373,9 @@ static inline void port_lock_from_isr(void) { /** * @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. */ static inline void port_unlock_from_isr(void) { @@ -316,6 +383,7 @@ static inline void port_unlock_from_isr(void) { /** * @brief Disables all the interrupt sources. + * @note Of course non-maskable interrupt sources are not included. */ static inline void port_disable(void) { @@ -323,6 +391,7 @@ static inline void port_disable(void) { /** * @brief Disables the interrupt sources below kernel-level priority. + * @note Interrupt sources above kernel level remains enabled. */ static inline void port_suspend(void) { @@ -344,6 +413,8 @@ static inline void port_enable(void) { */ static inline void port_wait_for_interrupt(void) { +#if PORT_XXX_ENABLE_WFI_IDLE +#endif } /** @@ -353,7 +424,7 @@ static inline void port_wait_for_interrupt(void) { */ static inline rtcnt_t port_rt_get_counter_value(void) { - return (rtcnt_t)0; + return 0; } #endif /* !defined(_FROM_ASM_) */ @@ -362,18 +433,20 @@ static inline rtcnt_t port_rt_get_counter_value(void) { /* Module late inclusions. */ /*===========================================================================*/ +/* The following code is not processed when the file is included from an + asm module.*/ #if !defined(_FROM_ASM_) -#if NIL_CFG_ST_TIMEDELTA > 0 -#if PORT_USE_ALT_TIMER == FALSE -#include "nilcore_timer.h" -#else -#include "nilcore_timer_alt.h" -#endif -#endif /* NIL_CFG_ST_TIMEDELTA > 0 */ +#if CH_CFG_ST_TIMEDELTA > 0 +#if !PORT_USE_ALT_TIMER +#include "chcore_timer.h" +#else /* PORT_USE_ALT_TIMER */ +#include "chcore_timer_alt.h" +#endif /* PORT_USE_ALT_TIMER */ +#endif /* CH_CFG_ST_TIMEDELTA > 0 */ #endif /* !defined(_FROM_ASM_) */ -#endif /* _NILCORE_H_ */ +#endif /* _CHCORE_H_ */ /** @} */ diff --git a/os/common/ports/templates/chtypes.h b/os/common/ports/templates/chtypes.h new file mode 100644 index 000000000..56549b36e --- /dev/null +++ b/os/common/ports/templates/chtypes.h @@ -0,0 +1,107 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file templates/chtypes.h + * @brief System types template. + * @details The types defined in this file may change depending on the target + * architecture. You may also try to optimize the size of the various + * types in order to privilege size or performance, be careful in + * doing so. + * + * @addtogroup types + * @{ + */ + +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ + +#include +#include +#include + +/** + * @name Common constants + */ +/** + * @brief Generic 'false' boolean constant. + */ +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +/** + * @brief Generic 'true' boolean constant. + */ +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE (!FALSE) +#endif +/** @} */ + +/** + * @name Kernel types + * @{ + */ +typedef uint32_t rtcnt_t; /**< Realtime counter. */ +typedef uint64_t rttime_t; /**< Realtime accumulator. */ +typedef uint32_t syssts_t; /**< System status word. */ +typedef uint8_t tmode_t; /**< Thread flags. */ +typedef uint8_t tstate_t; /**< Thread state. */ +typedef uint8_t trefs_t; /**< Thread references counter. */ +typedef uint8_t tslices_t; /**< Thread time slices counter.*/ +typedef uint32_t tprio_t; /**< Thread priority. */ +typedef int32_t msg_t; /**< Inter-thread message. */ +typedef int32_t eventid_t; /**< Numeric event identifier. */ +typedef uint32_t eventmask_t; /**< Mask of event identifiers. */ +typedef uint32_t eventflags_t; /**< Mask of event flags. */ +typedef int32_t cnt_t; /**< Generic signed counter. */ +typedef uint32_t ucnt_t; /**< Generic unsigned counter. */ +/** @} */ + +/** + * @brief ROM constant modifier. + * @note It is set to use the "const" keyword in this port. + */ +#define ROMCONST const + +/** + * @brief Makes functions not inlineable. + * @note If the compiler does not support such attribute then the + * realtime counter precision could be degraded. + */ +#define NOINLINE __attribute__((noinline)) + +/** + * @brief Optimized thread function declaration macro. + */ +#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg) + +/** + * @brief Packed variable specifier. + */ +#define PACKED_VAR __attribute__((packed)) + +/** + * @brief Memory alignment enforcement for variables. + */ +#define ALIGNED_VAR(n) __attribute__((aligned(n))) + +#endif /* _CHTYPES_H_ */ + +/** @} */ diff --git a/os/common/startup/ARM/compilers/GCC/mk/startup_lpc214x.mk b/os/common/startup/ARM/compilers/GCC/mk/startup_lpc214x.mk index 4f1af1875..baf301a34 100644 --- a/os/common/startup/ARM/compilers/GCC/mk/startup_lpc214x.mk +++ b/os/common/startup/ARM/compilers/GCC/mk/startup_lpc214x.mk @@ -1,9 +1,9 @@ # List of the ChibiOS generic LPC214x file. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARM/compilers/GCC/crt1.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARM/compilers/GCC/crt1.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARM/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/ARM/compilers/GCC/crt0.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARM/compilers/GCC/vectors.s \ + $(CHIBIOS)/os/common/startup/ARM/compilers/GCC/crt0.s -STARTUPINC = ${CHIBIOS}/os/common/ports/ARM/devices/LPC214x +STARTUPINC = ${CHIBIOS}/os/common/startup/ARM/devices/LPC214x -STARTUPLD = ${CHIBIOS}/os/common/ports/ARM/compilers/GCC/ld +STARTUPLD = ${CHIBIOS}/os/common/startup/ARM/compilers/GCC/ld diff --git a/os/common/startup/ARM/compilers/GCC/rules.ld b/os/common/startup/ARM/compilers/GCC/rules.ld index 6bda5170c..82d1c3270 100644 --- a/os/common/startup/ARM/compilers/GCC/rules.ld +++ b/os/common/startup/ARM/compilers/GCC/rules.ld @@ -117,6 +117,7 @@ SECTIONS { . = ALIGN(8); __stacks_base__ = .; + __main_thread_stack_base__ = .; . += __stacks_total_size__; . = ALIGN(8); __stacks_end__ = .; diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_k20x.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_k20x.mk index b7ea0f3be..0b723f929 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_k20x.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_k20x.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic K20x startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/K20x \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/KINETIS +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/K20x \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/KINETIS -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_kl2x.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_kl2x.mk index a073da004..8b743ec46 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_kl2x.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_kl2x.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic KL2x startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v6m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/KL2x \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/KINETIS +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/KL2x \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/KINETIS -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f0xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f0xx.mk index e705bd70f..466a58606 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f0xx.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f0xx.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic STM32F0xx startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v6m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F0xx \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/ST/STM32F0xx +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F0xx \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F0xx -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f1xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f1xx.mk index 748075f99..f6c169973 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f1xx.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f1xx.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic STM32F1xx startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F1xx \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/ST/STM32F1xx +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F1xx \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F1xx -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f2xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f2xx.mk index 9789041c2..8dc97e3ec 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f2xx.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f2xx.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic STM32F2xx startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F2xx \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/ST/STM32F2xx +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F2xx \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F2xx -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f3xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f3xx.mk index 6968d34a3..bd16abfe5 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f3xx.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f3xx.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic STM32F3xx startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F3xx \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/ST/STM32F3xx +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F3xx \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F3xx -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk index 28744ffb5..3083b1372 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic STM32F4xx startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F4xx \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/ST/STM32F4xx +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F4xx \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F4xx -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f7xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f7xx.mk index b2a8b1f56..ed18f97ee 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f7xx.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f7xx.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic STM32F7xx startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F7xx \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/ST/STM32F7xx +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F7xx \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F7xx -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l0xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l0xx.mk index 24c1ef054..3726c1711 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l0xx.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l0xx.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic STM32L0xx startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v6m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32L0xx \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/ST/STM32L0xx +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32L0xx \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/ST/STM32L0xx -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l1xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l1xx.mk index fcd588a9b..63fadc95d 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l1xx.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l1xx.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic STM32L1xx startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32L1xx \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/ST/STM32L1xx +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32L1xx \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/ST/STM32L1xx -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l4xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l4xx.mk index a8a3ec441..3c062b821 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l4xx.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l4xx.mk @@ -1,12 +1,12 @@ # List of the ChibiOS generic STM32L4xx startup and CMSIS files. -STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \ - $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c -STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s -STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \ - $(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32L4xx \ - $(CHIBIOS)/os/ext/CMSIS/include \ - $(CHIBIOS)/os/ext/CMSIS/ST/STM32L4xx +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32L4xx \ + $(CHIBIOS)/os/common/ext/CMSIS/include \ + $(CHIBIOS)/os/common/ext/CMSIS/ST/STM32L4xx -STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld diff --git a/os/common/startup/e200/compilers/GCC/mk/startup_spc560bcxx.mk b/os/common/startup/e200/compilers/GCC/mk/startup_spc560bcxx.mk index 2e067b149..6ca606b50 100644 --- a/os/common/startup/e200/compilers/GCC/mk/startup_spc560bcxx.mk +++ b/os/common/startup/e200/compilers/GCC/mk/startup_spc560bcxx.mk @@ -1,11 +1,11 @@ # List of the ChibiOS e200z0 SPC560BCxx startup files. STARTUPSRC = -STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560BCxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s +STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC560BCxx/boot.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s -STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC560BCxx +STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \ + ${CHIBIOS}/os/common/startup/e200/devices/SPC560BCxx -STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld +STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld diff --git a/os/common/startup/e200/compilers/GCC/mk/startup_spc560bxx.mk b/os/common/startup/e200/compilers/GCC/mk/startup_spc560bxx.mk index 5cfc4a81e..56a4a9813 100644 --- a/os/common/startup/e200/compilers/GCC/mk/startup_spc560bxx.mk +++ b/os/common/startup/e200/compilers/GCC/mk/startup_spc560bxx.mk @@ -1,11 +1,11 @@ # List of the ChibiOS e200z0 SPC560Bxx startup files. STARTUPSRC = -STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Bxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s +STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC560Bxx/boot.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s -STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC560Bxx +STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \ + ${CHIBIOS}/os/common/startup/e200/devices/SPC560Bxx -STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld +STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld diff --git a/os/common/startup/e200/compilers/GCC/mk/startup_spc560dxx.mk b/os/common/startup/e200/compilers/GCC/mk/startup_spc560dxx.mk index 4e8b633fd..0c5574013 100644 --- a/os/common/startup/e200/compilers/GCC/mk/startup_spc560dxx.mk +++ b/os/common/startup/e200/compilers/GCC/mk/startup_spc560dxx.mk @@ -1,11 +1,11 @@ # List of the ChibiOS e200z0 SPC560Dxx startup files. STARTUPSRC = -STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Dxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s +STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC560Dxx/boot.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s -STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC560Dxx +STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \ + ${CHIBIOS}/os/common/startup/e200/devices/SPC560Dxx -STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld +STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld diff --git a/os/common/startup/e200/compilers/GCC/mk/startup_spc560pxx.mk b/os/common/startup/e200/compilers/GCC/mk/startup_spc560pxx.mk index 72a62d787..fee580672 100644 --- a/os/common/startup/e200/compilers/GCC/mk/startup_spc560pxx.mk +++ b/os/common/startup/e200/compilers/GCC/mk/startup_spc560pxx.mk @@ -1,11 +1,11 @@ # List of the ChibiOS e200z0 SPC560Pxx startup files. STARTUPSRC = -STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Pxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s +STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC560Pxx/boot.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s -STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC560Pxx +STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \ + ${CHIBIOS}/os/common/startup/e200/devices/SPC560Pxx -STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld +STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld diff --git a/os/common/startup/e200/compilers/GCC/mk/startup_spc563mxx.mk b/os/common/startup/e200/compilers/GCC/mk/startup_spc563mxx.mk index 92af14e4c..61f786043 100644 --- a/os/common/startup/e200/compilers/GCC/mk/startup_spc563mxx.mk +++ b/os/common/startup/e200/compilers/GCC/mk/startup_spc563mxx.mk @@ -1,11 +1,11 @@ # List of the ChibiOS e200z3 SPC563Mxx startup files. STARTUPSRC = -STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC563Mxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s +STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC563Mxx/boot.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s -STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC563Mxx +STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \ + ${CHIBIOS}/os/common/startup/e200/devices/SPC563Mxx -STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld +STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld diff --git a/os/common/startup/e200/compilers/GCC/mk/startup_spc564axx.mk b/os/common/startup/e200/compilers/GCC/mk/startup_spc564axx.mk index a903aa8ff..976ae6dd1 100644 --- a/os/common/startup/e200/compilers/GCC/mk/startup_spc564axx.mk +++ b/os/common/startup/e200/compilers/GCC/mk/startup_spc564axx.mk @@ -1,11 +1,11 @@ # List of the ChibiOS e200z4 SPC564Axx startup files. STARTUPSRC = -STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC564Axx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s +STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC564Axx/boot.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s -STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC564Axx +STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \ + ${CHIBIOS}/os/common/startup/e200/devices/SPC564Axx -STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld +STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld diff --git a/os/common/startup/e200/compilers/GCC/mk/startup_spc56ecxx.mk b/os/common/startup/e200/compilers/GCC/mk/startup_spc56ecxx.mk index d2377e57f..e08bfd6de 100644 --- a/os/common/startup/e200/compilers/GCC/mk/startup_spc56ecxx.mk +++ b/os/common/startup/e200/compilers/GCC/mk/startup_spc56ecxx.mk @@ -1,11 +1,11 @@ # List of the ChibiOS e200z4 SPC56ECxx startup files. STARTUPSRC = -STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC56ECxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s +STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC56ECxx/boot.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s -STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC56ECxx +STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \ + ${CHIBIOS}/os/common/startup/e200/devices/SPC56ECxx -STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld +STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld diff --git a/os/common/startup/e200/compilers/GCC/mk/startup_spc56elxx.mk b/os/common/startup/e200/compilers/GCC/mk/startup_spc56elxx.mk index 40753b63f..8eae8535a 100644 --- a/os/common/startup/e200/compilers/GCC/mk/startup_spc56elxx.mk +++ b/os/common/startup/e200/compilers/GCC/mk/startup_spc56elxx.mk @@ -1,11 +1,11 @@ # List of the ChibiOS e200z4 SPC56ELxx startup files. STARTUPSRC = -STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC56ELxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s +STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC56ELxx/boot.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \ + $(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s -STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC56ELxx +STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \ + ${CHIBIOS}/os/common/startup/e200/devices/SPC56ELxx -STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld +STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld diff --git a/os/nil/include/nil.h b/os/nil/include/ch.h similarity index 100% rename from os/nil/include/nil.h rename to os/nil/include/ch.h diff --git a/os/nil/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk b/os/nil/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk deleted file mode 100644 index 6fa7d52ea..000000000 --- a/os/nil/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk +++ /dev/null @@ -1,8 +0,0 @@ -# List of the ChibiOS/NIL ARMv6M generic port files. -PORTSRC = $(CHIBIOS)/os/nil/ports/ARMCMx/nilcore.c \ - $(CHIBIOS)/os/nil/ports/ARMCMx/nilcore_v6m.c - -PORTASM = $(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v6m.s - -PORTINC = $(CHIBIOS)/os/nil/ports/ARMCMx \ - $(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC diff --git a/os/nil/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk b/os/nil/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk deleted file mode 100644 index 3e9c30125..000000000 --- a/os/nil/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk +++ /dev/null @@ -1,8 +0,0 @@ -# List of the ChibiOS/NIL ARMv7M generic port files. -PORTSRC = $(CHIBIOS)/os/nil/ports/ARMCMx/nilcore.c \ - $(CHIBIOS)/os/nil/ports/ARMCMx/nilcore_v7m.c - -PORTASM = $(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v7m.s - -PORTINC = $(CHIBIOS)/os/nil/ports/ARMCMx \ - $(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC diff --git a/os/nil/ports/AVR/compilers/GCC/mk/port.mk b/os/nil/ports/AVR/compilers/GCC/mk/port.mk deleted file mode 100644 index 0eaec1a5f..000000000 --- a/os/nil/ports/AVR/compilers/GCC/mk/port.mk +++ /dev/null @@ -1,7 +0,0 @@ -# List of the ChibiOS/RT AVR port files. -PORTSRC = ${CHIBIOS}/os/nil/ports/AVR/nilcore.c - -PORTASM = - -PORTINC = ${CHIBIOS}/os/nil/ports/AVR \ - ${CHIBIOS}/os/nil/ports/AVR/compilers/GCC diff --git a/os/nil/ports/e200/compilers/GCC/mk/port_spc560bcxx.mk b/os/nil/ports/e200/compilers/GCC/mk/port_spc560bcxx.mk deleted file mode 100644 index 050076219..000000000 --- a/os/nil/ports/e200/compilers/GCC/mk/port_spc560bcxx.mk +++ /dev/null @@ -1,14 +0,0 @@ -# List of the ChibiOS/NIL e200z0 SPC560BCxx port files. -PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c - -PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560BCxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \ - $(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s - -PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC560BCxx \ - ${CHIBIOS}/os/nil/ports/e200 \ - ${CHIBIOS}/os/nil/ports/e200/compilers/GCC - -PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld diff --git a/os/nil/ports/e200/compilers/GCC/mk/port_spc560bxx.mk b/os/nil/ports/e200/compilers/GCC/mk/port_spc560bxx.mk deleted file mode 100644 index 6089f4743..000000000 --- a/os/nil/ports/e200/compilers/GCC/mk/port_spc560bxx.mk +++ /dev/null @@ -1,14 +0,0 @@ -# List of the ChibiOS/NIL e200z0 SPC560Bxx port files. -PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c - -PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Bxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \ - $(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s - -PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC560Bxx \ - ${CHIBIOS}/os/nil/ports/e200 \ - ${CHIBIOS}/os/nil/ports/e200/compilers/GCC - -PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld diff --git a/os/nil/ports/e200/compilers/GCC/mk/port_spc560dxx.mk b/os/nil/ports/e200/compilers/GCC/mk/port_spc560dxx.mk deleted file mode 100644 index 91176f87b..000000000 --- a/os/nil/ports/e200/compilers/GCC/mk/port_spc560dxx.mk +++ /dev/null @@ -1,14 +0,0 @@ -# List of the ChibiOS/NIL e200z0 SPC560Dxx port files. -PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c - -PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Dxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \ - $(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s - -PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC560Dxx \ - ${CHIBIOS}/os/nil/ports/e200 \ - ${CHIBIOS}/os/nil/ports/e200/compilers/GCC - -PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld diff --git a/os/nil/ports/e200/compilers/GCC/mk/port_spc560pxx.mk b/os/nil/ports/e200/compilers/GCC/mk/port_spc560pxx.mk deleted file mode 100644 index 9342310aa..000000000 --- a/os/nil/ports/e200/compilers/GCC/mk/port_spc560pxx.mk +++ /dev/null @@ -1,14 +0,0 @@ -# List of the ChibiOS/NIL e200z0 SPC560Pxx port files. -PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c - -PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Pxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \ - $(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s - -PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC560Pxx \ - ${CHIBIOS}/os/nil/ports/e200 \ - ${CHIBIOS}/os/nil/ports/e200/compilers/GCC - -PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld diff --git a/os/nil/ports/e200/compilers/GCC/mk/port_spc563mxx.mk b/os/nil/ports/e200/compilers/GCC/mk/port_spc563mxx.mk deleted file mode 100644 index febbf22a8..000000000 --- a/os/nil/ports/e200/compilers/GCC/mk/port_spc563mxx.mk +++ /dev/null @@ -1,14 +0,0 @@ -# List of the ChibiOS/NIL e200z3 SPC563Mxx port files. -PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c - -PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC563Mxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \ - $(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s - -PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC563Mxx \ - ${CHIBIOS}/os/nil/ports/e200 \ - ${CHIBIOS}/os/nil/ports/e200/compilers/GCC - -PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld diff --git a/os/nil/ports/e200/compilers/GCC/mk/port_spc564axx.mk b/os/nil/ports/e200/compilers/GCC/mk/port_spc564axx.mk deleted file mode 100644 index 31b25c692..000000000 --- a/os/nil/ports/e200/compilers/GCC/mk/port_spc564axx.mk +++ /dev/null @@ -1,14 +0,0 @@ -# List of the ChibiOS/NIL e200z4 SPC564Axx port files. -PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c - -PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC564Axx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \ - $(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s - -PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC564Axx \ - ${CHIBIOS}/os/nil/ports/e200 \ - ${CHIBIOS}/os/nil/ports/e200/compilers/GCC - -PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld diff --git a/os/nil/ports/e200/compilers/GCC/mk/port_spc56ecxx.mk b/os/nil/ports/e200/compilers/GCC/mk/port_spc56ecxx.mk deleted file mode 100644 index 84ada33e1..000000000 --- a/os/nil/ports/e200/compilers/GCC/mk/port_spc56ecxx.mk +++ /dev/null @@ -1,14 +0,0 @@ -# List of the ChibiOS/NIL e200z4 SPC56ECxx port files. -PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c - -PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC56ECxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \ - $(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s - -PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC56ECxx \ - ${CHIBIOS}/os/nil/ports/e200 \ - ${CHIBIOS}/os/nil/ports/e200/compilers/GCC - -PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld diff --git a/os/nil/ports/e200/compilers/GCC/mk/port_spc56elxx.mk b/os/nil/ports/e200/compilers/GCC/mk/port_spc56elxx.mk deleted file mode 100644 index a913240e3..000000000 --- a/os/nil/ports/e200/compilers/GCC/mk/port_spc56elxx.mk +++ /dev/null @@ -1,14 +0,0 @@ -# List of the ChibiOS/NIL e200z4 SPC56ELxx port files. -PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c - -PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC56ELxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \ - $(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s - -PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC56ELxx \ - ${CHIBIOS}/os/nil/ports/e200 \ - ${CHIBIOS}/os/nil/ports/e200/compilers/GCC - -PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld diff --git a/os/nil/ports/e200/compilers/GCC/mk/port_spc57emxx.mk b/os/nil/ports/e200/compilers/GCC/mk/port_spc57emxx.mk deleted file mode 100644 index 669d371ea..000000000 --- a/os/nil/ports/e200/compilers/GCC/mk/port_spc57emxx.mk +++ /dev/null @@ -1,14 +0,0 @@ -# List of the ChibiOS/NIL e200z4 SPC57EMxx port files. -PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c - -PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC57EMxx/boot.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \ - $(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \ - $(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s - -PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \ - ${CHIBIOS}/os/common/ports/e200/devices/SPC57EMxx \ - ${CHIBIOS}/os/nil/ports/e200 \ - ${CHIBIOS}/os/nil/ports/e200/compilers/GCC - -PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld diff --git a/os/nil/src/nil.c b/os/nil/src/ch.c similarity index 100% rename from os/nil/src/nil.c rename to os/nil/src/ch.c diff --git a/os/nil/templates/nilconf.h b/os/nil/templates/chconf.h similarity index 51% rename from os/nil/templates/nilconf.h rename to os/nil/templates/chconf.h index c89fd61aa..234705f7e 100644 --- a/os/nil/templates/nilconf.h +++ b/os/nil/templates/chconf.h @@ -15,18 +15,20 @@ */ /** - * @file nilconf.h + * @file 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 NIL_CONFIG + * @addtogroup config * @details Kernel related settings and hooks. * @{ */ -#ifndef _NILCONF_H_ -#define _NILCONF_H_ +#ifndef _CHCONF_H_ +#define _CHCONF_H_ + +#define _CHIBIOS_NIL_CONF_ /*===========================================================================*/ /** @@ -40,7 +42,7 @@ * @note This number is not inclusive of the idle thread which is * Implicitly handled. */ -#define NIL_CFG_NUM_THREADS 1 +#define CH_CFG_NUM_THREADS 3 /** @} */ @@ -55,15 +57,15 @@ * @brief System time counter resolution. * @note Allowed values are 16 or 32 bits. */ -#define NIL_CFG_ST_RESOLUTION 32 +#define CH_CFG_ST_RESOLUTION 32 /** * @brief System tick frequency. - * @note This value together with the @p NIL_CFG_ST_RESOLUTION + * @note This value together with the @p CH_CFG_ST_RESOLUTION * option defines the maximum amount of time allowed for * timeouts. */ -#define NIL_CFG_ST_FREQUENCY 50000 +#define CH_CFG_ST_FREQUENCY 1000 /** * @brief Time delta constant for the tick-less mode. @@ -73,7 +75,7 @@ * The value one is not valid, timeouts are rounded up to * this value. */ -#define NIL_CFG_ST_TIMEDELTA 2 +#define CH_CFG_ST_TIMEDELTA 0 /** @} */ @@ -84,13 +86,80 @@ */ /*===========================================================================*/ +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_SEMAPHORES TRUE + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note Feature not currently implemented. + * @note The default is @p FALSE. + */ +#define CH_CFG_USE_MUTEXES FALSE + /** * @brief Events Flags APIs. * @details If enabled then the event flags APIs are included in the kernel. * * @note The default is @p TRUE. */ -#define NIL_CFG_USE_EVENTS TRUE +#define CH_CFG_USE_EVENTS TRUE + +/** + * @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_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_MAILBOXES TRUE + +/** + * @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. + */ +#define CH_CFG_USE_MEMCORE TRUE + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_HEAP TRUE + +/** + * @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. + */ +#define CH_CFG_USE_MEMPOOLS TRUE + +/** + * @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_CFG_USE_MEMCORE. + */ +#define CH_CFG_MEMCORE_SIZE 0 /** @} */ @@ -102,14 +171,40 @@ /*===========================================================================*/ /** - * @brief System assertions. + * @brief Debug option, kernel statistics. + * + * @note Feature not currently implemented. + * @note The default is @p FALSE. */ -#define NIL_CFG_ENABLE_ASSERTS FALSE +#define CH_DBG_STATISTICS FALSE + +/** + * @brief Debug option, system state check. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_SYSTEM_STATE_CHECK TRUE + +/** + * @brief Debug option, parameters checks. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_CHECKS TRUE + +/** + * @brief System assertions. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_ASSERTS TRUE /** * @brief Stack check. + * + * @note The default is @p FALSE. */ -#define NIL_CFG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE /** @} */ @@ -123,8 +218,8 @@ /** * @brief System initialization hook. */ -#if !defined(NIL_CFG_SYSTEM_INIT_HOOK) || defined(__DOXYGEN__) -#define NIL_CFG_SYSTEM_INIT_HOOK() { \ +#if !defined(CH_CFG_SYSTEM_INIT_HOOK) || defined(__DOXYGEN__) +#define CH_CFG_SYSTEM_INIT_HOOK() { \ } #endif @@ -132,13 +227,13 @@ * @brief Threads descriptor structure extension. * @details User fields added to the end of the @p thread_t structure. */ -#define NIL_CFG_THREAD_EXT_FIELDS \ +#define CH_CFG_THREAD_EXT_FIELDS \ /* Add threads custom fields here.*/ /** * @brief Threads initialization hook. */ -#define NIL_CFG_THREAD_EXT_INIT_HOOK(tr) { \ +#define CH_CFG_THREAD_EXT_INIT_HOOK(tr) { \ /* Add custom threads initialization code here.*/ \ } @@ -148,7 +243,7 @@ * should be invoked from here. * @note This macro can be used to activate a power saving mode. */ -#define NIL_CFG_IDLE_ENTER_HOOK() { \ +#define CH_CFG_IDLE_ENTER_HOOK() { \ } /** @@ -157,14 +252,14 @@ * should be invoked from here. * @note This macro can be used to deactivate a power saving mode. */ -#define NIL_CFG_IDLE_LEAVE_HOOK() { \ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ } /** * @brief System halt hook. */ -#if !defined(NIL_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__) -#define NIL_CFG_SYSTEM_HALT_HOOK(reason) { \ +#if !defined(CH_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__) +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ } #endif @@ -174,6 +269,6 @@ /* Port-specific settings (override port settings defaulted in nilcore.h). */ /*===========================================================================*/ -#endif /* _NILCONF_H_ */ +#endif /* _CHCONF_H_ */ /** @} */