From 1ea7355d85e316aadfd90468b3e808bb3dc95ee9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 16 Aug 2009 13:07:24 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1073 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/include/ch.h | 89 +++++++++++++ os/kernel/include/channels.h | 292 +++++++++++++++++++++++++++++++++++++++++ os/kernel/include/condvars.h | 80 +++++++++++ os/kernel/include/debug.h | 149 +++++++++++++++++++++ os/kernel/include/events.h | 145 ++++++++++++++++++++ os/kernel/include/heap.h | 43 ++++++ os/kernel/include/inline.h | 72 ++++++++++ os/kernel/include/lists.h | 92 +++++++++++++ os/kernel/include/mailboxes.h | 126 ++++++++++++++++++ os/kernel/include/mempools.h | 82 ++++++++++++ os/kernel/include/messages.h | 59 +++++++++ os/kernel/include/mutexes.h | 84 ++++++++++++ os/kernel/include/queues.h | 218 ++++++++++++++++++++++++++++++ os/kernel/include/scheduler.h | 110 ++++++++++++++++ os/kernel/include/semaphores.h | 99 ++++++++++++++ os/kernel/include/serial.h | 217 ++++++++++++++++++++++++++++++ os/kernel/include/sys.h | 184 ++++++++++++++++++++++++++ os/kernel/include/threads.h | 269 +++++++++++++++++++++++++++++++++++++ os/kernel/include/vt.h | 125 ++++++++++++++++++ 19 files changed, 2535 insertions(+) create mode 100644 os/kernel/include/ch.h create mode 100644 os/kernel/include/channels.h create mode 100644 os/kernel/include/condvars.h create mode 100644 os/kernel/include/debug.h create mode 100644 os/kernel/include/events.h create mode 100644 os/kernel/include/heap.h create mode 100644 os/kernel/include/inline.h create mode 100644 os/kernel/include/lists.h create mode 100644 os/kernel/include/mailboxes.h create mode 100644 os/kernel/include/mempools.h create mode 100644 os/kernel/include/messages.h create mode 100644 os/kernel/include/mutexes.h create mode 100644 os/kernel/include/queues.h create mode 100644 os/kernel/include/scheduler.h create mode 100644 os/kernel/include/semaphores.h create mode 100644 os/kernel/include/serial.h create mode 100644 os/kernel/include/sys.h create mode 100644 os/kernel/include/threads.h create mode 100644 os/kernel/include/vt.h (limited to 'os/kernel/include') diff --git a/os/kernel/include/ch.h b/os/kernel/include/ch.h new file mode 100644 index 000000000..0584b167e --- /dev/null +++ b/os/kernel/include/ch.h @@ -0,0 +1,89 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file ch.h + * @brief ChibiOS/RT main include file, it includes everything else. + * @addtogroup Kernel + * @{ + */ + +#ifndef _CH_H_ +#define _CH_H_ + +/** + * ChibiOS/RT identification macro. + */ +#define _CHIBIOS_RT_ + +/** + * Kernel version string. + */ +#define CH_KERNEL_VERSION "1.3.2unstable" + +/** + * Kernel version major number. + */ +#define CH_KERNEL_MAJOR 1 + +/** + * Kernel version minor number. + */ +#define CH_KERNEL_MINOR 3 + +/** + * Kernel version patch number. + */ +#define CH_KERNEL_PATCH 2 + +/* + * Common values. + */ +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#include +#include +#include "lists.h" +#include +#include "sys.h" +#include "vt.h" +#include "scheduler.h" +#include "semaphores.h" +#include "mutexes.h" +#include "condvars.h" +#include "events.h" +#include "messages.h" +#include "mailboxes.h" +#include "heap.h" +#include "mempools.h" +#include "threads.h" +#include "inline.h" +#include "queues.h" +#include "channels.h" +#include "serial.h" +#include "debug.h" + +#endif /* _CH_H_ */ + +/** @} */ diff --git a/os/kernel/include/channels.h b/os/kernel/include/channels.h new file mode 100644 index 000000000..a1c538f62 --- /dev/null +++ b/os/kernel/include/channels.h @@ -0,0 +1,292 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file channels.h + * @brief I/O channels + * @addtogroup Channels + * @{ + */ + +#ifndef _CHANNELS_H_ +#define _CHANNELS_H_ + +/** + * @brief @p BaseChannel specific methods. + */ +struct _base_channel_methods { + /** + * @brief Channel output check. + * @see chIOPutWouldBlock() + */ + bool_t (*putwouldblock)(void *instance); + /** + * @brief Channel input check. + * @see chIOGetWouldBlock() + */ + bool_t (*getwouldblock)(void *instance); + /** + * @brief Channel put method with timeout specification. + * @see chIOPut() + */ + msg_t (*put)(void *instance, uint8_t b, systime_t timeout); + /** + * @brief Channel get method with timeout specification. + * @see chIOGet() + */ + msg_t (*get)(void *instance, systime_t timeout); +}; + +/** + * @brief @p BaseChannel specific data. + * @note It is empty because @p BaseChannel is only an interface without + * implementation. + */ +struct _base_channel_data { +}; + +/** + * @brief @p BaseChannel virtual methods table. + */ +struct BaseChannelVMT { + /** + * @p BaseChannel class specific methods. + */ + struct _base_channel_methods m0; +}; + +/** + * @brief Base channel class. + * @details This class represents a generic, byte-wide, I/O channel. + */ +typedef struct { + /** + * Virtual Methods Table. + */ + const struct BaseChannelVMT *vmt; + /** + * @p BaseChannel class specific data. + */ + struct _base_channel_data d0; +} BaseChannel; + +/** + * @brief Channel output check. + * @details This function verifies if a subsequent @p chIOPut() would block. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @return The output queue status: + * @retval FALSE if the output queue has space and would not block a write + * operation. + * @retval TRUE if the output queue is full and would block a write operation. + */ +#define chIOPutWouldBlock(ip) ((ip)->vmt->m0.putwouldblock(ip)) + +/** + * @brief Channel input check. + * @details This function verifies if a subsequent @p chIOGett() would block. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @return The input queue status: + * @retval FALSE if the input queue contains data and would not block a read + * operation. + * @retval TRUE if the input queue is empty and would block a read operation. + */ +#define chIOGetWouldBlock(ip) ((ip)->vmt->m0.getwouldblock(ip)) + +/** + * @brief Channel blocking byte write. + * @details This function writes a byte value to a channel. If the channel + * is not ready to accept data then the calling thread is suspended. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @param[in] b the byte value to be written to the channel + * @return The operation status: + * @retval Q_OK if the operation succeeded. + * @retval Q_RESET if the channel associated queue (if any) was reset. + */ +#define chIOPut(ip, b) ((ip)->vmt->m0.put(ip, b, TIME_INFINITE)) + +/** + * @brief Channel blocking byte write with timeout. + * @details This function writes a byte value to a channel. If the channel + * is not ready to accept data then the calling thread is suspended. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @param[in] b the byte value to be written to the channel + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status: + * @retval Q_OK if the operation succeeded. + * @retval Q_TIMEOUT if the specified time expired. + * @retval Q_RESET if the channel associated queue (if any) was reset. + */ +#define chIOPutTimeout(ip, b, timeout) ((ip)->vmt->m0.put(ip, b, timeout)) + +/** + * @brief Channel blocking byte read. + * @details This function reads a byte value from a channel. If the data + * is not available then the calling thread is suspended. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @return A byte value from the queue or: + * @retval Q_RESET if the channel associated queue (if any) was reset. + */ +#define chIOGet(ip) ((ip)->vmt->m0.get(ip, TIME_INFINITE)) + +/** + * @brief Channel blocking byte read with timeout. + * @details This function reads a byte value from a channel. If the data + * is not available then the calling thread is suspended. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @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 byte value from the queue or: + * @retval Q_TIMEOUT if the specified time expired. + * @retval Q_RESET if the channel associated queue (if any) was reset. + */ +#define chIOGetTimeout(ip, timeout) ((ip)->vmt->m0.get(ip, timeout)) + +#if CH_USE_EVENTS +/** + * @brief @p BaseAsynchronousChannel specific methods. + */ +struct _base_asynchronous_channel_methods { + /** + * Channel asynchronous write method. + * @see chIOWrite() + */ + size_t (*write)(void *instance, uint8_t *buffer, size_t n); + /** + * Channel asynchronous read method. + * @see chIORead() + */ + size_t (*read)(void *instance, uint8_t *buffer, size_t n); +}; + +/** + * @brief @p BaseAsynchronousChannel specific data. + */ +struct _base_asynchronous_channel_data { + /** + * Data Available @p EventSource. This event is generated when some incoming + * data is inserted in the input queue. + */ + EventSource ievent; + /** + * Data Transmitted @p EventSource. This event is generated when the + * output queue is empty. + */ + EventSource oevent; +}; + +/** + * @brief @p BaseAsynchronousChannel virtual methods table. + */ +struct BaseAsynchronousChannelVMT { + /** + * @p BaseChannel class inherited methods. + */ + struct _base_channel_methods m0; + /** + * @p BaseAsynchronousChannel class specific methods. + */ + struct _base_asynchronous_channel_methods m1; +}; + +/** + * @extends BaseChannel + * + * @brief Base asynchronous channel class. + * @details This class extends @p BaseChannel by adding methods for + * asynchronous I/O in an event-driven environment. + */ +typedef struct { + /** + * Virtual Methods Table. + */ + const struct BaseAsynchronousChannelVMT *vmt; + /** + * @p BaseChannel class inherited data. + */ + struct _base_channel_data d0; + /** + * @p BaseAsynchronousChannel class specific data. + */ + struct _base_asynchronous_channel_data d1; +} BaseAsynchronousChannel; + +/** + * @brief Channel non-blocking write. + * @details The function writes data from a buffer to a channel. The + * transfer is non-blocking and can return zero if the channel is + * not read to accept data. + * + * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class + * @param[out] bp pointer to the buffer where the data is stored + * @param[in] n the maximum amount of data to be transferred + * @return The number of bytes transferred. + */ +#define chIOWrite(ip, bp, n) ((ip)->vmt->m1.write(ip, bp, n)) + +/** + * @brief Channel non-blocking read. + * @details The function reads data from a channel into a buffer. The + * transfer is non-blocking and can return zero if the channel has + * no data immediately available. + * + * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class + * @param[out] bp pointer to the buffer where the input data is copied + * @param[in] n the maximum amount of data to be transferred + * @return The number of bytes transferred. + */ +#define chIORead(ip, bp, n) ((ip)->vmt->m1.read(ip, bp, n)) + +/** + * @brief Returns the write event source. + * @details The write event source is broadcasted when the channel is ready + * for write operations. This usually happens when the internal + * output queue becomes empty. + * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class + * @return A pointer to an @p EventSource object. + */ +#define chIOGetWriteEventSource(ip) (&((ip)->vmt->d1.oevent)) + +/** + * @brief Returns the read event source. + * @details The read event source is broadcasted when the channel is ready + * for read operations. This usually happens when the internal + * input queue becomes non-empty. + * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class + * @return A pointer to an @p EventSource object. + */ +#define chIOGetReadEventSource(ip) (&((ip)->vmt->d1.ievent)) + +#endif /* CH_USE_EVENTS */ + +#endif /* _CHANNELS_H_ */ + +/** @} */ diff --git a/os/kernel/include/condvars.h b/os/kernel/include/condvars.h new file mode 100644 index 000000000..d68637f21 --- /dev/null +++ b/os/kernel/include/condvars.h @@ -0,0 +1,80 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/* + Concepts and parts of this file are contributed by and Copyright (C) 2008 + of Leon Woestenberg. + */ + +/** + * @file condvars.h + * @brief Condition Variables macros and structures. + * @addtogroup CondVars + * @{ + */ + +#ifndef _CONDVARS_H_ +#define _CONDVARS_H_ + +#if CH_USE_CONDVARS && CH_USE_MUTEXES + +/** + * @brief CondVar structure. + */ +typedef struct CondVar { + ThreadsQueue c_queue; /**< CondVar threads queue.*/ +} CondVar; + +#ifdef __cplusplus +extern "C" { +#endif + void chCondInit(CondVar *cp); + void chCondSignal(CondVar *cp); + void chCondSignalI(CondVar *cp); + void chCondBroadcast(CondVar *cp); + void chCondBroadcastI(CondVar *cp); + msg_t chCondWait(CondVar *cp); + msg_t chCondWaitS(CondVar *cp); +#if CH_USE_CONDVARS_TIMEOUT + msg_t chCondWaitTimeout(CondVar *cp, systime_t time); + msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time); +#endif +#ifdef __cplusplus +} +#endif + +/** + * @brief Data part of a static condition variable initializer. + * @details This macro should be used when statically initializing a condition + * variable that is part of a bigger structure. + */ +#define _CONDVAR_DATA(name) {_THREADSQUEUE_DATA(name.c_queue)} + +/** + * @brief Static condition variable initializer. + * @details Statically initialized condition variables require no explicit + * initialization using @p chCondInit(). + * @param name the name of the condition variable + */ +#define CONDVAR_DECL(name) CondVar name = _CONDVAR_DATA(name) + +#endif /* CH_USE_CONDVARS && CH_USE_MUTEXES */ + +#endif /* _CONDVARS_H_ */ + +/** @} */ diff --git a/os/kernel/include/debug.h b/os/kernel/include/debug.h new file mode 100644 index 000000000..67a5d65b4 --- /dev/null +++ b/os/kernel/include/debug.h @@ -0,0 +1,149 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file debug.h + * @brief Debug macros and structures. + * @addtogroup Debug + * @{ + */ + +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +/** + * @brief Trace buffer entries. + */ +#ifndef TRACE_BUFFER_SIZE +#define TRACE_BUFFER_SIZE 64 +#endif + +/** + * @brief Fill value for thread stack area in debug mode. + */ +#ifndef STACK_FILL_VALUE +#define STACK_FILL_VALUE 0x55 +#endif + +/** + * @brief Fill value for thread area in debug mode. + * @note The chosen default value is 0xFF in order to make evident which + * thread fields were not initialized when inspecting the memory with + * a debugger. A uninitialized field is not an error in itself but it + * better to know it. + */ +#ifndef THREAD_FILL_VALUE +#define THREAD_FILL_VALUE 0xFF +#endif + +/** + * @brief Trace buffer record. + */ +typedef struct { + void *cse_wtobjp; /**< Object where going to sleep.*/ + systime_t cse_time; /**< Time of the switch event.*/ + uint16_t cse_state: 4; /**< Switched out thread state.*/ + uint16_t cse_tid: 12; /**< Switched in thdread id.*/ +} CtxSwcEvent; + +/** + * @brief Trace buffer header. + */ +typedef struct { + unsigned tb_size; /**< Trace buffer size (records).*/ + CtxSwcEvent *tb_ptr; /**< Pointer to the ring buffer front.*/ + CtxSwcEvent tb_buffer[TRACE_BUFFER_SIZE]; /**< Ring buffer.*/ +} TraceBuffer; + +#define __QUOTE_THIS(p) #p + +#if CH_DBG_ENABLE_CHECKS +/** + * Function parameter check, if the condition check fails then the kernel + * panics. + * @param c the condition to be verified to be true + * @param func the undecorated function name + * @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. + */ +#define chDbgCheck(c, func) { \ + if (!(c)) \ + chDbgPanic(__QUOTE_THIS(func)"(), line "__QUOTE_THIS(__LINE__)); \ +} +#else /* !CH_DBG_ENABLE_CHECKS */ +#define chDbgCheck(c, func) { \ + (void)(c), (void)__QUOTE_THIS(func)"(), line "__QUOTE_THIS(__LINE__); \ +} +#endif /* !CH_DBG_ENABLE_CHECKS */ + +#if CH_DBG_ENABLE_ASSERTS +/** + * Condition assertion, if the condition check fails then the kernel panics + * with the specified message. + * @param c the condition to be verified to be true + * @param m the text message + * @param r a remark string + * @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS switch is + * specified in @p chconf.h else the macro does nothing. + * @note The convention for the message is the following:
+ * @(), #@ + * @note The remark string is not currently used except for putting a comment + * in the code about the assert. + */ +#define chDbgAssert(c, m, r) { \ + if (!(c)) \ + chDbgPanic(m); \ +} +#else /* !CH_DBG_ENABLE_ASSERTS */ +#define chDbgAssert(c, m, r) {(void)(c);} +#endif /* !CH_DBG_ENABLE_ASSERTS */ + +#if !(CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK) +/* When the debug features are disabled this function is replaced by an empty + * macro.*/ +#define chDbgPanic(msg) {} +#endif + +#if !CH_DBG_ENABLE_TRACE +/* When the trace feature is disabled this function is replaced by an empty + * macro.*/ +#define chDbgTrace(otp, ntp) {} +#endif + +#if !defined(__DOXYGEN__) +#ifdef __cplusplus +extern "C" { +#endif +#if CH_DBG_ENABLE_TRACE + extern TraceBuffer trace_buffer; + void trace_init(void); + void chDbgTrace(Thread *otp, Thread *ntp); +#endif +#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK + extern char *panic_msg; + void chDbgPanic(char *msg); +#endif +#ifdef __cplusplus +} +#endif +#endif /* !defined(__DOXYGEN__) */ + +#endif /* _DEBUG_H_ */ + +/** @} */ diff --git a/os/kernel/include/events.h b/os/kernel/include/events.h new file mode 100644 index 000000000..c8bf0c6e6 --- /dev/null +++ b/os/kernel/include/events.h @@ -0,0 +1,145 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file events.h + * @brief Events macros and structures. + * @addtogroup Events + * @{ + */ + +#ifndef _EVENTS_H_ +#define _EVENTS_H_ + +#if CH_USE_EVENTS + +typedef struct EventListener EventListener; + +/** + * @brief Event Listener structure. + */ +struct EventListener { + EventListener *el_next; /**< Next Event Listener registered on + the Event Source.*/ + Thread *el_listener; /**< Thread interested in the Event + Source.*/ + eventmask_t el_mask; /**< Event flags mask associated by the + thread to the Event Source.*/ +}; + +/** + * @brief Event Source structure. + */ +typedef struct EventSource { + EventListener *es_next; /**< First Event Listener registered on + the Event Source.*/ +} EventSource; + +/** + * @brief Data part of a static event source initializer. + * @details This macro should be used when statically initializing an event + * source that is part of a bigger structure. + * @param name the name of the event source variable + */ +#define _EVENTSOURCE_DATA(name) {(void *)(&name)} + +/** + * @brief Static event source initializer. + * @details Statically initialized event sources require no explicit + * initialization using @p chEvtInit(). + * @param name the name of the event source variable + */ +#define EVENTSOURCE_DECL(name) EventSource name = _EVENTSOURCE_DATA(name) + +/** All events allowed mask.*/ +#define ALL_EVENTS -1 + +/** Returns the event mask from the event identifier.*/ +#define EVENT_MASK(eid) (1 << (eid)) + +/** + * Registers an Event Listener on an Event Source. + * @param esp pointer to the @p EventSource structure + * @param elp pointer to the @p EventListener structure + * @param eid numeric identifier assigned to the Event Listener. The identifier + * is used as index for the event callback function. + * The value must range between zero and the size, in bit, of the + * @p eventid_t type minus one. + * @note Multiple Event Listeners can use the same event identifier, the + * listener will share the callback function. + */ +#define chEvtRegister(esp, elp, eid) chEvtRegisterMask(esp, elp, EVENT_MASK(eid)) + +/** + * Initializes an Event Source. + * @param esp pointer to the @p EventSource structure + * @note Can be called with interrupts disabled or enabled. + */ +#define chEvtInit(esp) \ + ((esp)->es_next = (EventListener *)(void *)(esp)) + +/** + * Verifies if there is at least one @p EventListener registered on the + * @p EventSource. + * @param esp pointer to the @p EventSource structure + * @note Can be called with interrupts disabled or enabled. + */ +#define chEvtIsListening(esp) \ + ((void *)(esp) != (void *)(esp)->es_next) + +/** Event Handler callback function.*/ +typedef void (*evhandler_t)(eventid_t); + +#ifdef __cplusplus +extern "C" { +#endif + void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask); + void chEvtUnregister(EventSource *esp, EventListener *elp); + eventmask_t chEvtClear(eventmask_t mask); + eventmask_t chEvtPend(eventmask_t mask); + void chEvtSignal(Thread *tp, eventmask_t mask); + void chEvtSignalI(Thread *tp, eventmask_t mask); + void chEvtBroadcast(EventSource *esp); + void chEvtBroadcastI(EventSource *esp); + void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask); +#if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT + eventmask_t chEvtWaitOne(eventmask_t ewmask); + eventmask_t chEvtWaitAny(eventmask_t ewmask); + eventmask_t chEvtWaitAll(eventmask_t ewmask); +#endif +#if CH_USE_EVENTS_TIMEOUT + eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time); + eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time); + eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time); +#endif +#ifdef __cplusplus +} +#endif + +#if !CH_OPTIMIZE_SPEED && CH_USE_EVENTS_TIMEOUT +#define chEvtWaitOne(ewmask) chEvtWaitOneTimeout(ewmask, TIME_INFINITE) +#define chEvtWaitAny(ewmask) chEvtWaitAnyTimeout(ewmask, TIME_INFINITE) +#define chEvtWaitAll(ewmask) chEvtWaitAllTimeout(ewmask, TIME_INFINITE) +#endif + +#endif /* CH_USE_EVENTS */ + +#endif /* _EVENTS_H_ */ + +/** @} */ diff --git a/os/kernel/include/heap.h b/os/kernel/include/heap.h new file mode 100644 index 000000000..4c9571070 --- /dev/null +++ b/os/kernel/include/heap.h @@ -0,0 +1,43 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file heap.h + * @brief Heap macros and structures. + * @addtogroup Heap + * @{ + */ + +#ifndef _HEAP_H_ +#define _HEAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + void heap_init(void); + void *chHeapAlloc(size_t size); + void chHeapFree(void *p); + size_t chHeapStatus(size_t *sizep); +#ifdef __cplusplus +} +#endif + +#endif /* _HEAP_H_ */ + +/** @} */ diff --git a/os/kernel/include/inline.h b/os/kernel/include/inline.h new file mode 100644 index 000000000..42775d5cb --- /dev/null +++ b/os/kernel/include/inline.h @@ -0,0 +1,72 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _INLINE_H_ +#define _INLINE_H_ + +/** + * @file inline.h + * @brief Kernel inlined functions. + */ + +/* + * Inlined functions if CH_OPTIMIZE_SPEED is enabled. + * Note: static inlined functions do not duplicate the code in every module + * this is true for GCC, not sure about other compilers. + */ +#if CH_OPTIMIZE_SPEED +static INLINE void prio_insert(Thread *tp, ThreadsQueue *tqp) { + + Thread *cp = (Thread *)tqp; + do { + cp = cp->p_next; + } while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio)); + tp->p_prev = (tp->p_next = cp)->p_prev; + tp->p_prev->p_next = cp->p_prev = tp; +} + +static INLINE void queue_insert(Thread *tp, ThreadsQueue *tqp) { + + tp->p_prev = (tp->p_next = (Thread *)tqp)->p_prev; + tp->p_prev->p_next = tqp->p_prev = tp; +} + +static INLINE Thread *fifo_remove(ThreadsQueue *tqp) { + Thread *tp = tqp->p_next; + + (tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp; + return tp; +} + +static INLINE Thread *lifo_remove(ThreadsQueue *tqp) { + Thread *tp = tqp->p_prev; + + (tqp->p_prev = tp->p_prev)->p_next = (Thread *)tqp; + return tp; +} + +static INLINE Thread *dequeue(Thread *tp) { + + tp->p_prev->p_next = tp->p_next; + tp->p_next->p_prev = tp->p_prev; + return tp; +} +#endif /* CH_OPTIMIZE_SPEED */ + +#endif /* _INLINE_H_ */ diff --git a/os/kernel/include/lists.h b/os/kernel/include/lists.h new file mode 100644 index 000000000..bc3fd7272 --- /dev/null +++ b/os/kernel/include/lists.h @@ -0,0 +1,92 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file lists.h + * @brief Thread queues/lists macros and structures. + * @addtogroup ThreadLists + * @{ + */ + +#ifndef _LISTS_H_ +#define _LISTS_H_ + +typedef struct Thread Thread; + +/** + * Threads queue initialization. + */ +#define queue_init(tqp) ((tqp)->p_next = (tqp)->p_prev = (Thread *)(tqp)); + +/** + * Macro evaluating to @p TRUE if the specified threads queue is empty. + */ +#define isempty(p) ((p)->p_next == (Thread *)(p)) + +/** + * Macro evaluating to @p TRUE if the specified threads queue is not empty. + */ +#define notempty(p) ((p)->p_next != (Thread *)(p)) + +/** + * @brief Data part of a static threads queue initializer. + * @details This macro should be used when statically initializing a threads + * queue that is part of a bigger structure. + * @param name the name of the threads queue variable + */ +#define _THREADSQUEUE_DATA(name) {(Thread *)&name, (Thread *)&name} + +/** + * @brief Static threads queue initializer. + * @details Statically initialized threads queues require no explicit + * initialization using @p queue_init(). + * @param name the name of the threads queue variable + */ +#define THREADSQUEUE_DECL(name) ThreadsQueue name = _THREADSQUEUE_DATA(name) + +/** + * @brief Generic threads bidirectional linked list header and element. + * @extends ThreadsList + */ +typedef struct { + Thread *p_next; /**< First @p Thread in the queue, or + @p ThreadQueue when empty.*/ + Thread *p_prev; /**< Last @p Thread in the queue, or + @p ThreadQueue when empty.*/ +} ThreadsQueue; + +#if !CH_OPTIMIZE_SPEED + +#ifdef __cplusplus +extern "C" { +#endif + void prio_insert(Thread *tp, ThreadsQueue *tqp); + void queue_insert(Thread *tp, ThreadsQueue *tqp); + Thread *fifo_remove(ThreadsQueue *tqp); + Thread *lifo_remove(ThreadsQueue *tqp); + Thread *dequeue(Thread *tp); +#ifdef __cplusplus +} +#endif + +#endif /* !CH_OPTIMIZE_SPEED */ + +#endif /* _LISTS_H_ */ + +/** @} */ diff --git a/os/kernel/include/mailboxes.h b/os/kernel/include/mailboxes.h new file mode 100644 index 000000000..075806da8 --- /dev/null +++ b/os/kernel/include/mailboxes.h @@ -0,0 +1,126 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file mailboxes.h + * @brief Mailboxes macros and structures. + * @addtogroup Mailboxes + * @{ + */ + +#ifndef _MAILBOXES_H_ +#define _MAILBOXES_H_ + +#if CH_USE_MAILBOXES + +typedef struct { + msg_t *mb_buffer; /**< Pointer to the mailbox buffer.*/ + msg_t *mb_top; /**< Pointer to the first location + after the buffer.*/ + msg_t *mb_wrptr; /**< Write pointer.*/ + msg_t *mb_rdptr; /**< Read pointer.*/ + Semaphore mb_fullsem; /**< Full counter @p Semaphore.*/ + Semaphore mb_emptysem; /**< Empty counter @p Semaphore.*/ +} Mailbox; + +#ifdef __cplusplus +extern "C" { +#endif + void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n); + void chMBReset(Mailbox *mbp); + msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout); + msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t timeout); + msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout); + msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t timeout); + msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t timeout); + msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t timeout); +#ifdef __cplusplus +} +#endif + +/** + * Returns the mailbox buffer size. + * @param[in] mbp the pointer to an initialized Mailbox object + */ +#define chMBSize(mbp) \ + ((mbp)->mb_top - (mbp)->mb_buffer) + +/** + * Returns the free space into the mailbox. + * @param[in] mbp the pointer to an initialized Mailbox object + * @return The number of empty message slots. + * @note Can be invoked in any system state but if invoked out of a locked + * state then the returned value may change after reading. + * @note The returned value can be less than zero when there are waiting + * threads on the internal semaphore. + */ +#define chMBGetEmpty(mbp) chSemGetCounterI(&(mbp)->mb_emptysem) + +/** + * Returns the number of messages into the mailbox. + * @param[in] mbp the pointer to an initialized Mailbox object + * @return The number of queued messages. + * @note Can be invoked in any system state but if invoked out of a locked + * state then the returned value may change after reading. + * @note The returned value can be less than zero when there are waiting + * threads on the internal semaphore. + */ +#define chMBGetFull(mbp) chSemGetCounterI(&(mbp)->mb_fullsem) + +/** + * Returns the next message in the queue without removing it. + * @note A message must be waiting in the queue for this function to work or + * it would return garbage. The correct way to use this macro is to + * use @p chMBGetFull() and then use this macro, all within a lock state. + */ +#define chMBPeek(mbp) (*(mbp)->mb_rdptr) + +/** + * @brief Data part of a static mailbox initializer. + * @details This macro should be used when statically initializing a + * mailbox that is part of a bigger structure. + * @param name the name of the mailbox variable + * @param buffer pointer to the mailbox buffer area + * @param size size of the mailbox buffer area + */ +#define _MAILBOX_DATA(name, buffer, size) { \ + (msg_t *)(buffer), \ + (msg_t *)(buffer) + size, \ + (msg_t *)(buffer), \ + (msg_t *)(buffer), \ + _SEMAPHORE_DATA(name.mb_fullsem, 0), \ + _SEMAPHORE_DATA(name.mb_emptysem, size), \ +} + +/** + * @brief Static mailbox initializer. + * @details Statically initialized mailboxes require no explicit + * initialization using @p chMBInit(). + * @param name the name of the mailbox variable + * @param buffer pointer to the mailbox buffer area + * @param size size of the mailbox buffer area + */ +#define MAILBOX_DECL(name, buffer, size) \ + Mailbox name = _MAILBOX_DATA(name, buffer, size) + +#endif /* CH_USE_MAILBOXES */ + +#endif /* _MAILBOXES_H_ */ + +/** @} */ diff --git a/os/kernel/include/mempools.h b/os/kernel/include/mempools.h new file mode 100644 index 000000000..38e54b3d8 --- /dev/null +++ b/os/kernel/include/mempools.h @@ -0,0 +1,82 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file mempools.h + * @brief Memory Pools macros and structures. + * @addtogroup MemoryPools + * @{ + */ + +#ifndef _MEMPOOLS_H_ +#define _MEMPOOLS_H_ + +#if CH_USE_MEMPOOLS + +/** + * @brief Memory pool free object header. + */ +struct pool_header { + struct pool_header *ph_next; +}; + +/** + * @brief Memory pool descriptor. + */ +typedef struct { + struct pool_header *mp_next; /**< Pointer to the header.*/ + size_t mp_object_size; /**< Memory pool objects size.*/ +} MemoryPool; + +/** + * @brief Data part of a static memory pool initializer. + * @details This macro should be used when statically initializing a + * memory pool that is part of a bigger structure. + * @param name the name of the memory pool variable + * @param size size of the memory pool contained objects + */ +#define _MEMORYPOOL_DATA(name, size) {NULL, size} + +/** + * @brief Static memory pool initializer. + * @details Statically initialized memory pools require no explicit + * initialization using @p chPoolInit(). + * @param name the name of the memory pool variable + * @param size size of the memory pool contained objects + */ +#define MEMORYPOOL_DECL(name, size) \ + MemoryPool name = _MEMORYPOOL_DATA(name, size) + +#ifdef __cplusplus +extern "C" { +#endif + void chPoolInit(MemoryPool *mp, size_t size); + void *chPoolAllocI(MemoryPool *mp); + void *chPoolAlloc(MemoryPool *mp); + void chPoolFreeI(MemoryPool *mp, void *objp); + void chPoolFree(MemoryPool *mp, void *objp); +#ifdef __cplusplus +} +#endif + +#endif /* CH_USE_MEMPOOLS */ + +#endif /* _MEMPOOLS_H_ */ + +/** @} */ diff --git a/os/kernel/include/messages.h b/os/kernel/include/messages.h new file mode 100644 index 000000000..ee1449a82 --- /dev/null +++ b/os/kernel/include/messages.h @@ -0,0 +1,59 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file messages.h + * @brief Messages macros and structures. + * @addtogroup Messages + * @{ + */ + +#ifndef _MESSAGES_H_ +#define _MESSAGES_H_ + +#if CH_USE_MESSAGES + +/** + * Evaluates to TRUE if the thread has pending messages. + */ +#define chMsgIsPendingI(tp) \ + ((tp)->p_msgqueue.p_next != (Thread *)&(tp)->p_msgqueue) + +/** + * Returns the first message in the queue. + */ +#define chMsgGetI(tp) \ + ((tp)->p_msgqueue.p_next->p_msg) + +#ifdef __cplusplus +extern "C" { +#endif + msg_t chMsgSend(Thread *tp, msg_t msg); + msg_t chMsgWait(void); + msg_t chMsgGet(void); + void chMsgRelease(msg_t msg); +#ifdef __cplusplus +} +#endif + +#endif /* CH_USE_MESSAGES */ + +#endif /* _MESSAGES_H_ */ + +/** @} */ diff --git a/os/kernel/include/mutexes.h b/os/kernel/include/mutexes.h new file mode 100644 index 000000000..6ef6e48f4 --- /dev/null +++ b/os/kernel/include/mutexes.h @@ -0,0 +1,84 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file mutexes.h + * @brief Mutexes macros and structures. + * @addtogroup Mutexes + * @{ + */ + +#ifndef _MUTEXES_H_ +#define _MUTEXES_H_ + +#if CH_USE_MUTEXES + +/** + * @brief Mutex structure. + */ +typedef struct Mutex { + ThreadsQueue m_queue; /**< Queue of the threads sleeping on + this Mutex.*/ + Thread *m_owner; /**< Owner @p Thread pointer or + @p NULL.*/ + struct Mutex *m_next; /**< Next @p Mutex into an owner-list + or @p NULL.*/ +} Mutex; + +#ifdef __cplusplus +extern "C" { +#endif + void chMtxInit(Mutex *mp); + void chMtxLock(Mutex *mp); + void chMtxLockS(Mutex *mp); + bool_t chMtxTryLock(Mutex *mp); + bool_t chMtxTryLockS(Mutex *mp); + Mutex *chMtxUnlock(void); + Mutex *chMtxUnlockS(void); + void chMtxUnlockAll(void); +#ifdef __cplusplus +} +#endif + +/** + * @brief Data part of a static mutex initializer. + * @details This macro should be used when statically initializing a mutex + * that is part of a bigger structure. + * @param name the name of the mutex variable + */ +#define _MUTEX_DATA(name) {_THREADSQUEUE_DATA(name.m_queue), NULL, NULL} + +/** + * @brief Static mutex initializer. + * @details Statically initialized mutexes require no explicit initialization + * using @p chMtxInit(). + * @param name the name of the mutex variable + */ +#define MUTEX_DECL(name) Mutex name = _MUTEX_DATA(name) + +/** + * Returns @p TRUE if the mutex queue contains at least a waiting thread. + */ +#define chMtxQueueNotEmptyS(mp) notempty(&(mp)->m_queue) + +#endif /* CH_USE_MUTEXES */ + +#endif /* _MUTEXES_H_ */ + +/** @} */ diff --git a/os/kernel/include/queues.h b/os/kernel/include/queues.h new file mode 100644 index 000000000..6bd98b4f1 --- /dev/null +++ b/os/kernel/include/queues.h @@ -0,0 +1,218 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file queues.h I/O + * @brief Queues macros and structures. + * @addtogroup IOQueues + * @{ + */ + +#ifndef _QUEUES_H_ +#define _QUEUES_H_ + +/** Queue notification callback type. */ +typedef void (*qnotify_t)(void); + +/** Returned by the queue functions if the operation is successful. */ +#define Q_OK RDY_OK +/** Returned by the queue functions if a timeout occurs. */ +#define Q_TIMEOUT RDY_TIMEOUT +/** Returned by the queue functions if the queue is reset. */ +#define Q_RESET RDY_RESET +/** Returned by the queue functions if the queue is empty. */ +#define Q_EMPTY -3 +/** Returned by the queue functions if the queue is full. */ +#define Q_FULL -4 + +#if CH_USE_QUEUES +/** + * @brief Generic I/O queue structure. + * @details This structure represents a generic Input or Output asymmetrical + * queue. The queue is asymmetrical because one end is meant to be + * accessed from a thread context, and thus can be blocking, the other + * end is accessible from interrupt handlers or from within a kernel + * lock zone (see I-Locked and S-Locked states in + * @ref system_states) and is non-blocking. + */ +typedef struct { + uint8_t *q_buffer; /**< Pointer to the queue buffer.*/ + uint8_t *q_top; /**< Pointer to the first location + after the buffer.*/ + uint8_t *q_wrptr; /**< Write pointer.*/ + uint8_t *q_rdptr; /**< Read pointer.*/ + Semaphore q_sem; /**< Counter @p Semaphore.*/ + qnotify_t q_notify; /**< Data notification callback.*/ +} GenericQueue; + +/** Returns the queue's buffer size. */ +#define chQSize(q) ((q)->q_top - (q)->q_buffer) + +/** + * Returns the used space if used on an Input Queue and the empty space if + * used on an Output Queue. + * @note The returned value can be less than zero when there are waiting + * threads on the internal semaphore. + */ +#define chQSpace(q) chSemGetCounterI(&(q)->q_sem) + +/** + * @brief Input queue structure. + * @details This structure represents a generic asymmetrical input queue. + * Writing in the queue is non-blocking and can be performed from + * interrupt handlers or from within a kernel lock zone (see + * I-Locked and S-Locked states in @ref system_states). + * Reading the queue can be a blocking operation and is supposed to + * be performed by a system thread. + * @extends GenericQueue + */ +typedef GenericQueue InputQueue; + +/** Evaluates to @p TRUE if the specified Input Queue is empty. */ +#define chIQIsEmpty(q) (chQSpace(q) <= 0) + +/** Evaluates to @p TRUE if the specified Input Queue is full. */ +#define chIQIsFull(q) (chQSpace(q) >= chQSize(q)) + +/** + * @brief Input queue read. + * @details This function reads a byte value from an input queue. If the queue + * is empty then the calling thread is suspended until a byte arrives + * in the queue. + * + * @param[in] iqp pointer to an @p InputQueue structure + * @return A byte value from the queue or: + * @retval Q_RESET if the queue was reset. + */ +#define chIQGet(iqp) chIQGetTimeout(iqp, TIME_INFINITE) + +/** + * @brief Data part of a static input queue initializer. + * @details This macro should be used when statically initializing an + * input queue that is part of a bigger structure. + * @param name the name of the input queue variable + * @param buffer pointer to the queue buffer area + * @param size size of the queue buffer area + * @param inotify input notification callback pointer + */ +#define _INPUTQUEUE_DATA(name, buffer, size, inotify) { \ + (uint8_t *)(buffer), \ + (uint8_t *)(buffer) + size, \ + (uint8_t *)(buffer), \ + (uint8_t *)(buffer), \ + _SEMAPHORE_DATA(name.q_sem, 0), \ + inotify \ +} + +/** + * @brief Static input queue initializer. + * @details Statically initialized input queues require no explicit + * initialization using @p chIQInit(). + * @param name the name of the input queue variable + * @param buffer pointer to the queue buffer area + * @param size size of the queue buffer area + * @param inotify input notification callback pointer + */ +#define INPUTQUEUE_DECL(name, buffer, size, inotify) \ + InputQueue name = _INPUTQUEUE_DATA(name, buffer, size, inotify) + +/** + * @brief Output queue structure. + * @details This structure represents a generic asymmetrical output queue. + * Reading from the queue is non-blocking and can be performed from + * interrupt handlers or from within a kernel lock zone (see + * I-Locked and S-Locked states in @ref system_states). + * Writing the queue can be a blocking operation and is supposed to + * be performed by a system thread. + * @extends GenericQueue + */ +typedef GenericQueue OutputQueue; + +/** Evaluates to @p TRUE if the specified Output Queue is empty. */ +#define chOQIsEmpty(q) (chQSpace(q) >= chQSize(q)) + +/** Evaluates to @p TRUE if the specified Output Queue is full. */ +#define chOQIsFull(q) (chQSpace(q) <= 0) + +/** + * @brief Output queue write. + * @details This function writes a byte value to an output queue. If the queue + * is full then the calling thread is suspended until there is space + * in the queue. + * + * @param[in] oqp pointer to an @p OutputQueue structure + * @param[in] b the byte value to be written in the queue + * @return The operation status: + * @retval Q_OK if the operation succeeded. + * @retval Q_RESET if the queue was reset. + */ +#define chOQPut(oqp, b) chOQPutTimeout(oqp, b, TIME_INFINITE) + +/** + * @brief Data part of a static output queue initializer. + * @details This macro should be used when statically initializing an + * output queue that is part of a bigger structure. + * @param name the name of the output queue variable. + * @param buffer pointer to the queue buffer area + * @param size size of the queue buffer area + * @param onotify output notification callback pointer + */ +#define _OUTPUTQUEUE_DATA(name, buffer, size, onotify) { \ + (uint8_t *)(buffer), \ + (uint8_t *)(buffer) + size, \ + (uint8_t *)(buffer), \ + (uint8_t *)(buffer), \ + _SEMAPHORE_DATA(name.q_sem, size), \ + onotify \ +} + +/** + * @brief Static output queue initializer. + * @details Statically initialized output queues require no explicit + * initialization using @p chOQInit(). + * @param name the name of the output queue variable + * @param buffer pointer to the queue buffer area + * @param size size of the queue buffer area + * @param onotify output notification callback pointer + */ +#define OUTPUTQUEUE_DECL(name, buffer, size, onotify) \ + InputQueue name = _OUTPUTQUEUE_DATA(name, buffer, size, onotify) + +#ifdef __cplusplus +extern "C" { +#endif + void chIQInit(InputQueue *qp, uint8_t *buffer, size_t size, qnotify_t inotify); + void chIQResetI(InputQueue *qp); + msg_t chIQPutI(InputQueue *qp, uint8_t b); + msg_t chIQGetTimeout(InputQueue *qp, systime_t timeout); + size_t chIQRead(InputQueue *qp, uint8_t *buffer, size_t n); + + void chOQInit(OutputQueue *queue, uint8_t *buffer, size_t size, qnotify_t onotify); + void chOQResetI(OutputQueue *queue); + msg_t chOQPutTimeout(OutputQueue *queue, uint8_t b, systime_t timeout); + msg_t chOQGetI(OutputQueue *queue); + size_t chOQWrite(OutputQueue *queue, uint8_t *buffer, size_t n); +#ifdef __cplusplus +} +#endif +#endif /* CH_USE_QUEUES */ + +#endif /* _QUEUES_H_ */ + +/** @} */ diff --git a/os/kernel/include/scheduler.h b/os/kernel/include/scheduler.h new file mode 100644 index 000000000..648cb7bc5 --- /dev/null +++ b/os/kernel/include/scheduler.h @@ -0,0 +1,110 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file scheduler.h + * @brief Scheduler macros and structures. + * @addtogroup Scheduler + * @{ + */ + +#ifndef _SCHEDULER_H_ +#define _SCHEDULER_H_ + +/** Default thread wakeup low level message. */ +#define RDY_OK 0 +/** Low level message sent to a thread awakened by a timeout. */ +#define RDY_TIMEOUT -1 +/** Low level message sent to a thread awakened by a reset operation. */ +#define RDY_RESET -2 + +#define NOPRIO 0 /**< Ready list header priority.*/ +#define IDLEPRIO 1 /**< Idle thread priority.*/ +#define LOWPRIO 2 /**< Lowest user priority.*/ +#define NORMALPRIO 64 /**< Normal user priority.*/ +#define HIGHPRIO 127 /**< Highest user priority.*/ +#define ABSPRIO 255 /**< Greatest possible priority.*/ + +/** + * Zero time specification for some syscalls with a timeout + * specification. + * @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter, + * see the specific function documentation. + */ +#define TIME_IMMEDIATE ((systime_t)-1) + +/** + * Infinite time specification for all the syscalls with a timeout + * specification. + */ +#define TIME_INFINITE ((systime_t)0) + +/** The priority of the first thread on the given ready list. */ +#define firstprio(rlp) ((rlp)->p_next->p_prio) + +/** + * @brief Ready list header. + * + * @extends ThreadsQueue + */ +typedef struct { + Thread *p_next; /**< Next @p Thread in the ready list.*/ + Thread *p_prev; /**< Previous @p Thread in the ready + list.*/ + /* End of the fields shared with the ThreadsQueue structure. */ + tprio_t r_prio; /**< This field must be initialized to + zero.*/ + /* End of the fields shared with the Thread structure. */ +#if CH_USE_ROUNDROBIN + cnt_t r_preempt; /**< Round robin counter.*/ +#endif +#ifndef CH_CURRP_REGISTER_CACHE + Thread *r_current; /**< The currently running thread.*/ +#endif +} ReadyList; + +extern ReadyList rlist; + +/* + * Scheduler APIs. + */ +#ifdef __cplusplus +extern "C" { +#endif + void scheduler_init(void); + Thread *chSchReadyI(Thread *tp); + void chSchGoSleepS(tstate_t newstate); + msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time); + void chSchWakeupS(Thread *tp, msg_t msg); + void chSchDoRescheduleI(void); + void chSchRescheduleS(void); + bool_t chSchRescRequiredI(void); +#ifdef __cplusplus +} +#endif + +#ifdef CH_CURRP_REGISTER_CACHE +register Thread *currp asm(CH_CURRP_REGISTER_CACHE); +#else +#define currp rlist.r_current +#endif + +#endif /* _SCHEDULER_H_ */ + +/** @} */ diff --git a/os/kernel/include/semaphores.h b/os/kernel/include/semaphores.h new file mode 100644 index 000000000..833fc5cd2 --- /dev/null +++ b/os/kernel/include/semaphores.h @@ -0,0 +1,99 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file semaphores.h + * @brief Semaphores macros and structures. + * @addtogroup Semaphores + * @{ + */ + +#ifndef _SEMAPHORES_H_ +#define _SEMAPHORES_H_ + +#if CH_USE_SEMAPHORES + +/** + * @brief Semaphore structure. + */ +typedef struct Semaphore { + ThreadsQueue s_queue; /**< Queue of the threads sleeping on + this semaphore.*/ + cnt_t s_cnt; /**< The semaphore counter.*/ +} Semaphore; + +#ifdef __cplusplus +extern "C" { +#endif + void chSemInit(Semaphore *sp, cnt_t n); + void chSemReset(Semaphore *sp, cnt_t n); + void chSemResetI(Semaphore *sp, cnt_t n); + msg_t chSemWait(Semaphore *sp); + msg_t chSemWaitS(Semaphore *sp); + msg_t chSemWaitTimeout(Semaphore *sp, systime_t time); + msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time); + void chSemSignal(Semaphore *sp); + void chSemSignalI(Semaphore *sp); +#if CH_USE_SEMSW + msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw); +#endif +#ifdef __cplusplus +} +#endif + +/** + * @brief Data part of a static semaphore initializer. + * @details This macro should be used when statically initializing a semaphore + * that is part of a bigger structure. + * @param name the name of the semaphore variable + * @param n the counter initial value, this value must be non-negative + */ +#define _SEMAPHORE_DATA(name, n) {_THREADSQUEUE_DATA(name.s_queue), n} + +/** + * @brief Static semaphore initializer. + * @details Statically initialized semaphores require no explicit initialization + * using @p chSemInit(). + * @param name the name of the semaphore variable + * @param n the counter initial value, this value must be non-negative + */ +#define SEMAPHORE_DECL(name, n) Semaphore name = _SEMAPHORE_DATA(name, n) + +/** + * Decreases the semaphore counter, this macro can be used when it is ensured + * that the counter would not become negative. + */ +#define chSemFastWaitI(sp) ((sp)->s_cnt--) + +/** + * Increases the semaphore counter, this macro can be used when the counter is + * not negative. + */ +#define chSemFastSignalI(sp) ((sp)->s_cnt++) + +/** + * Returns the semaphore counter current value. + */ +#define chSemGetCounterI(sp) ((sp)->s_cnt) + +#endif /* CH_USE_SEMAPHORES */ + +#endif /* _SEMAPHORES_H_ */ + +/** @} */ diff --git a/os/kernel/include/serial.h b/os/kernel/include/serial.h new file mode 100644 index 000000000..deaca3d97 --- /dev/null +++ b/os/kernel/include/serial.h @@ -0,0 +1,217 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file serial.h + * @brief Serial Drivers macros and structures. + * @addtogroup Serial + * @{ + */ + +#ifndef _SERIAL_H_ +#define _SERIAL_H_ + +#if CH_USE_SERIAL_FULLDUPLEX + +/** No pending conditions.*/ +#define SD_NO_ERROR 0 +/** Connection happened.*/ +#define SD_CONNECTED 1 +/** Disconnection happened.*/ +#define SD_DISCONNECTED 2 +/** Parity error happened.*/ +#define SD_PARITY_ERROR 4 +/** Framing error happened.*/ +#define SD_FRAMING_ERROR 8 +/** Overflow happened.*/ +#define SD_OVERRUN_ERROR 16 +/** Break detected.*/ +#define SD_BREAK_DETECTED 32 + +/** Serial Driver condition flags type.*/ +typedef uint8_t dflags_t; + +/** + * @brief @p FullDuplexDriver specific methods. + */ +struct _full_duplex_driver_methods { +}; + +/** + * @brief @p FullDuplexDriver specific data. + */ +struct _full_duplex_driver_data { + /** + * Input queue, incoming data can be read from this input queue by + * using the queues APIs. + */ + InputQueue iqueue; + /** + * Output queue, outgoing data can be written to this output queue by + * using the queues APIs. + */ + OutputQueue oqueue; + /** + * Status Change @p EventSource. This event is generated when one or more + * condition flags change. + */ + EventSource sevent; + /** + * I/O driver status flags. + */ + dflags_t flags; +}; + +/** + * @brief @p FullDuplexDriver virtual methods table. + */ +struct FullDuplexDriverVMT { + /** + * @p BaseChannel class inherited methods. + */ + struct _base_channel_methods m0; + /** + * @p BaseAsynchronousChannel class inherited methods. + */ + struct _base_asynchronous_channel_methods m1; + /** + * @p FullDuplexDriver specific methods. + */ + struct _full_duplex_driver_methods m2; +}; + +/** + * @extends BaseAsynchronousChannel + * + * @brief Full duplex serial driver class. + * @details This class extends @p GenericSerialDriver by adding physical I/O + * queues. + */ +typedef struct { + /** + * Virtual Methods Table. + */ + const struct FullDuplexDriverVMT *vmt; + /** + * @p BaseChannel class inherited data. + */ + struct _base_channel_data d0; + /** + * @p BaseAsynchronousChannel class inherited data. + */ + struct _base_asynchronous_channel_data d1; + /** + * @p FullDuplexDriver specific data. + */ + struct _full_duplex_driver_data d2; +} FullDuplexDriver; + +#ifdef __cplusplus +extern "C" { +#endif + void chFDDInit(FullDuplexDriver *sd, + uint8_t *ib, size_t isize, qnotify_t inotify, + uint8_t *ob, size_t osize, qnotify_t onotify); + void chFDDIncomingDataI(FullDuplexDriver *sd, uint8_t b); + msg_t chFDDRequestDataI(FullDuplexDriver *sd); + void chFDDAddFlagsI(FullDuplexDriver *sd, dflags_t mask); + dflags_t chFDDGetAndClearFlags(FullDuplexDriver *sd); +#ifdef __cplusplus +} +#endif + +/** + * @brief Direct output check on a @p FullDuplexDriver. + * @details This function bypasses the indirect access to the channel and + * checks directly the output queue. This is faster but cannot + * be used to check different channels implementations. + * @see chIOPutWouldBlock() + */ +#define chFDDPutWouldBlock(sd) chOQIsFull(&(sd)->d2.oqueue) + +/** + * @brief Direct input check on a @p FullDuplexDriver. + * @details This function bypasses the indirect access to the channel and + * checks directly the input queue. This is faster but cannot + * be used to check different channels implementations. + * @see chIOGetWouldBlock() + */ +#define chFDDGetWouldBlock(sd) chIQIsEmpty(&(sd)->d2.iqueue) + +/** + * @brief Direct blocking write to a @p FullDuplexDriver. + * @details This function bypasses the indirect access to the channel and + * writes directly on the output queue. This is faster but cannot + * be used to write to different channels implementations. + * @see chIOPut() + */ +#define chFDDPut(sd, b) chOQPut(&(sd)->d2.oqueue, b) + +/** + * @brief Direct blocking write on a @p FullDuplexDriver with timeout + * specification. + * @details This function bypasses the indirect access to the channel and + * writes directly on the output queue. This is faster but cannot + * be used to write to different channels implementations. + * @see chIOPutTimeout() + */ +#define chFDDPutTimeout(sd, b, t) chOQPutTimeout(&(sd)->d2.iqueue, b, t) + +/** + * @brief Direct blocking read from a @p FullDuplexDriver. + * @details This function bypasses the indirect access to the channel and + * reads directly from the input queue. This is faster but cannot + * be used to read from different channels implementations. + * @see chIOGet() + */ +#define chFDDGet(sd) chIQGet(&(sd)->d2.iqueue) + +/** + * @brief Direct blocking read from a @p FullDuplexDriver with timeout + * specification. + * @details This function bypasses the indirect access to the channel and + * reads directly from the input queue. This is faster but cannot + * be used to read from different channels implementations. + * @see chIOGetTimeout() + */ +#define chFDDGetTimeout(sd, t) chIQGetTimeout(&(sd)->d2.iqueue, t) + +/** + * @brief Direct non-blocking write to a @p FullDuplexDriver. + * @details This function bypasses the indirect access to the channel and + * writes directly to the output queue. This is faster but cannot + * be used to write from different channels implementations. + * @see chIOWrite() + */ +#define chFDDWrite(sd, b, n) chOQWrite(&(sd)->d2.oqueue, b, n) + +/** + * @brief Direct non-blocking read on a @p FullDuplexDriver. + * @details This function bypasses the indirect access to the channel and + * reads directly from the input queue. This is faster but cannot + * be used to read from different channels implementations. + * @see chIORead() + */ +#define chFDDRead(sd, b, n) chIQRead(&(sd)->d2.iqueue, b, n) + +#endif /* CH_USE_SERIAL_FULLDUPLEX */ + +#endif /* _SERIAL_H_ */ + +/** @} */ diff --git a/os/kernel/include/sys.h b/os/kernel/include/sys.h new file mode 100644 index 000000000..a84d33da8 --- /dev/null +++ b/os/kernel/include/sys.h @@ -0,0 +1,184 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file sys.h + * @brief System related macros and structures. + * @addtogroup System + * @{ + */ + +#ifndef _SYS_H_ +#define _SYS_H_ + +/** + * @brief Halts the system. + * @details This function is invoked by the operating system when an + * unrecoverable error is detected (as example because a programming error in + * the application code that triggers an assertion while in debug mode). + */ +#define chSysHalt() port_halt() + +/** + * @brief Performs a context switch. + * + * @param otp the thread to be switched out + * @param ntp the thread to be switched in + */ +#define chSysSwitchI(otp, ntp) port_switch(otp, ntp) + +/** + * @brief Raises the system interrupt priority mask to the maximum level. + * @details All the maskable interrupt sources are disabled regardless their + * hardware priority. + * + * @note The implementation is architecture dependent, it may just disable the + * interrupts or be exactly equivalent to @p chSysDisable(). + * @note Do not invoke this API from within a kernel lock. + */ +#define chSysDisable() port_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 The implementation is architecture dependent, it may just disable the + * interrupts. + * @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. + */ +#define chSysSuspend() port_suspend() + +/** + * @brief Lowers the system interrupt priority mask to user level. + * @details All the interrupt sources are enabled. + * + * @note The implementation is architecture dependent, it may just enable the + * interrupts. + * @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. + */ +#define chSysEnable() port_enable() + +/** + * @brief Enters the kernel lock mode. + * + * @note The use of kernel lock mode is not recommended in the user code, it is + * a better idea to use the semaphores or mutexes instead. + * @see CH_USE_NESTED_LOCKS + */ +#if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__) +#if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__) +#define chSysLock() { \ + if (currp->p_locks++ == 0) \ + port_lock(); \ +} +#endif /* CH_OPTIMIZE_SPEED */ +#else /* !CH_USE_NESTED_LOCKS */ +#define chSysLock() port_lock() +#endif /* !CH_USE_NESTED_LOCKS */ + +/** + * @brief Leaves the kernel lock mode. + * + * @note The use of kernel lock mode is not recommended in the user code, it is + * a better idea to use the semaphores or mutexes instead. + * @see CH_USE_NESTED_LOCKS + */ +#if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__) +#if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__) +#define chSysUnlock() { \ + if (--currp->p_locks == 0) \ + port_unlock(); \ +} +#endif /* CH_OPTIMIZE_SPEED */ +#else /* !CH_USE_NESTED_LOCKS */ +#define chSysUnlock() port_unlock() +#endif /* !CH_USE_NESTED_LOCKS */ + +/** + * @brief Enters the kernel lock mode from within an interrupt handler. + * + * @note This API may do nothing on some architectures, it is required because + * on ports that support preemptable interrupt handlers it is required to + * raise the interrupt mask to the same level of the system mutual + * exclusion zone.
+ * 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. + */ +#define chSysLockFromIsr() port_lock_from_isr() + +/** + * @brief Leaves the kernel lock mode from within an interrupt handler. + * + * @note This API may do nothing on some architectures, it is required because + * on ports that support preemptable interrupt handlers it is required to + * raise the interrupt mask to the same level of the system mutual + * exclusion zone.
+ * 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. + */ +#define chSysUnlockFromIsr() port_unlock_from_isr() + +/** + * @brief IRQ handler enter code. + * + * @note Usually IRQ handlers functions are also declared naked. + * @note On some architectures this macro can be empty. + */ +#define CH_IRQ_PROLOGUE() PORT_IRQ_PROLOGUE() + +/** + * @brief IRQ handler exit code. + * + * @note Usually IRQ handlers function are also declared naked. + * @note This macro usually performs the final reschedulation by using + * @p chSchRescRequiredI() and @p chSchDoRescheduleI(). + */ +#define CH_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE() + +/** + * @brief Standard IRQ handler declaration. + * + * @note @p id can be a function name or a vector number depending on the + * port implementation. + */ +#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id) + +#ifdef __cplusplus +extern "C" { +#endif + void chSysInit(void); + void chSysTimerHandlerI(void); +#if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED + void chSysLock(void); + void chSysUnlock(void); +#endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */ +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_H_ */ + +/** @} */ diff --git a/os/kernel/include/threads.h b/os/kernel/include/threads.h new file mode 100644 index 000000000..07e068854 --- /dev/null +++ b/os/kernel/include/threads.h @@ -0,0 +1,269 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file threads.h + * @brief Threads macros and structures. + * @addtogroup Threads + * @{ + */ + +#ifndef _THREADS_H_ +#define _THREADS_H_ + +/** + * @brief Structure representing a thread. + * + * @extends ThreadsQueue + * @note Not all the listed fields are always needed, by switching off some + * not needed ChibiOS/RT subsystems it is possible to save RAM space by + * shrinking the @p Thread structure. + */ +struct Thread { + Thread *p_next; /**< Next @p Thread in the threads + list/queue.*/ + /* End of the fields shared with the ThreadsList structure. */ + Thread *p_prev; /**< Previous @p Thread in the threads + queue.*/ + /* End of the fields shared with the ThreadsQueue structure. */ + tprio_t p_prio; /**< Thread priority.*/ + /* End of the fields shared with the ReadyList structure. */ + tstate_t p_state; /**< Current thread state.*/ + tmode_t p_flags; /**< Various flags.*/ + struct context p_ctx; /**< Processor context.*/ +#if CH_USE_NESTED_LOCKS + cnt_t p_locks; /**< Number of nested locks.*/ +#endif +#if CH_DBG_THREADS_PROFILING + volatile systime_t p_time; /**< Consumed time. + @note This field can overflow.*/ +#endif + /* + * The following fields are merged in unions because they are all + * state-specific fields. This trick saves some extra space for each + * thread in the system. + */ + union { + msg_t p_rdymsg; /**< Thread wakeup code.*/ + msg_t p_exitcode; /**< The thread exit code + (@p PREXIT state).*/ + void *p_wtobjp; /**< Generic kernel object pointer used + for opaque access.*/ +#if CH_USE_SEMAPHORES + Semaphore *p_wtsemp; /**< Semaphore where the thread is + waiting on (@p PRWTSEM state).*/ +#endif +#if CH_USE_MUTEXES + Mutex *p_wtmtxp; /**< Mutex where the thread is waiting + on (@p PRWTMTX state).*/ +#endif +#if CH_USE_CONDVARS + CondVar *p_wtcondp; /**< CondVar where the thread is + waiting on (@p PRWTCOND state).*/ +#endif +#if CH_USE_MESSAGES + Thread *p_wtthdp; /**< Destination thread for message + send @p PRSNDMSG state).*/ +#endif +#if CH_USE_EVENTS + eventmask_t p_ewmask; /**< Enabled events mask (@p PRWTOREVT + or @p PRWTANDEVT states).*/ +#endif + }; + /* + * Start of the optional fields. + */ +#if CH_USE_WAITEXIT + Thread *p_waiting; /**< Thread waiting for termination.*/ +#endif +#if CH_USE_MESSAGES + ThreadsQueue p_msgqueue; /**< Message queue.*/ + msg_t p_msg; /**< The message.*/ +#endif +#if CH_USE_EVENTS + eventmask_t p_epending; /**< Pending events mask.*/ +#endif +#if CH_USE_MUTEXES + Mutex *p_mtxlist; /**< List of the mutexes owned by this + thread, @p NULL terminated.*/ + tprio_t p_realprio; /**< Thread's own, non-inherited, + priority.*/ +#endif +#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS + void *p_mpool; /**< Memory Pool where the thread + workspace is returned.*/ +#endif + /* Extra fields defined in chconf.h */ + THREAD_EXT_FIELDS +}; + +/** Thread state: Ready to run, waiting on the ready list.*/ +#define PRREADY 0 +/** Thread state: Currently running. */ +#define PRCURR 1 +/** Thread state: Thread created in suspended state. */ +#define PRSUSPENDED 2 +/** Thread state: Waiting on a semaphore. */ +#define PRWTSEM 3 +/** Thread state: Waiting on a mutex. */ +#define PRWTMTX 4 +/** Thread state: Waiting in @p chThdSleep() or @p chThdSleepUntil(). */ +#define PRWTCOND 5 +/** Thread state: Waiting in @p chCondWait(). */ +#define PRSLEEP 6 +/** Thread state: Waiting in @p chThdWait(). */ +#define PRWAIT 7 +/** Thread state: Waiting in @p chEvtWaitOneTimeout() or + @p chEvtWaitAnyTimeout(). */ +#define PRWTOREVT 8 +/** Thread state: Waiting in @p chEvtWaitAllTimeout(). */ +#define PRWTANDEVT 9 +/** Thread state: Waiting in @p chMsgSend(). */ +#define PRSNDMSG 10 +/** Thread state: Waiting in @p chMsgWait(). */ +#define PRWTMSG 11 +/** Thread state: After termination.*/ +#define PREXIT 12 + +/* + * Various flags into the thread p_flags field. + */ +#define P_MEM_MODE_MASK 3 /* Thread memory mode mask. */ +#define P_MEM_MODE_STATIC 0 /* Thread memory mode: static. */ +#define P_MEM_MODE_HEAP 1 /* Thread memory mode: heap. */ +#define P_MEM_MODE_MEMPOOL 2 /* Thread memory mode: mempool. */ +#define P_TERMINATE 4 /* Termination requested. */ + +/* Not an API, don't use into the application code.*/ +Thread *init_thread(Thread *tp, tprio_t prio); + +/** Thread function.*/ +typedef msg_t (*tfunc_t)(void *); + +/* + * Threads APIs. + */ +#ifdef __cplusplus +extern "C" { +#endif + Thread *chThdInit(void *wsp, size_t size, + tprio_t prio, tfunc_t pf, void *arg); + Thread *chThdCreateStatic(void *wsp, size_t size, + tprio_t prio, tfunc_t pf, void *arg); +#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP + Thread *chThdCreateFromHeap(size_t size, tprio_t prio, + tfunc_t pf, void *arg); +#endif +#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS + Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, + tfunc_t pf, void *arg); +#endif + tprio_t chThdSetPriority(tprio_t newprio); + Thread *chThdResume(Thread *tp); + void chThdTerminate(Thread *tp); + void chThdSleep(systime_t time); + void chThdSleepUntil(systime_t time); + void chThdExit(msg_t msg); +#if CH_USE_WAITEXIT + msg_t chThdWait(Thread *tp); +#endif +#ifdef __cplusplus +} +#endif + +/** Returns the pointer to the @p Thread currently in execution.*/ +#define chThdSelf() currp + +/** Returns the current thread priority.*/ +#define chThdGetPriority() (currp->p_prio) + +/** Returns the pointer to the @p Thread local storage area, if any.*/ +#define chThdLS() (void *)(currp + 1) + +/** + * Verifies if the specified thread is in the @p PREXIT state. + * + * @param[in] tp the pointer to the thread + * @retval TRUE thread terminated. + * @retval FALSE thread not terminated. + */ +#define chThdTerminated(tp) ((tp)->p_state == PREXIT) + +/** + * Verifies if the current thread has a termination request pending. + * + * @retval TRUE termination request pended. + * @retval FALSE termination request not pended. + */ +#define chThdShouldTerminate() (currp->p_flags & P_TERMINATE) + +/** + * Resumes a thread created with @p chThdInit(). + * + * @param[in] tp the pointer to the thread + */ +#define chThdResumeI(tp) chSchReadyI(tp) + +/** + * Suspends the invoking thread for the specified time. + * + * @param[in] time the delay in system ticks, the special values are handled as + * follow: + * - @a TIME_INFINITE the thread enters an infinite sleep + * state. + * - @a TIME_IMMEDIATE this value is accepted but interpreted + * as a normal time specification not as an immediate timeout + * specification. + * . + */ +#define chThdSleepS(time) chSchGoSleepTimeoutS(PRSLEEP, time) + +/** + * Delays the invoking thread for the specified number of seconds. + * + * @param[in] sec the time in seconds + * @note The specified time is rounded up to a value allowed by the real + * system clock. + * @note The maximum specified value is implementation dependent. + */ +#define chThdSleepSeconds(sec) chThdSleep(S2ST(sec)) + +/** + * Delays the invoking thread for the specified number of milliseconds. + * + * @param[in] msec the time in milliseconds + * @note The specified time is rounded up to a value allowed by the real + * system clock. + * @note The maximum specified value is implementation dependent. + */ +#define chThdSleepMilliseconds(msec) chThdSleep(MS2ST(msec)) + +/** + * Delays the invoking thread for the specified number of microseconds. + * + * @param[in] usec the time in microseconds + * @note The specified time is rounded up to a value allowed by the real + * system clock. + * @note The maximum specified value is implementation dependent. + */ +#define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec)) + +#endif /* _THREADS_H_ */ + +/** @} */ diff --git a/os/kernel/include/vt.h b/os/kernel/include/vt.h new file mode 100644 index 000000000..003cffd45 --- /dev/null +++ b/os/kernel/include/vt.h @@ -0,0 +1,125 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file vt.h + * @brief Time macros and structures. + * @addtogroup Time + * @{ + */ + +#ifndef _VT_H_ +#define _VT_H_ + +/** + * Time conversion utility. Converts from seconds to system ticks number. + */ +#define S2ST(sec) ((systime_t)((sec) * CH_FREQUENCY)) + +/** + * Time conversion utility. Converts from milliseconds to system ticks number. + * @note The result is rounded upward to the next tick boundary. + */ +#define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / 1000L) + 1L)) + +/** + * Time conversion utility. Converts from microseconds to system ticks number. + * @note The result is rounded upward to the next tick boundary. + */ +#define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / 1000000L) + 1L)) + +/** Virtual Timer callback function.*/ +typedef void (*vtfunc_t)(void *); + +typedef struct VirtualTimer VirtualTimer; + +/** + * @brief Virtual Timer descriptor structure. + * @extends DeltaList + */ +struct VirtualTimer { + VirtualTimer *vt_next; /**< Next timer in the delta list.*/ + VirtualTimer *vt_prev; /**< Previous timer in the delta list.*/ + systime_t vt_time; /**< Time delta before timeout.*/ + vtfunc_t vt_func; /**< Timer callback function pointer. + The pointer is reset to zero after + the callback is invoked.*/ + void *vt_par; /**< Timer callback function + parameter.*/ +}; + +/** + * @brief Virtual timers list header. + * @note The delta list is implemented as a double link bidirectional list in + * order to make the unlink time constant, the reset of a virtual timer + * is often used in the code. + */ +typedef struct { + VirtualTimer *vt_next; /**< Next timer in the delta list (the + one that will be triggered next).*/ + VirtualTimer *vt_prev; /**< Last timer in the delta list.*/ + systime_t vt_time; /**< Must be initialized to -1.*/ + volatile systime_t vt_systime; /**< System Time counter.*/ +} VTList; + +extern VTList vtlist; + +#define chVTDoTickI() { \ + vtlist.vt_systime++; \ + if (&vtlist != (VTList *)vtlist.vt_next) { \ + VirtualTimer *vtp; \ + \ + --vtlist.vt_next->vt_time; \ + while (!(vtp = vtlist.vt_next)->vt_time) { \ + vtfunc_t fn = vtp->vt_func; \ + vtp->vt_func = NULL; \ + (vtp->vt_next->vt_prev = (void *)&vtlist)->vt_next = vtp->vt_next;\ + fn(vtp->vt_par); \ + } \ + } \ +} + +/* + * Virtual Timers APIs. + */ +#ifdef __cplusplus +extern "C" { +#endif + void vt_init(void); + void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par); + void chVTResetI(VirtualTimer *vtp); + bool_t chTimeIsWithin(systime_t start, systime_t end); +#ifdef __cplusplus +} +#endif + +/** Returns TRUE if the speciified timer is armed.*/ +#define chVTIsArmedI(vtp) ((vtp)->vt_func != NULL) + +/** + * Returns the number of system ticks since the @p chSysInit() invocation. + * @return the system ticks number + * @note The counter can reach its maximum and then returns to zero. + * @note This function is designed to work with the @p chThdSleepUntil(). + */ +#define chTimeNow() (vtlist.vt_systime) + +#endif /* _VT_H_ */ + +/** @} */ -- cgit v1.2.3