diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2013-08-10 14:51:16 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2013-08-10 14:51:16 +0000 |
commit | a1435e018bfc9919cb76b1356509ecc883767fb4 (patch) | |
tree | b82f74e9eee194c8b04ba4a0dd0b88810813caf8 /os/rt/include | |
parent | eb7a1a15b23341693864c6fc13ac5eab5c1d6122 (diff) | |
download | ChibiOS-a1435e018bfc9919cb76b1356509ecc883767fb4.tar.gz ChibiOS-a1435e018bfc9919cb76b1356509ecc883767fb4.tar.bz2 ChibiOS-a1435e018bfc9919cb76b1356509ecc883767fb4.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6123 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/rt/include')
-rw-r--r-- | os/rt/include/ch.h | 137 | ||||
-rw-r--r-- | os/rt/include/chbsem.h | 312 | ||||
-rw-r--r-- | os/rt/include/chcond.h | 117 | ||||
-rw-r--r-- | os/rt/include/chdebug.h | 257 | ||||
-rw-r--r-- | os/rt/include/chdynamic.h | 96 | ||||
-rw-r--r-- | os/rt/include/chevents.h | 240 | ||||
-rw-r--r-- | os/rt/include/chglobal.h | 179 | ||||
-rw-r--r-- | os/rt/include/chheap.h | 119 | ||||
-rw-r--r-- | os/rt/include/chlists.h | 195 | ||||
-rw-r--r-- | os/rt/include/chmboxes.h | 200 | ||||
-rw-r--r-- | os/rt/include/chmemcore.h | 114 | ||||
-rw-r--r-- | os/rt/include/chmempools.h | 169 | ||||
-rw-r--r-- | os/rt/include/chmsg.h | 120 | ||||
-rw-r--r-- | os/rt/include/chmtx.h | 126 | ||||
-rw-r--r-- | os/rt/include/chqueues.h | 431 | ||||
-rw-r--r-- | os/rt/include/chregistry.h | 167 | ||||
-rw-r--r-- | os/rt/include/chschd.h | 218 | ||||
-rw-r--r-- | os/rt/include/chsem.h | 154 | ||||
-rw-r--r-- | os/rt/include/chstats.h | 110 | ||||
-rw-r--r-- | os/rt/include/chstreams.h | 147 | ||||
-rw-r--r-- | os/rt/include/chsys.h | 346 | ||||
-rw-r--r-- | os/rt/include/chthreads.h | 406 | ||||
-rw-r--r-- | os/rt/include/chtm.h | 100 | ||||
-rw-r--r-- | os/rt/include/chvt.h | 403 |
24 files changed, 4863 insertions, 0 deletions
diff --git a/os/rt/include/ch.h b/os/rt/include/ch.h new file mode 100644 index 000000000..6af6b8d4d --- /dev/null +++ b/os/rt/include/ch.h @@ -0,0 +1,137 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ch.h
+ * @brief ChibiOS/RT main include file.
+ * @details This header includes all the required kernel headers so it is the
+ * only kernel header you usually want to include in your application.
+ *
+ * @addtogroup kernel_info
+ * @details Kernel related info.
+ * @{
+ */
+
+#ifndef _CH_H_
+#define _CH_H_
+
+/**
+ * @brief ChibiOS/RT identification macro.
+ */
+#define _CHIBIOS_RT_
+
+/**
+ * @brief Kernel version string.
+ */
+#define CH_KERNEL_VERSION "3.0.0dev"
+
+/**
+ * @name Kernel version
+ * @{
+ */
+/**
+ * @brief Kernel version major number.
+ */
+#define CH_KERNEL_MAJOR 3
+
+/**
+ * @brief Kernel version minor number.
+ */
+#define CH_KERNEL_MINOR 0
+
+/**
+ * @brief Kernel version patch number.
+ */
+#define CH_KERNEL_PATCH 0
+/** @} */
+
+/**
+ * @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
+
+/**
+ * @brief Generic success constant.
+ * @details This constant is functionally equivalent to @p false but more
+ * readable, it can be used as return value of all those functions
+ * returning a @p bool as a status indicator.
+ */
+#if !defined(CH_SUCCESS) || defined(__DOXYGEN__)
+#define CH_SUCCESS false
+#endif
+
+/**
+ * @brief Generic failure constant.
+ * @details This constant is functionally equivalent to @p true but more
+ * readable, it can be used as return value of all those functions
+ * returning a @p bool as a status indicator.
+ */
+#if !defined(CH_FAILED) || defined(__DOXYGEN__)
+#define CH_FAILED true
+#endif
+/** @} */
+
+/* Forward declarations.*/
+typedef struct thread thread_t;
+typedef struct virtual_timer virtual_timer_t;
+
+/* Inclusion of all the kernel sub-headers.*/
+#include "chconf.h"
+#include "chtypes.h"
+#include "chdebug.h"
+#include "chcore.h"
+#include "chtm.h"
+#include "chstats.h"
+#include "chsys.h"
+#include "chglobal.h"
+#include "chvt.h"
+#include "chthreads.h"
+#include "chlists.h"
+#include "chschd.h"
+#include "chregistry.h"
+#include "chsem.h"
+#include "chbsem.h"
+#include "chmtx.h"
+#include "chcond.h"
+#include "chevents.h"
+#include "chmsg.h"
+#include "chmboxes.h"
+#include "chmemcore.h"
+#include "chheap.h"
+#include "chmempools.h"
+#include "chdynamic.h"
+#include "chqueues.h"
+#include "chstreams.h"
+
+#endif /* _CH_H_ */
+
+/** @} */
diff --git a/os/rt/include/chbsem.h b/os/rt/include/chbsem.h new file mode 100644 index 000000000..6a5397e8e --- /dev/null +++ b/os/rt/include/chbsem.h @@ -0,0 +1,312 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chbsem.h
+ * @brief Binary semaphores structures and macros.
+ *
+ * @addtogroup binary_semaphores
+ * @details Binary semaphores related APIs and services.
+ *
+ * <h2>Operation mode</h2>
+ * Binary semaphores are implemented as a set of macros 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:
+ * - <b>Taken</b>, 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.
+ * - <b>Not taken</b>, when its counter has a value of one.
+ * .
+ * Binary semaphores are different from mutexes because there is no
+ * the 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.<br>
+ * 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 || 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 bs_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.bs_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->bs_sem, taken ? 0 : 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 RDY_OK if the binary semaphore has been successfully taken.
+ * @retval RDY_RESET if the binary semaphore has been reset using
+ * @p bsemReset().
+ *
+ * @api
+ */
+static inline msg_t chBSemWait(binary_semaphore_t *bsp) {
+
+ return chSemWait(&bsp->bs_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 RDY_OK if the binary semaphore has been successfully taken.
+ * @retval RDY_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->bs_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 RDY_OK if the binary semaphore has been successfully taken.
+ * @retval RDY_RESET if the binary semaphore has been reset using
+ * @p bsemReset().
+ * @retval RDY_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->bs_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 RDY_OK if the binary semaphore has been successfully taken.
+ * @retval RDY_RESET if the binary semaphore has been reset using
+ * @p bsemReset().
+ * @retval RDY_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->bs_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 RDY_RESET instead of @p RDY_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->bs_sem, taken ? 0 : 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 RDY_RESET instead of @p RDY_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->bs_sem, taken ? 0 : 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->bs_sem.s_cnt < 1)
+ chSemSignalI(&bsp->bs_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->bs_sem.s_cnt > 0 ? false : true;
+}
+
+#endif /* CH_CFG_USE_SEMAPHORES */
+
+#endif /* _CHBSEM_H_ */
+
+/** @} */
diff --git a/os/rt/include/chcond.h b/os/rt/include/chcond.h new file mode 100644 index 000000000..802d59d3a --- /dev/null +++ b/os/rt/include/chcond.h @@ -0,0 +1,117 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ Concepts and parts of this file have been contributed by Leon Woestenberg.
+ */
+
+/**
+ * @file chcond.h
+ * @brief Condition Variables macros and structures.
+ *
+ * @addtogroup condvars
+ * @{
+ */
+
+#ifndef _CHCOND_H_
+#define _CHCOND_H_
+
+#if CH_CFG_USE_CONDVARS || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !CH_CFG_USE_MUTEXES
+#error "CH_CFG_USE_CONDVARS requires CH_CFG_USE_MUTEXES"
+#endif
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief condition_variable_t structure.
+ */
+typedef struct condition_variable {
+ threads_queue_t c_queue; /**< @brief Condition variable
+ threads queue. */
+} condition_variable_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Data part of a static condition variable initializer.
+ * @details This macro should be used when statically initializing a condition
+ * variable that is part of a bigger structure.
+ *
+ * @param[in] name the name of the condition variable
+ */
+#define _CONDVAR_DATA(name) {_threads_queue_t_DATA(name.c_queue)}
+
+/**
+ * @brief Static condition variable initializer.
+ * @details Statically initialized condition variables require no explicit
+ * initialization using @p chCondInit().
+ *
+ * @param[in] name the name of the condition variable
+ */
+#define CONDVAR_DECL(name) condition_variable_t name = _CONDVAR_DATA(name)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chCondObjectInit(condition_variable_t *cp);
+ void chCondSignal(condition_variable_t *cp);
+ void chCondSignalI(condition_variable_t *cp);
+ void chCondBroadcast(condition_variable_t *cp);
+ void chCondBroadcastI(condition_variable_t *cp);
+ msg_t chCondWait(condition_variable_t *cp);
+ msg_t chCondWaitS(condition_variable_t *cp);
+#if CH_CFG_USE_CONDVARS_TIMEOUT
+ msg_t chCondWaitTimeout(condition_variable_t *cp, systime_t time);
+ msg_t chCondWaitTimeoutS(condition_variable_t *cp, systime_t time);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+#endif /* CH_CFG_USE_CONDVARS */
+
+#endif /* _CHCOND_H_ */
+
+/** @} */
diff --git a/os/rt/include/chdebug.h b/os/rt/include/chdebug.h new file mode 100644 index 000000000..836645f07 --- /dev/null +++ b/os/rt/include/chdebug.h @@ -0,0 +1,257 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chdebug.h
+ * @brief Debug macros and structures.
+ *
+ * @addtogroup debug
+ * @{
+ */
+
+#ifndef _CHDEBUG_H_
+#define _CHDEBUG_H_
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Debug related settings
+ * @{
+ */
+/**
+ * @brief Trace buffer entries.
+ */
+#ifndef CH_DBG_TRACE_BUFFER_SIZE
+#define CH_DBG_TRACE_BUFFER_SIZE 64
+#endif
+
+/**
+ * @brief Fill value for thread stack area in debug mode.
+ */
+#ifndef CH_DBG_STACK_FILL_VALUE
+#define CH_DBG_STACK_FILL_VALUE 0x55
+#endif
+
+/**
+ * @brief Fill value for thread area in debug mode.
+ * @note The chosen default value is 0xFF in order to make evident which
+ * thread fields were not initialized when inspecting the memory with
+ * a debugger. A uninitialized field is not an error in itself but it
+ * better to know it.
+ */
+#ifndef CH_DBG_THREAD_FILL_VALUE
+#define CH_DBG_THREAD_FILL_VALUE 0xFF
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || \
+ CH_DBG_ENABLE_STACK_CHECK || CH_DBG_SYSTEM_STATE_CHECK
+#define CH_DBG_ENABLED TRUE
+#else
+#define CH_DBG_ENABLED FALSE
+#endif
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
+/**
+ * @brief Trace buffer record.
+ */
+typedef struct {
+ /**
+ * @brief Time of the switch event.
+ */
+ systime_t se_time;
+ /**
+ * @brief Switched in thread.
+ */
+ thread_t *se_tp;
+ /**
+ * @brief Object where going to sleep.
+ */
+ void *se_wtobjp;
+ /**
+ * @brief Switched out thread state.
+ */
+ uint8_t se_state;
+} ch_swc_event_t;
+
+/**
+ * @brief Trace buffer header.
+ */
+typedef struct {
+ /**
+ * @brief Trace buffer size (entries).
+ */
+ unsigned tb_size;
+ /**
+ * @brief Pointer to the buffer front.
+ */
+ ch_swc_event_t *tb_ptr;
+ /**
+ * @brief Ring buffer.
+ */
+ ch_swc_event_t tb_buffer[CH_DBG_TRACE_BUFFER_SIZE];
+} ch_trace_buffer_t;
+#endif /* CH_DBG_ENABLE_TRACE */
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+#define __QUOTE_THIS(p) #p
+
+#if CH_DBG_SYSTEM_STATE_CHECK
+#define _dbg_enter_lock() (ch.dbg_lock_cnt = 1)
+#define _dbg_leave_lock() (ch.dbg_lock_cnt = 0)
+#endif
+
+/* When the state checker feature is disabled then the following functions
+ are replaced by an empty macro.*/
+#if !CH_DBG_SYSTEM_STATE_CHECK
+#define _dbg_enter_lock()
+#define _dbg_leave_lock()
+#define _dbg_check_disable()
+#define _dbg_check_suspend()
+#define _dbg_check_enable()
+#define _dbg_check_lock()
+#define _dbg_check_unlock()
+#define _dbg_check_lock_from_isr()
+#define _dbg_check_unlock_from_isr()
+#define _dbg_check_enter_isr()
+#define _dbg_check_leave_isr()
+#define chDbgCheckClassI()
+#define chDbgCheckClassS()
+#endif
+
+/* When the trace feature is disabled this function is replaced by an empty
+ macro.*/
+#if !CH_DBG_ENABLE_TRACE
+#define _dbg_trace(otp)
+#endif
+
+/* When the debug features are disabled this function is replaced by an empty
+ macro.*/
+#if !CH_DBG_ENABLED
+#define chDbgPanic(msg) {}
+#endif
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+#if CH_DBG_ENABLE_CHECKS || defined(__DOXYGEN__)
+/**
+ * @brief Function parameters check.
+ * @details If the condition check fails then the kernel panics and halts.
+ * @note The condition is tested only if the @p CH_DBG_ENABLE_CHECKS switch
+ * is specified in @p chconf.h else the macro does nothing.
+ *
+ * @param[in] c the condition to be verified to be true
+ *
+ * @api
+ */
+#if !defined(chDbgCheck)
+#define chDbgCheck(c) { \
+ if (!(c)) \
+ chDbgPanic("C:"__QUOTE_THIS(__FUNCTION__)":"__QUOTE_THIS(__LINE__)); \
+}
+#endif /* !defined(chDbgCheck) */
+
+#else /* !CH_DBG_ENABLE_CHECKS */
+#define chDbgCheck(c) {(void)(c);}
+#endif /* !CH_DBG_ENABLE_CHECKS */
+
+#if CH_DBG_ENABLE_ASSERTS || defined(__DOXYGEN__)
+/**
+ * @brief Condition assertion.
+ * @details If the condition check fails then the kernel panics with a
+ * message and halts.
+ * @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS switch
+ * is specified in @p chconf.h else the macro does nothing.
+ * @note The remark string is not currently used except for putting a
+ * comment in the code about the assertion.
+ *
+ * @param[in] c the condition to be verified to be true
+ * @param[in] r a remark string
+ *
+ * @api
+ */
+#if !defined(chDbgAssert)
+#define chDbgAssert(c, r) { \
+ if (!(c)) \
+ chDbgPanic("A:"__QUOTE_THIS(__FUNCTION__)":"__QUOTE_THIS(__LINE__)); \
+}
+#endif /* !defined(chDbgAssert) */
+#else /* !CH_DBG_ENABLE_ASSERTS */
+#define chDbgAssert(c, r) {(void)(c);}
+#endif /* !CH_DBG_ENABLE_ASSERTS */
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if CH_DBG_SYSTEM_STATE_CHECK
+ void _dbg_check_disable(void);
+ void _dbg_check_suspend(void);
+ void _dbg_check_enable(void);
+ void _dbg_check_lock(void);
+ void _dbg_check_unlock(void);
+ void _dbg_check_lock_from_isr(void);
+ void _dbg_check_unlock_from_isr(void);
+ void _dbg_check_enter_isr(void);
+ void _dbg_check_leave_isr(void);
+ void chDbgCheckClassI(void);
+ void chDbgCheckClassS(void);
+#endif
+#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
+ void _trace_init(void);
+ void _dbg_trace(thread_t *otp);
+#endif
+#if CH_DBG_ENABLED
+ void chDbgPanic(const char *msg);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+#endif /* _CHDEBUG_H_ */
+
+/** @} */
diff --git a/os/rt/include/chdynamic.h b/os/rt/include/chdynamic.h new file mode 100644 index 000000000..cb72bb244 --- /dev/null +++ b/os/rt/include/chdynamic.h @@ -0,0 +1,96 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chdynamic.h
+ * @brief Dynamic threads macros and structures.
+ *
+ * @addtogroup dynamic_threads
+ * @{
+ */
+
+#ifndef _CHDYNAMIC_H_
+#define _CHDYNAMIC_H_
+
+#if CH_CFG_USE_DYNAMIC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*
+ * Module dependencies check.
+ */
+#if CH_CFG_USE_DYNAMIC && !CH_CFG_USE_WAITEXIT
+#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_WAITEXIT"
+#endif
+#if CH_CFG_USE_DYNAMIC && !CH_CFG_USE_HEAP && !CH_CFG_USE_MEMPOOLS
+#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
+ thread_t *chThdAddRef(thread_t *tp);
+ void chThdRelease(thread_t *tp);
+#if CH_CFG_USE_HEAP
+ thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size,
+ tprio_t prio, tfunc_t pf, void *arg);
+#endif
+#if CH_CFG_USE_MEMPOOLS
+ 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 */
+
+#endif /* _CHDYNAMIC_H_ */
+
+/** @} */
diff --git a/os/rt/include/chevents.h b/os/rt/include/chevents.h new file mode 100644 index 000000000..e15d0e6cb --- /dev/null +++ b/os/rt/include/chevents.h @@ -0,0 +1,240 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ Concepts and parts of this file have been contributed by Scott (skute).
+ */
+
+/**
+ * @file chevents.h
+ * @brief Events macros and structures.
+ *
+ * @addtogroup events
+ * @{
+ */
+
+#ifndef _CHEVENTS_H_
+#define _CHEVENTS_H_
+
+#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+typedef struct event_listener event_listener_t;
+
+/**
+ * @brief Event Listener structure.
+ */
+struct event_listener {
+ event_listener_t *el_next; /**< @brief Next Event Listener
+ registered on the event
+ source. */
+ thread_t *el_listener; /**< @brief Thread interested in the
+ event source. */
+ eventmask_t el_mask; /**< @brief Event identifiers mask. */
+ eventflags_t el_flags; /**< @brief Flags added to the listener
+ by the event source.*/
+};
+
+/**
+ * @brief Event Source structure.
+ */
+typedef struct event_source {
+ event_listener_t *es_next; /**< @brief First Event Listener
+ registered on the Event
+ Source. */
+} event_source_t;
+
+/**
+ * @brief Event Handler callback function.
+ */
+typedef void (*evhandler_t)(eventid_t);
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @brief All events allowed mask.
+ */
+#define ALL_EVENTS ((eventmask_t)-1)
+
+/**
+ * @brief Returns an event mask from an event identifier.
+ */
+#define EVENT_MASK(eid) ((eventmask_t)(1 << (eid)))
+
+/**
+ * @brief Data part of a static event source initializer.
+ * @details This macro should be used when statically initializing an event
+ * source that is part of a bigger structure.
+ * @param name the name of the event source variable
+ */
+#define _EVENTSOURCE_DATA(name) {(void *)(&name)}
+
+/**
+ * @brief Static event source initializer.
+ * @details Statically initialized event sources require no explicit
+ * initialization using @p chEvtInit().
+ *
+ * @param name the name of the event source variable
+ */
+#define EVENTSOURCE_DECL(name) event_source_t name = _EVENTSOURCE_DATA(name)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chEvtRegisterMask(event_source_t *esp,
+ event_listener_t *elp,
+ eventmask_t mask);
+ void chEvtUnregister(event_source_t *esp, event_listener_t *elp);
+ eventmask_t chEvtGetAndClearEvents(eventmask_t mask);
+ eventmask_t chEvtAddEvents(eventmask_t mask);
+ eventflags_t chEvtGetAndClearFlags(event_listener_t *elp);
+ eventflags_t chEvtGetAndClearFlagsI(event_listener_t *elp);
+ void chEvtSignal(thread_t *tp, eventmask_t mask);
+ void chEvtSignalI(thread_t *tp, eventmask_t mask);
+ void chEvtBroadcastFlags(event_source_t *esp, eventflags_t flags);
+ void chEvtBroadcastFlagsI(event_source_t *esp, eventflags_t flags);
+ void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask);
+#if CH_CFG_OPTIMIZE_SPEED || !CH_CFG_USE_EVENTS_TIMEOUT
+ eventmask_t chEvtWaitOne(eventmask_t mask);
+ eventmask_t chEvtWaitAny(eventmask_t mask);
+ eventmask_t chEvtWaitAll(eventmask_t mask);
+#endif
+#if CH_CFG_USE_EVENTS_TIMEOUT
+ eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time);
+ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time);
+ eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#if !CH_CFG_OPTIMIZE_SPEED && CH_CFG_USE_EVENTS_TIMEOUT
+#define chEvtWaitOne(mask) chEvtWaitOneTimeout(mask, TIME_INFINITE)
+#define chEvtWaitAny(mask) chEvtWaitAnyTimeout(mask, TIME_INFINITE)
+#define chEvtWaitAll(mask) chEvtWaitAllTimeout(mask, TIME_INFINITE)
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Initializes an Event Source.
+ * @note This function can be invoked before the kernel is initialized
+ * because it just prepares a @p event_source_t structure.
+ *
+ * @param[in] esp pointer to the @p event_source_t structure
+ *
+ * @init
+ */
+static inline void chEvtObjectInit(event_source_t *esp) {
+
+ esp->es_next = (event_listener_t *)(void *)esp;
+}
+
+/**
+ * @brief Registers an Event Listener on an Event Source.
+ * @note Multiple Event Listeners can use the same event identifier, the
+ * listener will share the callback function.
+ *
+ * @param[in] esp pointer to the @p event_source_t structure
+ * @param[out] elp pointer to the @p event_listener_t structure
+ * @param[in] eid numeric identifier assigned to the Event Listener. The
+ * identifier is used as index for the event callback
+ * function.
+ * The value must range between zero and the size, in bit,
+ * of the @p eventid_t type minus one.
+ *
+ * @api
+ */
+static inline void chEvtRegister(event_source_t *esp,
+ event_listener_t *elp,
+ eventid_t eid) {
+
+ chEvtRegisterMask(esp, elp, EVENT_MASK(eid));
+}
+
+/**
+ * @brief Verifies if there is at least one @p event_listener_t registered.
+ *
+ * @param[in] esp pointer to the @p event_source_t structure
+ *
+ * @iclass
+ */
+static inline bool chEvtIsListeningI(event_source_t *esp) {
+
+ return (bool)((void *)esp != (void *)esp->es_next);
+}
+
+/**
+ * @brief Signals all the Event Listeners registered on the specified Event
+ * Source.
+ *
+ * @param[in] esp pointer to the @p event_source_t structure
+ *
+ * @api
+ */
+static inline void chEvtBroadcast(event_source_t *esp) {
+
+ chEvtBroadcastFlags(esp, 0);
+}
+
+/**
+ * @brief Signals all the Event Listeners registered on the specified Event
+ * Source.
+ * @post This function does not reschedule so a call to a rescheduling
+ * function must be performed before unlocking the kernel. Note that
+ * interrupt handlers always reschedule on exit so an explicit
+ * reschedule must not be performed in ISRs.
+ *
+ * @param[in] esp pointer to the @p event_source_t structure
+ *
+ * @iclass
+ */
+static inline void chEvtBroadcastI(event_source_t *esp) {
+
+ chEvtBroadcastFlagsI(esp, 0);
+}
+
+#endif /* CH_CFG_USE_EVENTS */
+
+#endif /* _CHEVENTS_H_ */
+
+/** @} */
diff --git a/os/rt/include/chglobal.h b/os/rt/include/chglobal.h new file mode 100644 index 000000000..0d49d9a45 --- /dev/null +++ b/os/rt/include/chglobal.h @@ -0,0 +1,179 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chglobal.h
+ * @brief Data structures with global scope header.
+ *
+ * @addtogroup global
+ */
+
+#ifndef _CHGLOBAL_H_
+#define _CHGLOBAL_H_
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Generic threads single link list, it works like a stack.
+ */
+typedef struct {
+
+ thread_t *p_next; /**< @brief Next in the list/queue. */
+} threads_list_t;
+
+/**
+ * @extends threads_list_t
+ *
+ * @brief Generic threads bidirectional linked list header and element.
+ */
+typedef struct {
+ thread_t *p_next; /**< @brief Next in the list/queue. */
+ thread_t *p_prev; /**< @brief Previous in the queue. */
+} threads_queue_t;
+
+/**
+ * @extends threads_queue_t
+ *
+ * @brief Ready list header.
+ */
+typedef struct {
+ threads_queue_t r_queue; /**< @brief Threads queue. */
+ tprio_t r_prio; /**< @brief This field must be
+ initialized to zero. */
+ struct context r_ctx; /**< @brief Not used, present because
+ offsets. */
+#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__)
+ thread_t *r_newer; /**< @brief Newer registry element. */
+ thread_t *r_older; /**< @brief Older registry element. */
+#endif
+ /* End of the fields shared with the thread_t structure.*/
+ thread_t *r_current; /**< @brief The currently running
+ thread. */
+} ready_list_t;
+
+/**
+ * @brief Virtual timers list header.
+ * @note The timers list is implemented as a double link bidirectional list
+ * in order to make the unlink time constant, the reset of a virtual
+ * timer is often used in the code.
+ */
+typedef struct {
+ virtual_timer_t *vt_next; /**< @brief Next timer in the delta
+ list. */
+ virtual_timer_t *vt_prev; /**< @brief Last timer in the delta
+ list. */
+ systime_t vt_delta; /**< @brief Must be initialized to -1. */
+#if CH_CFG_TIMEDELTA == 0 || defined(__DOXYGEN__)
+ volatile systime_t vt_systime; /**< @brief System Time counter. */
+#endif
+#if CH_CFG_TIMEDELTA > 0 || defined(__DOXYGEN__)
+ /**
+ * @brief System time of the last tick event.
+ */
+ systime_t vt_lasttime;/**< @brief System time of the last
+ tick event. */
+#endif
+} virtual_timers_list_t;
+
+/**
+ * @brief System data structure.
+ * @note This structure contain all the data areas used by the OS except
+ * stacks.
+ */
+typedef struct ch_system {
+ /**
+ * @brief Ready list header.
+ */
+ ready_list_t rlist;
+ /**
+ * @brief Virtual timers delta list header.
+ */
+ virtual_timers_list_t vtlist;
+#if CH_CFG_USE_TM || defined(__DOXYGEN__)
+ /**
+ * @brief Measurement calibration value.
+ */
+ rtcnt_t measurement_offset;
+#endif
+#if CH_DBG_STATISTICS || defined(__DOXYGEN__)
+ /**
+ * @brief Global kernel statistics.
+ */
+ kernel_stats_t kernel_stats;
+#endif
+#if CH_DBG_ENABLED || defined(__DOXYGEN__)
+ /**
+ * @brief Pointer to the panic message.
+ * @details This pointer is meant to be accessed through the debugger, it is
+ * written once and then the system is halted.
+ */
+ const char *dbg_panic_msg;
+#endif
+#if CH_DBG_SYSTEM_STATE_CHECK || defined(__DOXYGEN__)
+ /**
+ * @brief ISR nesting level.
+ */
+ cnt_t dbg_isr_cnt;
+ /**
+ * @brief Lock nesting level.
+ */
+ cnt_t dbg_lock_cnt;
+#endif
+#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
+ /**
+ * @brief Public trace buffer.
+ */
+ ch_trace_buffer_t dbg_trace_buffer;
+#endif
+} ch_system_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern ch_system_t ch;
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+#endif /* _CHGLOBAL_H_ */
+
+/** @} */
diff --git a/os/rt/include/chheap.h b/os/rt/include/chheap.h new file mode 100644 index 000000000..73e0d4148 --- /dev/null +++ b/os/rt/include/chheap.h @@ -0,0 +1,119 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chheap.h
+ * @brief Heaps macros and structures.
+ *
+ * @addtogroup heaps
+ * @{
+ */
+
+#ifndef _CHHEAP_H_
+#define _CHHEAP_H_
+
+#if CH_CFG_USE_HEAP || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !CH_CFG_USE_MEMCORE
+#error "CH_CFG_USE_HEAP requires CH_CFG_USE_MEMCORE"
+#endif
+
+#if !CH_CFG_USE_MUTEXES && !CH_CFG_USE_SEMAPHORES
+#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 Memory heap block header.
+ */
+union heap_header {
+ stkalign_t align;
+ struct {
+ union {
+ union heap_header *next; /**< @brief Next block in free list. */
+ memory_heap_t *heap; /**< @brief Block owner heap. */
+ } u; /**< @brief Overlapped fields. */
+ size_t size; /**< @brief Size of the memory block. */
+ } h;
+};
+
+/**
+ * @brief Structure describing a memory heap.
+ */
+struct memory_heap {
+ memgetfunc_t h_provider; /**< @brief Memory blocks provider for
+ this heap. */
+ union heap_header h_free; /**< @brief Free blocks list header. */
+#if CH_CFG_USE_MUTEXES
+ mutex_t h_mtx; /**< @brief Heap access mutex. */
+#else
+ semaphore_t h_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 *chHeapAlloc(memory_heap_t *heapp, size_t size);
+ void chHeapFree(void *p);
+ size_t chHeapStatus(memory_heap_t *heapp, size_t *sizep);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+#endif /* CH_CFG_USE_HEAP */
+
+#endif /* _CHHEAP_H_ */
+
+/** @} */
diff --git a/os/rt/include/chlists.h b/os/rt/include/chlists.h new file mode 100644 index 000000000..69a42bcce --- /dev/null +++ b/os/rt/include/chlists.h @@ -0,0 +1,195 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chlists.h
+ * @brief Thread queues/lists inlined code.
+ *
+ * @addtogroup internals
+ * @{
+ */
+
+#ifndef _CHLISTS_H_
+#define _CHLISTS_H_
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Data part of a static threads queue initializer.
+ * @details This macro should be used when statically initializing a threads
+ * queue that is part of a bigger structure.
+ *
+ * @param[in] name the name of the threads queue variable
+ */
+#define _threads_queue_t_DATA(name) {(thread_t *)&name, (thread_t *)&name}
+
+/**
+ * @brief Static threads queue initializer.
+ * @details Statically initialized threads queues require no explicit
+ * initialization using @p queue_init().
+ *
+ * @param[in] name the name of the threads queue variable
+ */
+#define threads_queue_t_DECL(name) \
+ threads_queue_t name = _threads_queue_t_DATA(name)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Threads list initialization.
+ *
+ * @notapi
+ */
+static inline void list_init(threads_list_t *tlp) {
+
+ tlp->p_next = (thread_t *)tlp;
+}
+
+/**
+ * @brief Evaluates to @p true if the specified threads list is empty.
+ *
+ * @notapi
+ */
+static inline bool list_isempty(threads_list_t *tlp) {
+
+ return (bool)(tlp->p_next == (thread_t *)tlp);
+}
+
+/**
+ * @brief Evaluates to @p true if the specified threads list is not empty.
+ *
+ * @notapi
+ */
+static inline bool list_notempty(threads_list_t *tlp) {
+
+ return (bool)(tlp->p_next != (thread_t *)tlp);
+}
+
+/**
+ * @brief Threads queue initialization.
+ *
+ * @notapi
+ */
+static inline void queue_init(threads_queue_t *tqp) {
+
+ tqp->p_next = tqp->p_prev = (thread_t *)tqp;
+}
+
+/**
+ * @brief Evaluates to @p true if the specified threads queue is empty.
+ *
+ * @notapi
+ */
+static inline bool queue_isempty(threads_queue_t *tqp) {
+
+ return (bool)(tqp->p_next == (thread_t *)tqp);
+}
+
+/**
+ * @brief Evaluates to @p true if the specified threads queue is not empty.
+ *
+ * @notapi
+ */
+static inline bool queue_notempty(threads_queue_t *tqp) {
+
+ return (bool)(tqp->p_next != (thread_t *)tqp);
+}
+
+/* If the performance code path has been chosen then all the following
+ functions are inlined into the various kernel modules.*/
+#if CH_CFG_OPTIMIZE_SPEED
+static inline void list_insert(thread_t *tp, threads_list_t *tlp) {
+
+ tp->p_next = tlp->p_next;
+ tlp->p_next = tp;
+}
+
+static inline thread_t *list_remove(threads_list_t *tlp) {
+
+ thread_t *tp = tlp->p_next;
+ tlp->p_next = tp->p_next;
+ return tp;
+}
+
+static inline void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) {
+
+ thread_t *cp = (thread_t *)tqp;
+ do {
+ cp = cp->p_next;
+ } while ((cp != (thread_t *)tqp) && (cp->p_prio >= tp->p_prio));
+ tp->p_next = cp;
+ tp->p_prev = cp->p_prev;
+ tp->p_prev->p_next = cp->p_prev = tp;
+}
+
+static inline void queue_insert(thread_t *tp, threads_queue_t *tqp) {
+
+ tp->p_next = (thread_t *)tqp;
+ tp->p_prev = tqp->p_prev;
+ tp->p_prev->p_next = tqp->p_prev = tp;
+}
+
+static inline thread_t *queue_fifo_remove(threads_queue_t *tqp) {
+ thread_t *tp = tqp->p_next;
+
+ (tqp->p_next = tp->p_next)->p_prev = (thread_t *)tqp;
+ return tp;
+}
+
+static inline thread_t *queue_lifo_remove(threads_queue_t *tqp) {
+ thread_t *tp = tqp->p_prev;
+
+ (tqp->p_prev = tp->p_prev)->p_next = (thread_t *)tqp;
+ return tp;
+}
+
+static inline thread_t *queue_dequeue(thread_t *tp) {
+
+ tp->p_prev->p_next = tp->p_next;
+ tp->p_next->p_prev = tp->p_prev;
+ return tp;
+}
+#endif /* CH_CFG_OPTIMIZE_SPEED */
+
+#endif /* _CHLISTS_H_ */
diff --git a/os/rt/include/chmboxes.h b/os/rt/include/chmboxes.h new file mode 100644 index 000000000..8d1dedfd1 --- /dev/null +++ b/os/rt/include/chmboxes.h @@ -0,0 +1,200 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chmboxes.h
+ * @brief Mailboxes macros and structures.
+ *
+ * @addtogroup mailboxes
+ * @{
+ */
+
+#ifndef _CHMBOXES_H_
+#define _CHMBOXES_H_
+
+#if CH_CFG_USE_MAILBOXES || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !CH_CFG_USE_SEMAPHORES
+#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 *mb_buffer; /**< @brief Pointer to the mailbox
+ buffer. */
+ msg_t *mb_top; /**< @brief Pointer to the location
+ after the buffer. */
+ msg_t *mb_wrptr; /**< @brief Write pointer. */
+ msg_t *mb_rdptr; /**< @brief Read pointer. */
+ semaphore_t mb_fullsem; /**< @brief Full counter
+ @p semaphore_t. */
+ semaphore_t mb_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.mb_fullsem, 0), \
+ _SEMAPHORE_DATA(name.mb_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);
+ 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
+ *
+ * @iclass
+ */
+static inline size_t chMBSizeI(mailbox_t *mbp) {
+
+ return (size_t)(mbp->mb_top - mbp->mb_buffer);
+}
+
+/**
+ * @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->mb_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->mb_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.
+ *
+ * @iclass
+ */
+static inline cnt_t chMBPeekI(mailbox_t *mbp) {
+
+ chDbgCheckClassI();
+
+ return *mbp->mb_rdptr;
+}
+
+#endif /* CH_CFG_USE_MAILBOXES */
+
+#endif /* _CHMBOXES_H_ */
+
+/** @} */
diff --git a/os/rt/include/chmemcore.h b/os/rt/include/chmemcore.h new file mode 100644 index 000000000..314e94365 --- /dev/null +++ b/os/rt/include/chmemcore.h @@ -0,0 +1,114 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chmemcore.h
+ * @brief Core memory manager macros and structures.
+ *
+ * @addtogroup memcore
+ * @{
+ */
+
+#ifndef _CHMEMCORE_H_
+#define _CHMEMCORE_H_
+
+#if CH_CFG_USE_MEMCORE || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Memory get function.
+ * @note This type must be assignment compatible with the @p chMemAlloc()
+ * function.
+ */
+typedef void *(*memgetfunc_t)(size_t size);
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @name Alignment support macros
+ */
+/**
+ * @brief Alignment size constant.
+ */
+#define MEM_ALIGN_SIZE sizeof(stkalign_t)
+
+/**
+ * @brief Alignment mask constant.
+ */
+#define MEM_ALIGN_MASK (MEM_ALIGN_SIZE - 1)
+
+/**
+ * @brief Alignment helper macro.
+ */
+#define MEM_ALIGN_PREV(p) ((size_t)(p) & ~MEM_ALIGN_MASK)
+
+/**
+ * @brief Alignment helper macro.
+ */
+#define MEM_ALIGN_NEXT(p) MEM_ALIGN_PREV((size_t)(p) + MEM_ALIGN_MASK)
+
+/**
+ * @brief Returns whatever a pointer or memory size is aligned to
+ * the type @p align_t.
+ */
+#define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _core_init(void);
+ void *chCoreAlloc(size_t size);
+ void *chCoreAllocI(size_t size);
+ size_t chCoreStatus(void);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+#endif /* CH_CFG_USE_MEMCORE */
+
+#endif /* _CHMEMCORE_H_ */
+
+/** @} */
diff --git a/os/rt/include/chmempools.h b/os/rt/include/chmempools.h new file mode 100644 index 000000000..85b94fc73 --- /dev/null +++ b/os/rt/include/chmempools.h @@ -0,0 +1,169 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chmempools.h
+ * @brief Memory Pools macros and structures.
+ *
+ * @addtogroup pools
+ * @{
+ */
+
+#ifndef _CHMEMPOOLS_H_
+#define _CHMEMPOOLS_H_
+
+#if CH_CFG_USE_MEMPOOLS || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+#if !CH_CFG_USE_MEMCORE
+#error "CH_CFG_USE_MEMPOOLS requires CH_CFG_USE_MEMCORE"
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Memory pool free object header.
+ */
+struct pool_header {
+ struct pool_header *ph_next; /**< @brief Pointer to the next pool
+ header in the list. */
+};
+
+/**
+ * @brief Memory pool descriptor.
+ */
+typedef struct {
+ struct pool_header *mp_next; /**< @brief Pointer to the header. */
+ size_t mp_object_size; /**< @brief Memory pool objects
+ size. */
+ memgetfunc_t mp_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 */
+
+#endif /* _CHMEMPOOLS_H_ */
+
+/** @} */
diff --git a/os/rt/include/chmsg.h b/os/rt/include/chmsg.h new file mode 100644 index 000000000..ff07edfb3 --- /dev/null +++ b/os/rt/include/chmsg.h @@ -0,0 +1,120 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chmsg.h
+ * @brief Messages macros and structures.
+ *
+ * @addtogroup messages
+ * @{
+ */
+
+#ifndef _CHMSG_H_
+#define _CHMSG_H_
+
+#if CH_CFG_USE_MESSAGES || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ msg_t chMsgSend(thread_t *tp, msg_t msg);
+ thread_t * chMsgWait(void);
+ void chMsgRelease(thread_t *tp, msg_t msg);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+/**
+ * @brief Evaluates to @p true if the thread has pending messages.
+ *
+ * @iclass
+ */
+static inline bool chMsgIsPendingI(thread_t *tp) {
+
+ chDbgCheckClassI();
+
+ return (bool)(tp->p_msgqueue.p_next != (thread_t *)&tp->p_msgqueue);
+}
+
+/**
+ * @brief Returns the message carried by the specified thread.
+ * @pre This function must be invoked immediately after exiting a call
+ * to @p chMsgWait().
+ *
+ * @param[in] tp pointer to the thread
+ * @return The message carried by the sender.
+ *
+ * @api
+ */
+static inline msg_t chMsgGet(thread_t *tp) {
+
+ return tp->p_msg;
+}
+
+/**
+ * @brief Releases the thread waiting on top of the messages queue.
+ * @pre Invoke this function only after a message has been received
+ * using @p chMsgWait().
+ *
+ * @param[in] tp pointer to the thread
+ * @param[in] msg message to be returned to the sender
+ *
+ * @sclass
+ */
+static inline void chMsgReleaseS(thread_t *tp, msg_t msg) {
+
+ chDbgCheckClassS();
+
+ chSchWakeupS(tp, msg);
+}
+
+#endif /* CH_CFG_USE_MESSAGES */
+
+#endif /* _CHMSG_H_ */
+
+/** @} */
diff --git a/os/rt/include/chmtx.h b/os/rt/include/chmtx.h new file mode 100644 index 000000000..a4ff5e49f --- /dev/null +++ b/os/rt/include/chmtx.h @@ -0,0 +1,126 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chmtx.h
+ * @brief Mutexes macros and structures.
+ *
+ * @addtogroup mutexes
+ * @{
+ */
+
+#ifndef _CHMTX_H_
+#define _CHMTX_H_
+
+#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Mutex structure.
+ */
+typedef struct mutex {
+ threads_queue_t m_queue; /**< @brief Queue of the threads sleeping
+ on this mutex. */
+ thread_t *m_owner; /**< @brief Owner @p thread_t pointer or
+ @p NULL. */
+ mutex_t *m_next; /**< @brief Next @p mutex_t into an
+ owner-list or @p NULL. */
+} mutex_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Data part of a static mutex initializer.
+ * @details This macro should be used when statically initializing a mutex
+ * that is part of a bigger structure.
+ *
+ * @param[in] name the name of the mutex variable
+ */
+#define _MUTEX_DATA(name) {_threads_queue_t_DATA(name.m_queue), NULL, NULL}
+
+/**
+ * @brief Static mutex initializer.
+ * @details Statically initialized mutexes require no explicit initialization
+ * using @p chMtxInit().
+ *
+ * @param[in] name the name of the mutex variable
+ */
+#define MUTEX_DECL(name) mutex_t name = _MUTEX_DATA(name)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chMtxObjectInit(mutex_t *mp);
+ void chMtxLock(mutex_t *mp);
+ void chMtxLockS(mutex_t *mp);
+ bool chMtxTryLock(mutex_t *mp);
+ bool chMtxTryLockS(mutex_t *mp);
+ mutex_t *chMtxUnlock(void);
+ mutex_t *chMtxUnlockS(void);
+ void chMtxUnlockAll(void);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Returns @p true if the mutex queue contains at least a waiting
+ * thread.
+ *
+ * @deprecated
+ * @sclass
+ */
+static inline bool chMtxQueueNotEmptyS(mutex_t *mp) {
+
+ chDbgCheckClassS();
+
+ return queue_notempty(&mp->m_queue);
+}
+
+#endif /* CH_CFG_USE_MUTEXES */
+
+#endif /* _CHMTX_H_ */
+
+/** @} */
diff --git a/os/rt/include/chqueues.h b/os/rt/include/chqueues.h new file mode 100644 index 000000000..c050285ac --- /dev/null +++ b/os/rt/include/chqueues.h @@ -0,0 +1,431 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chqueues.h
+ * @brief I/O Queues macros and structures.
+ *
+ * @addtogroup io_queues
+ * @{
+ */
+
+#ifndef _CHQUEUES_H_
+#define _CHQUEUES_H_
+
+#if CH_CFG_USE_QUEUES || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/**
+ * @name Queue functions returned status value
+ * @{
+ */
+#define Q_OK RDY_OK /**< @brief Operation successful. */
+#define Q_TIMEOUT RDY_TIMEOUT /**< @brief Timeout condition. */
+#define Q_RESET RDY_RESET /**< @brief Queue has been reset. */
+#define Q_EMPTY -3 /**< @brief Queue empty. */
+#define Q_FULL -4 /**< @brief Queue full, */
+/** @} */
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a generic I/O queue structure.
+ */
+typedef struct io_queue io_queue_t;
+
+/** @brief Queue notification callback type.*/
+typedef void (*qnotify_t)(io_queue_t *qp);
+
+/**
+ * @brief Generic I/O queue structure.
+ * @details This structure represents a generic Input or Output asymmetrical
+ * queue. The queue is asymmetrical because one end is meant to be
+ * accessed from a thread context, and thus can be blocking, the other
+ * end is accessible from interrupt handlers or from within a kernel
+ * lock zone (see <b>I-Locked</b> and <b>S-Locked</b> states in
+ * @ref system_states) and is non-blocking.
+ */
+struct io_queue {
+ threads_queue_t q_waiting; /**< @brief Queue of waiting threads. */
+ size_t q_counter; /**< @brief Resources counter. */
+ uint8_t *q_buffer; /**< @brief Pointer to the queue buffer.*/
+ uint8_t *q_top; /**< @brief Pointer to the first location
+ after the buffer. */
+ uint8_t *q_wrptr; /**< @brief Write pointer. */
+ uint8_t *q_rdptr; /**< @brief Read pointer. */
+ qnotify_t q_notify; /**< @brief Data notification callback. */
+ void *q_link; /**< @brief Application defined field. */
+};
+
+/**
+ * @extends io_queue_t
+ *
+ * @brief Type of an input queue structure.
+ * @details This structure represents a generic asymmetrical input queue.
+ * Writing to the queue is non-blocking and can be performed from
+ * interrupt handlers or from within a kernel lock zone (see
+ * <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states).
+ * Reading the queue can be a blocking operation and is supposed to
+ * be performed by a system thread.
+ */
+typedef io_queue_t input_queue_t;
+
+/**
+ * @extends io_queue_t
+ *
+ * @brief Type of an output queue structure.
+ * @details This structure represents a generic asymmetrical output queue.
+ * Reading from the queue is non-blocking and can be performed from
+ * interrupt handlers or from within a kernel lock zone (see
+ * <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states).
+ * Writing the queue can be a blocking operation and is supposed to
+ * be performed by a system thread.
+ */
+typedef io_queue_t output_queue_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Data part of a static input queue initializer.
+ * @details This macro should be used when statically initializing an
+ * input queue that is part of a bigger structure.
+ *
+ * @param[in] name the name of the input queue variable
+ * @param[in] buffer pointer to the queue buffer area
+ * @param[in] size size of the queue buffer area
+ * @param[in] inotify input notification callback pointer
+ * @param[in] link application defined pointer
+ */
+#define _INPUTQUEUE_DATA(name, buffer, size, inotify, link) { \
+ _threads_queue_t_DATA(name), \
+ 0, \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer) + (size), \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer), \
+ (inotify), \
+ (link) \
+}
+
+/**
+ * @brief Static input queue initializer.
+ * @details Statically initialized input queues require no explicit
+ * initialization using @p chIQInit().
+ *
+ * @param[in] name the name of the input queue variable
+ * @param[in] buffer pointer to the queue buffer area
+ * @param[in] size size of the queue buffer area
+ * @param[in] inotify input notification callback pointer
+ * @param[in] link application defined pointer
+ */
+#define INPUTQUEUE_DECL(name, buffer, size, inotify, link) \
+ input_queue_t name = _INPUTQUEUE_DATA(name, buffer, size, inotify, link)
+
+/**
+ * @brief Data part of a static output queue initializer.
+ * @details This macro should be used when statically initializing an
+ * output queue that is part of a bigger structure.
+ *
+ * @param[in] name the name of the output queue variable
+ * @param[in] buffer pointer to the queue buffer area
+ * @param[in] size size of the queue buffer area
+ * @param[in] onotify output notification callback pointer
+ * @param[in] link application defined pointer
+ */
+#define _OUTPUTQUEUE_DATA(name, buffer, size, onotify, link) { \
+ _threads_queue_t_DATA(name), \
+ (size), \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer) + (size), \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer), \
+ (onotify), \
+ (link) \
+}
+
+/**
+ * @brief Static output queue initializer.
+ * @details Statically initialized output queues require no explicit
+ * initialization using @p chOQInit().
+ *
+ * @param[in] name the name of the output queue variable
+ * @param[in] buffer pointer to the queue buffer area
+ * @param[in] size size of the queue buffer area
+ * @param[in] onotify output notification callback pointer
+ * @param[in] link application defined pointer
+ */
+#define OUTPUTQUEUE_DECL(name, buffer, size, onotify, link) \
+ output_queue_t name = _OUTPUTQUEUE_DATA(name, buffer, size, onotify, link)
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Returns the queue's buffer size.
+ *
+ * @param[in] qp pointer to a @p io_queue_t structure.
+ * @return The buffer size.
+ *
+ * @iclass
+ */
+#define chQSizeI(qp) ((size_t)((qp)->q_top - (qp)->q_buffer))
+
+/**
+ * @brief Queue space.
+ * @details Returns the used space if used on an input queue or the empty
+ * space if used on an output queue.
+ *
+ * @param[in] qp pointer to a @p io_queue_t structure.
+ * @return The buffer space.
+ *
+ * @iclass
+ */
+#define chQSpaceI(qp) ((qp)->q_counter)
+
+/**
+ * @brief Returns the queue application-defined link.
+ *
+ * @param[in] qp pointer to a @p io_queue_t structure.
+ * @return The application-defined link.
+ *
+ * @xclass
+ */
+#define chQGetLinkX(qp) ((qp)->q_link)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chIQObjectInit(input_queue_t *iqp, uint8_t *bp, size_t size,
+ qnotify_t infy, void *link);
+ void chIQResetI(input_queue_t *iqp);
+ msg_t chIQPutI(input_queue_t *iqp, uint8_t b);
+ msg_t chIQGetTimeout(input_queue_t *iqp, systime_t time);
+ size_t chIQReadTimeout(input_queue_t *iqp, uint8_t *bp,
+ size_t n, systime_t time);
+
+ void chOQObjectInit(output_queue_t *oqp, uint8_t *bp, size_t size,
+ qnotify_t onfy, void *link);
+ void chOQResetI(output_queue_t *oqp);
+ msg_t chOQPutTimeout(output_queue_t *oqp, uint8_t b, systime_t time);
+ msg_t chOQGetI(output_queue_t *oqp);
+ size_t chOQWriteTimeout(output_queue_t *oqp, const uint8_t *bp,
+ size_t n, systime_t time);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Returns the filled space into an input queue.
+ *
+ * @param[in] iqp pointer to an @p input_queue_t structure
+ * @return The number of full bytes in the queue.
+ * @retval 0 if the queue is empty.
+ *
+ * @iclass
+ */
+static inline size_t chIQGetFullI(input_queue_t *iqp) {
+
+ chDbgCheckClassI();
+
+ return (size_t)chQSpaceI(iqp);
+}
+
+/**
+ * @brief Returns the empty space into an input queue.
+ *
+ * @param[in] iqp pointer to an @p input_queue_t structure
+ * @return The number of empty bytes in the queue.
+ * @retval 0 if the queue is full.
+ *
+ * @iclass
+ */
+static inline size_t chIQGetEmptyI(input_queue_t *iqp) {
+
+ chDbgCheckClassI();
+
+ return (size_t)(chQSizeI(iqp) - chQSpaceI(iqp));
+}
+
+/**
+ * @brief Evaluates to @p true if the specified input queue is empty.
+ *
+ * @param[in] iqp pointer to an @p input_queue_t structure.
+ * @return The queue status.
+ * @retval false if the queue is not empty.
+ * @retval true if the queue is empty.
+ *
+ * @iclass
+ */
+static inline bool chIQIsEmptyI(input_queue_t *iqp) {
+
+ chDbgCheckClassI();
+
+ return (bool)(chQSpaceI(iqp) <= 0);
+}
+
+/**
+ * @brief Evaluates to @p true if the specified input queue is full.
+ *
+ * @param[in] iqp pointer to an @p input_queue_t structure.
+ * @return The queue status.
+ * @retval false if the queue is not full.
+ * @retval true if the queue is full.
+ *
+ * @iclass
+ */
+static inline bool chIQIsFullI(input_queue_t *iqp) {
+
+ chDbgCheckClassI();
+
+ return (bool)((iqp->q_wrptr == iqp->q_rdptr) && (iqp->q_counter != 0));
+}
+
+/**
+ * @brief Input queue read.
+ * @details This function reads a byte value from an input queue. If the queue
+ * is empty then the calling thread is suspended until a byte arrives
+ * in the queue.
+ *
+ * @param[in] iqp pointer to an @p input_queue_t structure
+ * @return A byte value from the queue.
+ * @retval Q_RESET if the queue has been reset.
+ *
+ * @api
+ */
+static inline msg_t chIQGet(input_queue_t *iqp) {
+
+ return chIQGetTimeout(iqp, TIME_INFINITE);
+}
+
+/**
+ * @brief Returns the filled space into an output queue.
+ *
+ * @param[in] oqp pointer to an @p output_queue_t structure
+ * @return The number of full bytes in the queue.
+ * @retval 0 if the queue is empty.
+ *
+ * @iclass
+ */
+static inline size_t chOQGetFullI(output_queue_t *oqp) {
+
+ chDbgCheckClassI();
+
+ return (size_t)(chQSizeI(oqp) - chQSpaceI(oqp));
+}
+
+/**
+ * @brief Returns the empty space into an output queue.
+ *
+ * @param[in] oqp pointer to an @p output_queue_t structure
+ * @return The number of empty bytes in the queue.
+ * @retval 0 if the queue is full.
+ *
+ * @iclass
+ */
+static inline size_t chOQGetEmptyI(output_queue_t *oqp) {
+
+ chDbgCheckClassI();
+
+ return (size_t)chQSpaceI(oqp);
+}
+
+/**
+ * @brief Evaluates to @p true if the specified output queue is empty.
+ *
+ * @param[in] oqp pointer to an @p output_queue_t structure.
+ * @return The queue status.
+ * @retval false if the queue is not empty.
+ * @retval true if the queue is empty.
+ *
+ * @iclass
+ */
+static inline bool chOQIsEmptyI(output_queue_t *oqp) {
+
+ chDbgCheckClassI();
+
+ return (bool)((oqp->q_wrptr == oqp->q_rdptr) && (oqp->q_counter != 0));
+}
+
+/**
+ * @brief Evaluates to @p true if the specified output queue is full.
+ *
+ * @param[in] oqp pointer to an @p output_queue_t structure.
+ * @return The queue status.
+ * @retval false if the queue is not full.
+ * @retval true if the queue is full.
+ *
+ * @iclass
+ */
+static inline bool chOQIsFullI(output_queue_t *oqp) {
+
+ chDbgCheckClassI();
+
+ return (bool)(chQSpaceI(oqp) <= 0);
+}
+
+/**
+ * @brief Output queue write.
+ * @details This function writes a byte value to an output queue. If the queue
+ * is full then the calling thread is suspended until there is space
+ * in the queue.
+ *
+ * @param[in] oqp pointer to an @p output_queue_t structure
+ * @param[in] b the byte value to be written in the queue
+ * @return The operation status.
+ * @retval Q_OK if the operation succeeded.
+ * @retval Q_RESET if the queue has been reset.
+ *
+ * @api
+ */
+static inline msg_t chOQPut(output_queue_t *oqp, uint8_t b) {
+
+ return chOQPutTimeout(oqp, b, TIME_INFINITE);
+}
+
+#endif /* CH_CFG_USE_QUEUES */
+
+#endif /* _CHQUEUES_H_ */
+
+/** @} */
diff --git a/os/rt/include/chregistry.h b/os/rt/include/chregistry.h new file mode 100644 index 000000000..e4cbb0d68 --- /dev/null +++ b/os/rt/include/chregistry.h @@ -0,0 +1,167 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chregistry.h
+ * @brief Threads registry macros and structures.
+ *
+ * @addtogroup registry
+ * @{
+ */
+
+#ifndef _CHREGISTRY_H_
+#define _CHREGISTRY_H_
+
+#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ChibiOS/RT memory signature record.
+ */
+typedef struct {
+ char ch_identifier[4]; /**< @brief Always set to "main". */
+ uint8_t ch_zero; /**< @brief Must be zero. */
+ uint8_t ch_size; /**< @brief Size of this structure. */
+ uint16_t ch_version; /**< @brief Encoded ChibiOS/RT version. */
+ uint8_t ch_ptrsize; /**< @brief Size of a pointer. */
+ uint8_t ch_timesize; /**< @brief Size of a @p systime_t. */
+ uint8_t ch_threadsize; /**< @brief Size of a @p thread_t. */
+ uint8_t cf_off_prio; /**< @brief Offset of @p p_prio field. */
+ uint8_t cf_off_ctx; /**< @brief Offset of @p p_ctx field. */
+ uint8_t cf_off_newer; /**< @brief Offset of @p p_newer field. */
+ uint8_t cf_off_older; /**< @brief Offset of @p p_older field. */
+ uint8_t cf_off_name; /**< @brief Offset of @p p_name field. */
+ uint8_t cf_off_stklimit; /**< @brief Offset of @p p_stklimit
+ field. */
+ uint8_t cf_off_state; /**< @brief Offset of @p p_state field. */
+ uint8_t cf_off_flags; /**< @brief Offset of @p p_flags field. */
+ uint8_t cf_off_refs; /**< @brief Offset of @p p_refs field. */
+ uint8_t cf_off_preempt; /**< @brief Offset of @p p_preempt
+ field. */
+ uint8_t cf_off_time; /**< @brief Offset of @p p_time field. */
+} chdebug_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Removes a thread from the registry list.
+ * @note This macro is not meant for use in application code.
+ *
+ * @param[in] tp thread to remove from the registry
+ */
+#define REG_REMOVE(tp) { \
+ (tp)->p_older->p_newer = (tp)->p_newer; \
+ (tp)->p_newer->p_older = (tp)->p_older; \
+}
+
+/**
+ * @brief Adds a thread to the registry list.
+ * @note This macro is not meant for use in application code.
+ *
+ * @param[in] tp thread to add to the registry
+ */
+#define REG_INSERT(tp) { \
+ (tp)->p_newer = (thread_t *)&ch.rlist; \
+ (tp)->p_older = ch.rlist.r_older; \
+ (tp)->p_older->p_newer = ch.rlist.r_older = (tp); \
+}
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ extern ROMCONST chdebug_t ch_debug;
+ thread_t *chRegFirstThread(void);
+ thread_t *chRegNextThread(thread_t *tp);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Sets the current thread name.
+ * @pre This function only stores the pointer to the name if the option
+ * @p CH_CFG_USE_REGISTRY is enabled else no action is performed.
+ *
+ * @param[in] p thread name as a zero terminated string
+ *
+ * @api
+ */
+static inline void chRegSetThreadName(const char *name) {
+
+#if CH_CFG_USE_REGISTRY
+ currp->p_name = name;
+#else
+ (void)name;
+#endif
+}
+
+/**
+ * @brief Returns the name of the specified thread.
+ * @pre This function only returns the pointer to the name if the option
+ * @p CH_CFG_USE_REGISTRY is enabled else @p NULL is returned.
+ *
+ * @param[in] tp pointer to the thread
+ *
+ * @return Thread name as a zero terminated string.
+ * @retval NULL if the thread name has not been set.
+ *
+ * @iclass
+ */
+static inline const char *chRegGetThreadNameI(thread_t *tp) {
+
+ chDbgCheckClassI();
+
+#if CH_CFG_USE_REGISTRY
+ return tp->p_name;
+#else
+ (void)tp;
+ return NULL;
+#endif
+}
+
+#endif /* CH_CFG_USE_REGISTRY */
+
+#endif /* _CHREGISTRY_H_ */
+
+/** @} */
diff --git a/os/rt/include/chschd.h b/os/rt/include/chschd.h new file mode 100644 index 000000000..248f707c8 --- /dev/null +++ b/os/rt/include/chschd.h @@ -0,0 +1,218 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chschd.h
+ * @brief Scheduler macros and structures.
+ *
+ * @addtogroup scheduler
+ * @{
+ */
+
+#ifndef _CHSCHD_H_
+#define _CHSCHD_H_
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/**
+ * @name Wakeup status codes
+ * @{
+ */
+#define RDY_OK 0 /**< @brief Normal wakeup message. */
+#define RDY_TIMEOUT -1 /**< @brief Wakeup caused by a timeout
+ condition. */
+#define RDY_RESET -2 /**< @brief Wakeup caused by a reset
+ condition. */
+/** @} */
+
+/**
+ * @name Priority constants
+ * @{
+ */
+#define NOPRIO 0 /**< @brief Ready list header priority. */
+#define IDLEPRIO 1 /**< @brief Idle thread priority. */
+#define LOWPRIO 2 /**< @brief Lowest user priority. */
+#define NORMALPRIO 64 /**< @brief Normal user priority. */
+#define HIGHPRIO 127 /**< @brief Highest user priority. */
+#define ABSPRIO 255 /**< @brief Greatest possible priority. */
+/** @} */
+
+/**
+ * @name Special time constants
+ * @{
+ */
+/**
+ * @brief Zero time specification for some functions with a timeout
+ * specification.
+ * @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
+ * see the specific function documentation.
+ */
+#define TIME_IMMEDIATE ((systime_t)0)
+
+/**
+ * @brief Infinite time specification for all functions with a timeout
+ * specification.
+ */
+#define TIME_INFINITE ((systime_t)-1)
+/** @} */
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Returns the priority of the first thread on the given ready list.
+ *
+ * @notapi
+ */
+#define firstprio(rlp) ((rlp)->p_next->p_prio)
+
+/**
+ * @brief Current thread pointer access macro.
+ * @note This macro is not meant to be used in the application code but
+ * only from within the kernel, use the @p chThdSelf() API instead.
+ * @note It is forbidden to use this macro in order to change the pointer
+ * (currp = something), use @p setcurrp() instead.
+ */
+#define currp ch.rlist.r_current
+
+/**
+ * @brief Current thread pointer change macro.
+ * @note This macro is not meant to be used in the application code but
+ * only from within the kernel.
+ *
+ * @notapi
+ */
+#define setcurrp(tp) (currp = (tp))
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+/*
+ * Scheduler APIs.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _scheduler_init(void);
+ thread_t *chSchReadyI(thread_t *tp);
+ void chSchGoSleepS(tstate_t newstate);
+ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time);
+ void chSchWakeupS(thread_t *tp, msg_t msg);
+ void chSchRescheduleS(void);
+ bool chSchIsPreemptionRequired(void);
+ void chSchDoRescheduleBehind(void);
+ void chSchDoRescheduleAhead(void);
+ void chSchDoReschedule(void);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Determines if the current thread must reschedule.
+ * @details This function returns @p true if there is a ready thread with
+ * higher priority.
+ *
+ * @iclass
+ */
+static inline bool chSchIsRescRequiredI(void) {
+
+ chDbgCheckClassI();
+
+ return firstprio(&ch.rlist.r_queue) > currp->p_prio;
+}
+
+/**
+ * @brief Determines if yielding is possible.
+ * @details This function returns @p true if there is a ready thread with
+ * equal or higher priority.
+ *
+ * @sclass
+ */
+static inline bool chSchCanYieldS(void) {
+
+ chDbgCheckClassI();
+
+ return firstprio(&ch.rlist.r_queue) >= currp->p_prio;
+}
+
+/**
+ * @brief Yields the time slot.
+ * @details Yields the CPU control to the next thread in the ready list with
+ * equal or higher priority, if any.
+ *
+ * @sclass
+ */
+static inline void chSchDoYieldS(void) {
+
+ chDbgCheckClassS();
+
+ if (chSchCanYieldS())
+ chSchDoRescheduleBehind();
+}
+
+/**
+ * @brief Inline-able preemption code.
+ * @details This is the common preemption code, this function must be invoked
+ * exclusively from the port layer.
+ *
+ * @special
+ */
+static inline void chSchPreemption(void) {
+ tprio_t p1 = firstprio(&ch.rlist.r_queue);
+ tprio_t p2 = currp->p_prio;
+
+#if CH_CFG_TIME_QUANTUM > 0
+ if (currp->p_preempt) {
+ if (p1 > p2)
+ chSchDoRescheduleAhead();
+ }
+ else {
+ if (p1 >= p2)
+ chSchDoRescheduleBehind();
+ }
+#else /* CH_CFG_TIME_QUANTUM == 0 */
+ if (p1 >= p2)
+ chSchDoRescheduleAhead();
+#endif /* CH_CFG_TIME_QUANTUM == 0 */
+}
+
+#endif /* _CHSCHD_H_ */
+
+/** @} */
diff --git a/os/rt/include/chsem.h b/os/rt/include/chsem.h new file mode 100644 index 000000000..21ee14293 --- /dev/null +++ b/os/rt/include/chsem.h @@ -0,0 +1,154 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chsem.h
+ * @brief Semaphores macros and structures.
+ *
+ * @addtogroup semaphores
+ * @{
+ */
+
+#ifndef _CHSEM_H_
+#define _CHSEM_H_
+
+#if CH_CFG_USE_SEMAPHORES || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Semaphore structure.
+ */
+typedef struct semaphore {
+ threads_queue_t s_queue; /**< @brief Queue of the threads sleeping
+ on this semaphore. */
+ cnt_t s_cnt; /**< @brief The semaphore counter. */
+} 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] n the counter initial value, this value must be
+ * non-negative
+ */
+#define _SEMAPHORE_DATA(name, n) {_threads_queue_t_DATA(name.s_queue), n}
+
+/**
+ * @brief Static semaphore initializer.
+ * @details Statically initialized semaphores require no explicit
+ * initialization using @p chSemInit().
+ *
+ * @param[in] name the name of the semaphore variable
+ * @param[in] n the counter initial value, this value must be
+ * non-negative
+ */
+#define SEMAPHORE_DECL(name, n) semaphore_t name = _SEMAPHORE_DATA(name, n)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chSemObjectInit(semaphore_t *sp, cnt_t n);
+ void chSemReset(semaphore_t *sp, cnt_t n);
+ void chSemResetI(semaphore_t *sp, cnt_t n);
+ msg_t chSemWait(semaphore_t *sp);
+ msg_t chSemWaitS(semaphore_t *sp);
+ msg_t chSemWaitTimeout(semaphore_t *sp, systime_t time);
+ msg_t chSemWaitTimeoutS(semaphore_t *sp, systime_t time);
+ void chSemSignal(semaphore_t *sp);
+ void chSemSignalI(semaphore_t *sp);
+ void chSemAddCounterI(semaphore_t *sp, cnt_t n);
+ msg_t chSemSignalWait(semaphore_t *sps, semaphore_t *spw);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Decreases the semaphore counter.
+ * @details This macro can be used when the counter is known to be positive.
+ *
+ * @iclass
+ */
+static inline void chSemFastWaitI(semaphore_t *sp) {
+
+ chDbgCheckClassI();
+
+ sp->s_cnt--;
+}
+
+/**
+ * @brief Increases the semaphore counter.
+ * @details This macro can be used when the counter is known to be not
+ * negative.
+ *
+ * @iclass
+ */
+static inline void chSemFastSignalI(semaphore_t *sp) {
+
+ chDbgCheckClassI();
+
+ sp->s_cnt++;
+}
+
+/**
+ * @brief Returns the semaphore counter current value.
+ *
+ * @iclass
+ */
+static inline cnt_t chSemGetCounterI(semaphore_t *sp) {
+
+ chDbgCheckClassI();
+
+ return sp->s_cnt;
+}
+
+#endif /* CH_CFG_USE_SEMAPHORES */
+
+#endif /* _CHSEM_H_ */
+
+/** @} */
diff --git a/os/rt/include/chstats.h b/os/rt/include/chstats.h new file mode 100644 index 000000000..389fbf583 --- /dev/null +++ b/os/rt/include/chstats.h @@ -0,0 +1,110 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chstats.h
+ * @brief Statistics module macros and structures.
+ *
+ * @addtogroup statistics
+ * @{
+ */
+
+#ifndef _CHSTATS_H_
+#define _CHSTATS_H_
+
+#if CH_DBG_STATISTICS || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+#if !CH_CFG_USE_TM
+#error "CH_DBG_STATISTICS requires CH_CFG_USE_TM"
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a kernel statistics structure.
+ */
+typedef struct {
+ ucnt_t n_irq; /**< @brief Number of IRQs. */
+ ucnt_t n_ctxswc; /**< @brief Number of context switches. */
+ time_measurement_t m_crit_thd; /**< @brief Measurement of threads
+ critical zones duration. */
+ time_measurement_t m_crit_isr; /**< @brief Measurement of ISRs critical
+ zones duration. */
+} kernel_stats_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern kernel_stats_t kernel_stats;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _stats_init(void);
+ void _stats_increase_irq(void);
+ void _stats_ctxswc(thread_t *ntp, thread_t *otp);
+ void _stats_start_measure_crit_thd(void);
+ void _stats_stop_measure_crit_thd(void);
+ void _stats_start_measure_crit_isr(void);
+ void _stats_stop_measure_crit_isr(void);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+#else /* !CH_DBG_STATISTICS */
+
+/* Stub functions for when the statistics module is disabled. */
+#define _stats_increase_irq()
+#define _stats_ctxswc(old, new)
+#define _stats_start_measure_crit_thd()
+#define _stats_stop_measure_crit_thd()
+#define _stats_start_measure_crit_isr()
+#define _stats_stop_measure_crit_isr()
+
+#endif /* !CH_DBG_STATISTICS */
+
+#endif /* _CHSTATS_H_ */
+
+/** @} */
diff --git a/os/rt/include/chstreams.h b/os/rt/include/chstreams.h new file mode 100644 index 000000000..b9c40cac2 --- /dev/null +++ b/os/rt/include/chstreams.h @@ -0,0 +1,147 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chstreams.h
+ * @brief Data streams.
+ * @details This header defines abstract interfaces useful to access generic
+ * data streams in a standardized way.
+ *
+ * @addtogroup data_streams
+ * @details This module define an abstract interface for generic data streams.
+ * Note that no code is present, just abstract interfaces-like
+ * structures, you should look at the system as to a set of
+ * abstract C++ classes (even if written in C). This system
+ * has then advantage to make the access to data streams
+ * independent from the implementation logic.<br>
+ * The stream interface can be used as base class for high level
+ * object types such as files, sockets, serial ports, pipes etc.
+ * @{
+ */
+
+#ifndef _CHSTREAMS_H_
+#define _CHSTREAMS_H_
+
+/**
+ * @brief BaseSequentialStream specific methods.
+ */
+#define _base_sequential_stream_methods \
+ /* Stream write buffer method.*/ \
+ size_t (*write)(void *instance, const uint8_t *bp, size_t n); \
+ /* Stream read buffer method.*/ \
+ size_t (*read)(void *instance, uint8_t *bp, size_t n); \
+ /* Channel put method, blocking.*/ \
+ msg_t (*put)(void *instance, uint8_t b); \
+ /* Channel get method, blocking.*/ \
+ msg_t (*get)(void *instance); \
+
+/**
+ * @brief @p BaseSequentialStream specific data.
+ * @note It is empty because @p BaseSequentialStream is only an interface
+ * without implementation.
+ */
+#define _base_sequential_stream_data
+
+/**
+ * @brief @p BaseSequentialStream virtual methods table.
+ */
+struct BaseSequentialStreamVMT {
+ _base_sequential_stream_methods
+};
+
+/**
+ * @brief Base stream class.
+ * @details This class represents a generic blocking unbuffered sequential
+ * data stream.
+ */
+typedef struct {
+ /** @brief Virtual Methods Table.*/
+ const struct BaseSequentialStreamVMT *vmt;
+ _base_sequential_stream_data
+} BaseSequentialStream;
+
+/**
+ * @name Macro Functions (BaseSequentialStream)
+ * @{
+ */
+/**
+ * @brief Sequential Stream write.
+ * @details The function writes data from a buffer to a stream.
+ *
+ * @param[in] ip pointer to a @p BaseSequentialStream or derived class
+ * @param[in] bp pointer to the data buffer
+ * @param[in] n the maximum amount of data to be transferred
+ * @return The number of bytes transferred. The return value can
+ * be less than the specified number of bytes if an
+ * end-of-file condition has been met.
+ *
+ * @api
+ */
+#define chSequentialStreamWrite(ip, bp, n) ((ip)->vmt->write(ip, bp, n))
+
+/**
+ * @brief Sequential Stream read.
+ * @details The function reads data from a stream into a buffer.
+ *
+ * @param[in] ip pointer to a @p BaseSequentialStream or derived class
+ * @param[out] bp pointer to the data buffer
+ * @param[in] n the maximum amount of data to be transferred
+ * @return The number of bytes transferred. The return value can
+ * be less than the specified number of bytes if an
+ * end-of-file condition has been met.
+ *
+ * @api
+ */
+#define chSequentialStreamRead(ip, bp, n) ((ip)->vmt->read(ip, bp, n))
+
+/**
+ * @brief Sequential Stream blocking byte write.
+ * @details This function writes a byte value to a channel. If the channel
+ * is not ready to accept data then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[in] b the byte value to be written to the channel
+ *
+ * @return The operation status.
+ * @retval Q_OK if the operation succeeded.
+ * @retval Q_RESET if an end-of-file condition has been met.
+ *
+ * @api
+ */
+#define chSequentialStreamPut(ip, b) ((ip)->vmt->put(ip, b))
+
+/**
+ * @brief Sequential Stream blocking byte read.
+ * @details This function reads a byte value from a channel. If the data
+ * is not available then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ *
+ * @return A byte value from the queue.
+ * @retval Q_RESET if an end-of-file condition has been met.
+ *
+ * @api
+ */
+#define chSequentialStreamGet(ip) ((ip)->vmt->get(ip))
+/** @} */
+
+#endif /* _CHSTREAMS_H_ */
+
+/** @} */
diff --git a/os/rt/include/chsys.h b/os/rt/include/chsys.h new file mode 100644 index 000000000..475e090bd --- /dev/null +++ b/os/rt/include/chsys.h @@ -0,0 +1,346 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chsys.h
+ * @brief System related macros and structures.
+ *
+ * @addtogroup system
+ * @{
+ */
+
+#ifndef _CHSYS_H_
+#define _CHSYS_H_
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @name ISRs abstraction macros
+ */
+/**
+ * @brief IRQ handler enter code.
+ * @note Usually IRQ handlers functions are also declared naked.
+ * @note On some architectures this macro can be empty.
+ *
+ * @special
+ */
+#define CH_IRQ_PROLOGUE() \
+ PORT_IRQ_PROLOGUE(); \
+ _stats_increase_irq(); \
+ _dbg_check_enter_isr()
+
+/**
+ * @brief IRQ handler exit code.
+ * @note Usually IRQ handlers function are also declared naked.
+ * @note This macro usually performs the final reschedule by using
+ * @p chSchIsPreemptionRequired() and @p chSchDoReschedule().
+ *
+ * @special
+ */
+#define CH_IRQ_EPILOGUE() \
+ _dbg_check_leave_isr(); \
+ PORT_IRQ_EPILOGUE()
+
+/**
+ * @brief Standard normal IRQ handler declaration.
+ * @note @p id can be a function name or a vector number depending on the
+ * port implementation.
+ *
+ * @special
+ */
+#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
+/** @} */
+
+/**
+ * @name Fast ISRs abstraction macros
+ */
+/**
+ * @brief Standard fast IRQ handler declaration.
+ * @note @p id can be a function name or a vector number depending on the
+ * port implementation.
+ * @note Not all architectures support fast interrupts.
+ *
+ * @special
+ */
+#define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
+/** @} */
+
+/**
+ * @name Time conversion utilities for the realtime counter
+ * @{
+ */
+/**
+ * @brief Seconds to realtime counter.
+ * @details Converts from seconds to realtime counter cycles.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] sec number of seconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define S2RTV(sec) (CH_CFG_RTC_FREQUENCY * (sec))
+
+/**
+ * @brief Milliseconds to realtime counter.
+ * @details Converts from milliseconds to realtime counter cycles.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] msec number of milliseconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define MS2RTC(msec) (rtcnt_t)(((CH_CFG_RTC_FREQUENCY + 999UL) / \
+ 1000UL) * (msec))
+
+/**
+ * @brief Microseconds to realtime counter.
+ * @details Converts from microseconds to realtime counter cycles.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] usec number of microseconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define US2RTC(usec) (rtcnt_t)(((CH_CFG_RTC_FREQUENCY + 999999UL) / \
+ 1000000UL) * (usec))
+
+/**
+ * @brief Realtime counter cycles to seconds.
+ * @details Converts from realtime counter cycles number to seconds.
+ *
+ * @param[in] n number of cycles
+ * @return The number of seconds.
+ *
+ * @api
+ */
+#define RTC2S(n) (rtcnt_t)(CH_CFG_RTC_FREQUENCY / (freq))
+
+/**
+ * @brief Realtime counter cycles to milliseconds.
+ * @details Converts from realtime counter cycles number to milliseconds.
+ *
+ * @param[in] n number of cycles
+ * @return The number of milliseconds.
+ *
+ * @api
+ */
+#define RTC2MS(n) ((n) / (CH_CFG_RTC_FREQUENCY / 1000UL))
+
+/**
+ * @brief Realtime counter cycles to microseconds.
+ * @details Converts from realtime counter cycles number to microseconds.
+ *
+ * @param[in] n number of cycles
+ * @return The number of microseconds.
+ *
+ * @api
+ */
+#define RTC2US(n) ((n) / (CH_CFG_RTC_FREQUENCY / 1000000UL))
+/** @} */
+
+/**
+ * @brief Returns the current value of the system real time counter.
+ * @note This function is only available if the port layer supports the
+ * option @p CH_PORT_SUPPORTS_RT.
+ *
+ * @return The value of the system realtime counter of
+ * type rtcnt_t.
+ *
+ * @xclass
+ */
+#if CH_PORT_SUPPORTS_RT || defined(__DOXYGEN__)
+#define chSysGetRealtimeCounterX() (rtcnt_t)port_rt_get_counter_value()
+#endif
+
+/**
+ * @brief Performs a context switch.
+ * @note Not a user function, it is meant to be invoked by the scheduler
+ * itself or from within the port layer.
+ *
+ * @param[in] ntp the thread to be switched in
+ * @param[in] otp the thread to be switched out
+ *
+ * @special
+ */
+#define chSysSwitch(ntp, otp) { \
+ \
+ _dbg_trace(otp); \
+ _stats_ctxswc(ntp, otp); \
+ CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp); \
+ port_switch(ntp, otp); \
+}
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chSysInit(void);
+ void chSysHalt(void);
+ void chSysTimerHandlerI(void);
+ syssts_t chSysGetAndLockX(void);
+ void chSysRestoreLockX(syssts_t sts);
+#if CH_PORT_SUPPORTS_RT
+ bool chSysIsCounterWithinX(rtcnt_t cnt, rtcnt_t start, rtcnt_t end);
+ void chSysPolledDelayX(rtcnt_t cycles);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Raises the system interrupt priority mask to the maximum level.
+ * @details All the maskable interrupt sources are disabled regardless their
+ * hardware priority.
+ * @note Do not invoke this API from within a kernel lock.
+ *
+ * @special
+ */
+static inline void chSysDisable(void) {
+
+ port_disable();
+ _dbg_check_disable();
+}
+
+/**
+ * @brief Raises the system interrupt priority mask to system level.
+ * @details The interrupt sources that should not be able to preempt the kernel
+ * are disabled, interrupt sources with higher priority are still
+ * enabled.
+ * @note Do not invoke this API from within a kernel lock.
+ * @note This API is no replacement for @p chSysLock(), the @p chSysLock()
+ * could do more than just disable the interrupts.
+ *
+ * @special
+ */
+static inline void chSysSuspend(void) {
+
+ port_suspend();
+ _dbg_check_suspend();
+}
+
+/**
+ * @brief Lowers the system interrupt priority mask to user level.
+ * @details All the interrupt sources are enabled.
+ * @note Do not invoke this API from within a kernel lock.
+ * @note This API is no replacement for @p chSysUnlock(), the
+ * @p chSysUnlock() could do more than just enable the interrupts.
+ *
+ * @special
+ */
+static inline void chSysEnable(void) {
+
+ _dbg_check_enable();
+ port_enable();
+}
+
+/**
+ * @brief Enters the kernel lock mode.
+ *
+ * @special
+ */
+static inline void chSysLock(void) {
+
+ port_lock();
+ _stats_start_measure_crit_thd();
+ _dbg_check_lock();
+}
+
+/**
+ * @brief Leaves the kernel lock mode.
+ *
+ * @special
+ */
+static inline void chSysUnlock(void) {
+
+ _dbg_check_unlock();
+ _stats_stop_measure_crit_thd();
+ port_unlock();
+}
+
+/**
+ * @brief Enters the kernel lock mode from within an interrupt handler.
+ * @note This API may do nothing on some architectures, it is required
+ * because on ports that support preemptable interrupt handlers
+ * it is required to raise the interrupt mask to the same level of
+ * the system mutual exclusion zone.<br>
+ * It is good practice to invoke this API before invoking any I-class
+ * syscall from an interrupt handler.
+ * @note This API must be invoked exclusively from interrupt handlers.
+ *
+ * @special
+ */
+static inline void chSysLockFromISR(void) {
+
+ port_lock_from_isr();
+ _stats_start_measure_crit_isr();
+ _dbg_check_lock_from_isr();
+}
+
+/**
+ * @brief Leaves the kernel lock mode from within an interrupt handler.
+ *
+ * @note This API may do nothing on some architectures, it is required
+ * because on ports that support preemptable interrupt handlers
+ * it is required to raise the interrupt mask to the same level of
+ * the system mutual exclusion zone.<br>
+ * It is good practice to invoke this API after invoking any I-class
+ * syscall from an interrupt handler.
+ * @note This API must be invoked exclusively from interrupt handlers.
+ *
+ * @special
+ */
+static inline void chSysUnlockFromISR(void) {
+
+ _dbg_check_unlock_from_isr();
+ _stats_stop_measure_crit_isr();
+ port_unlock_from_isr();
+}
+
+#endif /* _CHSYS_H_ */
+
+/** @} */
diff --git a/os/rt/include/chthreads.h b/os/rt/include/chthreads.h new file mode 100644 index 000000000..22f499edf --- /dev/null +++ b/os/rt/include/chthreads.h @@ -0,0 +1,406 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chthreads.h
+ * @brief Threads module macros and structures.
+ *
+ * @addtogroup threads
+ * @{
+ */
+
+#ifndef _CHTHREADS_H_
+#define _CHTHREADS_H_
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/**
+ * @name Thread states
+ * @{
+ */
+#define CH_STATE_READY 0 /**< @brief Waiting on the ready list. */
+#define CH_STATE_CURRENT 1 /**< @brief Currently running. */
+#define CH_STATE_SUSPENDED 2 /**< @brief Created in suspended state. */
+#define CH_STATE_WTSEM 3 /**< @brief Waiting on a semaphore. */
+#define CH_STATE_WTMTX 4 /**< @brief Waiting on a mutex. */
+#define CH_STATE_WTCOND 5 /**< @brief Waiting on a condition
+ variable. */
+#define CH_STATE_SLEEPING 6 /**< @brief Waiting in @p chThdSleep()
+ or @p chThdSleepUntil(). */
+#define CH_STATE_WTEXIT 7 /**< @brief Waiting in @p chThdWait(). */
+#define CH_STATE_WTOREVT 8 /**< @brief Waiting for an event. */
+#define CH_STATE_WTANDEVT 9 /**< @brief Waiting for several events. */
+#define CH_STATE_SNDMSGQ 10 /**< @brief Sending a message, in queue.*/
+#define CH_STATE_SNDMSG 11 /**< @brief Sent a message, waiting
+ answer. */
+#define CH_STATE_WTMSG 12 /**< @brief Waiting for a message. */
+#define CH_STATE_WTQUEUE 13 /**< @brief Waiting on an I/O queue. */
+#define CH_STATE_FINAL 14 /**< @brief Thread terminated. */
+
+/**
+ * @brief Thread states as array of strings.
+ * @details Each element in an array initialized with this macro can be
+ * indexed using the numeric thread state values.
+ */
+#define CH_STATE_NAMES \
+ "READY", "CURRENT", "SUSPENDED", "WTSEM", "WTMTX", "WTCOND", "SLEEPING", \
+ "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "WTQUEUE", \
+ "FINAL"
+/** @} */
+
+/**
+ * @name Thread flags and attributes
+ * @{
+ */
+#define CH_FLAG_MODE_MASK 3 /**< @brief Thread memory mode mask. */
+#define CH_FLAG_MODE_STATIC 0 /**< @brief Static thread. */
+#define CH_FLAG_MODE_HEAP 1 /**< @brief Thread allocated from a
+ Memory Heap. */
+#define CH_FLAG_MODE_MEMPOOL 2 /**< @brief Thread allocated from a
+ Memory Pool. */
+#define CH_FLAG_TERMINATE 4 /**< @brief Termination requested flag. */
+/** @} */
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/* Forward declaration required by the mutexes stack structure present
+ in every thread.*/
+#if CH_CFG_USE_MUTEXES
+typedef struct mutex mutex_t;
+#endif
+
+/**
+ * @extends threads_queue_t
+ *
+ * @brief Structure representing a thread.
+ * @note Not all the listed fields are always needed, by switching off some
+ * not needed ChibiOS/RT subsystems it is possible to save RAM space
+ * by shrinking the @p thread_t structure.
+ */
+typedef struct thread {
+ thread_t *p_next; /**< @brief Next in the list/queue. */
+ /* End of the fields shared with the threads_list_t structure.*/
+ thread_t *p_prev; /**< @brief Previous in the queue. */
+ /* End of the fields shared with the threads_queue_t structure.*/
+ tprio_t p_prio; /**< @brief Thread priority. */
+ struct context p_ctx; /**< @brief Processor context. */
+#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__)
+ thread_t *p_newer; /**< @brief Newer registry element. */
+ thread_t *p_older; /**< @brief Older registry element. */
+#endif
+ /* End of the fields shared with the ReadyList structure. */
+#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__)
+ /**
+ * @brief Thread name or @p NULL.
+ */
+ const char *p_name;
+#endif
+#if CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
+ /**
+ * @brief Thread stack boundary.
+ */
+ stkalign_t *p_stklimit;
+#endif
+ /**
+ * @brief Current thread state.
+ */
+ tstate_t p_state;
+ /**
+ * @brief Various thread flags.
+ */
+ tmode_t p_flags;
+#if CH_CFG_USE_DYNAMIC || defined(__DOXYGEN__)
+ /**
+ * @brief References to this thread.
+ */
+ trefs_t p_refs;
+#endif
+ /**
+ * @brief Number of ticks remaining to this thread.
+ */
+#if (CH_CFG_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
+ tslices_t p_preempt;
+#endif
+#if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__)
+ /**
+ * @brief Thread consumed time in ticks.
+ * @note This field can overflow.
+ */
+ volatile systime_t p_time;
+#endif
+ /**
+ * @brief State-specific fields.
+ * @note All the fields declared in this union are only valid in the
+ * specified state or condition and are thus volatile.
+ */
+ union {
+ /**
+ * @brief Thread wakeup code.
+ * @note This field contains the low level message sent to the thread
+ * by the waking thread or interrupt handler. The value is valid
+ * after exiting the @p chSchWakeupS() function.
+ */
+ msg_t rdymsg;
+ /**
+ * @brief Thread exit code.
+ * @note The thread termination code is stored in this field in order
+ * to be retrieved by the thread performing a @p chThdWait() on
+ * this thread.
+ */
+ msg_t exitcode;
+ /**
+ * @brief Pointer to a generic "wait" object.
+ * @note This field is used to get a generic pointer to a synchronization
+ * object and is valid when the thread is in one of the wait
+ * states.
+ */
+ void *wtobjp;
+#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
+ /**
+ * @brief Enabled events mask.
+ * @note This field is only valid while the thread is in the
+ * @p CH_STATE_WTOREVT or @p CH_STATE_WTANDEVT states.
+ */
+ eventmask_t ewmask;
+#endif
+ } p_u;
+#if CH_CFG_USE_WAITEXIT || defined(__DOXYGEN__)
+ /**
+ * @brief Termination waiting list.
+ */
+ threads_list_t p_waiting;
+#endif
+#if CH_CFG_USE_MESSAGES || defined(__DOXYGEN__)
+ /**
+ * @brief Messages queue.
+ */
+ threads_queue_t p_msgqueue;
+ /**
+ * @brief Thread message.
+ */
+ msg_t p_msg;
+#endif
+#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
+ /**
+ * @brief Pending events mask.
+ */
+ eventmask_t p_epending;
+#endif
+#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
+ /**
+ * @brief List of the mutexes owned by this thread.
+ * @note The list is terminated by a @p NULL in this field.
+ */
+ mutex_t *p_mtxlist;
+ /**
+ * @brief Thread's own, non-inherited, priority.
+ */
+ tprio_t p_realprio;
+#endif
+#if (CH_CFG_USE_DYNAMIC && CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
+ /**
+ * @brief Memory Pool where the thread workspace is returned.
+ */
+ void *p_mpool;
+#endif
+#if CH_DBG_STATISTICS || defined(__DOXYGEN__)
+ time_measurement_t p_stats;
+#endif
+#if defined(CH_CFG_THREAD_EXTRA_FIELDS)
+ /* Extra fields defined in chconf.h.*/
+ CH_CFG_THREAD_EXTRA_FIELDS
+#endif
+} thread_t;
+
+/**
+ * @brief Thread function.
+ */
+typedef msg_t (*tfunc_t)(void *);
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Returns a pointer to the current @p thread_t.
+ * @note Can be invoked in any context.
+ *
+ * @special
+ */
+#define chThdSelf() currp
+
+/**
+ * @brief Returns the current thread priority.
+ * @note Can be invoked in any context.
+ *
+ * @special
+ */
+#define chThdGetPriority() (currp->p_prio)
+
+/**
+ * @brief Returns the number of ticks consumed by the specified thread.
+ * @note This function is only available when the
+ * @p CH_DBG_THREADS_PROFILING configuration option is enabled.
+ * @note Can be invoked in any context.
+ *
+ * @param[in] tp pointer to the thread
+ *
+ * @special
+ */
+#define chThdGetTicks(tp) ((tp)->p_time)
+
+/**
+ * @brief Verifies if the specified thread is in the @p CH_STATE_FINAL state.
+ * @note Can be invoked in any context.
+ *
+ * @param[in] tp pointer to the thread
+ * @retval true thread terminated.
+ * @retval false thread not terminated.
+ *
+ * @special
+ */
+#define chThdTerminated(tp) ((tp)->p_state == CH_STATE_FINAL)
+
+/**
+ * @brief Verifies if the current thread has a termination request pending.
+ * @note Can be invoked in any context.
+ *
+ * @retval true termination request pending.
+ * @retval false termination request not pending.
+ *
+ * @special
+ */
+#define chThdShouldTerminate() (currp->p_flags & CH_FLAG_TERMINATE)
+
+/**
+ * @brief Resumes a thread created with @p chThdCreateI().
+ *
+ * @param[in] tp pointer to the thread
+ *
+ * @iclass
+ */
+#define chThdResumeI(tp) chSchReadyI(tp)
+
+/**
+ * @brief Suspends the invoking thread for the specified time.
+ *
+ * @param[in] time the delay in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
+ *
+ * @sclass
+ */
+#define chThdSleepS(time) chSchGoSleepTimeoutS(CH_STATE_SLEEPING, time)
+
+/**
+ * @brief Delays the invoking thread for the specified number of seconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] sec time in seconds, must be different from zero
+ *
+ * @api
+ */
+#define chThdSleepSeconds(sec) chThdSleep(S2ST(sec))
+
+/**
+ * @brief Delays the invoking thread for the specified number of
+ * milliseconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] msec time in milliseconds, must be different from zero
+ *
+ * @api
+ */
+#define chThdSleepMilliseconds(msec) chThdSleep(MS2ST(msec))
+
+/**
+ * @brief Delays the invoking thread for the specified number of
+ * microseconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] usec time in microseconds, must be different from zero
+ *
+ * @api
+ */
+#define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec))
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ thread_t *_thread_init(thread_t *tp, tprio_t prio);
+#if CH_DBG_FILL_THREADS
+ void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v);
+#endif
+ thread_t *chThdCreateI(void *wsp, size_t size,
+ tprio_t prio, tfunc_t pf, void *arg);
+ thread_t *chThdCreateStatic(void *wsp, size_t size,
+ tprio_t prio, tfunc_t pf, void *arg);
+ tprio_t chThdSetPriority(tprio_t newprio);
+ thread_t *chThdResume(thread_t *tp);
+ void chThdTerminate(thread_t *tp);
+ void chThdSleep(systime_t time);
+ void chThdSleepUntil(systime_t time);
+ void chThdYield(void);
+ void chThdExit(msg_t msg);
+ void chThdExitS(msg_t msg);
+#if CH_CFG_USE_WAITEXIT
+ msg_t chThdWait(thread_t *tp);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+#endif /* _CHTHREADS_H_ */
+
+/** @} */
diff --git a/os/rt/include/chtm.h b/os/rt/include/chtm.h new file mode 100644 index 000000000..93e24d48c --- /dev/null +++ b/os/rt/include/chtm.h @@ -0,0 +1,100 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chtm.h
+ * @brief Time Measurement module macros and structures.
+ *
+ * @addtogroup time_measurement
+ * @{
+ */
+
+#ifndef _CHTM_H_
+#define _CHTM_H_
+
+#if CH_CFG_USE_TM || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !CH_PORT_SUPPORTS_RT
+#error "CH_CFG_USE_TM requires CH_PORT_SUPPORTS_RT"
+#endif
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a Time Measurement object.
+ * @note The maximum measurable time period depends on the implementation
+ * of the realtime counter and its clock frequency.
+ * @note The measurement is not 100% cycle-accurate, it can be in excess
+ * of few cycles depending on the compiler and target architecture.
+ * @note Interrupts can affect measurement if the measurement is performed
+ * with interrupts enabled.
+ */
+typedef struct {
+ rtcnt_t best; /**< @brief Best measurement. */
+ rtcnt_t worst; /**< @brief Worst measurement. */
+ rtcnt_t last; /**< @brief Last measurement. */
+ ucnt_t n; /**< @brief Number of measurements. */
+ rttime_t cumulative; /**< @brief Cumulative measurement. */
+} time_measurement_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _tm_init(void);
+ void chTMObjectInit(time_measurement_t *tmp);
+ NOINLINE void chTMStartMeasurementX(time_measurement_t *tmp);
+ NOINLINE void chTMStopMeasurementX(time_measurement_t *tmp);
+ NOINLINE void chTMChainMeasurementToX(time_measurement_t *tmp1,
+ time_measurement_t *tmp2);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+#endif /* CH_CFG_USE_TM */
+
+#endif /* _CHTM_H_ */
+
+/** @} */
diff --git a/os/rt/include/chvt.h b/os/rt/include/chvt.h new file mode 100644 index 000000000..ae1aee316 --- /dev/null +++ b/os/rt/include/chvt.h @@ -0,0 +1,403 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chvt.h
+ * @brief Time and Virtual Timers module macros and structures.
+ *
+ * @addtogroup time
+ * @{
+ */
+
+#ifndef _CHVT_H_
+#define _CHVT_H_
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if CH_CFG_ST_FREQUENCY <= 0
+#error "invalid CH_CFG_ST_FREQUENCY specified"
+#endif
+
+#if (CH_CFG_TIMEDELTA < 0) || (CH_CFG_TIMEDELTA == 1)
+#error "invalid CH_CFG_TIMEDELTA specified"
+#endif
+
+#if (CH_CFG_TIMEDELTA > 0) && (CH_CFG_TIME_QUANTUM > 0)
+#error "(CH_CFG_TIMEDELTA > 0) is not compatible with (CH_CFG_TIME_QUANTUM > 0)"
+#endif
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a Virtual Timer callback function.
+ */
+typedef void (*vtfunc_t)(void *);
+
+/**
+ * @brief Type of a Virtual Timer structure.
+ */
+typedef struct virtual_timer virtual_timer_t;
+
+/**
+ * @extends virtual_timers_list_t
+ *
+ * @brief Virtual Timer descriptor structure.
+ */
+struct virtual_timer {
+ virtual_timer_t *vt_next; /**< @brief Next timer in the list. */
+ virtual_timer_t *vt_prev; /**< @brief Previous timer in the list. */
+ systime_t vt_delta; /**< @brief Time delta before timeout. */
+ vtfunc_t vt_func; /**< @brief Timer callback function
+ pointer. */
+ void *vt_par; /**< @brief Timer callback function
+ parameter. */
+};
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @name Time conversion utilities
+ * @{
+ */
+/**
+ * @brief Seconds to system ticks.
+ * @details Converts from seconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] sec number of seconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define S2ST(sec) \
+ ((systime_t)((uint32_t)(sec) * (uint32_t)CH_CFG_ST_FREQUENCY))
+
+/**
+ * @brief Milliseconds to system ticks.
+ * @details Converts from milliseconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] msec number of milliseconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define MS2ST(msec) \
+ ((systime_t)(((((uint32_t)(msec)) * \
+ ((uint32_t)CH_CFG_ST_FREQUENCY) - 1UL) / 1000UL) + 1UL))
+
+/**
+ * @brief Microseconds to system ticks.
+ * @details Converts from microseconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] usec number of microseconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define US2ST(usec) \
+ ((systime_t)(((((uint32_t)(usec)) * \
+ ((uint32_t)CH_CFG_ST_FREQUENCY) - 1UL) / 1000000UL) + 1UL))
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+/*
+ * Virtual Timers APIs.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _vt_init(void);
+ bool chVTIsTimeWithinX(systime_t time, systime_t start, systime_t end);
+ void chVTDoSetI(virtual_timer_t *vtp, systime_t delay,
+ vtfunc_t vtfunc, void *par);
+ void chVTDoResetI(virtual_timer_t *vtp);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Initializes a @p virtual_timer_t object.
+ * @note Initializing a timer object is not strictly required because
+ * the function @p chVTSetI() initializes the object too. This
+ * function is only useful if you need to perform a @p chVTIsArmed()
+ * check before calling @p chVTSetI().
+ *
+ * @param[out] vtp the @p virtual_timer_t structure pointer
+ *
+ * @init
+ */
+static inline void chVTObjectInit(virtual_timer_t *vtp) {
+
+ vtp->vt_func = NULL;
+}
+
+/**
+ * @brief Current system time.
+ * @details Returns the number of system ticks since the @p chSysInit()
+ * invocation.
+ * @note The counter can reach its maximum and then restart from zero.
+ * @note This function can be called from any context but its atomicity
+ * is not guaranteed on architectures whose word size is less than
+ * @systime_t size.
+ *
+ * @return The system time in ticks.
+ *
+ * @xclass
+ */
+static inline systime_t chVTGetSystemTimeX(void) {
+
+#if CH_CFG_TIMEDELTA == 0
+ return ch.vtlist.vt_systime;
+#else /* CH_CFG_TIMEDELTA > 0 */
+ return port_timer_get_time();
+#endif /* CH_CFG_TIMEDELTA > 0 */
+}
+
+/**
+ * @brief Current system time.
+ * @details Returns the number of system ticks since the @p chSysInit()
+ * invocation.
+ * @note The counter can reach its maximum and then restart from zero.
+ *
+ * @return The system time in ticks.
+ *
+ * @api
+ */
+static inline systime_t chVTGetSystemTime(void) {
+ systime_t systime;
+
+ chSysLock();
+ systime = chVTGetSystemTimeX();
+ chSysUnlock();
+ return systime;
+}
+
+/**
+ * @brief Checks if the current system time is within the specified time
+ * window.
+ * @note When start==end then the function returns always true because the
+ * whole time range is specified.
+ *
+ * @param[in] start the start of the time window (inclusive)
+ * @param[in] end the end of the time window (non inclusive)
+ * @retval true current time within the specified time window.
+ * @retval false current time not within the specified time window.
+ *
+ * @xclass
+ */
+static inline bool chVTIsSystemTimeWithinX(systime_t start, systime_t end) {
+
+ chDbgCheckClassI();
+
+ return chVTIsTimeWithinX(chVTGetSystemTimeX(), start, end);
+}
+
+/**
+ * @brief Checks if the current system time is within the specified time
+ * window.
+ * @note When start==end then the function returns always true because the
+ * whole time range is specified.
+ *
+ * @param[in] start the start of the time window (inclusive)
+ * @param[in] end the end of the time window (non inclusive)
+ * @retval true current time within the specified time window.
+ * @retval false current time not within the specified time window.
+ *
+ * @api
+ */
+static inline bool chVTIsSystemTimeWithin(systime_t start, systime_t end) {
+
+ return chVTIsTimeWithinX(chVTGetSystemTime(), start, end);
+}
+
+/**
+ * @brief Returns @p true if the specified timer is armed.
+ * @pre The timer must have been initialized using @p chVTObjectInit()
+ * or @p chVTSetI() (or @p chVTSetI() variants).
+ *
+ * @param[in] vtp the @p virtual_timer_t structure pointer
+ * @return true if the timer is armed.
+ *
+ * @iclass
+ */
+static inline bool chVTIsArmedI(virtual_timer_t *vtp) {
+
+ chDbgCheckClassI();
+
+ return (bool)(vtp->vt_func != NULL);
+}
+
+/**
+ * @brief Disables a Virtual Timer.
+ * @note The timer is first checked and disabled only if armed.
+ *
+ * @param[in] vtp the @p virtual_timer_t structure pointer
+ *
+ * @iclass
+ */
+static inline void chVTResetI(virtual_timer_t *vtp) {
+
+ if (chVTIsArmedI(vtp))
+ chVTDoResetI(vtp);
+}
+
+/**
+ * @brief Disables a Virtual Timer.
+ * @note The timer is first checked and disabled only if armed.
+ *
+ * @param[in] vtp the @p virtual_timer_t structure pointer
+ *
+ * @api
+ */
+static inline void chVTReset(virtual_timer_t *vtp) {
+
+ chSysLock();
+ chVTResetI(vtp);
+ chSysUnlock();
+}
+
+/**
+ * @brief Enables a virtual timer.
+ * @details If the virtual timer was already enabled then it is re-enabled
+ * using the new parameters.
+ *
+ * @param[in] vtp the @p virtual_timer_t structure pointer
+ * @param[in] delay the number of ticks before the operation timeouts.
+ * @param[in] vtfunc the timer callback function. After invoking the
+ * callback the timer is disabled and the structure can
+ * be disposed or reused.
+ * @param[in] par a parameter that will be passed to the callback
+ * function
+ *
+ * @iclass
+ */
+static inline void chVTSetI(virtual_timer_t *vtp, systime_t delay,
+ vtfunc_t vtfunc, void *par) {
+
+ chVTResetI(vtp);
+ chVTDoSetI(vtp, delay, vtfunc, par);
+}
+
+/**
+ * @brief Enables a virtual timer.
+ * @details If the virtual timer was already enabled then it is re-enabled
+ * using the new parameters.
+ *
+ * @param[in] vtp the @p virtual_timer_t structure pointer
+ * @param[in] delay the number of ticks before the operation timeouts.
+ * @param[in] vtfunc the timer callback function. After invoking the
+ * callback the timer is disabled and the structure can
+ * be disposed or reused.
+ * @param[in] par a parameter that will be passed to the callback
+ * function
+ *
+ * @api
+ */
+static inline void chVTSet(virtual_timer_t *vtp, systime_t delay,
+ vtfunc_t vtfunc, void *par) {
+
+ chSysLock();
+ chVTSetI(vtp, delay, vtfunc, par);
+ chSysUnlock();
+}
+
+/**
+ * @brief Virtual timers ticker.
+ * @note The system lock is released before entering the callback and
+ * re-acquired immediately after. It is callback's responsibility
+ * to acquire the lock if needed. This is done in order to reduce
+ * interrupts jitter when many timers are in use.
+ *
+ * @iclass
+ */
+static inline void chVTDoTickI(void) {
+
+ chDbgCheckClassI();
+
+#if CH_CFG_TIMEDELTA == 0
+ ch.vtlist.vt_systime++;
+ if (&ch.vtlist != (virtual_timers_list_t *)ch.vtlist.vt_next) {
+ virtual_timer_t *vtp;
+
+ --ch.vtlist.vt_next->vt_delta;
+ while (!(vtp = ch.vtlist.vt_next)->vt_delta) {
+ vtfunc_t fn = vtp->vt_func;
+ vtp->vt_func = (vtfunc_t)NULL;
+ vtp->vt_next->vt_prev = (void *)&ch.vtlist;
+ ch.vtlist.vt_next = vtp->vt_next;
+ chSysUnlockFromISR();
+ fn(vtp->vt_par);
+ chSysLockFromISR();
+ }
+ }
+#else /* CH_CFG_TIMEDELTA > 0 */
+ virtual_timer_t *vtp;
+ systime_t now = chVTGetSystemTimeX();
+ systime_t delta = now - ch.vtlist.vt_lasttime;
+
+ while ((vtp = ch.vtlist.vt_next)->vt_delta <= delta) {
+ delta -= vtp->vt_delta;
+ ch.vtlist.vt_lasttime += vtp->vt_delta;
+ vtfunc_t fn = vtp->vt_func;
+ vtp->vt_func = (vtfunc_t)NULL;
+ vtp->vt_next->vt_prev = (void *)&ch.vtlist;
+ ch.vtlist.vt_next = vtp->vt_next;
+ chSysUnlockFromISR();
+ fn(vtp->vt_par);
+ chSysLockFromISR();
+ }
+ if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
+ /* The list is empty, no tick event needed so the alarm timer
+ is stopped.*/
+ port_timer_stop_alarm();
+ }
+ else {
+ /* Updating the alarm to the next deadline.*/
+ port_timer_set_alarm(now + vtp->vt_delta);
+ }
+#endif /* CH_CFG_TIMEDELTA > 0 */
+}
+
+#endif /* _CHVT_H_ */
+
+/** @} */
|