Add software
This commit is contained in:
@ -0,0 +1,150 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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 "2.6.8"
|
||||
|
||||
/**
|
||||
* @name Kernel version
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Kernel version major number.
|
||||
*/
|
||||
#define CH_KERNEL_MAJOR 2
|
||||
|
||||
/**
|
||||
* @brief Kernel version minor number.
|
||||
*/
|
||||
#define CH_KERNEL_MINOR 6
|
||||
|
||||
/**
|
||||
* @brief Kernel version patch number.
|
||||
*/
|
||||
#define CH_KERNEL_PATCH 8
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @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_t 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_t as a status indicator.
|
||||
*/
|
||||
#if !defined(CH_FAILED) || defined(__DOXYGEN__)
|
||||
#define CH_FAILED TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#include "chconf.h"
|
||||
#include "chtypes.h"
|
||||
#include "chlists.h"
|
||||
#include "chcore.h"
|
||||
#include "chsys.h"
|
||||
#include "chvt.h"
|
||||
#include "chschd.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 "chthreads.h"
|
||||
#include "chdynamic.h"
|
||||
#include "chregistry.h"
|
||||
#include "chinline.h"
|
||||
#include "chqueues.h"
|
||||
#include "chstreams.h"
|
||||
#include "chfiles.h"
|
||||
#include "chdebug.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _idle_thread(void *p);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CH_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,258 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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_USE_SEMAPHORES
|
||||
* option must be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHBSEM_H_
|
||||
#define _CHBSEM_H_
|
||||
|
||||
#if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @extends Semaphore
|
||||
*
|
||||
* @brief Binary semaphore type.
|
||||
*/
|
||||
typedef struct {
|
||||
Semaphore bs_sem;
|
||||
} BinarySemaphore;
|
||||
|
||||
/**
|
||||
* @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) \
|
||||
BinarySemaphore name = _BSEMAPHORE_DATA(name, taken)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Initializes a binary semaphore.
|
||||
*
|
||||
* @param[out] bsp pointer to a @p BinarySemaphore 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
|
||||
*/
|
||||
#define chBSemInit(bsp, taken) chSemInit(&(bsp)->bs_sem, (taken) ? 0 : 1)
|
||||
|
||||
/**
|
||||
* @brief Wait operation on the binary semaphore.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p BinarySemaphore 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
|
||||
*/
|
||||
#define chBSemWait(bsp) chSemWait(&(bsp)->bs_sem)
|
||||
|
||||
/**
|
||||
* @brief Wait operation on the binary semaphore.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p BinarySemaphore 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
|
||||
*/
|
||||
#define chBSemWaitS(bsp) chSemWaitS(&(bsp)->bs_sem)
|
||||
|
||||
/**
|
||||
* @brief Wait operation on the binary semaphore.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p BinarySemaphore 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
|
||||
*/
|
||||
#define chBSemWaitTimeout(bsp, time) chSemWaitTimeout(&(bsp)->bs_sem, (time))
|
||||
|
||||
/**
|
||||
* @brief Wait operation on the binary semaphore.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p BinarySemaphore 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
|
||||
*/
|
||||
#define chBSemWaitTimeoutS(bsp, time) chSemWaitTimeoutS(&(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.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p BinarySemaphore 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
|
||||
*/
|
||||
#define chBSemReset(bsp, taken) chSemReset(&(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.
|
||||
* @note This function does not reschedule.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p BinarySemaphore 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
|
||||
*/
|
||||
#define chBSemResetI(bsp, taken) chSemResetI(&(bsp)->bs_sem, (taken) ? 0 : 1)
|
||||
|
||||
/**
|
||||
* @brief Performs a signal operation on a binary semaphore.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p BinarySemaphore structure
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chBSemSignal(bsp) { \
|
||||
chSysLock(); \
|
||||
chBSemSignalI((bsp)); \
|
||||
chSchRescheduleS(); \
|
||||
chSysUnlock(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Performs a signal operation on a binary semaphore.
|
||||
* @note This function does not reschedule.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p BinarySemaphore structure
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chBSemSignalI(bsp) { \
|
||||
if ((bsp)->bs_sem.s_cnt < 1) \
|
||||
chSemSignalI(&(bsp)->bs_sem); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the binary semaphore current state.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p BinarySemaphore 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
|
||||
*/
|
||||
#define chBSemGetStateI(bsp) ((bsp)->bs_sem.s_cnt > 0 ? FALSE : TRUE)
|
||||
/** @} */
|
||||
|
||||
#endif /* CH_USE_SEMAPHORES */
|
||||
|
||||
#endif /* _CHBSEM_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
/*
|
||||
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_USE_CONDVARS || defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* Module dependencies check.
|
||||
*/
|
||||
#if !CH_USE_MUTEXES
|
||||
#error "CH_USE_CONDVARS requires CH_USE_MUTEXES"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief CondVar structure.
|
||||
*/
|
||||
typedef struct CondVar {
|
||||
ThreadsQueue c_queue; /**< @brief CondVar threads queue.*/
|
||||
} CondVar;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chCondInit(CondVar *cp);
|
||||
void chCondSignal(CondVar *cp);
|
||||
void chCondSignalI(CondVar *cp);
|
||||
void chCondBroadcast(CondVar *cp);
|
||||
void chCondBroadcastI(CondVar *cp);
|
||||
msg_t chCondWait(CondVar *cp);
|
||||
msg_t chCondWaitS(CondVar *cp);
|
||||
#if CH_USE_CONDVARS_TIMEOUT
|
||||
msg_t chCondWaitTimeout(CondVar *cp, systime_t time);
|
||||
msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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) {_THREADSQUEUE_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) CondVar name = _CONDVAR_DATA(name)
|
||||
|
||||
#endif /* CH_USE_CONDVARS */
|
||||
|
||||
#endif /* _CHCOND_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,254 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chdebug.h
|
||||
* @brief Debug macros and structures.
|
||||
*
|
||||
* @addtogroup debug
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHDEBUG_H_
|
||||
#define _CHDEBUG_H_
|
||||
|
||||
#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
|
||||
|
||||
#define __QUOTE_THIS(p) #p
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
* @name Debug related settings
|
||||
* @{
|
||||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Trace buffer entries.
|
||||
*/
|
||||
#ifndef CH_TRACE_BUFFER_SIZE
|
||||
#define CH_TRACE_BUFFER_SIZE 64
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Fill value for thread stack area in debug mode.
|
||||
*/
|
||||
#ifndef CH_STACK_FILL_VALUE
|
||||
#define CH_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_THREAD_FILL_VALUE
|
||||
#define CH_THREAD_FILL_VALUE 0xFF
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* System state checker related code and variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#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()
|
||||
#else
|
||||
#define dbg_enter_lock() (dbg_lock_cnt = 1)
|
||||
#define dbg_leave_lock() (dbg_lock_cnt = 0)
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Trace related structures and macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Trace buffer record.
|
||||
*/
|
||||
typedef struct {
|
||||
systime_t se_time; /**< @brief Time of the switch event. */
|
||||
Thread *se_tp; /**< @brief Switched in thread. */
|
||||
void *se_wtobjp; /**< @brief Object where going to sleep.*/
|
||||
uint8_t se_state; /**< @brief Switched out thread state. */
|
||||
} ch_swc_event_t;
|
||||
|
||||
/**
|
||||
* @brief Trace buffer header.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned tb_size; /**< @brief Trace buffer size (entries).*/
|
||||
ch_swc_event_t *tb_ptr; /**< @brief Pointer to the buffer front.*/
|
||||
/** @brief Ring buffer.*/
|
||||
ch_swc_event_t tb_buffer[CH_TRACE_BUFFER_SIZE];
|
||||
} ch_trace_buffer_t;
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern ch_trace_buffer_t dbg_trace_buffer;
|
||||
#endif
|
||||
|
||||
#endif /* CH_DBG_ENABLE_TRACE */
|
||||
|
||||
#if !CH_DBG_ENABLE_TRACE
|
||||
/* When the trace feature is disabled this function is replaced by an empty
|
||||
macro.*/
|
||||
#define dbg_trace(otp)
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Parameters checking related macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if CH_DBG_ENABLE_CHECKS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
* @param[in] func the undecorated function name
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#if !defined(chDbgCheck)
|
||||
#define chDbgCheck(c, func) { \
|
||||
if (!(c)) \
|
||||
chDbgPanic(__QUOTE_THIS(func)"()"); \
|
||||
}
|
||||
#endif /* !defined(chDbgCheck) */
|
||||
/** @} */
|
||||
#else /* !CH_DBG_ENABLE_CHECKS */
|
||||
#define chDbgCheck(c, func) { \
|
||||
(void)(c), (void)__QUOTE_THIS(func)"()"; \
|
||||
}
|
||||
#endif /* !CH_DBG_ENABLE_CHECKS */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Assertions related macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if CH_DBG_ENABLE_ASSERTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Condition assertion.
|
||||
* @details If the condition check fails then the kernel panics with the
|
||||
* specified 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 convention for the message is the following:<br>
|
||||
* @<function_name@>(), #@<assert_number@>
|
||||
* @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] m the text message
|
||||
* @param[in] r a remark string
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#if !defined(chDbgAssert)
|
||||
#define chDbgAssert(c, m, r) { \
|
||||
if (!(c)) \
|
||||
chDbgPanic(m); \
|
||||
}
|
||||
#endif /* !defined(chDbgAssert) */
|
||||
/** @} */
|
||||
#else /* !CH_DBG_ENABLE_ASSERTS */
|
||||
#define chDbgAssert(c, m, r) {(void)(c);}
|
||||
#endif /* !CH_DBG_ENABLE_ASSERTS */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Panic related macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !CH_DBG_ENABLED
|
||||
/* When the debug features are disabled this function is replaced by an empty
|
||||
macro.*/
|
||||
#define chDbgPanic(msg) {}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
extern cnt_t dbg_isr_cnt;
|
||||
extern cnt_t dbg_lock_cnt;
|
||||
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 *otp);
|
||||
#endif
|
||||
#if CH_DBG_ENABLED
|
||||
extern const char *dbg_panic_msg;
|
||||
void chDbgPanic(const char *msg);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CHDEBUG_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chdynamic.h
|
||||
* @brief Dynamic threads macros and structures.
|
||||
*
|
||||
* @addtogroup dynamic_threads
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHDYNAMIC_H_
|
||||
#define _CHDYNAMIC_H_
|
||||
|
||||
#if CH_USE_DYNAMIC || defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* Module dependencies check.
|
||||
*/
|
||||
#if CH_USE_DYNAMIC && !CH_USE_WAITEXIT
|
||||
#error "CH_USE_DYNAMIC requires CH_USE_WAITEXIT"
|
||||
#endif
|
||||
#if CH_USE_DYNAMIC && !CH_USE_HEAP && !CH_USE_MEMPOOLS
|
||||
#error "CH_USE_DYNAMIC requires CH_USE_HEAP and/or CH_USE_MEMPOOLS"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dynamic threads APIs.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
Thread *chThdAddRef(Thread *tp);
|
||||
void chThdRelease(Thread *tp);
|
||||
#if CH_USE_HEAP
|
||||
Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
|
||||
tprio_t prio, tfunc_t pf, void *arg);
|
||||
#endif
|
||||
#if CH_USE_MEMPOOLS
|
||||
Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
|
||||
tfunc_t pf, void *arg);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CH_USE_DYNAMIC */
|
||||
|
||||
#endif /* _CHDYNAMIC_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,212 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
/*
|
||||
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_USE_EVENTS || defined(__DOXYGEN__)
|
||||
|
||||
typedef struct EventListener EventListener;
|
||||
|
||||
/**
|
||||
* @brief Event Listener structure.
|
||||
*/
|
||||
struct EventListener {
|
||||
EventListener *el_next; /**< @brief Next Event Listener
|
||||
registered on the Event
|
||||
Source. */
|
||||
Thread *el_listener; /**< @brief Thread interested in the
|
||||
Event Source. */
|
||||
eventmask_t el_mask; /**< @brief Event flags mask associated
|
||||
by the thread to the Event
|
||||
Source. */
|
||||
flagsmask_t el_flags; /**< @brief Flags added to the listener
|
||||
by the event source. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Event Source structure.
|
||||
*/
|
||||
typedef struct EventSource {
|
||||
EventListener *es_next; /**< @brief First Event Listener
|
||||
registered on the Event
|
||||
Source. */
|
||||
} EventSource;
|
||||
|
||||
/**
|
||||
* @brief Event Handler callback function.
|
||||
*/
|
||||
typedef void (*evhandler_t)(eventid_t);
|
||||
|
||||
/**
|
||||
* @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) EventSource name = _EVENTSOURCE_DATA(name)
|
||||
|
||||
/**
|
||||
* @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)))
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @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 EventSource structure
|
||||
* @param[out] elp pointer to the @p EventListener 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 eventmask_t type minus one.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chEvtRegister(esp, elp, eid) \
|
||||
chEvtRegisterMask(esp, elp, EVENT_MASK(eid))
|
||||
|
||||
/**
|
||||
* @brief Initializes an Event Source.
|
||||
* @note This function can be invoked before the kernel is initialized
|
||||
* because it just prepares a @p EventSource structure.
|
||||
*
|
||||
* @param[out] esp pointer to the @p EventSource structure
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
#define chEvtInit(esp) \
|
||||
((esp)->es_next = (EventListener *)(void *)(esp))
|
||||
|
||||
/**
|
||||
* @brief Verifies if there is at least one @p EventListener registered.
|
||||
*
|
||||
* @param[in] esp pointer to the @p EventSource structure
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chEvtIsListeningI(esp) \
|
||||
((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 EventSource structure
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chEvtBroadcast(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 EventSource structure
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chEvtBroadcastI(esp) chEvtBroadcastFlagsI(esp, 0)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chEvtRegisterMask(EventSource *esp,
|
||||
EventListener *elp,
|
||||
eventmask_t mask);
|
||||
void chEvtUnregister(EventSource *esp, EventListener *elp);
|
||||
eventmask_t chEvtGetAndClearEvents(eventmask_t mask);
|
||||
eventmask_t chEvtAddEvents(eventmask_t mask);
|
||||
flagsmask_t chEvtGetAndClearFlags(EventListener *elp);
|
||||
flagsmask_t chEvtGetAndClearFlagsI(EventListener *elp);
|
||||
void chEvtSignal(Thread *tp, eventmask_t mask);
|
||||
void chEvtSignalI(Thread *tp, eventmask_t mask);
|
||||
void chEvtBroadcastFlags(EventSource *esp, flagsmask_t flags);
|
||||
void chEvtBroadcastFlagsI(EventSource *esp, flagsmask_t flags);
|
||||
void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask);
|
||||
#if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT
|
||||
eventmask_t chEvtWaitOne(eventmask_t mask);
|
||||
eventmask_t chEvtWaitAny(eventmask_t mask);
|
||||
eventmask_t chEvtWaitAll(eventmask_t mask);
|
||||
#endif
|
||||
#if CH_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_OPTIMIZE_SPEED && CH_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
|
||||
|
||||
#endif /* CH_USE_EVENTS */
|
||||
|
||||
#endif /* _CHEVENTS_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,172 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chfiles.h
|
||||
* @brief Data files.
|
||||
* @details This header defines abstract interfaces useful to access generic
|
||||
* data files in a standardized way.
|
||||
*
|
||||
* @addtogroup data_files
|
||||
* @details This module define an abstract interface for generic data files by
|
||||
* extending the @p BaseSequentialStream interface. Note that no code
|
||||
* is present, data files are just abstract interface-like structures,
|
||||
* you should look at the systems as to a set of abstract C++ classes
|
||||
* (even if written in C). This system has the advantage to make the
|
||||
* access to streams independent from the implementation logic.<br>
|
||||
* The data files interface can be used as base class for high level
|
||||
* object types such as an API for a File System implementation.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHFILES_H_
|
||||
#define _CHFILES_H_
|
||||
|
||||
/**
|
||||
* @brief No error return code.
|
||||
*/
|
||||
#define FILE_OK 0
|
||||
|
||||
/**
|
||||
* @brief Error code from the file stream methods.
|
||||
*/
|
||||
#define FILE_ERROR 0xFFFFFFFFUL
|
||||
|
||||
/**
|
||||
* @brief File offset type.
|
||||
*/
|
||||
typedef uint32_t fileoffset_t;
|
||||
|
||||
/**
|
||||
* @brief BaseFileStream specific methods.
|
||||
*/
|
||||
#define _base_file_stream_methods \
|
||||
_base_sequential_stream_methods \
|
||||
/* File close method.*/ \
|
||||
uint32_t (*close)(void *instance); \
|
||||
/* Get last error code method.*/ \
|
||||
int (*geterror)(void *instance); \
|
||||
/* File get size method.*/ \
|
||||
fileoffset_t (*getsize)(void *instance); \
|
||||
/* File get current position method.*/ \
|
||||
fileoffset_t (*getposition)(void *instance); \
|
||||
/* File seek method.*/ \
|
||||
uint32_t (*lseek)(void *instance, fileoffset_t offset);
|
||||
|
||||
/**
|
||||
* @brief @p BaseFileStream specific data.
|
||||
* @note It is empty because @p BaseFileStream is only an interface
|
||||
* without implementation.
|
||||
*/
|
||||
#define _base_file_stream_data \
|
||||
_base_sequential_stream_data
|
||||
|
||||
/**
|
||||
* @extends BaseSequentialStreamVMT
|
||||
*
|
||||
* @brief @p BaseFileStream virtual methods table.
|
||||
*/
|
||||
struct BaseFileStreamVMT {
|
||||
_base_file_stream_methods
|
||||
};
|
||||
|
||||
/**
|
||||
* @extends BaseSequentialStream
|
||||
*
|
||||
* @brief Base file stream class.
|
||||
* @details This class represents a generic file data stream.
|
||||
*/
|
||||
typedef struct {
|
||||
/** @brief Virtual Methods Table.*/
|
||||
const struct BaseFileStreamVMT *vmt;
|
||||
_base_file_stream_data
|
||||
} BaseFileStream;
|
||||
|
||||
/**
|
||||
* @name Macro Functions (BaseFileStream)
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Base file Stream close.
|
||||
* @details The function closes a file stream.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseFileStream or derived class
|
||||
* @return The operation status.
|
||||
* @retval FILE_OK no error.
|
||||
* @retval FILE_ERROR operation failed.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chFileStreamClose(ip) ((ip)->vmt->close(ip))
|
||||
|
||||
/**
|
||||
* @brief Returns an implementation dependent error code.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseFileStream or derived class
|
||||
* @return Implementation dependent error code.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chFileStreamGetError(ip) ((ip)->vmt->geterror(ip))
|
||||
|
||||
/**
|
||||
* @brief Returns the current file size.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseFileStream or derived class
|
||||
* @return The file size.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chFileStreamGetSize(ip) ((ip)->vmt->getsize(ip))
|
||||
|
||||
/**
|
||||
* @brief Returns the current file pointer position.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseFileStream or derived class
|
||||
* @return The current position inside the file.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chFileStreamGetPosition(ip) ((ip)->vmt->getposition(ip))
|
||||
|
||||
/**
|
||||
* @brief Moves the file current pointer to an absolute position.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseFileStream or derived class
|
||||
* @param[in] offset new absolute position
|
||||
* @return The operation status.
|
||||
* @retval FILE_OK no error.
|
||||
* @retval FILE_ERROR operation failed.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chFileStreamSeek(ip, offset) ((ip)->vmt->lseek(ip, offset))
|
||||
/** @} */
|
||||
|
||||
#endif /* _CHFILES_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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chheap.h
|
||||
* @brief Heaps macros and structures.
|
||||
*
|
||||
* @addtogroup heaps
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHHEAP_H_
|
||||
#define _CHHEAP_H_
|
||||
|
||||
#if CH_USE_HEAP || defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* Module dependencies check.
|
||||
*/
|
||||
#if !CH_USE_MEMCORE && !CH_USE_MALLOC_HEAP
|
||||
#error "CH_USE_HEAP requires CH_USE_MEMCORE or CH_USE_MALLOC_HEAP"
|
||||
#endif
|
||||
|
||||
#if !CH_USE_MUTEXES && !CH_USE_SEMAPHORES
|
||||
#error "CH_USE_HEAP requires CH_USE_MUTEXES and/or CH_USE_SEMAPHORES"
|
||||
#endif
|
||||
|
||||
typedef struct memory_heap MemoryHeap;
|
||||
|
||||
/**
|
||||
* @brief Memory heap block header.
|
||||
*/
|
||||
union heap_header {
|
||||
stkalign_t align;
|
||||
struct {
|
||||
union {
|
||||
union heap_header *next; /**< @brief Next block in free list. */
|
||||
MemoryHeap *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_USE_MUTEXES
|
||||
Mutex h_mtx; /**< @brief Heap access mutex. */
|
||||
#else
|
||||
Semaphore h_sem; /**< @brief Heap access semaphore. */
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _heap_init(void);
|
||||
#if !CH_USE_MALLOC_HEAP
|
||||
void chHeapInit(MemoryHeap *heapp, void *buf, size_t size);
|
||||
#endif
|
||||
void *chHeapAlloc(MemoryHeap *heapp, size_t size);
|
||||
void chHeapFree(void *p);
|
||||
size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CH_USE_HEAP */
|
||||
|
||||
#endif /* _CHHEAP_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chinline.h
|
||||
* @brief Kernel inlined functions.
|
||||
* @details In this file there are a set of inlined functions if the
|
||||
* @p CH_OPTIMIZE_SPEED is enabled.
|
||||
*/
|
||||
|
||||
#ifndef _CHINLINE_H_
|
||||
#define _CHINLINE_H_
|
||||
|
||||
/* If the performance code path has been chosen then all the following
|
||||
functions are inlined into the various kernel modules.*/
|
||||
#if CH_OPTIMIZE_SPEED
|
||||
static INLINE void prio_insert(Thread *tp, ThreadsQueue *tqp) {
|
||||
|
||||
Thread *cp = (Thread *)tqp;
|
||||
do {
|
||||
cp = cp->p_next;
|
||||
} while ((cp != (Thread *)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 *tp, ThreadsQueue *tqp) {
|
||||
|
||||
tp->p_next = (Thread *)tqp;
|
||||
tp->p_prev = tqp->p_prev;
|
||||
tp->p_prev->p_next = tqp->p_prev = tp;
|
||||
}
|
||||
|
||||
static INLINE Thread *fifo_remove(ThreadsQueue *tqp) {
|
||||
Thread *tp = tqp->p_next;
|
||||
|
||||
(tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp;
|
||||
return tp;
|
||||
}
|
||||
|
||||
static INLINE Thread *lifo_remove(ThreadsQueue *tqp) {
|
||||
Thread *tp = tqp->p_prev;
|
||||
|
||||
(tqp->p_prev = tp->p_prev)->p_next = (Thread *)tqp;
|
||||
return tp;
|
||||
}
|
||||
|
||||
static INLINE Thread *dequeue(Thread *tp) {
|
||||
|
||||
tp->p_prev->p_next = tp->p_next;
|
||||
tp->p_next->p_prev = tp->p_prev;
|
||||
return tp;
|
||||
}
|
||||
|
||||
static INLINE void list_insert(Thread *tp, ThreadsList *tlp) {
|
||||
|
||||
tp->p_next = tlp->p_next;
|
||||
tlp->p_next = tp;
|
||||
}
|
||||
|
||||
static INLINE Thread *list_remove(ThreadsList *tlp) {
|
||||
|
||||
Thread *tp = tlp->p_next;
|
||||
tlp->p_next = tp->p_next;
|
||||
return tp;
|
||||
}
|
||||
#endif /* CH_OPTIMIZE_SPEED */
|
||||
|
||||
#endif /* _CHINLINE_H_ */
|
@ -0,0 +1,134 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chlists.h
|
||||
* @brief Thread queues/lists macros and structures.
|
||||
* @note All the macros present in this module, while public, are not
|
||||
* an OS API and should not be directly used in the user applications
|
||||
* code.
|
||||
*
|
||||
* @addtogroup internals
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHLISTS_H_
|
||||
#define _CHLISTS_H_
|
||||
|
||||
typedef struct Thread Thread;
|
||||
|
||||
/**
|
||||
* @brief Threads queue initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define queue_init(tqp) ((tqp)->p_next = (tqp)->p_prev = (Thread *)(tqp));
|
||||
|
||||
/**
|
||||
* @brief Threads list initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define list_init(tlp) ((tlp)->p_next = (Thread *)(tlp))
|
||||
|
||||
/**
|
||||
* @brief Evaluates to @p TRUE if the specified threads queue or list is
|
||||
* empty.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define isempty(p) ((p)->p_next == (Thread *)(p))
|
||||
|
||||
/**
|
||||
* @brief Evaluates to @p TRUE if the specified threads queue or list is
|
||||
* not empty.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define notempty(p) ((p)->p_next != (Thread *)(p))
|
||||
|
||||
/**
|
||||
* @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 _THREADSQUEUE_DATA(name) {(Thread *)&name, (Thread *)&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 THREADSQUEUE_DECL(name) ThreadsQueue name = _THREADSQUEUE_DATA(name)
|
||||
|
||||
/**
|
||||
* @extends ThreadsList
|
||||
*
|
||||
* @brief Generic threads bidirectional linked list header and element.
|
||||
*/
|
||||
typedef struct {
|
||||
Thread *p_next; /**< First @p Thread in the queue, or
|
||||
@p ThreadQueue when empty. */
|
||||
Thread *p_prev; /**< Last @p Thread in the queue, or
|
||||
@p ThreadQueue when empty. */
|
||||
} ThreadsQueue;
|
||||
|
||||
/**
|
||||
* @brief Generic threads single link list, it works like a stack.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
Thread *p_next; /**< Last pushed @p Thread on the stack
|
||||
list, or pointer to itself if
|
||||
empty. */
|
||||
} ThreadsList;
|
||||
|
||||
#if !CH_OPTIMIZE_SPEED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void prio_insert(Thread *tp, ThreadsQueue *tqp);
|
||||
void queue_insert(Thread *tp, ThreadsQueue *tqp);
|
||||
Thread *fifo_remove(ThreadsQueue *tqp);
|
||||
Thread *lifo_remove(ThreadsQueue *tqp);
|
||||
Thread *dequeue(Thread *tp);
|
||||
void list_insert(Thread *tp, ThreadsList *tlp);
|
||||
Thread *list_remove(ThreadsList *tlp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !CH_OPTIMIZE_SPEED */
|
||||
|
||||
#endif /* _CHLISTS_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,170 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmboxes.h
|
||||
* @brief Mailboxes macros and structures.
|
||||
*
|
||||
* @addtogroup mailboxes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHMBOXES_H_
|
||||
#define _CHMBOXES_H_
|
||||
|
||||
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* Module dependencies check.
|
||||
*/
|
||||
#if !CH_USE_SEMAPHORES
|
||||
#error "CH_USE_MAILBOXES requires CH_USE_SEMAPHORES"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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 mb_fullsem; /**< @brief Full counter
|
||||
@p Semaphore. */
|
||||
Semaphore mb_emptysem; /**< @brief Empty counter
|
||||
@p Semaphore. */
|
||||
} Mailbox;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n);
|
||||
void chMBReset(Mailbox *mbp);
|
||||
msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout);
|
||||
msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t timeout);
|
||||
msg_t chMBPostI(Mailbox *mbp, msg_t msg);
|
||||
msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout);
|
||||
msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t timeout);
|
||||
msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg);
|
||||
msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t timeout);
|
||||
msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t timeout);
|
||||
msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the mailbox buffer size.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chMBSizeI(mbp) \
|
||||
((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 object
|
||||
* @return The number of empty message slots.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chMBGetFreeCountI(mbp) 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 object
|
||||
* @return The number of queued messages.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chMBGetUsedCountI(mbp) 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
|
||||
*/
|
||||
#define chMBPeekI(mbp) (*(mbp)->mb_rdptr)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @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 name = _MAILBOX_DATA(name, buffer, size)
|
||||
|
||||
#endif /* CH_USE_MAILBOXES */
|
||||
|
||||
#endif /* _CHMBOXES_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmemcore.h
|
||||
* @brief Core memory manager macros and structures.
|
||||
*
|
||||
* @addtogroup memcore
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHMEMCORE_H_
|
||||
#define _CHMEMCORE_H_
|
||||
|
||||
/**
|
||||
* @brief Memory get function.
|
||||
* @note This type must be assignment compatible with the @p chMemAlloc()
|
||||
* function.
|
||||
*/
|
||||
typedef void *(*memgetfunc_t)(size_t size);
|
||||
|
||||
/**
|
||||
* @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)
|
||||
/** @} */
|
||||
|
||||
#if CH_USE_MEMCORE || defined(__DOXYGEN__)
|
||||
|
||||
#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
|
||||
|
||||
#endif /* CH_USE_MEMCORE */
|
||||
|
||||
#endif /* _CHMEMCORE_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmempools.h
|
||||
* @brief Memory Pools macros and structures.
|
||||
*
|
||||
* @addtogroup pools
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHMEMPOOLS_H_
|
||||
#define _CHMEMPOOLS_H_
|
||||
|
||||
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @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. */
|
||||
} MemoryPool;
|
||||
|
||||
/**
|
||||
* @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) \
|
||||
MemoryPool name = _MEMORYPOOL_DATA(name, size, provider)
|
||||
|
||||
/**
|
||||
* @name Macro 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 MemoryPool structure
|
||||
* @param[in] objp the pointer to the object to be added
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chPoolAdd(mp, 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 MemoryPool structure
|
||||
* @param[in] objp the pointer to the object to be added
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chPoolAddI(mp, objp) chPoolFreeI(mp, objp)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider);
|
||||
void chPoolLoadArray(MemoryPool *mp, void *p, size_t n);
|
||||
void *chPoolAllocI(MemoryPool *mp);
|
||||
void *chPoolAlloc(MemoryPool *mp);
|
||||
void chPoolFreeI(MemoryPool *mp, void *objp);
|
||||
void chPoolFree(MemoryPool *mp, void *objp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CH_USE_MEMPOOLS */
|
||||
|
||||
#endif /* _CHMEMPOOLS_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmsg.h
|
||||
* @brief Messages macros and structures.
|
||||
*
|
||||
* @addtogroup messages
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHMSG_H_
|
||||
#define _CHMSG_H_
|
||||
|
||||
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Evaluates to TRUE if the thread has pending messages.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chMsgIsPendingI(tp) \
|
||||
((tp)->p_msgqueue.p_next != (Thread *)&(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
|
||||
*/
|
||||
#define chMsgGet(tp) ((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
|
||||
*/
|
||||
#define chMsgReleaseS(tp, msg) chSchWakeupS(tp, msg)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
msg_t chMsgSend(Thread *tp, msg_t msg);
|
||||
Thread * chMsgWait(void);
|
||||
void chMsgRelease(Thread *tp, msg_t msg);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CH_USE_MESSAGES */
|
||||
|
||||
#endif /* _CHMSG_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmtx.h
|
||||
* @brief Mutexes macros and structures.
|
||||
*
|
||||
* @addtogroup mutexes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHMTX_H_
|
||||
#define _CHMTX_H_
|
||||
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Mutex structure.
|
||||
*/
|
||||
typedef struct Mutex {
|
||||
ThreadsQueue m_queue; /**< @brief Queue of the threads sleeping
|
||||
on this Mutex. */
|
||||
Thread *m_owner; /**< @brief Owner @p Thread pointer or
|
||||
@p NULL. */
|
||||
struct Mutex *m_next; /**< @brief Next @p Mutex into an
|
||||
owner-list or @p NULL. */
|
||||
} Mutex;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chMtxInit(Mutex *mp);
|
||||
void chMtxLock(Mutex *mp);
|
||||
void chMtxLockS(Mutex *mp);
|
||||
bool_t chMtxTryLock(Mutex *mp);
|
||||
bool_t chMtxTryLockS(Mutex *mp);
|
||||
Mutex *chMtxUnlock(void);
|
||||
Mutex *chMtxUnlockS(void);
|
||||
void chMtxUnlockAll(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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) {_THREADSQUEUE_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 name = _MUTEX_DATA(name)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns @p TRUE if the mutex queue contains at least a waiting
|
||||
* thread.
|
||||
*
|
||||
* @sclass
|
||||
*/
|
||||
#define chMtxQueueNotEmptyS(mp) notempty(&(mp)->m_queue)
|
||||
/** @} */
|
||||
|
||||
#endif /* CH_USE_MUTEXES */
|
||||
|
||||
#endif /* _CHMTX_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,376 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chqueues.h
|
||||
* @brief I/O Queues macros and structures.
|
||||
*
|
||||
* @addtogroup io_queues
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHQUEUES_H_
|
||||
#define _CHQUEUES_H_
|
||||
|
||||
#if CH_USE_QUEUES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @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, */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Type of a generic I/O queue structure.
|
||||
*/
|
||||
typedef struct GenericQueue GenericQueue;
|
||||
|
||||
/** @brief Queue notification callback type.*/
|
||||
typedef void (*qnotify_t)(GenericQueue *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 GenericQueue {
|
||||
ThreadsQueue 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. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the queue's buffer size.
|
||||
*
|
||||
* @param[in] qp pointer to a @p GenericQueue 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 GenericQueue structure.
|
||||
* @return The buffer space.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chQSpaceI(qp) ((qp)->q_counter)
|
||||
|
||||
/**
|
||||
* @brief Returns the queue application-defined link.
|
||||
* @note This function can be called in any context.
|
||||
*
|
||||
* @param[in] qp pointer to a @p GenericQueue structure.
|
||||
* @return The application-defined link.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define chQGetLink(qp) ((qp)->q_link)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @extends GenericQueue
|
||||
*
|
||||
* @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 GenericQueue InputQueue;
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the filled space into an input queue.
|
||||
*
|
||||
* @param[in] iqp pointer to an @p InputQueue structure
|
||||
* @return The number of full bytes in the queue.
|
||||
* @retval 0 if the queue is empty.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chIQGetFullI(iqp) chQSpaceI(iqp)
|
||||
|
||||
/**
|
||||
* @brief Returns the empty space into an input queue.
|
||||
*
|
||||
* @param[in] iqp pointer to an @p InputQueue structure
|
||||
* @return The number of empty bytes in the queue.
|
||||
* @retval 0 if the queue is full.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chIQGetEmptyI(iqp) (chQSizeI(iqp) - chQSpaceI(iqp))
|
||||
|
||||
/**
|
||||
* @brief Evaluates to @p TRUE if the specified input queue is empty.
|
||||
*
|
||||
* @param[in] iqp pointer to an @p InputQueue structure.
|
||||
* @return The queue status.
|
||||
* @retval FALSE if the queue is not empty.
|
||||
* @retval TRUE if the queue is empty.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chIQIsEmptyI(iqp) ((bool_t)(chQSpaceI(iqp) <= 0))
|
||||
|
||||
/**
|
||||
* @brief Evaluates to @p TRUE if the specified input queue is full.
|
||||
*
|
||||
* @param[in] iqp pointer to an @p InputQueue structure.
|
||||
* @return The queue status.
|
||||
* @retval FALSE if the queue is not full.
|
||||
* @retval TRUE if the queue is full.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chIQIsFullI(iqp) ((bool_t)(((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 InputQueue structure
|
||||
* @return A byte value from the queue.
|
||||
* @retval Q_RESET if the queue has been reset.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chIQGet(iqp) chIQGetTimeout(iqp, TIME_INFINITE)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @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) { \
|
||||
_THREADSQUEUE_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) \
|
||||
InputQueue name = _INPUTQUEUE_DATA(name, buffer, size, inotify, link)
|
||||
|
||||
/**
|
||||
* @extends GenericQueue
|
||||
*
|
||||
* @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 GenericQueue OutputQueue;
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the filled space into an output queue.
|
||||
*
|
||||
* @param[in] oqp pointer to an @p OutputQueue structure
|
||||
* @return The number of full bytes in the queue.
|
||||
* @retval 0 if the queue is empty.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chOQGetFullI(oqp) (chQSizeI(oqp) - chQSpaceI(oqp))
|
||||
|
||||
/**
|
||||
* @brief Returns the empty space into an output queue.
|
||||
*
|
||||
* @param[in] oqp pointer to an @p OutputQueue structure
|
||||
* @return The number of empty bytes in the queue.
|
||||
* @retval 0 if the queue is full.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chOQGetEmptyI(oqp) chQSpaceI(oqp)
|
||||
|
||||
/**
|
||||
* @brief Evaluates to @p TRUE if the specified output queue is empty.
|
||||
*
|
||||
* @param[in] oqp pointer to an @p OutputQueue structure.
|
||||
* @return The queue status.
|
||||
* @retval FALSE if the queue is not empty.
|
||||
* @retval TRUE if the queue is empty.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chOQIsEmptyI(oqp) ((bool_t)(((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 OutputQueue structure.
|
||||
* @return The queue status.
|
||||
* @retval FALSE if the queue is not full.
|
||||
* @retval TRUE if the queue is full.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chOQIsFullI(oqp) ((bool_t)(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 OutputQueue 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
|
||||
*/
|
||||
#define chOQPut(oqp, b) chOQPutTimeout(oqp, b, TIME_INFINITE)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @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) { \
|
||||
_THREADSQUEUE_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) \
|
||||
OutputQueue name = _OUTPUTQUEUE_DATA(name, buffer, size, onotify, link)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy,
|
||||
void *link);
|
||||
void chIQResetI(InputQueue *iqp);
|
||||
msg_t chIQPutI(InputQueue *iqp, uint8_t b);
|
||||
msg_t chIQGetTimeout(InputQueue *iqp, systime_t time);
|
||||
size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
|
||||
size_t n, systime_t time);
|
||||
|
||||
void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy,
|
||||
void *link);
|
||||
void chOQResetI(OutputQueue *oqp);
|
||||
msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time);
|
||||
msg_t chOQGetI(OutputQueue *oqp);
|
||||
size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp,
|
||||
size_t n, systime_t time);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* CH_USE_QUEUES */
|
||||
|
||||
#endif /* _CHQUEUES_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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chregistry.h
|
||||
* @brief Threads registry macros and structures.
|
||||
*
|
||||
* @addtogroup registry
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHREGISTRY_H_
|
||||
#define _CHREGISTRY_H_
|
||||
|
||||
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @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 struct. */
|
||||
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;
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Sets the current thread name.
|
||||
* @pre This function only stores the pointer to the name if the option
|
||||
* @p CH_USE_REGISTRY is enabled else no action is performed.
|
||||
*
|
||||
* @param[in] p thread name as a zero terminated string
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chRegSetThreadName(p) (currp->p_name = (p))
|
||||
|
||||
/**
|
||||
* @brief Returns the name of the specified thread.
|
||||
* @pre This function only returns the pointer to the name if the option
|
||||
* @p CH_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.
|
||||
*/
|
||||
#define chRegGetThreadName(tp) ((tp)->p_name)
|
||||
/** @} */
|
||||
#else /* !CH_USE_REGISTRY */
|
||||
#define chRegSetThreadName(p)
|
||||
#define chRegGetThreadName(tp) NULL
|
||||
#endif /* !CH_USE_REGISTRY */
|
||||
|
||||
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @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 *)&rlist; \
|
||||
(tp)->p_older = rlist.r_older; \
|
||||
(tp)->p_older->p_newer = rlist.r_older = (tp); \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern ROMCONST chdebug_t ch_debug;
|
||||
Thread *chRegFirstThread(void);
|
||||
Thread *chRegNextThread(Thread *tp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CH_USE_REGISTRY */
|
||||
|
||||
#endif /* _CHREGISTRY_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,244 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chschd.h
|
||||
* @brief Scheduler macros and structures.
|
||||
*
|
||||
* @addtogroup scheduler
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHSCHD_H_
|
||||
#define _CHSCHD_H_
|
||||
|
||||
/**
|
||||
* @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)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Returns the priority of the first thread on the given ready list.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define firstprio(rlp) ((rlp)->p_next->p_prio)
|
||||
|
||||
/**
|
||||
* @extends ThreadsQueue
|
||||
*
|
||||
* @brief Ready list header.
|
||||
*/
|
||||
#if !defined(PORT_OPTIMIZED_READYLIST_STRUCT) || defined(__DOXYGEN__)
|
||||
typedef struct {
|
||||
ThreadsQueue 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_USE_REGISTRY || defined(__DOXYGEN__)
|
||||
Thread *r_newer; /**< @brief Newer registry element. */
|
||||
Thread *r_older; /**< @brief Older registry element. */
|
||||
#endif
|
||||
/* End of the fields shared with the Thread structure.*/
|
||||
Thread *r_current; /**< @brief The currently running
|
||||
thread. */
|
||||
} ReadyList;
|
||||
#endif /* !defined(PORT_OPTIMIZED_READYLIST_STRUCT) */
|
||||
|
||||
#if !defined(PORT_OPTIMIZED_RLIST_EXT) && !defined(__DOXYGEN__)
|
||||
extern ReadyList rlist;
|
||||
#endif /* !defined(PORT_OPTIMIZED_RLIST_EXT) */
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
#if !defined(PORT_OPTIMIZED_CURRP) || defined(__DOXYGEN__)
|
||||
#define currp rlist.r_current
|
||||
#endif /* !defined(PORT_OPTIMIZED_CURRP) */
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
#if !defined(PORT_OPTIMIZED_SETCURRP) || defined(__DOXYGEN__)
|
||||
#define setcurrp(tp) (currp = (tp))
|
||||
#endif /* !defined(PORT_OPTIMIZED_SETCURRP) */
|
||||
|
||||
/*
|
||||
* Scheduler APIs.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _scheduler_init(void);
|
||||
#if !defined(PORT_OPTIMIZED_READYI)
|
||||
Thread *chSchReadyI(Thread *tp);
|
||||
#endif
|
||||
#if !defined(PORT_OPTIMIZED_GOSLEEPS)
|
||||
void chSchGoSleepS(tstate_t newstate);
|
||||
#endif
|
||||
#if !defined(PORT_OPTIMIZED_GOSLEEPTIMEOUTS)
|
||||
msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time);
|
||||
#endif
|
||||
#if !defined(PORT_OPTIMIZED_WAKEUPS)
|
||||
void chSchWakeupS(Thread *tp, msg_t msg);
|
||||
#endif
|
||||
#if !defined(PORT_OPTIMIZED_RESCHEDULES)
|
||||
void chSchRescheduleS(void);
|
||||
#endif
|
||||
#if !defined(PORT_OPTIMIZED_ISPREEMPTIONREQUIRED)
|
||||
bool_t chSchIsPreemptionRequired(void);
|
||||
#endif
|
||||
#if !defined(PORT_OPTIMIZED_DORESCHEDULEBEHIND) || defined(__DOXYGEN__)
|
||||
void chSchDoRescheduleBehind(void);
|
||||
#endif
|
||||
#if !defined(PORT_OPTIMIZED_DORESCHEDULEAHEAD) || defined(__DOXYGEN__)
|
||||
void chSchDoRescheduleAhead(void);
|
||||
#endif
|
||||
#if !defined(PORT_OPTIMIZED_DORESCHEDULE)
|
||||
void chSchDoReschedule(void);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Macro 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
|
||||
*/
|
||||
#if !defined(PORT_OPTIMIZED_ISRESCHREQUIREDI) || defined(__DOXYGEN__)
|
||||
#define chSchIsRescRequiredI() (firstprio(&rlist.r_queue) > currp->p_prio)
|
||||
#endif /* !defined(PORT_OPTIMIZED_ISRESCHREQUIREDI) */
|
||||
|
||||
/**
|
||||
* @brief Determines if yielding is possible.
|
||||
* @details This function returns @p TRUE if there is a ready thread with
|
||||
* equal or higher priority.
|
||||
*
|
||||
* @sclass
|
||||
*/
|
||||
#if !defined(PORT_OPTIMIZED_CANYIELDS) || defined(__DOXYGEN__)
|
||||
#define chSchCanYieldS() (firstprio(&rlist.r_queue) >= currp->p_prio)
|
||||
#endif /* !defined(PORT_OPTIMIZED_CANYIELDS) */
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
#if !defined(PORT_OPTIMIZED_DOYIELDS) || defined(__DOXYGEN__)
|
||||
#define chSchDoYieldS() { \
|
||||
if (chSchCanYieldS()) \
|
||||
chSchDoRescheduleBehind(); \
|
||||
}
|
||||
#endif /* !defined(PORT_OPTIMIZED_DOYIELDS) */
|
||||
|
||||
/**
|
||||
* @brief Inline-able preemption code.
|
||||
* @details This is the common preemption code, this function must be invoked
|
||||
* exclusively from the port layer.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
|
||||
#define chSchPreemption() { \
|
||||
tprio_t p1 = firstprio(&rlist.r_queue); \
|
||||
tprio_t p2 = currp->p_prio; \
|
||||
if (currp->p_preempt) { \
|
||||
if (p1 > p2) \
|
||||
chSchDoRescheduleAhead(); \
|
||||
} \
|
||||
else { \
|
||||
if (p1 >= p2) \
|
||||
chSchDoRescheduleBehind(); \
|
||||
} \
|
||||
}
|
||||
#else /* CH_TIME_QUANTUM == 0 */
|
||||
#define chSchPreemption() { \
|
||||
if (p1 >= p2) \
|
||||
chSchDoRescheduleAhead(); \
|
||||
}
|
||||
#endif /* CH_TIME_QUANTUM == 0 */
|
||||
/** @} */
|
||||
|
||||
#endif /* _CHSCHD_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chsem.h
|
||||
* @brief Semaphores macros and structures.
|
||||
*
|
||||
* @addtogroup semaphores
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHSEM_H_
|
||||
#define _CHSEM_H_
|
||||
|
||||
#if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Semaphore structure.
|
||||
*/
|
||||
typedef struct Semaphore {
|
||||
ThreadsQueue s_queue; /**< @brief Queue of the threads sleeping
|
||||
on this semaphore. */
|
||||
cnt_t s_cnt; /**< @brief The semaphore counter. */
|
||||
} Semaphore;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chSemInit(Semaphore *sp, cnt_t n);
|
||||
void chSemReset(Semaphore *sp, cnt_t n);
|
||||
void chSemResetI(Semaphore *sp, cnt_t n);
|
||||
msg_t chSemWait(Semaphore *sp);
|
||||
msg_t chSemWaitS(Semaphore *sp);
|
||||
msg_t chSemWaitTimeout(Semaphore *sp, systime_t time);
|
||||
msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time);
|
||||
void chSemSignal(Semaphore *sp);
|
||||
void chSemSignalI(Semaphore *sp);
|
||||
void chSemAddCounterI(Semaphore *sp, cnt_t n);
|
||||
#if CH_USE_SEMSW
|
||||
msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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) {_THREADSQUEUE_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 name = _SEMAPHORE_DATA(name, n)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Decreases the semaphore counter.
|
||||
* @details This macro can be used when the counter is known to be positive.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chSemFastWaitI(sp) ((sp)->s_cnt--)
|
||||
|
||||
/**
|
||||
* @brief Increases the semaphore counter.
|
||||
* @details This macro can be used when the counter is known to be not
|
||||
* negative.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chSemFastSignalI(sp) ((sp)->s_cnt++)
|
||||
|
||||
/**
|
||||
* @brief Returns the semaphore counter current value.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chSemGetCounterI(sp) ((sp)->s_cnt)
|
||||
/** @} */
|
||||
|
||||
#endif /* CH_USE_SEMAPHORES */
|
||||
|
||||
#endif /* _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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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 BaseSequentialStream 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 BaseSequentialStream 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_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,254 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chsys.h
|
||||
* @brief System related macros and structures.
|
||||
*
|
||||
* @addtogroup system
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHSYS_H_
|
||||
#define _CHSYS_H_
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
#if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Returns a pointer to the idle thread.
|
||||
* @pre In order to use this function the option @p CH_NO_IDLE_THREAD
|
||||
* must be disabled.
|
||||
* @note The reference counter of the idle thread is not incremented but
|
||||
* it is not strictly required being the idle thread a static
|
||||
* object.
|
||||
*
|
||||
* @return Pointer to the idle thread.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chSysGetIdleThread() (rlist.r_queue.p_prev)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Halts the system.
|
||||
* @details This function is invoked by the operating system when an
|
||||
* unrecoverable error is detected, for example because a programming
|
||||
* error in the application code that triggers an assertion while
|
||||
* in debug mode.
|
||||
* @note Can be invoked from any system state.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
|
||||
#define chSysHalt() port_halt()
|
||||
#else
|
||||
#define chSysHalt() { \
|
||||
SYSTEM_HALT_HOOK(); \
|
||||
port_halt(); \
|
||||
}
|
||||
#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); \
|
||||
THREAD_CONTEXT_SWITCH_HOOK(ntp, otp); \
|
||||
port_switch(ntp, otp); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
#define chSysDisable() { \
|
||||
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
|
||||
*/
|
||||
#define chSysSuspend() { \
|
||||
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
|
||||
*/
|
||||
#define chSysEnable() { \
|
||||
dbg_check_enable(); \
|
||||
port_enable(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters the kernel lock mode.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define chSysLock() { \
|
||||
port_lock(); \
|
||||
dbg_check_lock(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Leaves the kernel lock mode.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define chSysUnlock() { \
|
||||
dbg_check_unlock(); \
|
||||
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
|
||||
*/
|
||||
#define chSysLockFromIsr() { \
|
||||
port_lock_from_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
|
||||
*/
|
||||
#define chSysUnlockFromIsr() { \
|
||||
dbg_check_unlock_from_isr(); \
|
||||
port_unlock_from_isr(); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @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(); \
|
||||
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)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chSysInit(void);
|
||||
void chSysTimerHandlerI(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CHSYS_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,387 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chthreads.h
|
||||
* @brief Threads macros and structures.
|
||||
*
|
||||
* @addtogroup threads
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHTHREADS_H_
|
||||
#define _CHTHREADS_H_
|
||||
|
||||
/**
|
||||
* @name Thread states
|
||||
* @{
|
||||
*/
|
||||
#define THD_STATE_READY 0 /**< @brief Waiting on the ready list. */
|
||||
#define THD_STATE_CURRENT 1 /**< @brief Currently running. */
|
||||
#define THD_STATE_SUSPENDED 2 /**< @brief Created in suspended state. */
|
||||
#define THD_STATE_WTSEM 3 /**< @brief Waiting on a semaphore. */
|
||||
#define THD_STATE_WTMTX 4 /**< @brief Waiting on a mutex. */
|
||||
#define THD_STATE_WTCOND 5 /**< @brief Waiting on a condition
|
||||
variable. */
|
||||
#define THD_STATE_SLEEPING 6 /**< @brief Waiting in @p chThdSleep()
|
||||
or @p chThdSleepUntil(). */
|
||||
#define THD_STATE_WTEXIT 7 /**< @brief Waiting in @p chThdWait(). */
|
||||
#define THD_STATE_WTOREVT 8 /**< @brief Waiting for an event. */
|
||||
#define THD_STATE_WTANDEVT 9 /**< @brief Waiting for several events. */
|
||||
#define THD_STATE_SNDMSGQ 10 /**< @brief Sending a message, in queue.*/
|
||||
#define THD_STATE_SNDMSG 11 /**< @brief Sent a message, waiting
|
||||
answer. */
|
||||
#define THD_STATE_WTMSG 12 /**< @brief Waiting for a message. */
|
||||
#define THD_STATE_WTQUEUE 13 /**< @brief Waiting on an I/O queue. */
|
||||
#define THD_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 THD_STATE_NAMES \
|
||||
"READY", "CURRENT", "SUSPENDED", "WTSEM", "WTMTX", "WTCOND", "SLEEPING", \
|
||||
"WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "WTQUEUE", \
|
||||
"FINAL"
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Thread flags and attributes
|
||||
* @{
|
||||
*/
|
||||
#define THD_MEM_MODE_MASK 3 /**< @brief Thread memory mode mask. */
|
||||
#define THD_MEM_MODE_STATIC 0 /**< @brief Static thread. */
|
||||
#define THD_MEM_MODE_HEAP 1 /**< @brief Thread allocated from a
|
||||
Memory Heap. */
|
||||
#define THD_MEM_MODE_MEMPOOL 2 /**< @brief Thread allocated from a
|
||||
Memory Pool. */
|
||||
#define THD_TERMINATE 4 /**< @brief Termination requested flag. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @extends ThreadsQueue
|
||||
*
|
||||
* @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 structure.
|
||||
*/
|
||||
struct Thread {
|
||||
Thread *p_next; /**< @brief Next in the list/queue. */
|
||||
/* End of the fields shared with the ThreadsList structure. */
|
||||
Thread *p_prev; /**< @brief Previous in the queue. */
|
||||
/* End of the fields shared with the ThreadsQueue structure. */
|
||||
tprio_t p_prio; /**< @brief Thread priority. */
|
||||
struct context p_ctx; /**< @brief Processor context. */
|
||||
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
||||
Thread *p_newer; /**< @brief Newer registry element. */
|
||||
Thread *p_older; /**< @brief Older registry element. */
|
||||
#endif
|
||||
/* End of the fields shared with the ReadyList structure. */
|
||||
#if CH_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_USE_DYNAMIC || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief References to this thread.
|
||||
*/
|
||||
trefs_t p_refs;
|
||||
#endif
|
||||
/**
|
||||
* @brief Number of ticks remaining to this thread.
|
||||
*/
|
||||
#if (CH_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_USE_EVENTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Enabled events mask.
|
||||
* @note This field is only valid while the thread is in the
|
||||
* @p THD_STATE_WTOREVT or @p THD_STATE_WTANDEVT states.
|
||||
*/
|
||||
eventmask_t ewmask;
|
||||
#endif
|
||||
} p_u;
|
||||
#if CH_USE_WAITEXIT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Termination waiting list.
|
||||
*/
|
||||
ThreadsList p_waiting;
|
||||
#endif
|
||||
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Messages queue.
|
||||
*/
|
||||
ThreadsQueue p_msgqueue;
|
||||
/**
|
||||
* @brief Thread message.
|
||||
*/
|
||||
msg_t p_msg;
|
||||
#endif
|
||||
#if CH_USE_EVENTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Pending events mask.
|
||||
*/
|
||||
eventmask_t p_epending;
|
||||
#endif
|
||||
#if CH_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 *p_mtxlist;
|
||||
/**
|
||||
* @brief Thread's own, non-inherited, priority.
|
||||
*/
|
||||
tprio_t p_realprio;
|
||||
#endif
|
||||
#if (CH_USE_DYNAMIC && CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Memory Pool where the thread workspace is returned.
|
||||
*/
|
||||
void *p_mpool;
|
||||
#endif
|
||||
#if defined(THREAD_EXT_FIELDS)
|
||||
/* Extra fields defined in chconf.h.*/
|
||||
THREAD_EXT_FIELDS
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Thread function.
|
||||
*/
|
||||
typedef msg_t (*tfunc_t)(void *);
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns a pointer to the current @p Thread.
|
||||
* @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 Returns the pointer to the @p Thread local storage area, if any.
|
||||
* @note Can be invoked in any context.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define chThdLS() (void *)(currp + 1)
|
||||
|
||||
/**
|
||||
* @brief Verifies if the specified thread is in the @p THD_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 == THD_STATE_FINAL)
|
||||
|
||||
/**
|
||||
* @brief Verifies if the current thread has a termination request pending.
|
||||
* @note Can be invoked in any context.
|
||||
*
|
||||
* @retval 0 termination request not pending.
|
||||
* @retval !0 termination request pending.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define chThdShouldTerminate() (currp->p_flags & THD_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(THD_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))
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* Threads APIs.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
Thread *_thread_init(Thread *tp, tprio_t prio);
|
||||
#if CH_DBG_FILL_THREADS
|
||||
void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v);
|
||||
#endif
|
||||
Thread *chThdCreateI(void *wsp, size_t size,
|
||||
tprio_t prio, tfunc_t pf, void *arg);
|
||||
Thread *chThdCreateStatic(void *wsp, size_t size,
|
||||
tprio_t prio, tfunc_t pf, void *arg);
|
||||
tprio_t chThdSetPriority(tprio_t newprio);
|
||||
Thread *chThdResume(Thread *tp);
|
||||
void chThdTerminate(Thread *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_USE_WAITEXIT
|
||||
msg_t chThdWait(Thread *tp);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CHTHREADS_H_ */
|
||||
|
||||
/** @} */
|
@ -0,0 +1,262 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chvt.h
|
||||
* @brief Time macros and structures.
|
||||
*
|
||||
* @addtogroup time
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHVT_H_
|
||||
#define _CHVT_H_
|
||||
|
||||
/**
|
||||
* @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)((sec) * CH_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_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_FREQUENCY) - 1UL) / \
|
||||
1000000UL) + 1UL))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Virtual Timer callback function.
|
||||
*/
|
||||
typedef void (*vtfunc_t)(void *);
|
||||
|
||||
/**
|
||||
* @brief Virtual Timer structure type.
|
||||
*/
|
||||
typedef struct VirtualTimer VirtualTimer;
|
||||
|
||||
/**
|
||||
* @extends VTList
|
||||
*
|
||||
* @brief Virtual Timer descriptor structure.
|
||||
*/
|
||||
struct VirtualTimer {
|
||||
VirtualTimer *vt_next; /**< @brief Next timer in the delta
|
||||
list. */
|
||||
VirtualTimer *vt_prev; /**< @brief Previous timer in the delta
|
||||
list. */
|
||||
systime_t vt_time; /**< @brief Time delta before timeout. */
|
||||
vtfunc_t vt_func; /**< @brief Timer callback function
|
||||
pointer. */
|
||||
void *vt_par; /**< @brief Timer callback function
|
||||
parameter. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Virtual timers list header.
|
||||
* @note The delta 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 {
|
||||
VirtualTimer *vt_next; /**< @brief Next timer in the delta
|
||||
list. */
|
||||
VirtualTimer *vt_prev; /**< @brief Last timer in the delta
|
||||
list. */
|
||||
systime_t vt_time; /**< @brief Must be initialized to -1. */
|
||||
volatile systime_t vt_systime; /**< @brief System Time counter. */
|
||||
} VTList;
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
#define chVTDoTickI() { \
|
||||
vtlist.vt_systime++; \
|
||||
if (&vtlist != (VTList *)vtlist.vt_next) { \
|
||||
VirtualTimer *vtp; \
|
||||
\
|
||||
--vtlist.vt_next->vt_time; \
|
||||
while (!(vtp = vtlist.vt_next)->vt_time) { \
|
||||
vtfunc_t fn = vtp->vt_func; \
|
||||
vtp->vt_func = (vtfunc_t)NULL; \
|
||||
vtp->vt_next->vt_prev = (void *)&vtlist; \
|
||||
(&vtlist)->vt_next = vtp->vt_next; \
|
||||
chSysUnlockFromIsr(); \
|
||||
fn(vtp->vt_par); \
|
||||
chSysLockFromIsr(); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns @p TRUE if the specified timer is armed.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chVTIsArmedI(vtp) ((vtp)->vt_func != NULL)
|
||||
|
||||
/**
|
||||
* @brief Enables a virtual timer.
|
||||
* @note The associated function is invoked from interrupt context.
|
||||
*
|
||||
* @param[out] vtp the @p VirtualTimer structure pointer
|
||||
* @param[in] time the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @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
|
||||
*/
|
||||
#define chVTSet(vtp, time, vtfunc, par) { \
|
||||
chSysLock(); \
|
||||
chVTSetI(vtp, time, vtfunc, par); \
|
||||
chSysUnlock(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a Virtual Timer.
|
||||
* @note The timer is first checked and disabled only if armed.
|
||||
*
|
||||
* @param[in] vtp the @p VirtualTimer structure pointer
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chVTReset(vtp) { \
|
||||
chSysLock(); \
|
||||
if (chVTIsArmedI(vtp)) \
|
||||
chVTResetI(vtp); \
|
||||
chSysUnlock(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 is designed to work with the @p chThdSleepUntil().
|
||||
*
|
||||
* @return The system time in ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chTimeNow() (vtlist.vt_systime)
|
||||
|
||||
/**
|
||||
* @brief Returns the elapsed time since the specified start time.
|
||||
*
|
||||
* @param[in] start start time
|
||||
* @return The elapsed time.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chTimeElapsedSince(start) (chTimeNow() - (start))
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
#define chTimeIsWithin(start, end) \
|
||||
(chTimeElapsedSince(start) < ((end) - (start)))
|
||||
/** @} */
|
||||
|
||||
extern VTList vtlist;
|
||||
|
||||
/*
|
||||
* Virtual Timers APIs.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _vt_init(void);
|
||||
void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par);
|
||||
void chVTResetI(VirtualTimer *vtp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CHVT_H_ */
|
||||
|
||||
/** @} */
|
Reference in New Issue
Block a user