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_ */
/** @} */