From 48026bb824fd2d9cfb00ecd040db6ef3a416bae9 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Fri, 22 Jan 2021 21:43:36 -0500 Subject: upload initial port --- ChibiOS_20.3.2/os/rt/include/ch.h | 135 +++++ ChibiOS_20.3.2/os/rt/include/chalign.h | 120 +++++ ChibiOS_20.3.2/os/rt/include/chchecks.h | 263 ++++++++++ ChibiOS_20.3.2/os/rt/include/chcond.h | 116 +++++ ChibiOS_20.3.2/os/rt/include/chdebug.h | 169 ++++++ ChibiOS_20.3.2/os/rt/include/chdynamic.h | 99 ++++ ChibiOS_20.3.2/os/rt/include/chevents.h | 291 +++++++++++ ChibiOS_20.3.2/os/rt/include/chmsg.h | 212 ++++++++ ChibiOS_20.3.2/os/rt/include/chmtx.h | 168 ++++++ ChibiOS_20.3.2/os/rt/include/chregistry.h | 185 +++++++ ChibiOS_20.3.2/os/rt/include/chrestrictions.h | 118 +++++ ChibiOS_20.3.2/os/rt/include/chschd.h | 716 ++++++++++++++++++++++++++ ChibiOS_20.3.2/os/rt/include/chsem.h | 200 +++++++ ChibiOS_20.3.2/os/rt/include/chstats.h | 105 ++++ ChibiOS_20.3.2/os/rt/include/chsys.h | 469 +++++++++++++++++ ChibiOS_20.3.2/os/rt/include/chsystypes.h | 130 +++++ ChibiOS_20.3.2/os/rt/include/chthreads.h | 440 ++++++++++++++++ ChibiOS_20.3.2/os/rt/include/chtime.h | 492 ++++++++++++++++++ ChibiOS_20.3.2/os/rt/include/chtm.h | 109 ++++ ChibiOS_20.3.2/os/rt/include/chtrace.h | 256 +++++++++ ChibiOS_20.3.2/os/rt/include/chvt.h | 362 +++++++++++++ 21 files changed, 5155 insertions(+) create mode 100644 ChibiOS_20.3.2/os/rt/include/ch.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chalign.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chchecks.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chcond.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chdebug.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chdynamic.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chevents.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chmsg.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chmtx.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chregistry.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chrestrictions.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chschd.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chsem.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chstats.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chsys.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chsystypes.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chthreads.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chtime.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chtm.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chtrace.h create mode 100644 ChibiOS_20.3.2/os/rt/include/chvt.h (limited to 'ChibiOS_20.3.2/os/rt/include') diff --git a/ChibiOS_20.3.2/os/rt/include/ch.h b/ChibiOS_20.3.2/os/rt/include/ch.h new file mode 100644 index 0000000..200383b --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/ch.h @@ -0,0 +1,135 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/ch.h + * @brief ChibiOS/RT main include file. + * + * @addtogroup kernel_info + * @details This header includes all the required kernel headers so it is the + * only kernel header you usually want to include in your application. + * @details Kernel related info. + * @{ + */ + +#ifndef CH_H +#define CH_H + +/** + * @brief ChibiOS/RT identification macro. + */ +#define _CHIBIOS_RT_ + +/** + * @brief Stable release flag. + */ +#define CH_KERNEL_STABLE 1 + +/** + * @name ChibiOS/RT version identification + * @{ + */ +/** + * @brief Kernel version string. + */ +#define CH_KERNEL_VERSION "6.1.2" + +/** + * @brief Kernel version major number. + */ +#define CH_KERNEL_MAJOR 6 + +/** + * @brief Kernel version minor number. + */ +#define CH_KERNEL_MINOR 1 + +/** + * @brief Kernel version patch number. + */ +#define CH_KERNEL_PATCH 2 +/** @} */ + +/** + * @name Constants for configuration options + */ +/** + * @brief Generic 'false' preprocessor boolean constant. + * @note It is meant to be used in configuration files as switch. + */ +#if !defined(FALSE) || defined(__DOXYGEN__) +#define FALSE 0 +#endif + +/** + * @brief Generic 'true' preprocessor boolean constant. + * @note It is meant to be used in configuration files as switch. + */ +#if !defined(TRUE) || defined(__DOXYGEN__) +#define TRUE 1 +#endif +/** @} */ + +/* Configuration headers, checks and licensing restrictions.*/ +#include "chconf.h" +#include "chchecks.h" +#include "chlicense.h" +#include "chrestrictions.h" + +/* Early function prototype required by the following headers.*/ +#ifdef __cplusplus +extern "C" { +#endif + void chSysHalt(const char *reason); +#ifdef __cplusplus +} +#endif + +/* Base kernel headers.*/ +#include "chtypes.h" /* CHTODO: Rename and rework.*/ +#include "chsystypes.h" +#include "chdebug.h" +#include "chtime.h" +#include "chalign.h" +#include "chcore.h" +#include "chtrace.h" +#include "chtm.h" +#include "chstats.h" +#include "chschd.h" +#include "chsys.h" +#include "chvt.h" +#include "chthreads.h" + +/* Optional subsystems headers.*/ +#include "chregistry.h" +#include "chsem.h" +#include "chmtx.h" +#include "chcond.h" +#include "chevents.h" +#include "chmsg.h" + +/* OSLIB.*/ +#include "chlib.h" + +/* Headers dependent on the OSLIB.*/ +#include "chdynamic.h" + +#endif /* CH_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chalign.h b/ChibiOS_20.3.2/os/rt/include/chalign.h new file mode 100644 index 0000000..56e5f1c --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chalign.h @@ -0,0 +1,120 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chalign.h + * @brief Memory alignment macros and structures. + * + * @addtogroup mem + * @details Memory Alignment services. + * @{ + */ + +#ifndef CHALIGN_H +#define CHALIGN_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @name Memory alignment support macros + */ +/** + * @brief Alignment mask constant. + * + * @param[in] a alignment, must be a power of two + */ +#define MEM_ALIGN_MASK(a) ((size_t)(a) - 1U) + +/** + * @brief Aligns to the previous aligned memory address. + * + * @param[in] p variable to be aligned + * @param[in] a alignment, must be a power of two + */ +#define MEM_ALIGN_PREV(p, a) \ + /*lint -save -e9033 [10.8] The cast is safe.*/ \ + ((size_t)(p) & ~MEM_ALIGN_MASK(a)) \ + /*lint -restore*/ + +/** + * @brief Aligns to the next aligned memory address. + * + * @param[in] p variable to be aligned + * @param[in] a alignment, must be a power of two + */ +#define MEM_ALIGN_NEXT(p, a) \ + /*lint -save -e9033 [10.8] The cast is safe.*/ \ + MEM_ALIGN_PREV((size_t)(p) + MEM_ALIGN_MASK(a), (a)) \ + /*lint -restore*/ + +/** + * @brief Returns whatever a pointer or memory size is aligned. + * + * @param[in] p variable to be aligned + * @param[in] a alignment, must be a power of two + */ +#define MEM_IS_ALIGNED(p, a) (((size_t)(p) & MEM_ALIGN_MASK(a)) == 0U) + +/** + * @brief Returns whatever a constant is a valid alignment. + * @details Valid alignments are powers of two. + * + * @param[in] a alignment to be checked, must be a constant + */ +#define MEM_IS_VALID_ALIGNMENT(a) \ + (((size_t)(a) != 0U) && (((size_t)(a) & ((size_t)(a) - 1U)) == 0U)) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CHALIGN_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chchecks.h b/ChibiOS_20.3.2/os/rt/include/chchecks.h new file mode 100644 index 0000000..c2d16c0 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chchecks.h @@ -0,0 +1,263 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chchecks.h + * @brief Configuration file checks header. + * + * @addtogroup conf_checks + * @details This module performs a series of checks on configuration data, + * it is able to detect and reject obsolete or incomplete + * @p chconf.h files. + * @{ + */ + +#ifndef CHCHECKS_H +#define CHCHECKS_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/* Configuration file checks.*/ +#if !defined(_CHIBIOS_RT_CONF_) +#error "invalid configuration file" +#endif + +#if !defined(_CHIBIOS_RT_CONF_VER_6_1_) +#error "obsolete or unknown configuration file" +#endif + +/* System timers checks.*/ +#if !defined(CH_CFG_ST_RESOLUTION) +#error "CH_CFG_ST_RESOLUTION not defined in chconf.h" +#endif + +#if !defined(CH_CFG_ST_FREQUENCY) +#error "CH_CFG_ST_FREQUENCY not defined in chconf.h" +#endif + +#if !defined(CH_CFG_INTERVALS_SIZE) +#error "CH_CFG_INTERVALS_SIZE not defined in chconf.h" +#endif + +#if !defined(CH_CFG_TIME_TYPES_SIZE) +#error "CH_CFG_TIME_TYPES_SIZE not defined in chconf.h" +#endif + +#if !defined(CH_CFG_ST_TIMEDELTA) +#error "CH_CFG_ST_TIMEDELTA not defined in chconf.h" +#endif + +/* Kernel parameters and options checks.*/ +#if !defined(CH_CFG_TIME_QUANTUM) +#error "CH_CFG_TIME_QUANTUM not defined in chconf.h" +#endif + +#if !defined(CH_CFG_MEMCORE_SIZE) +#error "CH_CFG_MEMCORE_SIZE not defined in chconf.h" +#endif + +#if !defined(CH_CFG_NO_IDLE_THREAD) +#error "CH_CFG_NO_IDLE_THREAD not defined in chconf.h" +#endif + +/* Performance options checks.*/ +#if !defined(CH_CFG_OPTIMIZE_SPEED) +#error "CH_CFG_OPTIMIZE_SPEED not defined in chconf.h" +#endif + +/* Subsystem options checks.*/ +#if !defined(CH_CFG_USE_TM) +#error "CH_CFG_USE_TM not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_REGISTRY) +#error "CH_CFG_USE_REGISTRY not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_WAITEXIT) +#error "CH_CFG_USE_WAITEXIT not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_SEMAPHORES) +#error "CH_CFG_USE_SEMAPHORES not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) +#error "CH_CFG_USE_SEMAPHORES_PRIORITY not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_MUTEXES) +#error "CH_CFG_USE_MUTEXES not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) +#error "CH_CFG_USE_MUTEXES_RECURSIVE not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_CONDVARS) +#error "CH_CFG_USE_CONDVARS not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) +#error "CH_CFG_USE_CONDVARS_TIMEOUT not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_EVENTS) +#error "CH_CFG_USE_EVENTS not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_EVENTS_TIMEOUT) +#error "CH_CFG_USE_EVENTS_TIMEOUT not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_MESSAGES) +#error "CH_CFG_USE_MESSAGES not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_MESSAGES_PRIORITY) +#error "CH_CFG_USE_MESSAGES_PRIORITY not defined in chconf.h" +#endif + +#if !defined(CH_CFG_USE_DYNAMIC) +#error "CH_CFG_USE_DYNAMIC not defined in chconf.h" +#endif + +/* Debug options checks.*/ +#if !defined(CH_DBG_STATISTICS) +#error "CH_DBG_STATISTICS not defined in chconf.h" +#endif + +#if !defined(CH_DBG_SYSTEM_STATE_CHECK) +#error "CH_DBG_SYSTEM_STATE_CHECK not defined in chconf.h" +#endif + +#if !defined(CH_DBG_ENABLE_CHECKS) +#error "CH_DBG_ENABLE_CHECKS not defined in chconf.h" +#endif + +#if !defined(CH_DBG_ENABLE_ASSERTS) +#error "CH_DBG_ENABLE_ASSERTS not defined in chconf.h" +#endif + +#if !defined(CH_DBG_TRACE_MASK) +#error "CH_DBG_TRACE_MASK not defined in chconf.h" +#endif + +#if !defined(CH_DBG_TRACE_BUFFER_SIZE) +#error "CH_DBG_TRACE_BUFFER_SIZE not defined in chconf.h" +#endif + +#if !defined(CH_DBG_ENABLE_STACK_CHECK) +#error "CH_DBG_ENABLE_STACK_CHECK not defined in chconf.h" +#endif + +#if !defined(CH_DBG_FILL_THREADS) +#error "CH_DBG_FILL_THREADS not defined in chconf.h" +#endif + +#if !defined(CH_DBG_THREADS_PROFILING) +#error "CH_DBG_THREADS_PROFILING not defined in chconf.h" +#endif + +/* System hooks checks.*/ +#if !defined(CH_CFG_SYSTEM_INIT_HOOK) +#error "CH_CFG_SYSTEM_INIT_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_SYSTEM_EXTRA_FIELDS) +#error "CH_CFG_SYSTEM_EXTRA_FIELDS not defined in chconf.h" +#endif + +#if !defined(CH_CFG_THREAD_EXTRA_FIELDS) +#error "CH_CFG_THREAD_EXTRA_FIELDS not defined in chconf.h" +#endif + +#if !defined(CH_CFG_THREAD_INIT_HOOK) +#error "CH_CFG_THREAD_INIT_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_THREAD_EXIT_HOOK) +#error "CH_CFG_THREAD_EXIT_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_CONTEXT_SWITCH_HOOK) +#error "CH_CFG_CONTEXT_SWITCH_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_IRQ_PROLOGUE_HOOK) +#error "CH_CFG_IRQ_PROLOGUE_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_IRQ_EPILOGUE_HOOK) +#error "CH_CFG_IRQ_EPILOGUE_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_IDLE_ENTER_HOOK) +#error "CH_CFG_IDLE_ENTER_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_IDLE_LEAVE_HOOK) +#error "CH_CFG_IDLE_LEAVE_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_IDLE_LOOP_HOOK) +#error "CH_CFG_IDLE_LOOP_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_SYSTEM_TICK_HOOK) +#error "CH_CFG_SYSTEM_TICK_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_SYSTEM_HALT_HOOK) +#error "CH_CFG_SYSTEM_HALT_HOOK not defined in chconf.h" +#endif + +#if !defined(CH_CFG_TRACE_HOOK) +#error "CH_CFG_TRACE_HOOK not defined in chconf.h" +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CHCHECKS_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chcond.h b/ChibiOS_20.3.2/os/rt/include/chcond.h new file mode 100644 index 0000000..b6d7f96 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chcond.h @@ -0,0 +1,116 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/* + Concepts and parts of this file have been contributed by Leon Woestenberg. + */ + +/** + * @file rt/include/chcond.h + * @brief Condition Variables macros and structures. + * + * @addtogroup condvars + * @{ + */ + +#ifndef CHCOND_H +#define CHCOND_H + +#if (CH_CFG_USE_CONDVARS == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if CH_CFG_USE_MUTEXES == FALSE +#error "CH_CFG_USE_CONDVARS requires CH_CFG_USE_MUTEXES" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief condition_variable_t structure. + */ +typedef struct condition_variable { + threads_queue_t queue; /**< @brief Condition variable + threads queue. */ +} condition_variable_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Data part of a static condition variable initializer. + * @details This macro should be used when statically initializing a condition + * variable that is part of a bigger structure. + * + * @param[in] name the name of the condition variable + */ +#define _CONDVAR_DATA(name) {_THREADS_QUEUE_DATA(name.queue)} + +/** + * @brief Static condition variable initializer. + * @details Statically initialized condition variables require no explicit + * initialization using @p chCondInit(). + * + * @param[in] name the name of the condition variable + */ +#define CONDVAR_DECL(name) condition_variable_t name = _CONDVAR_DATA(name) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void chCondObjectInit(condition_variable_t *cp); + void chCondSignal(condition_variable_t *cp); + void chCondSignalI(condition_variable_t *cp); + void chCondBroadcast(condition_variable_t *cp); + void chCondBroadcastI(condition_variable_t *cp); + msg_t chCondWait(condition_variable_t *cp); + msg_t chCondWaitS(condition_variable_t *cp); +#if CH_CFG_USE_CONDVARS_TIMEOUT == TRUE + msg_t chCondWaitTimeout(condition_variable_t *cp, sysinterval_t timeout); + msg_t chCondWaitTimeoutS(condition_variable_t *cp, sysinterval_t timeout); +#endif +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CH_CFG_USE_CONDVARS == TRUE */ + +#endif /* CHCOND_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chdebug.h b/ChibiOS_20.3.2/os/rt/include/chdebug.h new file mode 100644 index 0000000..240d1ca --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chdebug.h @@ -0,0 +1,169 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chdebug.h + * @brief Debug support macros and structures. + * + * @addtogroup checks_assertions + * @{ + */ + +#ifndef CHDEBUG_H +#define CHDEBUG_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Debug related settings + * @{ + */ +/** + * @brief Fill value for thread stack area in debug mode. + */ +#if !defined(CH_DBG_STACK_FILL_VALUE) || defined(__DOXYGEN__) +#define CH_DBG_STACK_FILL_VALUE 0x55 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +#if CH_DBG_SYSTEM_STATE_CHECK == TRUE +#define _dbg_enter_lock() (ch.dbg.lock_cnt = (cnt_t)1) +#define _dbg_leave_lock() (ch.dbg.lock_cnt = (cnt_t)0) +#endif + +/* When the state checker feature is disabled then the following functions + are replaced by an empty macro.*/ +#if CH_DBG_SYSTEM_STATE_CHECK == FALSE +#define _dbg_enter_lock() +#define _dbg_leave_lock() +#define _dbg_check_disable() +#define _dbg_check_suspend() +#define _dbg_check_enable() +#define _dbg_check_lock() +#define _dbg_check_unlock() +#define _dbg_check_lock_from_isr() +#define _dbg_check_unlock_from_isr() +#define _dbg_check_enter_isr() +#define _dbg_check_leave_isr() +#define chDbgCheckClassI() +#define chDbgCheckClassS() +#endif + +/** + * @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 + * + * @api + */ +#if !defined(chDbgCheck) +#define chDbgCheck(c) do { \ + /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \ + if (CH_DBG_ENABLE_CHECKS != FALSE) { \ + if (!(c)) { \ + /*lint -restore*/ \ + chSysHalt(__func__); \ + } \ + } \ +} while (false) +#endif /* !defined(chDbgCheck) */ + +/** + * @brief Condition assertion. + * @details If the condition check fails then the kernel panics with a + * message and halts. + * @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS switch + * is specified in @p chconf.h else the macro does nothing. + * @note The remark string is not currently used except for putting a + * comment in the code about the assertion. + * + * @param[in] c the condition to be verified to be true + * @param[in] r a remark string + * + * @api + */ +#if !defined(chDbgAssert) +#define chDbgAssert(c, r) do { \ + /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \ + if (CH_DBG_ENABLE_ASSERTS != FALSE) { \ + if (!(c)) { \ + /*lint -restore*/ \ + chSysHalt(__func__); \ + } \ + } \ +} while (false) +#endif /* !defined(chDbgAssert) */ +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +#if CH_DBG_SYSTEM_STATE_CHECK == TRUE + 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 +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CHDEBUG_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chdynamic.h b/ChibiOS_20.3.2/os/rt/include/chdynamic.h new file mode 100644 index 0000000..6f44c40 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chdynamic.h @@ -0,0 +1,99 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chdynamic.h + * @brief Dynamic threads macros and structures. + * + * @addtogroup dynamic_threads + * @{ + */ + +#ifndef CHDYNAMIC_H +#define CHDYNAMIC_H + +#if (CH_CFG_USE_DYNAMIC == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Module dependencies check. + */ +#if CH_CFG_USE_WAITEXIT == FALSE +#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_WAITEXIT" +#endif + +#if CH_CFG_USE_REGISTRY == FALSE +#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_REGISTRY" +#endif + +#if (CH_CFG_USE_HEAP == FALSE) && (CH_CFG_USE_MEMPOOLS == FALSE) +#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_HEAP and/or CH_CFG_USE_MEMPOOLS" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* + * Dynamic threads APIs. + */ +#ifdef __cplusplus +extern "C" { +#endif +#if CH_CFG_USE_HEAP == TRUE + thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size, + const char *name, tprio_t prio, + tfunc_t pf, void *arg); +#endif +#if CH_CFG_USE_MEMPOOLS == TRUE + thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, const char *name, + tprio_t prio, tfunc_t pf, void *arg); +#endif +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CH_CFG_USE_DYNAMIC == TRUE */ + +#endif /* CHDYNAMIC_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chevents.h b/ChibiOS_20.3.2/os/rt/include/chevents.h new file mode 100644 index 0000000..c81d51e --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chevents.h @@ -0,0 +1,291 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/* + Concepts and parts of this file have been contributed by Scott (skute). + */ + +/** + * @file rt/include/chevents.h + * @brief Events macros and structures. + * + * @addtogroup events + * @{ + */ + +#ifndef CHEVENTS_H +#define CHEVENTS_H + +#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +typedef struct event_listener event_listener_t; + +/** + * @brief Event Listener structure. + */ +struct event_listener { + event_listener_t *next; /**< @brief Next Event Listener + registered on the event + source. */ + thread_t *listener; /**< @brief Thread interested in the + event source. */ + eventmask_t events; /**< @brief Events to be set in + the listening thread. */ + eventflags_t flags; /**< @brief Flags added to the listener + by the event source. */ + eventflags_t wflags; /**< @brief Flags that this listener + interested in. */ +}; + +/** + * @brief Event Source structure. + */ +typedef struct event_source { + event_listener_t *next; /**< @brief First Event Listener + registered on the Event + Source. */ +} event_source_t; + +/** + * @brief Event Handler callback function. + */ +typedef void (*evhandler_t)(eventid_t id); + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief All events allowed mask. + */ +#define ALL_EVENTS ((eventmask_t)-1) + +/** + * @brief Returns an event mask from an event identifier. + */ +#define EVENT_MASK(eid) ((eventmask_t)1 << (eventmask_t)(eid)) + +/** + * @brief Data part of a static event source initializer. + * @details This macro should be used when statically initializing an event + * source that is part of a bigger structure. + * @param name the name of the event source variable + */ +#define _EVENTSOURCE_DATA(name) {(event_listener_t *)(&name)} + +/** + * @brief Static event source initializer. + * @details Statically initialized event sources require no explicit + * initialization using @p chEvtInit(). + * + * @param name the name of the event source variable + */ +#define EVENTSOURCE_DECL(name) event_source_t name = _EVENTSOURCE_DATA(name) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void chEvtRegisterMaskWithFlags(event_source_t *esp, + event_listener_t *elp, + eventmask_t events, + eventflags_t wflags); + void chEvtUnregister(event_source_t *esp, event_listener_t *elp); + eventmask_t chEvtGetAndClearEventsI(eventmask_t events); + eventmask_t chEvtGetAndClearEvents(eventmask_t events); + eventmask_t chEvtAddEvents(eventmask_t events); + eventflags_t chEvtGetAndClearFlags(event_listener_t *elp); + eventflags_t chEvtGetAndClearFlagsI(event_listener_t *elp); + void chEvtSignal(thread_t *tp, eventmask_t events); + void chEvtSignalI(thread_t *tp, eventmask_t events); + void chEvtBroadcastFlags(event_source_t *esp, eventflags_t flags); + void chEvtBroadcastFlagsI(event_source_t *esp, eventflags_t flags); + void chEvtDispatch(const evhandler_t *handlers, eventmask_t events); +#if (CH_CFG_OPTIMIZE_SPEED == TRUE) || (CH_CFG_USE_EVENTS_TIMEOUT == FALSE) + eventmask_t chEvtWaitOne(eventmask_t events); + eventmask_t chEvtWaitAny(eventmask_t events); + eventmask_t chEvtWaitAll(eventmask_t events); +#endif +#if CH_CFG_USE_EVENTS_TIMEOUT == TRUE + eventmask_t chEvtWaitOneTimeout(eventmask_t events, sysinterval_t timeout); + eventmask_t chEvtWaitAnyTimeout(eventmask_t events, sysinterval_t timeout); + eventmask_t chEvtWaitAllTimeout(eventmask_t events, sysinterval_t timeout); +#endif +#ifdef __cplusplus +} +#endif + +#if (CH_CFG_OPTIMIZE_SPEED == FALSE) && (CH_CFG_USE_EVENTS_TIMEOUT == TRUE) +#define chEvtWaitOne(mask) chEvtWaitOneTimeout(mask, TIME_INFINITE) +#define chEvtWaitAny(mask) chEvtWaitAnyTimeout(mask, TIME_INFINITE) +#define chEvtWaitAll(mask) chEvtWaitAllTimeout(mask, TIME_INFINITE) +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes an Event Source. + * @note This function can be invoked before the kernel is initialized + * because it just prepares a @p event_source_t structure. + * + * @param[in] esp pointer to the @p event_source_t structure + * + * @init + */ +static inline void chEvtObjectInit(event_source_t *esp) { + + esp->next = (event_listener_t *)esp; +} + +/** + * @brief Registers an Event Listener on an Event Source. + * @details Once a thread has registered as listener on an event source it + * will be notified of all events broadcasted there. + * @note Multiple Event Listeners can specify the same bits to be ORed to + * different threads. + * + * @param[in] esp pointer to the @p event_source_t structure + * @param[out] elp pointer to the @p event_listener_t structure + * @param[in] events the mask of events to be ORed to the thread when + * the event source is broadcasted + * + * @api + */ +static inline void chEvtRegisterMask(event_source_t *esp, + event_listener_t *elp, + eventmask_t events) { + + chEvtRegisterMaskWithFlags(esp, elp, events, (eventflags_t)-1); +} + +/** + * @brief Registers an Event Listener on an Event Source. + * @note Multiple Event Listeners can use the same event identifier, the + * listener will share the callback function. + * + * @param[in] esp pointer to the @p event_source_t structure + * @param[out] elp pointer to the @p event_listener_t structure + * @param[in] event numeric identifier assigned to the Event Listener. + * The value must range between zero and the size, in bit, + * of the @p eventmask_t type minus one. + * + * @api + */ +static inline void chEvtRegister(event_source_t *esp, + event_listener_t *elp, + eventid_t event) { + + chEvtRegisterMask(esp, elp, EVENT_MASK(event)); +} + +/** + * @brief Verifies if there is at least one @p event_listener_t registered. + * + * @param[in] esp pointer to the @p event_source_t structure + * @return The event source status. + * + * @iclass + */ +static inline bool chEvtIsListeningI(event_source_t *esp) { + + return (bool)(esp != (event_source_t *)esp->next); +} + +/** + * @brief Signals all the Event Listeners registered on the specified Event + * Source. + * + * @param[in] esp pointer to the @p event_source_t structure + * + * @api + */ +static inline void chEvtBroadcast(event_source_t *esp) { + + chEvtBroadcastFlags(esp, (eventflags_t)0); +} + +/** + * @brief Signals all the Event Listeners registered on the specified Event + * Source. + * @post This function does not reschedule so a call to a rescheduling + * function must be performed before unlocking the kernel. Note that + * interrupt handlers always reschedule on exit so an explicit + * reschedule must not be performed in ISRs. + * + * @param[in] esp pointer to the @p event_source_t structure + * + * @iclass + */ +static inline void chEvtBroadcastI(event_source_t *esp) { + + chEvtBroadcastFlagsI(esp, (eventflags_t)0); +} + +/** + * @brief Adds (OR) a set of events to the current thread, this is + * @b much faster than using @p chEvtBroadcast() or @p chEvtSignal(). + * + * @param[in] events the events to be added + * @return The mask of currently pending events. + * + * @iclass + */ +static inline eventmask_t chEvtAddEventsI(eventmask_t events) { + + return currp->epending |= events; +} + +/** + * @brief Returns the events mask. + * @details The pending events mask is returned but not altered in any way. + * + * @return The pending events mask. + * + * @api + */ +static inline eventmask_t chEvtGetEventsX(void) { + + return currp->epending; +} + +#endif /* CH_CFG_USE_EVENTS == TRUE */ + +#endif /* CHEVENTS_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chmsg.h b/ChibiOS_20.3.2/os/rt/include/chmsg.h new file mode 100644 index 0000000..6bd110a --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chmsg.h @@ -0,0 +1,212 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chmsg.h + * @brief Messages macros and structures. + * + * @addtogroup messages + * @{ + */ + +#ifndef CHMSG_H +#define CHMSG_H + +#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + msg_t chMsgSend(thread_t *tp, msg_t msg); + thread_t *chMsgWaitS(void); + thread_t *chMsgWaitTimeoutS(sysinterval_t timeout); + thread_t *chMsgPollS(void); + void chMsgRelease(thread_t *tp, msg_t msg); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/** + * @brief Suspends the thread and waits for an incoming message. + * @post After receiving a message the function @p chMsgGet() must be + * called in order to retrieve the message and then @p chMsgRelease() + * must be invoked in order to acknowledge the reception and send + * the answer. + * @note If the message is a pointer then you can assume that the data + * pointed by the message is stable until you invoke @p chMsgRelease() + * because the sending thread is suspended until then. + * @note The reference counter of the sender thread is not increased, the + * returned pointer is a temporary reference. + * + * @return A pointer to the thread carrying the message. + * + * @api + */ +static inline thread_t *chMsgWait(void) { + thread_t *tp; + + chSysLock(); + tp = chMsgWaitS(); + chSysUnlock(); + + return tp; +} + +/** + * @brief Suspends the thread and waits for an incoming message or a + * timeout to occur. + * @post After receiving a message the function @p chMsgGet() must be + * called in order to retrieve the message and then @p chMsgRelease() + * must be invoked in order to acknowledge the reception and send + * the answer. + * @note If the message is a pointer then you can assume that the data + * pointed by the message is stable until you invoke @p chMsgRelease() + * because the sending thread is suspended until then. + * @note The reference counter of the sender thread is not increased, the + * returned pointer is a temporary reference. + * + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return A pointer to the thread carrying the message. + * @retval NULL if a timeout occurred. + * + * @api + */ +static inline thread_t *chMsgWaitTimeout(sysinterval_t timeout) { + thread_t *tp; + + chSysLock(); + tp = chMsgWaitTimeoutS(timeout); + chSysUnlock(); + + return tp; +} + +/** + * @brief Poll to check for an incoming message. + * @post If a message is available the function @p chMsgGet() must be + * called in order to retrieve the message and then @p chMsgRelease() + * must be invoked in order to acknowledge the reception and send + * the answer. + * @note If the message is a pointer then you can assume that the data + * pointed by the message is stable until you invoke @p chMsgRelease() + * because the sending thread is suspended until then. + * @note The reference counter of the sender thread is not increased, the + * returned pointer is a temporary reference. + * + * @return A pointer to the thread carrying the message. + * @retval NULL if no incoming message waiting. + * + * @api + */ +static inline thread_t *chMsgPoll(void) { + thread_t *tp; + + chSysLock(); + tp = chMsgPollS(); + chSysUnlock(); + + return tp; +} + +/** + * @brief Evaluates to @p true if the thread has pending messages. + * + * @param[in] tp pointer to the thread + * @return The pending messages status. + * + * @iclass + */ +static inline bool chMsgIsPendingI(thread_t *tp) { + + chDbgCheckClassI(); + + return (bool)(tp->msgqueue.next != (thread_t *)&tp->msgqueue); +} + +/** + * @brief Returns the message carried by the specified thread. + * @pre This function must be invoked immediately after exiting a call + * to @p chMsgWait(). + * + * @param[in] tp pointer to the thread + * @return The message carried by the sender. + * + * @api + */ +static inline msg_t chMsgGet(thread_t *tp) { + + chDbgAssert(tp->state == CH_STATE_SNDMSG, "invalid state"); + + return tp->u.sentmsg; +} + +/** + * @brief Releases the thread waiting on top of the messages queue. + * @pre Invoke this function only after a message has been received + * using @p chMsgWait(). + * + * @param[in] tp pointer to the thread + * @param[in] msg message to be returned to the sender + * + * @sclass + */ +static inline void chMsgReleaseS(thread_t *tp, msg_t msg) { + + chDbgCheckClassS(); + + chSchWakeupS(tp, msg); +} + +#endif /* CH_CFG_USE_MESSAGES == TRUE */ + +#endif /* CHMSG_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chmtx.h b/ChibiOS_20.3.2/os/rt/include/chmtx.h new file mode 100644 index 0000000..6fa17f7 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chmtx.h @@ -0,0 +1,168 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chmtx.h + * @brief Mutexes macros and structures. + * + * @addtogroup mutexes + * @{ + */ + +#ifndef CHMTX_H +#define CHMTX_H + +#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a mutex structure. + */ +typedef struct ch_mutex mutex_t; + +/** + * @brief Mutex structure. + */ +struct ch_mutex { + threads_queue_t queue; /**< @brief Queue of the threads sleeping + on this mutex. */ + thread_t *owner; /**< @brief Owner @p thread_t pointer or + @p NULL. */ + mutex_t *next; /**< @brief Next @p mutex_t into an + owner-list or @p NULL. */ +#if (CH_CFG_USE_MUTEXES_RECURSIVE == TRUE) || defined(__DOXYGEN__) + cnt_t cnt; /**< @brief Mutex recursion counter. */ +#endif +}; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Data part of a static mutex initializer. + * @details This macro should be used when statically initializing a mutex + * that is part of a bigger structure. + * + * @param[in] name the name of the mutex variable + */ +#if (CH_CFG_USE_MUTEXES_RECURSIVE == TRUE) || defined(__DOXYGEN__) +#define _MUTEX_DATA(name) {_THREADS_QUEUE_DATA(name.queue), NULL, NULL, 0} +#else +#define _MUTEX_DATA(name) {_THREADS_QUEUE_DATA(name.queue), NULL, NULL} +#endif + +/** + * @brief Static mutex initializer. + * @details Statically initialized mutexes require no explicit initialization + * using @p chMtxInit(). + * + * @param[in] name the name of the mutex variable + */ +#define MUTEX_DECL(name) mutex_t name = _MUTEX_DATA(name) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void chMtxObjectInit(mutex_t *mp); + void chMtxLock(mutex_t *mp); + void chMtxLockS(mutex_t *mp); + bool chMtxTryLock(mutex_t *mp); + bool chMtxTryLockS(mutex_t *mp); + void chMtxUnlock(mutex_t *mp); + void chMtxUnlockS(mutex_t *mp); + void chMtxUnlockAll(void); + void chMtxUnlockAllS(void); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Returns @p true if the mutex queue contains at least a waiting + * thread. + * + * @param[out] mp pointer to a @p mutex_t structure + * @return The mutex queue status. + * + * @sclass + */ +static inline bool chMtxQueueNotEmptyS(mutex_t *mp) { + + chDbgCheckClassS(); + + return queue_notempty(&mp->queue); +} + +/** + * @brief Returns the mutex owner thread. + * + * @param[out] mp pointer to a @p mutex_t structure + * @return The owner thread. + * @retval NULL if the mutex is not owned. + * + * @iclass + */ +static inline thread_t *chMtxGetOwnerI(mutex_t *mp) { + + chDbgCheckClassI(); + + return mp->owner; +} + +/** + * @brief Returns the next mutex in the mutexes stack of the current thread. + * + * @return A pointer to the next mutex in the stack. + * @retval NULL if the stack is empty. + * + * @xclass + */ +static inline mutex_t *chMtxGetNextMutexX(void) { + + return chThdGetSelfX()->mtxlist; +} + +#endif /* CH_CFG_USE_MUTEXES == TRUE */ + +#endif /* CHMTX_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chregistry.h b/ChibiOS_20.3.2/os/rt/include/chregistry.h new file mode 100644 index 0000000..4c36fe7 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chregistry.h @@ -0,0 +1,185 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chregistry.h + * @brief Threads registry macros and structures. + * + * @addtogroup registry + * @{ + */ + +#ifndef CHREGISTRY_H +#define CHREGISTRY_H + +#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief ChibiOS/RT memory signature record. + */ +typedef struct { + char identifier[4]; /**< @brief Always set to "main". */ + uint8_t zero; /**< @brief Must be zero. */ + uint8_t size; /**< @brief Size of this structure. */ + uint16_t version; /**< @brief Encoded ChibiOS/RT version. */ + uint8_t ptrsize; /**< @brief Size of a pointer. */ + uint8_t timesize; /**< @brief Size of a @p systime_t. */ + uint8_t threadsize; /**< @brief Size of a @p thread_t. */ + uint8_t off_prio; /**< @brief Offset of @p prio field. */ + uint8_t off_ctx; /**< @brief Offset of @p ctx field. */ + uint8_t off_newer; /**< @brief Offset of @p newer field. */ + uint8_t off_older; /**< @brief Offset of @p older field. */ + uint8_t off_name; /**< @brief Offset of @p name field. */ + uint8_t off_stklimit; /**< @brief Offset of @p stklimit field.*/ + uint8_t off_state; /**< @brief Offset of @p state field. */ + uint8_t off_flags; /**< @brief Offset of @p flags field. */ + uint8_t off_refs; /**< @brief Offset of @p refs field. */ + uint8_t off_preempt; /**< @brief Offset of @p preempt field. */ + uint8_t off_time; /**< @brief Offset of @p time field. */ +} chdebug_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Removes a thread from the registry list. + * @note This macro is not meant for use in application code. + * + * @param[in] tp thread to remove from the registry + */ +#define REG_REMOVE(tp) { \ + (tp)->older->newer = (tp)->newer; \ + (tp)->newer->older = (tp)->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)->newer = (thread_t *)&ch.rlist; \ + (tp)->older = ch.rlist.older; \ + (tp)->older->newer = (tp); \ + ch.rlist.older = (tp); \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + extern ROMCONST chdebug_t ch_debug; + thread_t *chRegFirstThread(void); + thread_t *chRegNextThread(thread_t *tp); + thread_t *chRegFindThreadByName(const char *name); + thread_t *chRegFindThreadByPointer(thread_t *tp); + thread_t *chRegFindThreadByWorkingArea(stkalign_t *wa); +#ifdef __cplusplus +} +#endif + +#endif /* CH_CFG_USE_REGISTRY == TRUE */ + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Sets the current thread name. + * @pre This function only stores the pointer to the name if the option + * @p CH_CFG_USE_REGISTRY is enabled else no action is performed. + * + * @param[in] name thread name as a zero terminated string + * + * @api + */ +static inline void chRegSetThreadName(const char *name) { + +#if CH_CFG_USE_REGISTRY == TRUE + ch.rlist.current->name = name; +#else + (void)name; +#endif +} + +/** + * @brief Returns the name of the specified thread. + * @pre This function only returns the pointer to the name if the option + * @p CH_CFG_USE_REGISTRY is enabled else @p NULL is returned. + * + * @param[in] tp pointer to the thread + * + * @return Thread name as a zero terminated string. + * @retval NULL if the thread name has not been set. + * + */ +static inline const char *chRegGetThreadNameX(thread_t *tp) { + +#if CH_CFG_USE_REGISTRY == TRUE + return tp->name; +#else + (void)tp; + return NULL; +#endif +} + +/** + * @brief Changes the name of the specified thread. + * @pre This function only stores the pointer to the name if the option + * @p CH_CFG_USE_REGISTRY is enabled else no action is performed. + * + * @param[in] tp pointer to the thread + * @param[in] name thread name as a zero terminated string + * + * @xclass + */ +static inline void chRegSetThreadNameX(thread_t *tp, const char *name) { + +#if CH_CFG_USE_REGISTRY == TRUE + tp->name = name; +#else + (void)tp; + (void)name; +#endif +} + +#endif /* CHREGISTRY_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chrestrictions.h b/ChibiOS_20.3.2/os/rt/include/chrestrictions.h new file mode 100644 index 0000000..7c1840f --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chrestrictions.h @@ -0,0 +1,118 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chrestrictions.h + * @brief Licensing restrictions header. + * + * @addtogroup rt_restrictions + * @details This module is responsible for applying license-related + * restrictions to the configuration options. + * @{ + */ + +#ifndef CHRESTRICTIONS_H +#define CHRESTRICTIONS_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* License checks.*/ +#if !defined(CH_CUSTOMER_LIC_RT) || !defined(CH_LICENSE_FEATURES) +#error "malformed chlicense.h" +#endif + +#if CH_CUSTOMER_LIC_RT == FALSE +#error "ChibiOS/RT not licensed" +#endif + +#if (CH_LICENSE_FEATURES != CH_FEATURES_FULL) && \ + (CH_LICENSE_FEATURES != CH_FEATURES_INTERMEDIATE) && \ + (CH_LICENSE_FEATURES != CH_FEATURES_BASIC) +#error "invalid CH_LICENSE_FEATURES setting" +#endif + +/* Restrictions in basic and intermediate modes.*/ +#if (CH_LICENSE_FEATURES == CH_FEATURES_INTERMEDIATE) || \ + (CH_LICENSE_FEATURES == CH_FEATURES_BASIC) + +/* System tick limited to 1000hz.*/ +#if CH_CFG_ST_FREQUENCY > 1000 +#undef CH_CFG_ST_FREQUENCY +#define CH_CFG_ST_FREQUENCY 1000 +#endif + +/* Restricted subsystems.*/ +#undef CH_DBG_STATISTICS +#undef CH_DBG_TRACE_MASK + +#define CH_DBG_STATISTICS FALSE +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED + +#endif /* (CH_LICENSE_FEATURES == CH_FEATURES_INTERMEDIATE) || + (CH_LICENSE_FEATURES == CH_FEATURES_BASIC) */ + +/* Restrictions in basic mode.*/ +#if CH_LICENSE_FEATURES == CH_FEATURES_BASIC + +/* Tick-Less mode restricted.*/ +#undef CH_CFG_ST_TIMEDELTA +#define CH_CFG_ST_TIMEDELTA 0 + +/* Restricted subsystems.*/ +#undef CH_CFG_USE_TM +#undef CH_CFG_USE_MUTEXES +#undef CH_CFG_USE_CONDVARS +#undef CH_CFG_USE_DYNAMIC + +#define CH_CFG_USE_TM FALSE +#define CH_CFG_USE_MUTEXES FALSE +#define CH_CFG_USE_CONDVARS FALSE +#define CH_CFG_USE_DYNAMIC FALSE + +#endif /* CH_LICENSE_FEATURES == CH_FEATURES_BASIC */ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CHRESTRICTIONS_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chschd.h b/ChibiOS_20.3.2/os/rt/include/chschd.h new file mode 100644 index 0000000..edff108 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chschd.h @@ -0,0 +1,716 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chschd.h + * @brief Scheduler macros and structures. + * + * @addtogroup scheduler + * @{ + */ + +#ifndef CHSCHD_H +#define CHSCHD_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/** + * @name Wakeup status codes + * @{ + */ +#define MSG_OK (msg_t)0 /**< @brief Normal wakeup message. */ +#define MSG_TIMEOUT (msg_t)-1 /**< @brief Wakeup caused by a timeout + condition. */ +#define MSG_RESET (msg_t)-2 /**< @brief Wakeup caused by a reset + condition. */ +/** @} */ + +/** + * @name Priority constants + * @{ + */ +#define NOPRIO (tprio_t)0 /**< @brief Ready list header + priority. */ +#define IDLEPRIO (tprio_t)1 /**< @brief Idle priority. */ +#define LOWPRIO (tprio_t)2 /**< @brief Lowest priority. */ +#define NORMALPRIO (tprio_t)128 /**< @brief Normal priority. */ +#define HIGHPRIO (tprio_t)255 /**< @brief Highest priority. */ +/** @} */ + +/** + * @name Thread states + * @{ + */ +#define CH_STATE_READY (tstate_t)0 /**< @brief Waiting on the + ready list. */ +#define CH_STATE_CURRENT (tstate_t)1 /**< @brief Currently running. */ +#define CH_STATE_WTSTART (tstate_t)2 /**< @brief Just created. */ +#define CH_STATE_SUSPENDED (tstate_t)3 /**< @brief Suspended state. */ +#define CH_STATE_QUEUED (tstate_t)4 /**< @brief On a queue. */ +#define CH_STATE_WTSEM (tstate_t)5 /**< @brief On a semaphore. */ +#define CH_STATE_WTMTX (tstate_t)6 /**< @brief On a mutex. */ +#define CH_STATE_WTCOND (tstate_t)7 /**< @brief On a cond.variable.*/ +#define CH_STATE_SLEEPING (tstate_t)8 /**< @brief Sleeping. */ +#define CH_STATE_WTEXIT (tstate_t)9 /**< @brief Waiting a thread. */ +#define CH_STATE_WTOREVT (tstate_t)10 /**< @brief One event. */ +#define CH_STATE_WTANDEVT (tstate_t)11 /**< @brief Several events. */ +#define CH_STATE_SNDMSGQ (tstate_t)12 /**< @brief Sending a message, + in queue. */ +#define CH_STATE_SNDMSG (tstate_t)13 /**< @brief Sent a message, + waiting answer. */ +#define CH_STATE_WTMSG (tstate_t)14 /**< @brief Waiting for a + message. */ +#define CH_STATE_FINAL (tstate_t)15 /**< @brief Thread terminated. */ + +/** + * @brief Thread states as array of strings. + * @details Each element in an array initialized with this macro can be + * indexed using the numeric thread state values. + */ +#define CH_STATE_NAMES \ + "READY", "CURRENT", "WTSTART", "SUSPENDED", "QUEUED", "WTSEM", "WTMTX", \ + "WTCOND", "SLEEPING", "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", \ + "SNDMSG", "WTMSG", "FINAL" +/** @} */ + +/** + * @name Thread flags and attributes + * @{ + */ +#define CH_FLAG_MODE_MASK (tmode_t)3U /**< @brief Thread memory mode + mask. */ +#define CH_FLAG_MODE_STATIC (tmode_t)0U /**< @brief Static thread. */ +#define CH_FLAG_MODE_HEAP (tmode_t)1U /**< @brief Thread allocated + from a Memory Heap. */ +#define CH_FLAG_MODE_MPOOL (tmode_t)2U /**< @brief Thread allocated + from a Memory Pool. */ +#define CH_FLAG_TERMINATE (tmode_t)4U /**< @brief Termination requested + flag. */ +/** @} */ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Generic threads single link list, it works like a stack. + */ +struct ch_threads_list { + thread_t *next; /**< @brief Next in the list/queue. */ +}; + +/** + * @brief Generic threads bidirectional linked list header and element. + */ +struct ch_threads_queue { + thread_t *next; /**< @brief Next in the list/queue. */ + thread_t *prev; /**< @brief Previous in the queue. */ +}; + +/** + * @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 this structure. + */ +struct ch_thread { + threads_queue_t queue; /**< @brief Threads queue header. */ + tprio_t prio; /**< @brief Thread priority. */ + struct port_context ctx; /**< @brief Processor context. */ +#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) + thread_t *newer; /**< @brief Newer registry element. */ + thread_t *older; /**< @brief Older registry element. */ +#endif + /* End of the fields shared with the ReadyList structure. */ +#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) + /** + * @brief Thread name or @p NULL. + */ + const char *name; +#endif +#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \ + defined(__DOXYGEN__) + /** + * @brief Working area base address. + * @note This pointer is used for stack overflow checks and for + * dynamic threading. + */ + stkalign_t *wabase; +#endif + /** + * @brief Current thread state. + */ + tstate_t state; + /** + * @brief Various thread flags. + */ + tmode_t flags; +#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) + /** + * @brief References to this thread. + */ + trefs_t refs; +#endif + /** + * @brief Number of ticks remaining to this thread. + */ +#if (CH_CFG_TIME_QUANTUM > 0) || defined(__DOXYGEN__) + tslices_t ticks; +#endif +#if (CH_DBG_THREADS_PROFILING == TRUE) || defined(__DOXYGEN__) + /** + * @brief Thread consumed time in ticks. + * @note This field can overflow. + */ + volatile systime_t 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; + /** + * @brief Pointer to a generic thread reference object. + * @note This field is used to get a pointer to a synchronization + * object and is valid when the thread is in @p CH_STATE_SUSPENDED + * state. + */ + thread_reference_t *wttrp; +#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) + /** + * @brief Thread sent message. + */ + msg_t sentmsg; +#endif +#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__) + /** + * @brief Pointer to a generic semaphore object. + * @note This field is used to get a pointer to a synchronization + * object and is valid when the thread is in @p CH_STATE_WTSEM + * state. + */ + struct ch_semaphore *wtsemp; +#endif +#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) + /** + * @brief Pointer to a generic mutex object. + * @note This field is used to get a pointer to a synchronization + * object and is valid when the thread is in @p CH_STATE_WTMTX + * state. + */ + struct ch_mutex *wtmtxp; +#endif +#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) + /** + * @brief Enabled events mask. + * @note This field is only valid while the thread is in the + * @p CH_STATE_WTOREVT or @p CH_STATE_WTANDEVT states. + */ + eventmask_t ewmask; +#endif + } u; +#if (CH_CFG_USE_WAITEXIT == TRUE) || defined(__DOXYGEN__) + /** + * @brief Termination waiting list. + */ + threads_list_t waiting; +#endif +#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) + /** + * @brief Messages queue. + */ + threads_queue_t msgqueue; +#endif +#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) + /** + * @brief Pending events mask. + */ + eventmask_t epending; +#endif +#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) + /** + * @brief List of the mutexes owned by this thread. + * @note The list is terminated by a @p NULL in this field. + */ + struct ch_mutex *mtxlist; + /** + * @brief Thread's own, non-inherited, priority. + */ + tprio_t realprio; +#endif +#if ((CH_CFG_USE_DYNAMIC == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE)) || \ + defined(__DOXYGEN__) + /** + * @brief Memory Pool where the thread workspace is returned. + */ + void *mpool; +#endif +#if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__) + /** + * @brief Thread statistics. + */ + time_measurement_t stats; +#endif +#if defined(CH_CFG_THREAD_EXTRA_FIELDS) + /* Extra fields defined in chconf.h.*/ + CH_CFG_THREAD_EXTRA_FIELDS +#endif +}; + +/** + * @extends virtual_timers_list_t + * + * @brief Virtual Timer descriptor structure. + */ +struct ch_virtual_timer { + virtual_timer_t *next; /**< @brief Next timer in the list. */ + virtual_timer_t *prev; /**< @brief Previous timer in the list. */ + sysinterval_t delta; /**< @brief Time delta before timeout. */ + vtfunc_t func; /**< @brief Timer callback function + pointer. */ + void *par; /**< @brief Timer callback function + parameter. */ +}; + +/** + * @brief Virtual timers list header. + * @note The timers list is implemented as a double link bidirectional list + * in order to make the unlink time constant, the reset of a virtual + * timer is often used in the code. + */ +struct ch_virtual_timers_list { + virtual_timer_t *next; /**< @brief Next timer in the delta + list. */ + virtual_timer_t *prev; /**< @brief Last timer in the delta + list. */ + sysinterval_t delta; /**< @brief Must be initialized to -1. */ +#if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__) + volatile systime_t systime; /**< @brief System Time counter. */ +#endif +#if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__) + /** + * @brief System time of the last tick event. + */ + systime_t lasttime; /**< @brief System time of the last + tick event. */ +#endif +}; + +/** + * @extends threads_queue_t + */ +struct ch_ready_list { + threads_queue_t queue; /**< @brief Threads queue. */ + tprio_t prio; /**< @brief This field must be + initialized to zero. */ + struct port_context ctx; /**< @brief Not used, present because + offsets. */ +#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) + thread_t *newer; /**< @brief Newer registry element. */ + thread_t *older; /**< @brief Older registry element. */ +#endif + /* End of the fields shared with the thread_t structure.*/ + thread_t *current; /**< @brief The currently running + thread. */ +}; + +/** + * @brief System debug data structure. + */ +struct ch_system_debug { + /** + * @brief Pointer to the panic message. + * @details This pointer is meant to be accessed through the debugger, it is + * written once and then the system is halted. + * @note Accesses to this pointer must never be optimized out so the + * field itself is declared volatile. + */ + const char * volatile panic_msg; +#if (CH_DBG_SYSTEM_STATE_CHECK == TRUE) || defined(__DOXYGEN__) + /** + * @brief ISR nesting level. + */ + cnt_t isr_cnt; + /** + * @brief Lock nesting level. + */ + cnt_t lock_cnt; +#endif +#if (CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED) || defined(__DOXYGEN__) + /** + * @brief Public trace buffer. + */ + ch_trace_buffer_t trace_buffer; +#endif +}; + +/** + * @brief System data structure. + * @note This structure contain all the data areas used by the OS except + * stacks. + */ +struct ch_system { + /** + * @brief Ready list header. + */ + ready_list_t rlist; + /** + * @brief Virtual timers delta list header. + */ + virtual_timers_list_t vtlist; + /** + * @brief System debug. + */ + system_debug_t dbg; + /** + * @brief Main thread descriptor. + */ + thread_t mainthread; +#if (CH_CFG_USE_TM == TRUE) || defined(__DOXYGEN__) + /** + * @brief Time measurement calibration data. + */ + tm_calibration_t tm; +#endif +#if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__) + /** + * @brief Global kernel statistics. + */ + kernel_stats_t kernel_stats; +#endif + CH_CFG_SYSTEM_EXTRA_FIELDS +}; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Returns the priority of the first thread on the given ready list. + * + * @notapi + */ +#define firstprio(rlp) ((rlp)->next->prio) + +/** + * @brief Current thread pointer access macro. + * @note This macro is not meant to be used in the application code but + * only from within the kernel, use @p chThdGetSelfX() instead. + */ +#define currp ch.rlist.current + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern ch_system_t ch; +#endif + +/* + * Scheduler APIs. + */ +#ifdef __cplusplus +extern "C" { +#endif + void _scheduler_init(void); + thread_t *chSchReadyI(thread_t *tp); + thread_t *chSchReadyAheadI(thread_t *tp); + void chSchGoSleepS(tstate_t newstate); + msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout); + void chSchWakeupS(thread_t *ntp, msg_t msg); + void chSchRescheduleS(void); + bool chSchIsPreemptionRequired(void); + void chSchDoRescheduleBehind(void); + void chSchDoRescheduleAhead(void); + void chSchDoReschedule(void); +#if CH_CFG_OPTIMIZE_SPEED == FALSE + void queue_prio_insert(thread_t *tp, threads_queue_t *tqp); + void queue_insert(thread_t *tp, threads_queue_t *tqp); + thread_t *queue_fifo_remove(threads_queue_t *tqp); + thread_t *queue_lifo_remove(threads_queue_t *tqp); + thread_t *queue_dequeue(thread_t *tp); + void list_insert(thread_t *tp, threads_list_t *tlp); + thread_t *list_remove(threads_list_t *tlp); +#endif /* CH_CFG_OPTIMIZE_SPEED == FALSE */ +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Threads list initialization. + * + * @param[in] tlp pointer to the threads list object + * + * @notapi + */ +static inline void list_init(threads_list_t *tlp) { + + tlp->next = (thread_t *)tlp; +} + +/** + * @brief Evaluates to @p true if the specified threads list is empty. + * + * @param[in] tlp pointer to the threads list object + * @return The status of the list. + * + * @notapi + */ +static inline bool list_isempty(threads_list_t *tlp) { + + return (bool)(tlp->next == (thread_t *)tlp); +} + +/** + * @brief Evaluates to @p true if the specified threads list is not empty. + * + * @param[in] tlp pointer to the threads list object + * @return The status of the list. + * + * @notapi + */ +static inline bool list_notempty(threads_list_t *tlp) { + + return (bool)(tlp->next != (thread_t *)tlp); +} + +/** + * @brief Threads queue initialization. + * + * @param[in] tqp pointer to the threads queue object + * + * @notapi + */ +static inline void queue_init(threads_queue_t *tqp) { + + tqp->next = (thread_t *)tqp; + tqp->prev = (thread_t *)tqp; +} + +/** + * @brief Evaluates to @p true if the specified threads queue is empty. + * + * @param[in] tqp pointer to the threads queue object + * @return The status of the queue. + * + * @notapi + */ +static inline bool queue_isempty(const threads_queue_t *tqp) { + + return (bool)(tqp->next == (const thread_t *)tqp); +} + +/** + * @brief Evaluates to @p true if the specified threads queue is not empty. + * + * @param[in] tqp pointer to the threads queue object + * @return The status of the queue. + * + * @notapi + */ +static inline bool queue_notempty(const threads_queue_t *tqp) { + + return (bool)(tqp->next != (const thread_t *)tqp); +} + +/* If the performance code path has been chosen then all the following + functions are inlined into the various kernel modules.*/ +#if CH_CFG_OPTIMIZE_SPEED == TRUE +static inline void list_insert(thread_t *tp, threads_list_t *tlp) { + + tp->queue.next = tlp->next; + tlp->next = tp; +} + +static inline thread_t *list_remove(threads_list_t *tlp) { + + thread_t *tp = tlp->next; + tlp->next = tp->queue.next; + + return tp; +} + +static inline void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) { + + thread_t *cp = (thread_t *)tqp; + do { + cp = cp->queue.next; + } while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio)); + tp->queue.next = cp; + tp->queue.prev = cp->queue.prev; + tp->queue.prev->queue.next = tp; + cp->queue.prev = tp; +} + +static inline void queue_insert(thread_t *tp, threads_queue_t *tqp) { + + tp->queue.next = (thread_t *)tqp; + tp->queue.prev = tqp->prev; + tp->queue.prev->queue.next = tp; + tqp->prev = tp; +} + +static inline thread_t *queue_fifo_remove(threads_queue_t *tqp) { + thread_t *tp = tqp->next; + + tqp->next = tp->queue.next; + tqp->next->queue.prev = (thread_t *)tqp; + + return tp; +} + +static inline thread_t *queue_lifo_remove(threads_queue_t *tqp) { + thread_t *tp = tqp->prev; + + tqp->prev = tp->queue.prev; + tqp->prev->queue.next = (thread_t *)tqp; + + return tp; +} + +static inline thread_t *queue_dequeue(thread_t *tp) { + + tp->queue.prev->queue.next = tp->queue.next; + tp->queue.next->queue.prev = tp->queue.prev; + + return tp; +} +#endif /* CH_CFG_OPTIMIZE_SPEED == TRUE */ + +/** + * @brief Determines if the current thread must reschedule. + * @details This function returns @p true if there is a ready thread with + * higher priority. + * + * @return The priorities situation. + * @retval false if rescheduling is not necessary. + * @retval true if there is a ready thread at higher priority. + * + * @iclass + */ +static inline bool chSchIsRescRequiredI(void) { + + chDbgCheckClassI(); + + return firstprio(&ch.rlist.queue) > currp->prio; +} + +/** + * @brief Determines if yielding is possible. + * @details This function returns @p true if there is a ready thread with + * equal or higher priority. + * + * @return The priorities situation. + * @retval false if yielding is not possible. + * @retval true if there is a ready thread at equal or higher priority. + * + * @sclass + */ +static inline bool chSchCanYieldS(void) { + + chDbgCheckClassS(); + + return firstprio(&ch.rlist.queue) >= currp->prio; +} + +/** + * @brief Yields the time slot. + * @details Yields the CPU control to the next thread in the ready list with + * equal or higher priority, if any. + * + * @sclass + */ +static inline void chSchDoYieldS(void) { + + chDbgCheckClassS(); + + if (chSchCanYieldS()) { + chSchDoRescheduleBehind(); + } +} + +/** + * @brief Inline-able preemption code. + * @details This is the common preemption code, this function must be invoked + * exclusively from the port layer. + * + * @special + */ +static inline void chSchPreemption(void) { + tprio_t p1 = firstprio(&ch.rlist.queue); + tprio_t p2 = currp->prio; + +#if CH_CFG_TIME_QUANTUM > 0 + if (currp->ticks > (tslices_t)0) { + if (p1 > p2) { + chSchDoRescheduleAhead(); + } + } + else { + if (p1 >= p2) { + chSchDoRescheduleBehind(); + } + } +#else /* CH_CFG_TIME_QUANTUM == 0 */ + if (p1 > p2) { + chSchDoRescheduleAhead(); + } +#endif /* CH_CFG_TIME_QUANTUM == 0 */ +} + +#endif /* CHSCHD_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chsem.h b/ChibiOS_20.3.2/os/rt/include/chsem.h new file mode 100644 index 0000000..62406ee --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chsem.h @@ -0,0 +1,200 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chsem.h + * @brief Semaphores macros and structures. + * + * @addtogroup semaphores + * @{ + */ + +#ifndef CHSEM_H +#define CHSEM_H + +#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Semaphore structure. + */ +typedef struct ch_semaphore { + threads_queue_t queue; /**< @brief Queue of the threads sleeping + on this semaphore. */ + cnt_t cnt; /**< @brief The semaphore counter. */ +} semaphore_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Data part of a static semaphore initializer. + * @details This macro should be used when statically initializing a semaphore + * that is part of a bigger structure. + * + * @param[in] name the name of the semaphore variable + * @param[in] n the counter initial value, this value must be + * non-negative + */ +#define _SEMAPHORE_DATA(name, n) {_THREADS_QUEUE_DATA(name.queue), n} + +/** + * @brief Static semaphore initializer. + * @details Statically initialized semaphores require no explicit + * initialization using @p chSemInit(). + * + * @param[in] name the name of the semaphore variable + * @param[in] n the counter initial value, this value must be + * non-negative + */ +#define SEMAPHORE_DECL(name, n) semaphore_t name = _SEMAPHORE_DATA(name, n) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void chSemObjectInit(semaphore_t *sp, cnt_t n); + void chSemResetWithMessage(semaphore_t *sp, cnt_t n, msg_t msg); + void chSemResetWithMessageI(semaphore_t *sp, cnt_t n, msg_t msg); + msg_t chSemWait(semaphore_t *sp); + msg_t chSemWaitS(semaphore_t *sp); + msg_t chSemWaitTimeout(semaphore_t *sp, sysinterval_t timeout); + msg_t chSemWaitTimeoutS(semaphore_t *sp, sysinterval_t timeout); + void chSemSignal(semaphore_t *sp); + void chSemSignalI(semaphore_t *sp); + void chSemAddCounterI(semaphore_t *sp, cnt_t n); + msg_t chSemSignalWait(semaphore_t *sps, semaphore_t *spw); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Performs a reset operation on the semaphore. + * @post After invoking this function all the threads waiting on the + * semaphore, if any, are released and the semaphore counter is set + * to the specified, non negative, value. + * @note This function implicitly sends @p MSG_RESET as message. + * + * @param[in] sp pointer to a @p semaphore_t structure + * @param[in] n the new value of the semaphore counter. The value must + * be non-negative. + * + * @api + */ +static inline void chSemReset(semaphore_t *sp, cnt_t n) { + + chSemResetWithMessage(sp, n, MSG_RESET); +} + +/** + * @brief Performs a reset operation on the semaphore. + * @post After invoking this function all the threads waiting on the + * semaphore, if any, are released and the semaphore counter is set + * to the specified, non negative, value. + * @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. + * @note This function implicitly sends @p MSG_RESET as message. + * + * @param[in] sp pointer to a @p semaphore_t structure + * @param[in] n the new value of the semaphore counter. The value must + * be non-negative. + * + * @iclass + */ +static inline void chSemResetI(semaphore_t *sp, cnt_t n) { + + chSemResetWithMessageI(sp, n, MSG_RESET); +} + +/** + * @brief Decreases the semaphore counter. + * @details This macro can be used when the counter is known to be positive. + * + * @param[in] sp pointer to a @p semaphore_t structure + * + * @iclass + */ +static inline void chSemFastWaitI(semaphore_t *sp) { + + chDbgCheckClassI(); + + sp->cnt--; +} + +/** + * @brief Increases the semaphore counter. + * @details This macro can be used when the counter is known to be not + * negative. + * + * @param[in] sp pointer to a @p semaphore_t structure + * + * @iclass + */ +static inline void chSemFastSignalI(semaphore_t *sp) { + + chDbgCheckClassI(); + + sp->cnt++; +} + +/** + * @brief Returns the semaphore counter current value. + * + * @param[in] sp pointer to a @p semaphore_t structure + * @return The semaphore counter value. + * + * @iclass + */ +static inline cnt_t chSemGetCounterI(const semaphore_t *sp) { + + chDbgCheckClassI(); + + return sp->cnt; +} + +#endif /* CH_CFG_USE_SEMAPHORES == TRUE */ + +#endif /* CHSEM_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chstats.h b/ChibiOS_20.3.2/os/rt/include/chstats.h new file mode 100644 index 0000000..7225ea1 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chstats.h @@ -0,0 +1,105 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chstats.h + * @brief Statistics module macros and structures. + * + * @addtogroup statistics + * @{ + */ + +#ifndef CHSTATS_H +#define CHSTATS_H + +#if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +#if CH_CFG_USE_TM == FALSE +#error "CH_DBG_STATISTICS requires CH_CFG_USE_TM" +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a kernel statistics structure. + */ +typedef struct { + ucnt_t n_irq; /**< @brief Number of IRQs. */ + ucnt_t n_ctxswc; /**< @brief Number of context switches. */ + time_measurement_t m_crit_thd; /**< @brief Measurement of threads + critical zones duration. */ + time_measurement_t m_crit_isr; /**< @brief Measurement of ISRs critical + zones duration. */ +} kernel_stats_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void _stats_init(void); + void _stats_increase_irq(void); + void _stats_ctxswc(thread_t *ntp, thread_t *otp); + void _stats_start_measure_crit_thd(void); + void _stats_stop_measure_crit_thd(void); + void _stats_start_measure_crit_isr(void); + void _stats_stop_measure_crit_isr(void); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#else /* CH_DBG_STATISTICS == FALSE */ + +/* Stub functions for when the statistics module is disabled. */ +#define _stats_increase_irq() +#define _stats_ctxswc(old, new) +#define _stats_start_measure_crit_thd() +#define _stats_stop_measure_crit_thd() +#define _stats_start_measure_crit_isr() +#define _stats_stop_measure_crit_isr() + +#endif /* CH_DBG_STATISTICS == FALSE */ + +#endif /* CHSTATS_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chsys.h b/ChibiOS_20.3.2/os/rt/include/chsys.h new file mode 100644 index 0000000..afd2f36 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chsys.h @@ -0,0 +1,469 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chsys.h + * @brief System related macros and structures. + * + * @addtogroup system + * @{ + */ + +#ifndef CHSYS_H +#define CHSYS_H + +/*lint -sem(chSysHalt, r_no)*/ + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/** + * @name Masks of executable integrity checks. + * @{ + */ +#define CH_INTEGRITY_RLIST 1U +#define CH_INTEGRITY_VTLIST 2U +#define CH_INTEGRITY_REGISTRY 4U +#define CH_INTEGRITY_PORT 8U +/** @} */ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @name ISRs abstraction macros + */ +/** + * @brief Priority level validation macro. + * @details This macro determines if the passed value is a valid priority + * level for the underlying architecture. + * + * @param[in] prio the priority level + * @return Priority range result. + * @retval false if the priority is invalid or if the architecture + * does not support priorities. + * @retval true if the priority is valid. + */ +#if defined(PORT_IRQ_IS_VALID_PRIORITY) || defined(__DOXYGEN__) +#define CH_IRQ_IS_VALID_PRIORITY(prio) \ + PORT_IRQ_IS_VALID_PRIORITY(prio) +#else +#define CH_IRQ_IS_VALID_PRIORITY(prio) false +#endif + +/** + * @brief Priority level validation macro. + * @details This macro determines if the passed value is a valid priority + * level that cannot preempt the kernel critical zone. + * + * @param[in] prio the priority level + * @return Priority range result. + * @retval false if the priority is invalid or if the architecture + * does not support priorities. + * @retval true if the priority is valid. + */ +#if defined(PORT_IRQ_IS_VALID_KERNEL_PRIORITY) || defined(__DOXYGEN__) +#define CH_IRQ_IS_VALID_KERNEL_PRIORITY(prio) \ + PORT_IRQ_IS_VALID_KERNEL_PRIORITY(prio) +#else +#define CH_IRQ_IS_VALID_KERNEL_PRIORITY(prio) false +#endif + +/** + * @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(); \ + CH_CFG_IRQ_PROLOGUE_HOOK(); \ + _stats_increase_irq(); \ + _trace_isr_enter(__func__); \ + _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(); \ + _trace_isr_leave(__func__); \ + CH_CFG_IRQ_EPILOGUE_HOOK(); \ + PORT_IRQ_EPILOGUE() + +/** + * @brief Standard normal IRQ handler declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + * + * @special + */ +#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id) +/** @} */ + +/** + * @name Fast ISRs abstraction macros + */ +/** + * @brief Standard fast IRQ handler declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + * @note Not all architectures support fast interrupts. + * + * @special + */ +#define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id) +/** @} */ + +/** + * @name Time conversion utilities for the realtime counter + * @{ + */ +/** + * @brief Seconds to realtime counter. + * @details Converts from seconds to realtime counter cycles. + * @note The macro assumes that @p freq >= @p 1. + * + * @param[in] freq clock frequency, in Hz, of the realtime counter + * @param[in] sec number of seconds + * @return The number of cycles. + * + * @api + */ +#define S2RTC(freq, sec) ((freq) * (sec)) + +/** + * @brief Milliseconds to realtime counter. + * @details Converts from milliseconds to realtime counter cycles. + * @note The result is rounded upward to the next millisecond boundary. + * @note The macro assumes that @p freq >= @p 1000. + * + * @param[in] freq clock frequency, in Hz, of the realtime counter + * @param[in] msec number of milliseconds + * @return The number of cycles. + * + * @api + */ +#define MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec)) + +/** + * @brief Microseconds to realtime counter. + * @details Converts from microseconds to realtime counter cycles. + * @note The result is rounded upward to the next microsecond boundary. + * @note The macro assumes that @p freq >= @p 1000000. + * + * @param[in] freq clock frequency, in Hz, of the realtime counter + * @param[in] usec number of microseconds + * @return The number of cycles. + * + * @api + */ +#define US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec)) + +/** + * @brief Realtime counter cycles to seconds. + * @details Converts from realtime counter cycles number to seconds. + * @note The result is rounded up to the next second boundary. + * @note The macro assumes that @p freq >= @p 1. + * + * @param[in] freq clock frequency, in Hz, of the realtime counter + * @param[in] n number of cycles + * @return The number of seconds. + * + * @api + */ +#define RTC2S(freq, n) ((((n) - 1UL) / (freq)) + 1UL) + +/** + * @brief Realtime counter cycles to milliseconds. + * @details Converts from realtime counter cycles number to milliseconds. + * @note The result is rounded up to the next millisecond boundary. + * @note The macro assumes that @p freq >= @p 1000. + * + * @param[in] freq clock frequency, in Hz, of the realtime counter + * @param[in] n number of cycles + * @return The number of milliseconds. + * + * @api + */ +#define RTC2MS(freq, n) ((((n) - 1UL) / ((freq) / 1000UL)) + 1UL) + +/** + * @brief Realtime counter cycles to microseconds. + * @details Converts from realtime counter cycles number to microseconds. + * @note The result is rounded up to the next microsecond boundary. + * @note The macro assumes that @p freq >= @p 1000000. + * + * @param[in] freq clock frequency, in Hz, of the realtime counter + * @param[in] n number of cycles + * @return The number of microseconds. + * + * @api + */ +#define RTC2US(freq, n) ((((n) - 1UL) / ((freq) / 1000000UL)) + 1UL) +/** @} */ + +/** + * @brief Returns the current value of the system real time counter. + * @note This function is only available if the port layer supports the + * option @p PORT_SUPPORTS_RT. + * + * @return The value of the system realtime counter of + * type rtcnt_t. + * + * @xclass + */ +#if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__) +#define chSysGetRealtimeCounterX() (rtcnt_t)port_rt_get_counter_value() +#endif + +/** + * @brief Performs a context switch. + * @note Not a user function, it is meant to be invoked by the scheduler + * itself or from within the port layer. + * + * @param[in] ntp the thread to be switched in + * @param[in] otp the thread to be switched out + * + * @special + */ +#define chSysSwitch(ntp, otp) { \ + \ + _trace_switch(ntp, otp); \ + _stats_ctxswc(ntp, otp); \ + CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp); \ + port_switch(ntp, otp); \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern stkalign_t ch_idle_thread_wa[]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void chSysInit(void); + bool chSysIntegrityCheckI(unsigned testmask); + void chSysTimerHandlerI(void); + syssts_t chSysGetStatusAndLockX(void); + void chSysRestoreStatusX(syssts_t sts); +#if PORT_SUPPORTS_RT == TRUE + bool chSysIsCounterWithinX(rtcnt_t cnt, rtcnt_t start, rtcnt_t end); + void chSysPolledDelayX(rtcnt_t cycles); +#endif +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Raises the system interrupt priority mask to the maximum level. + * @details All the maskable interrupt sources are disabled regardless their + * hardware priority. + * @note Do not invoke this API from within a kernel lock. + * + * @special + */ +static inline void chSysDisable(void) { + + port_disable(); + _dbg_check_disable(); +} + +/** + * @brief Raises the system interrupt priority mask to system level. + * @details The interrupt sources that should not be able to preempt the kernel + * are disabled, interrupt sources with higher priority are still + * enabled. + * @note Do not invoke this API from within a kernel lock. + * @note This API is no replacement for @p chSysLock(), the @p chSysLock() + * could do more than just disable the interrupts. + * + * @special + */ +static inline void chSysSuspend(void) { + + port_suspend(); + _dbg_check_suspend(); +} + +/** + * @brief Lowers the system interrupt priority mask to user level. + * @details All the interrupt sources are enabled. + * @note Do not invoke this API from within a kernel lock. + * @note This API is no replacement for @p chSysUnlock(), the + * @p chSysUnlock() could do more than just enable the interrupts. + * + * @special + */ +static inline void chSysEnable(void) { + + _dbg_check_enable(); + port_enable(); +} + +/** + * @brief Enters the kernel lock state. + * + * @special + */ +static inline void chSysLock(void) { + + port_lock(); + _stats_start_measure_crit_thd(); + _dbg_check_lock(); +} + +/** + * @brief Leaves the kernel lock state. + * + * @special + */ +static inline void chSysUnlock(void) { + + _dbg_check_unlock(); + _stats_stop_measure_crit_thd(); + + /* The following condition can be triggered by the use of i-class functions + in a critical section not followed by a chSchRescheduleS(), this means + that the current thread has a lower priority than the next thread in + the ready list.*/ + chDbgAssert((ch.rlist.queue.next == (thread_t *)&ch.rlist.queue) || + (ch.rlist.current->prio >= ch.rlist.queue.next->prio), + "priority order violation"); + + port_unlock(); +} + +/** + * @brief Enters the kernel lock state 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.
+ * It is good practice to invoke this API before invoking any I-class + * syscall from an interrupt handler. + * @note This API must be invoked exclusively from interrupt handlers. + * + * @special + */ +static inline void chSysLockFromISR(void) { + + port_lock_from_isr(); + _stats_start_measure_crit_isr(); + _dbg_check_lock_from_isr(); +} + +/** + * @brief Leaves the kernel lock state 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.
+ * It is good practice to invoke this API after invoking any I-class + * syscall from an interrupt handler. + * @note This API must be invoked exclusively from interrupt handlers. + * + * @special + */ +static inline void chSysUnlockFromISR(void) { + + _dbg_check_unlock_from_isr(); + _stats_stop_measure_crit_isr(); + port_unlock_from_isr(); +} + +/** + * @brief Unconditionally enters the kernel lock state. + * @note Can be called without previous knowledge of the current lock state. + * The final state is "s-locked". + * + * @special + */ +static inline void chSysUnconditionalLock(void) { + + if (port_irq_enabled(port_get_irq_status())) { + chSysLock(); + } +} + +/** + * @brief Unconditionally leaves the kernel lock state. + * @note Can be called without previous knowledge of the current lock state. + * The final state is "normal". + * + * @special + */ +static inline void chSysUnconditionalUnlock(void) { + + if (!port_irq_enabled(port_get_irq_status())) { + chSysUnlock(); + } +} + +#if (CH_CFG_NO_IDLE_THREAD == FALSE) || defined(__DOXYGEN__) +/** + * @brief Returns a pointer to the idle thread. + * @pre In order to use this function the option @p CH_CFG_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. + * + * @xclass + */ +static inline thread_t *chSysGetIdleThreadX(void) { + + return ch.rlist.queue.prev; +} +#endif /* CH_CFG_NO_IDLE_THREAD == FALSE */ + +#endif /* CHSYS_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chsystypes.h b/ChibiOS_20.3.2/os/rt/include/chsystypes.h new file mode 100644 index 0000000..7ca9159 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chsystypes.h @@ -0,0 +1,130 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chsystypes.h + * @brief System types header. + * + * @addtogroup scheduler + * @{ + */ + +#ifndef CHSYSTYPES_H +#define CHSYSTYPES_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @extends threads_queue_t + * + * @brief Type of a thread structure. + */ +typedef struct ch_thread thread_t; + +/** + * @brief Type of a thread reference. + */ +typedef thread_t * thread_reference_t; + +/** + * @brief Type of a generic threads single link list, it works like a stack. + */ +typedef struct ch_threads_list threads_list_t; + +/** + * @extends threads_list_t + * + * @brief Type of a generic threads bidirectional linked list header and element. + */ +typedef struct ch_threads_queue threads_queue_t; + +/** + * @extends threads_queue_t + * + * @brief Type of a ready list header. + */ +typedef struct ch_ready_list ready_list_t; + +/** + * @brief Type of a Virtual Timer callback function. + */ +typedef void (*vtfunc_t)(void *p); + +/** + * @brief Type of a Virtual Timer structure. + */ +typedef struct ch_virtual_timer virtual_timer_t; + +/** + * @brief Type of virtual timers list header. + */ +typedef struct ch_virtual_timers_list virtual_timers_list_t; + +/** + * @brief Type of a system debug structure. + */ +typedef struct ch_system_debug system_debug_t; + +/** + * @brief Type of system data structure. + */ +typedef struct ch_system ch_system_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Utility to make the parameter a quoted string. + */ +#define __CH_STRINGIFY(a) #a + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CHSYSTYPES_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chthreads.h b/ChibiOS_20.3.2/os/rt/include/chthreads.h new file mode 100644 index 0000000..74f8952 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chthreads.h @@ -0,0 +1,440 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chthreads.h + * @brief Threads module macros and structures. + * + * @addtogroup threads + * @{ + */ + +#ifndef CHTHREADS_H +#define CHTHREADS_H + +/*lint -sem(chThdExit, r_no) -sem(chThdExitS, r_no)*/ + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Thread function. + */ +typedef void (*tfunc_t)(void *p); + +/** + * @brief Type of a thread descriptor. + */ +typedef struct { + /** + * @brief Thread name. + */ + const char *name; + /** + * @brief Pointer to the working area base. + */ + stkalign_t *wbase; + /** + * @brief End of the working area. + */ + stkalign_t *wend; + /** + * @brief Thread priority. + */ + tprio_t prio; + /** + * @brief Thread function pointer. + */ + tfunc_t funcp; + /** + * @brief Thread argument. + */ + void *arg; +} thread_descriptor_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @name Threads queues + */ +/** + * @brief Data part of a static threads queue object initializer. + * @details This macro should be used when statically initializing a threads + * queue that is part of a bigger structure. + * + * @param[in] name the name of the threads queue variable + */ +#define _THREADS_QUEUE_DATA(name) {(thread_t *)&name, (thread_t *)&name} + +/** + * @brief Static threads queue object initializer. + * @details Statically initialized threads queues require no explicit + * initialization using @p queue_init(). + * + * @param[in] name the name of the threads queue variable + */ +#define _THREADS_QUEUE_DECL(name) \ + threads_queue_t name = _THREADS_QUEUE_DATA(name) +/** @} */ + +/** + * @name Working Areas + */ +/** + * @brief Calculates the total Working Area size. + * + * @param[in] n the stack size to be assigned to the thread + * @return The total used memory in bytes. + * + * @api + */ +#define THD_WORKING_AREA_SIZE(n) \ + MEM_ALIGN_NEXT(sizeof(thread_t) + PORT_WA_SIZE(n), PORT_STACK_ALIGN) + +/** + * @brief Static working area allocation. + * @details This macro is used to allocate a static thread working area + * aligned as both position and size. + * + * @param[in] s the name to be assigned to the stack array + * @param[in] n the stack size to be assigned to the thread + * + * @api + */ +#define THD_WORKING_AREA(s, n) PORT_WORKING_AREA(s, n) + +/** + * @brief Base of a working area casted to the correct type. + * + * @param[in] s name of the working area + */ +#define THD_WORKING_AREA_BASE(s) ((stkalign_t *)(s)) + +/** + * @brief End of a working area casted to the correct type. + * + * @param[in] s name of the working area + */ +#define THD_WORKING_AREA_END(s) (THD_WORKING_AREA_BASE(s) + \ + (sizeof (s) / sizeof (stkalign_t))) +/** @} */ + +/** + * @name Threads abstraction macros + */ +/** + * @brief Thread declaration macro. + * @note Thread declarations should be performed using this macro because + * the port layer could define optimizations for thread functions. + */ +#define THD_FUNCTION(tname, arg) PORT_THD_FUNCTION(tname, arg) +/** @} */ + +/** + * @name Macro Functions + * @{ + */ +/** + * @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. + * @note Use of this macro for large values is not secure because + * integer overflows, make sure your value can be correctly + * converted. + * + * @param[in] sec time in seconds, must be different from zero + * + * @api + */ +#define chThdSleepSeconds(sec) chThdSleep(TIME_S2I(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. + * @note Use of this macro for large values is not secure because + * integer overflows, make sure your value can be correctly + * converted. + * + * @param[in] msec time in milliseconds, must be different from zero + * + * @api + */ +#define chThdSleepMilliseconds(msec) chThdSleep(TIME_MS2I(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. + * @note Use of this macro for large values is not secure because + * integer overflows, make sure your value can be correctly + * converted. + * + * @param[in] usec time in microseconds, must be different from zero + * + * @api + */ +#define chThdSleepMicroseconds(usec) chThdSleep(TIME_US2I(usec)) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + thread_t *_thread_init(thread_t *tp, const char *name, tprio_t prio); +#if CH_DBG_FILL_THREADS == TRUE + void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v); +#endif + thread_t *chThdCreateSuspendedI(const thread_descriptor_t *tdp); + thread_t *chThdCreateSuspended(const thread_descriptor_t *tdp); + thread_t *chThdCreateI(const thread_descriptor_t *tdp); + thread_t *chThdCreate(const thread_descriptor_t *tdp); + thread_t *chThdCreateStatic(void *wsp, size_t size, + tprio_t prio, tfunc_t pf, void *arg); + thread_t *chThdStart(thread_t *tp); +#if CH_CFG_USE_REGISTRY == TRUE + thread_t *chThdAddRef(thread_t *tp); + void chThdRelease(thread_t *tp); +#endif + void chThdExit(msg_t msg); + void chThdExitS(msg_t msg); +#if CH_CFG_USE_WAITEXIT == TRUE + msg_t chThdWait(thread_t *tp); +#endif + tprio_t chThdSetPriority(tprio_t newprio); + void chThdTerminate(thread_t *tp); + msg_t chThdSuspendS(thread_reference_t *trp); + msg_t chThdSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout); + void chThdResumeI(thread_reference_t *trp, msg_t msg); + void chThdResumeS(thread_reference_t *trp, msg_t msg); + void chThdResume(thread_reference_t *trp, msg_t msg); + msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout); + void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg); + void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg); + void chThdSleep(sysinterval_t time); + void chThdSleepUntil(systime_t time); + systime_t chThdSleepUntilWindowed(systime_t prev, systime_t next); + void chThdYield(void); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + + /** + * @brief Returns a pointer to the current @p thread_t. + * + * @return A pointer to the current thread. + * + * @xclass + */ +static inline thread_t *chThdGetSelfX(void) { + + return ch.rlist.current; +} + +/** + * @brief Returns the current thread priority. + * @note Can be invoked in any context. + * + * @return The current thread priority. + * + * @xclass + */ +static inline tprio_t chThdGetPriorityX(void) { + + return chThdGetSelfX()->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. + * + * @param[in] tp pointer to the thread + * @return The number of consumed system ticks. + * + * @xclass + */ +#if (CH_DBG_THREADS_PROFILING == TRUE) || defined(__DOXYGEN__) +static inline systime_t chThdGetTicksX(thread_t *tp) { + + return tp->time; +} +#endif + +#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \ + defined(__DOXYGEN__) +/** + * @brief Returns the working area base of the specified thread. + * + * @param[in] tp pointer to the thread + * @return The working area base pointer. + * + * @xclass + */ +static inline stkalign_t *chThdGetWorkingAreaX(thread_t *tp) { + + return tp->wabase; +} +#endif /* CH_DBG_ENABLE_STACK_CHECK == TRUE */ + +/** + * @brief Verifies if the specified thread is in the @p CH_STATE_FINAL state. + * + * @param[in] tp pointer to the thread + * @retval true thread terminated. + * @retval false thread not terminated. + * + * @xclass + */ +static inline bool chThdTerminatedX(thread_t *tp) { + + return (bool)(tp->state == CH_STATE_FINAL); +} + +/** + * @brief Verifies if the current thread has a termination request pending. + * + * @retval true termination request pending. + * @retval false termination request not pending. + * + * @xclass + */ +static inline bool chThdShouldTerminateX(void) { + + return (bool)((chThdGetSelfX()->flags & CH_FLAG_TERMINATE) != (tmode_t)0); +} + +/** + * @brief Resumes a thread created with @p chThdCreateI(). + * + * @param[in] tp pointer to the thread + * @return The pointer to the @p thread_t structure allocated for + * the thread into the working space area. + * + * @iclass + */ +static inline thread_t *chThdStartI(thread_t *tp) { + + chDbgAssert(tp->state == CH_STATE_WTSTART, "wrong state"); + + return chSchReadyI(tp); +} + +/** + * @brief Suspends the invoking thread for the specified number of ticks. + * + * @param[in] ticks 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 + */ +static inline void chThdSleepS(sysinterval_t ticks) { + + chDbgCheck(ticks != TIME_IMMEDIATE); + + (void) chSchGoSleepTimeoutS(CH_STATE_SLEEPING, ticks); +} + +/** + * @brief Initializes a threads queue object. + * + * @param[out] tqp pointer to the threads queue object + * + * @init + */ +static inline void chThdQueueObjectInit(threads_queue_t *tqp) { + + queue_init(tqp); +} + +/** + * @brief Evaluates to @p true if the specified queue is empty. + * + * @param[out] tqp pointer to the threads queue object + * @return The queue status. + * @retval false if the queue is not empty. + * @retval true if the queue is empty. + * + * @iclass + */ +static inline bool chThdQueueIsEmptyI(threads_queue_t *tqp) { + + chDbgCheckClassI(); + + return queue_isempty(tqp); +} + +/** + * @brief Dequeues and wakes up one thread from the threads queue object. + * @details Dequeues one thread from the queue without checking if the queue + * is empty. + * @pre The queue must contain at least an object. + * + * @param[in] tqp pointer to the threads queue object + * @param[in] msg the message code + * + * @iclass + */ +static inline void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) { + thread_t *tp; + + chDbgAssert(queue_notempty(tqp), "empty queue"); + + tp = queue_fifo_remove(tqp); + + chDbgAssert(tp->state == CH_STATE_QUEUED, "invalid state"); + + tp->u.rdymsg = msg; + (void) chSchReadyI(tp); +} + +#endif /* CHTHREADS_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chtime.h b/ChibiOS_20.3.2/os/rt/include/chtime.h new file mode 100644 index 0000000..c6c1de8 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chtime.h @@ -0,0 +1,492 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chtime.h + * @brief Time and intervals macros and structures. + * + * @addtogroup time_intervals + * @details This module is responsible for handling of system time and time + * intervals. + * @{ + */ + +#ifndef CHTIME_H +#define CHTIME_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/** + * @name Special time constants + * @{ + */ +/** + * @brief Zero interval 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 ((sysinterval_t)0) + +/** + * @brief Infinite interval specification for all functions with a timeout + * specification. + * @note Not all functions accept @p TIME_INFINITE as timeout parameter, + * see the specific function documentation. + */ +#define TIME_INFINITE ((sysinterval_t)-1) + +/** + * @brief Maximum interval constant usable as timeout. + */ +#define TIME_MAX_INTERVAL ((sysinterval_t)-2) + +/** + * @brief Maximum system of system time before it wraps. + */ +#define TIME_MAX_SYSTIME ((systime_t)-1) +/** @} */ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if (CH_CFG_ST_RESOLUTION != 16) && (CH_CFG_ST_RESOLUTION != 32) && \ + (CH_CFG_ST_RESOLUTION != 64) +#error "invalid CH_CFG_ST_RESOLUTION specified, must be 16, 32 or 64" +#endif + +#if CH_CFG_ST_FREQUENCY < 10 +#error "invalid CH_CFG_ST_FREQUENCY specified, must be >= 10" +#endif + +#if (CH_CFG_INTERVALS_SIZE != 16) && (CH_CFG_INTERVALS_SIZE != 32) && \ + (CH_CFG_INTERVALS_SIZE != 64) +#error "invalid CH_CFG_INTERVALS_SIZE specified, must be 16, 32 or 64" +#endif + +#if (CH_CFG_TIME_TYPES_SIZE != 16) && (CH_CFG_TIME_TYPES_SIZE != 32) +#error "invalid CH_CFG_TIME_TYPES_SIZE specified, must be 16 or 32" +#endif + +#if CH_CFG_INTERVALS_SIZE < CH_CFG_ST_RESOLUTION +#error "CH_CFG_INTERVALS_SIZE must be >= CH_CFG_ST_RESOLUTION" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of system time. + * @note It is selectable in configuration between 16, 32 or 64 bits. + */ +#if (CH_CFG_ST_RESOLUTION == 64) || defined(__DOXYGEN__) +typedef uint64_t systime_t; +#elif CH_CFG_ST_RESOLUTION == 32 +typedef uint32_t systime_t; +#elif CH_CFG_ST_RESOLUTION == 16 +typedef uint16_t systime_t; +#endif + +/** + * @brief Type of time interval. + * @note It is selectable in configuration between 16, 32 or 64 bits. + */ +#if (CH_CFG_INTERVALS_SIZE == 64) || defined(__DOXYGEN__) +typedef uint64_t sysinterval_t; +#elif CH_CFG_INTERVALS_SIZE == 32 +typedef uint32_t sysinterval_t; +#elif CH_CFG_INTERVALS_SIZE == 16 +typedef uint16_t sysinterval_t; +#endif + +#if (CH_CFG_TIME_TYPES_SIZE == 32) || defined(__DOXYGEN__) +/** + * @brief Type of seconds. + * @note It is selectable in configuration between 16 or 32 bits. + */ +typedef uint32_t time_secs_t; + +/** + * @brief Type of milliseconds. + * @note It is selectable in configuration between 16 or 32 bits. + */ +typedef uint32_t time_msecs_t; + +/** + * @brief Type of microseconds. + * @note It is selectable in configuration between 16 or 32 bits. + */ +typedef uint32_t time_usecs_t; + +/** + * @brief Type of time conversion variable. + * @note This type must have double width than other time types, it is + * only used internally for conversions. + */ +typedef uint64_t time_conv_t; + +#else +typedef uint16_t time_secs_t; +typedef uint16_t time_msecs_t; +typedef uint16_t time_usecs_t; +typedef uint32_t time_conv_t; +#endif + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @name Fast time conversion utilities + * @{ + */ +/** + * @brief Seconds to time interval. + * @details Converts from seconds to system ticks number. + * @note The result is rounded upward to the next tick boundary. + * @note Use of this macro for large values is not secure because + * integer overflows, make sure your value can be correctly + * converted. + * + * @param[in] secs number of seconds + * @return The number of ticks. + * + * @api + */ +#define TIME_S2I(secs) \ + ((sysinterval_t)((time_conv_t)(secs) * (time_conv_t)CH_CFG_ST_FREQUENCY)) + +/** + * @brief Milliseconds to time interval. + * @details Converts from milliseconds to system ticks number. + * @note The result is rounded upward to the next tick boundary. + * @note Use of this macro for large values is not secure because + * integer overflows, make sure your value can be correctly + * converted. + * + * @param[in] msecs number of milliseconds + * @return The number of ticks. + * + * @api + */ +#define TIME_MS2I(msecs) \ + ((sysinterval_t)((((time_conv_t)(msecs) * \ + (time_conv_t)CH_CFG_ST_FREQUENCY) + \ + (time_conv_t)999) / (time_conv_t)1000)) + +/** + * @brief Microseconds to time interval. + * @details Converts from microseconds to system ticks number. + * @note The result is rounded upward to the next tick boundary. + * @note Use of this macro for large values is not secure because + * integer overflows, make sure your value can be correctly + * converted. + * + * @param[in] usecs number of microseconds + * @return The number of ticks. + * + * @api + */ +#define TIME_US2I(usecs) \ + ((sysinterval_t)((((time_conv_t)(usecs) * \ + (time_conv_t)CH_CFG_ST_FREQUENCY) + \ + (time_conv_t)999999) / (time_conv_t)1000000)) + +/** + * @brief Time interval to seconds. + * @details Converts from system ticks number to seconds. + * @note The result is rounded up to the next second boundary. + * @note Use of this macro for large values is not secure because + * integer overflows, make sure your value can be correctly + * converted. + * + * @param[in] interval interval in ticks + * @return The number of seconds. + * + * @api + */ +#define TIME_I2S(interval) \ + (time_secs_t)(((time_conv_t)(interval) + \ + (time_conv_t)CH_CFG_ST_FREQUENCY - \ + (time_conv_t)1) / (time_conv_t)CH_CFG_ST_FREQUENCY) + +/** + * @brief Time interval to milliseconds. + * @details Converts from system ticks number to milliseconds. + * @note The result is rounded up to the next millisecond boundary. + * @note Use of this macro for large values is not secure because + * integer overflows, make sure your value can be correctly + * converted. + * + * @param[in] interval interval in ticks + * @return The number of milliseconds. + * + * @api + */ +#define TIME_I2MS(interval) \ + (time_msecs_t)((((time_conv_t)(interval) * (time_conv_t)1000) + \ + (time_conv_t)CH_CFG_ST_FREQUENCY - (time_conv_t)1) / \ + (time_conv_t)CH_CFG_ST_FREQUENCY) + +/** + * @brief Time interval to microseconds. + * @details Converts from system ticks number to microseconds. + * @note The result is rounded up to the next microsecond boundary. + * @note Use of this macro for large values is not secure because + * integer overflows, make sure your value can be correctly + * converted. + * + * @param[in] interval interval in ticks + * @return The number of microseconds. + * + * @api + */ +#define TIME_I2US(interval) \ + (time_msecs_t)((((time_conv_t)(interval) * (time_conv_t)1000000) + \ + (time_conv_t)CH_CFG_ST_FREQUENCY - (time_conv_t)1) / \ + (time_conv_t)CH_CFG_ST_FREQUENCY) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* + * Virtual Timers APIs. + */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @name Secure time conversion utilities + * @{ + */ +/** + * @brief Seconds to time interval. + * @details Converts from seconds to system ticks number. + * @note The result is rounded upward to the next tick boundary. + * + * @param[in] secs number of seconds + * @return The number of ticks. + * + * @special + */ +static inline sysinterval_t chTimeS2I(time_secs_t secs) { + time_conv_t ticks; + + ticks = (time_conv_t)secs * (time_conv_t)CH_CFG_ST_FREQUENCY; + + chDbgAssert(ticks <= (time_conv_t)TIME_MAX_INTERVAL, + "conversion overflow"); + + return (sysinterval_t)ticks; +} + +/** + * @brief Milliseconds to time interval. + * @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. + * + * @special + */ +static inline sysinterval_t chTimeMS2I(time_msecs_t msec) { + time_conv_t ticks; + + ticks = (((time_conv_t)msec * (time_conv_t)CH_CFG_ST_FREQUENCY) + + (time_conv_t)999) / (time_conv_t)1000; + + chDbgAssert(ticks <= (time_conv_t)TIME_MAX_INTERVAL, + "conversion overflow"); + + return (sysinterval_t)ticks; +} + +/** + * @brief Microseconds to time interval. + * @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. + * + * @special + */ +static inline sysinterval_t chTimeUS2I(time_usecs_t usec) { + time_conv_t ticks; + + ticks = (((time_conv_t)usec * (time_conv_t)CH_CFG_ST_FREQUENCY) + + (time_conv_t)999999) / (time_conv_t)1000000; + + chDbgAssert(ticks <= (time_conv_t)TIME_MAX_INTERVAL, + "conversion overflow"); + + return (sysinterval_t)ticks; +} + +/** + * @brief Time interval to seconds. + * @details Converts from system interval to seconds. + * @note The result is rounded up to the next second boundary. + * + * @param[in] interval interval in ticks + * @return The number of seconds. + * + * @special + */ +static inline time_secs_t chTimeI2S(sysinterval_t interval) { + time_conv_t secs; + + secs = ((time_conv_t)interval + + (time_conv_t)CH_CFG_ST_FREQUENCY - + (time_conv_t)1) / (time_conv_t)CH_CFG_ST_FREQUENCY; + + chDbgAssert(secs < (time_conv_t)((time_secs_t)-1), + "conversion overflow"); + + return (time_secs_t)secs; +} + +/** + * @brief Time interval to milliseconds. + * @details Converts from system interval to milliseconds. + * @note The result is rounded up to the next millisecond boundary. + * + * @param[in] interval interval in ticks + * @return The number of milliseconds. + * + * @special + */ +static inline time_msecs_t chTimeI2MS(sysinterval_t interval) { + time_conv_t msecs; + + msecs = (((time_conv_t)interval * (time_conv_t)1000) + + (time_conv_t)CH_CFG_ST_FREQUENCY - (time_conv_t)1) / + (time_conv_t)CH_CFG_ST_FREQUENCY; + + chDbgAssert(msecs < (time_conv_t)((time_msecs_t)-1), + "conversion overflow"); + + return (time_msecs_t)msecs; +} + +/** + * @brief Time interval to microseconds. + * @details Converts from system interval to microseconds. + * @note The result is rounded up to the next microsecond boundary. + * + * @param[in] interval interval in ticks + * @return The number of microseconds. + * + * @special + */ +static inline time_usecs_t chTimeI2US(sysinterval_t interval) { + time_conv_t usecs; + + usecs = (((time_conv_t)interval * (time_conv_t)1000000) + + (time_conv_t)CH_CFG_ST_FREQUENCY - (time_conv_t)1) / + (time_conv_t)CH_CFG_ST_FREQUENCY; + + chDbgAssert(usecs <= (time_conv_t)((time_usecs_t)-1), + "conversion overflow"); + + return (time_usecs_t)usecs; +} + +/** + * @brief Adds an interval to a system time returning a system time. + * + * @param[in] systime base system time + * @param[in] interval interval to be added + * @return The new system time. + * + * @xclass + */ +static inline systime_t chTimeAddX(systime_t systime, + sysinterval_t interval) { + +#if CH_CFG_ST_RESOLUTION != CH_CFG_INTERVALS_SIZE + chDbgCheck(interval <= (sysinterval_t)TIME_MAX_SYSTIME); +#endif + + return systime + (systime_t)interval; +} + +/** + * @brief Subtracts two system times returning an interval. + * + * @param[in] start first system time + * @param[in] end second system time + * @return The interval representing the time difference. + * + * @xclass + */ +static inline sysinterval_t chTimeDiffX(systime_t start, systime_t end) { + + /*lint -save -e9033 [10.8] This cast is required by the operation, it is + known that the destination type can be wider.*/ + return (sysinterval_t)((systime_t)(end - start)); + /*lint -restore*/ +} + +/** + * @brief Checks if the specified time is within the specified time range. + * @note When start==end then the function returns always false because the + * time window has zero size. + * + * @param[in] time the time to be verified + * @param[in] start the start of the time window (inclusive) + * @param[in] end the end of the time window (non inclusive) + * @retval true current time within the specified time window. + * @retval false current time not within the specified time window. + * + * @xclass + */ +static inline bool chTimeIsInRangeX(systime_t time, + systime_t start, + systime_t end) { + + return (bool)((systime_t)((systime_t)time - (systime_t)start) < + (systime_t)((systime_t)end - (systime_t)start)); +} + +/** @} */ + +#endif /* CHTIME_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chtm.h b/ChibiOS_20.3.2/os/rt/include/chtm.h new file mode 100644 index 0000000..f068251 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chtm.h @@ -0,0 +1,109 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chtm.h + * @brief Time Measurement module macros and structures. + * + * @addtogroup time_measurement + * @{ + */ + +#ifndef CHTM_H +#define CHTM_H + +#if (CH_CFG_USE_TM == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if PORT_SUPPORTS_RT == FALSE +#error "CH_CFG_USE_TM requires PORT_SUPPORTS_RT" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a time measurement calibration data. + */ +typedef struct { + /** + * @brief Measurement calibration value. + */ + rtcnt_t offset; +} tm_calibration_t; + +/** + * @brief Type of a Time Measurement object. + * @note The maximum measurable time period depends on the implementation + * of the realtime counter and its clock frequency. + * @note The measurement is not 100% cycle-accurate, it can be in excess + * of few cycles depending on the compiler and target architecture. + * @note Interrupts can affect measurement if the measurement is performed + * with interrupts enabled. + */ +typedef struct { + rtcnt_t best; /**< @brief Best measurement. */ + rtcnt_t worst; /**< @brief Worst measurement. */ + rtcnt_t last; /**< @brief Last measurement. */ + ucnt_t n; /**< @brief Number of measurements. */ + rttime_t cumulative; /**< @brief Cumulative measurement. */ +} time_measurement_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void _tm_init(void); + void chTMObjectInit(time_measurement_t *tmp); + NOINLINE void chTMStartMeasurementX(time_measurement_t *tmp); + NOINLINE void chTMStopMeasurementX(time_measurement_t *tmp); + NOINLINE void chTMChainMeasurementToX(time_measurement_t *tmp1, + time_measurement_t *tmp2); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CH_CFG_USE_TM == TRUE */ + +#endif /* CHTM_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chtrace.h b/ChibiOS_20.3.2/os/rt/include/chtrace.h new file mode 100644 index 0000000..c0a58ac --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chtrace.h @@ -0,0 +1,256 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chtrace.h + * @brief Tracer macros and structures. + * + * @addtogroup trace + * @{ + */ + +#ifndef CHTRACE_H +#define CHTRACE_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/** + * @name Trace record types + * @{ + */ +#define CH_TRACE_TYPE_UNUSED 0U +#define CH_TRACE_TYPE_SWITCH 1U +#define CH_TRACE_TYPE_ISR_ENTER 2U +#define CH_TRACE_TYPE_ISR_LEAVE 3U +#define CH_TRACE_TYPE_HALT 4U +#define CH_TRACE_TYPE_USER 5U +/** @} */ + +/** + * @name Events to trace + * @{ + */ +#define CH_DBG_TRACE_MASK_DISABLED 255U +#define CH_DBG_TRACE_MASK_NONE 0U +#define CH_DBG_TRACE_MASK_SWITCH 1U +#define CH_DBG_TRACE_MASK_ISR 2U +#define CH_DBG_TRACE_MASK_HALT 4U +#define CH_DBG_TRACE_MASK_USER 8U +#define CH_DBG_TRACE_MASK_SLOW (CH_DBG_TRACE_MASK_SWITCH | \ + CH_DBG_TRACE_MASK_HALT | \ + CH_DBG_TRACE_MASK_USER) +#define CH_DBG_TRACE_MASK_ALL (CH_DBG_TRACE_MASK_SWITCH | \ + CH_DBG_TRACE_MASK_ISR | \ + CH_DBG_TRACE_MASK_HALT | \ + CH_DBG_TRACE_MASK_USER) +/** @} */ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Debug related settings + * @{ + */ +/** + * @brief Trace buffer entries. + */ +#if !defined(CH_DBG_TRACE_MASK) || defined(__DOXYGEN__) +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED +#endif + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_BUFFER_SIZE) || defined(__DOXYGEN__) +#define CH_DBG_TRACE_BUFFER_SIZE 128 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +#if (CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED) || defined(__DOXYGEN__) +/*lint -save -e46 [6.1] An uint32_t is required.*/ +/** + * @brief Trace buffer record. + */ +typedef struct { + /** + * @brief Record type. + */ + uint32_t type:3; + /** + * @brief Switched out thread state. + */ + uint32_t state:5; + /** + * @brief Accurate time stamp. + * @note This field only available if the post supports + * @p PORT_SUPPORTS_RT else it is set to zero. + */ + uint32_t rtstamp:24; + /** + * @brief System time stamp of the switch event. + */ + systime_t time; + union { + /** + * @brief Structure representing a context switch. + */ + struct { + /** + * @brief Switched in thread. + */ + thread_t *ntp; + /** + * @brief Object where going to sleep. + */ + void *wtobjp; + } sw; + /** + * @brief Structure representing an ISR enter. + */ + struct { + /** + * @brief ISR function name taken using @p __func__. + */ + const char *name; + } isr; + /** + * @brief Structure representing an halt. + */ + struct { + /** + * @brief Halt error string. + */ + const char *reason; + } halt; + /** + * @brief User trace structure. + */ + struct { + /** + * @brief Trace user parameter 1. + */ + void *up1; + /** + * @brief Trace user parameter 2. + */ + void *up2; + } user; + } u; +} ch_trace_event_t; +/*lint -restore*/ + +/** + * @brief Trace buffer header. + */ +typedef struct { + /** + * @brief Suspended trace sources mask. + */ + uint16_t suspended; + /** + * @brief Trace buffer size (entries). + */ + uint16_t size; + /** + * @brief Pointer to the buffer front. + */ + ch_trace_event_t *ptr; + /** + * @brief Ring buffer. + */ + ch_trace_event_t buffer[CH_DBG_TRACE_BUFFER_SIZE]; +} ch_trace_buffer_t; +#endif /* CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED */ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/* When a trace feature is disabled the associated functions are replaced by + an empty macro. Note that the macros can be externally redefined in + order to interface 3rd parties tracing tools.*/ +#if CH_DBG_TRACE_MASK == CH_DBG_TRACE_MASK_DISABLED +#if !defined(_trace_init) +#define _trace_init() +#endif +#if !defined(_trace_switch) +#define _trace_switch(ntp, otp) +#endif +#if !defined(_trace_isr_enter) +#define _trace_isr_enter(isr) +#endif +#if !defined(_trace_isr_leave) +#define _trace_isr_leave(isr) +#endif +#if !defined(_trace_halt) +#define _trace_halt(reason) +#endif +#if !defined(chDbgWriteTraceI) +#define chDbgWriteTraceI(up1, up2) +#endif +#if !defined(chDbgWriteTrace) +#define chDbgWriteTrace(up1, up2) +#endif +#endif /* CH_DBG_TRACE_MASK == CH_DBG_TRACE_MASK_DISABLED */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +#if (CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED) || defined(__DOXYGEN__) + void _trace_init(void); + void _trace_switch(thread_t *ntp, thread_t *otp); + void _trace_isr_enter(const char *isr); + void _trace_isr_leave(const char *isr); + void _trace_halt(const char *reason); + void chDbgWriteTraceI(void *up1, void *up2); + void chDbgWriteTrace(void *up1, void *up2); + void chDbgSuspendTraceI(uint16_t mask); + void chDbgSuspendTrace(uint16_t mask); + void chDbgResumeTraceI(uint16_t mask); + void chDbgResumeTrace(uint16_t mask); +#endif /* CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED */ +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CHTRACE_H */ + +/** @} */ diff --git a/ChibiOS_20.3.2/os/rt/include/chvt.h b/ChibiOS_20.3.2/os/rt/include/chvt.h new file mode 100644 index 0000000..ed1c512 --- /dev/null +++ b/ChibiOS_20.3.2/os/rt/include/chvt.h @@ -0,0 +1,362 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file rt/include/chvt.h + * @brief Time and Virtual Timers module macros and structures. + * + * @addtogroup time + * @{ + */ + +#ifndef CHVT_H +#define CHVT_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if (CH_CFG_ST_TIMEDELTA < 0) || (CH_CFG_ST_TIMEDELTA == 1) +#error "invalid CH_CFG_ST_TIMEDELTA specified, must " \ + "be zero or greater than one" +#endif + +#if (CH_CFG_ST_TIMEDELTA > 0) && (CH_CFG_TIME_QUANTUM > 0) +#error "CH_CFG_TIME_QUANTUM not supported in tickless mode" +#endif + +#if (CH_CFG_ST_TIMEDELTA > 0) && (CH_DBG_THREADS_PROFILING == TRUE) +#error "CH_DBG_THREADS_PROFILING not supported in tickless mode" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* + * Virtual Timers APIs. + */ +#ifdef __cplusplus +extern "C" { +#endif + void _vt_init(void); + void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay, + vtfunc_t vtfunc, void *par); + void chVTDoResetI(virtual_timer_t *vtp); + void chVTDoTickI(void); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes a @p virtual_timer_t object. + * @note Initializing a timer object is not strictly required because + * the function @p chVTSetI() initializes the object too. This + * function is only useful if you need to perform a @p chVTIsArmed() + * check before calling @p chVTSetI(). + * + * @param[out] vtp the @p virtual_timer_t structure pointer + * + * @init + */ +static inline void chVTObjectInit(virtual_timer_t *vtp) { + + vtp->func = NULL; +} + +/** + * @brief Current system time. + * @details Returns the number of system ticks since the @p chSysInit() + * invocation. + * @note The counter can reach its maximum and then restart from zero. + * @note This function can be called from any context but its atomicity + * is not guaranteed on architectures whose word size is less than + * @p systime_t size. + * + * @return The system time in ticks. + * + * @xclass + */ +static inline systime_t chVTGetSystemTimeX(void) { + +#if CH_CFG_ST_TIMEDELTA == 0 + return ch.vtlist.systime; +#else /* CH_CFG_ST_TIMEDELTA > 0 */ + return port_timer_get_time(); +#endif /* CH_CFG_ST_TIMEDELTA > 0 */ +} + +/** + * @brief Current system time. + * @details Returns the number of system ticks since the @p chSysInit() + * invocation. + * @note The counter can reach its maximum and then restart from zero. + * + * @return The system time in ticks. + * + * @api + */ +static inline systime_t chVTGetSystemTime(void) { + systime_t systime; + + chSysLock(); + systime = chVTGetSystemTimeX(); + chSysUnlock(); + + return systime; +} + +/** + * @brief Returns the elapsed time since the specified start time. + * + * @param[in] start start time + * @return The elapsed time. + * + * @xclass + */ +static inline sysinterval_t chVTTimeElapsedSinceX(systime_t start) { + + return chTimeDiffX(start, chVTGetSystemTimeX()); +} + +/** + * @brief Checks if the current system time is within the specified time + * window. + * @note When start==end then the function returns always false because the + * time window has zero size. + * + * @param[in] start the start of the time window (inclusive) + * @param[in] end the end of the time window (non inclusive) + * @retval true current time within the specified time window. + * @retval false current time not within the specified time window. + * + * @xclass + */ +static inline bool chVTIsSystemTimeWithinX(systime_t start, systime_t end) { + + return chTimeIsInRangeX(chVTGetSystemTimeX(), start, end); +} + +/** + * @brief Checks if the current system time is within the specified time + * window. + * @note When start==end then the function returns always false because the + * time window has zero size. + * + * @param[in] start the start of the time window (inclusive) + * @param[in] end the end of the time window (non inclusive) + * @retval true current time within the specified time window. + * @retval false current time not within the specified time window. + * + * @api + */ +static inline bool chVTIsSystemTimeWithin(systime_t start, systime_t end) { + + return chTimeIsInRangeX(chVTGetSystemTime(), start, end); +} + +/** + * @brief Returns the time interval until the next timer event. + * @note The return value is not perfectly accurate and can report values + * in excess of @p CH_CFG_ST_TIMEDELTA ticks. + * @note The interval returned by this function is only meaningful if + * more timers are not added to the list until the returned time. + * + * @param[out] timep pointer to a variable that will contain the time + * interval until the next timer elapses. This pointer + * can be @p NULL if the information is not required. + * @return The time, in ticks, until next time event. + * @retval false if the timers list is empty. + * @retval true if the timers list contains at least one timer. + * + * @iclass + */ +static inline bool chVTGetTimersStateI(sysinterval_t *timep) { + + chDbgCheckClassI(); + + if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.next) { + return false; + } + + if (timep != NULL) { +#if CH_CFG_ST_TIMEDELTA == 0 + *timep = ch.vtlist.next->delta; +#else + *timep = (ch.vtlist.next->delta + (sysinterval_t)CH_CFG_ST_TIMEDELTA) - + chTimeDiffX(ch.vtlist.lasttime, chVTGetSystemTimeX()); +#endif + } + + return true; +} + +/** + * @brief Returns @p true if the specified timer is armed. + * @pre The timer must have been initialized using @p chVTObjectInit() + * or @p chVTDoSetI(). + * + * @param[in] vtp the @p virtual_timer_t structure pointer + * @return true if the timer is armed. + * + * @iclass + */ +static inline bool chVTIsArmedI(const virtual_timer_t *vtp) { + + chDbgCheckClassI(); + + return (bool)(vtp->func != NULL); +} + +/** + * @brief Returns @p true if the specified timer is armed. + * @pre The timer must have been initialized using @p chVTObjectInit() + * or @p chVTDoSetI(). + * + * @param[in] vtp the @p virtual_timer_t structure pointer + * @return true if the timer is armed. + * + * @api + */ +static inline bool chVTIsArmed(const virtual_timer_t *vtp) { + bool b; + + chSysLock(); + b = chVTIsArmedI(vtp); + chSysUnlock(); + + return b; +} + +/** + * @brief Disables a Virtual Timer. + * @note The timer is first checked and disabled only if armed. + * @pre The timer must have been initialized using @p chVTObjectInit() + * or @p chVTDoSetI(). + * + * @param[in] vtp the @p virtual_timer_t structure pointer + * + * @iclass + */ +static inline void chVTResetI(virtual_timer_t *vtp) { + + if (chVTIsArmedI(vtp)) { + chVTDoResetI(vtp); + } +} + +/** + * @brief Disables a Virtual Timer. + * @note The timer is first checked and disabled only if armed. + * @pre The timer must have been initialized using @p chVTObjectInit() + * or @p chVTDoSetI(). + * + * @param[in] vtp the @p virtual_timer_t structure pointer + * + * @api + */ +static inline void chVTReset(virtual_timer_t *vtp) { + + chSysLock(); + chVTResetI(vtp); + chSysUnlock(); +} + +/** + * @brief Enables a virtual timer. + * @details If the virtual timer was already enabled then it is re-enabled + * using the new parameters. + * @pre The timer must have been initialized using @p chVTObjectInit() + * or @p chVTDoSetI(). + * + * @param[in] vtp the @p virtual_timer_t structure pointer + * @param[in] delay 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 + * + * @iclass + */ +static inline void chVTSetI(virtual_timer_t *vtp, sysinterval_t delay, + vtfunc_t vtfunc, void *par) { + + chVTResetI(vtp); + chVTDoSetI(vtp, delay, vtfunc, par); +} + +/** + * @brief Enables a virtual timer. + * @details If the virtual timer was already enabled then it is re-enabled + * using the new parameters. + * @pre The timer must have been initialized using @p chVTObjectInit() + * or @p chVTDoSetI(). + * + * @param[in] vtp the @p virtual_timer_t structure pointer + * @param[in] delay 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 + */ +static inline void chVTSet(virtual_timer_t *vtp, sysinterval_t delay, + vtfunc_t vtfunc, void *par) { + + chSysLock(); + chVTSetI(vtp, delay, vtfunc, par); + chSysUnlock(); +} + +#endif /* CHVT_H */ + +/** @} */ -- cgit v1.2.3