First cleanup pass finished, queues and streams not yet removed.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@5999 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
d58064a533
commit
25ddb1c801
|
@ -302,20 +302,6 @@
|
||||||
#define CH_USE_HEAP TRUE
|
#define CH_USE_HEAP TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief C-runtime allocator.
|
|
||||||
* @details If enabled the the heap allocator APIs just wrap the C-runtime
|
|
||||||
* @p malloc() and @p free() functions.
|
|
||||||
*
|
|
||||||
* @note The default is @p FALSE.
|
|
||||||
* @note Requires @p CH_USE_HEAP.
|
|
||||||
* @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
|
|
||||||
* appropriate documentation.
|
|
||||||
*/
|
|
||||||
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
|
||||||
#define CH_USE_MALLOC_HEAP FALSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Memory Pools Allocator APIs.
|
* @brief Memory Pools Allocator APIs.
|
||||||
* @details If enabled then the memory pools allocator APIs are included
|
* @details If enabled then the memory pools allocator APIs are included
|
||||||
|
|
|
@ -230,7 +230,7 @@ typedef struct {
|
||||||
#define _base_asynchronous_channel_data \
|
#define _base_asynchronous_channel_data \
|
||||||
_base_channel_data \
|
_base_channel_data \
|
||||||
/* I/O condition event source.*/ \
|
/* I/O condition event source.*/ \
|
||||||
EventSource event;
|
event_source_t event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends BaseChannelVMT
|
* @extends BaseChannelVMT
|
||||||
|
@ -264,11 +264,11 @@ typedef struct {
|
||||||
*
|
*
|
||||||
* @param[in] ip pointer to a @p BaseAsynchronousChannel or derived
|
* @param[in] ip pointer to a @p BaseAsynchronousChannel or derived
|
||||||
* class
|
* class
|
||||||
* @return A pointer to an @p EventSource object.
|
* @return A pointer to an @p event_source_t object.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
#define chnGetEventSource(ip) (&((ip)->event))
|
#define chnGetevent_source_t(ip) (&((ip)->event))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds status flags to the listeners's flags mask.
|
* @brief Adds status flags to the listeners's flags mask.
|
||||||
|
|
|
@ -124,7 +124,7 @@ static void usart_deinit(USART_TypeDef *u) {
|
||||||
* @param[in] isr USART ISR register value
|
* @param[in] isr USART ISR register value
|
||||||
*/
|
*/
|
||||||
static void set_error(SerialDriver *sdp, uint32_t isr) {
|
static void set_error(SerialDriver *sdp, uint32_t isr) {
|
||||||
flagsmask_t sts = 0;
|
eventflags_t sts = 0;
|
||||||
|
|
||||||
if (isr & USART_ISR_ORE)
|
if (isr & USART_ISR_ORE)
|
||||||
sts |= SD_OVERRUN_ERROR;
|
sts |= SD_OVERRUN_ERROR;
|
||||||
|
|
|
@ -128,19 +128,6 @@ typedef struct thread thread_t;
|
||||||
#include "chdynamic.h"
|
#include "chdynamic.h"
|
||||||
#include "chqueues.h"
|
#include "chqueues.h"
|
||||||
#include "chstreams.h"
|
#include "chstreams.h"
|
||||||
#include "chfiles.h"
|
|
||||||
|
|
||||||
#if !defined(__DOXYGEN__)
|
|
||||||
extern WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
void _idle_thread(void *p);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _CH_H_ */
|
#endif /* _CH_H_ */
|
||||||
|
|
||||||
|
|
|
@ -74,11 +74,11 @@ extern "C" {
|
||||||
thread_t *chThdAddRef(thread_t *tp);
|
thread_t *chThdAddRef(thread_t *tp);
|
||||||
void chThdRelease(thread_t *tp);
|
void chThdRelease(thread_t *tp);
|
||||||
#if CH_USE_HEAP
|
#if CH_USE_HEAP
|
||||||
thread_t *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
|
thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size,
|
||||||
tprio_t prio, tfunc_t pf, void *arg);
|
tprio_t prio, tfunc_t pf, void *arg);
|
||||||
#endif
|
#endif
|
||||||
#if CH_USE_MEMPOOLS
|
#if CH_USE_MEMPOOLS
|
||||||
thread_t *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
|
thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, tprio_t prio,
|
||||||
tfunc_t pf, void *arg);
|
tfunc_t pf, void *arg);
|
||||||
#endif
|
#endif
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -50,32 +50,30 @@
|
||||||
/* Module data structures and types. */
|
/* Module data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
typedef struct EventListener EventListener;
|
typedef struct event_listener event_listener_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Event Listener structure.
|
* @brief Event Listener structure.
|
||||||
*/
|
*/
|
||||||
struct EventListener {
|
struct event_listener {
|
||||||
EventListener *el_next; /**< @brief Next Event Listener
|
event_listener_t *el_next; /**< @brief Next Event Listener
|
||||||
registered on the Event
|
registered on the event
|
||||||
Source. */
|
source. */
|
||||||
thread_t *el_listener; /**< @brief Thread interested in the
|
thread_t *el_listener; /**< @brief Thread interested in the
|
||||||
Event Source. */
|
event source. */
|
||||||
eventmask_t el_mask; /**< @brief Event flags mask associated
|
eventmask_t el_mask; /**< @brief Event identifiers mask. */
|
||||||
by the thread to the Event
|
eventflags_t el_flags; /**< @brief Flags added to the listener
|
||||||
Source. */
|
|
||||||
flagsmask_t el_flags; /**< @brief Flags added to the listener
|
|
||||||
by the event source.*/
|
by the event source.*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Event Source structure.
|
* @brief Event Source structure.
|
||||||
*/
|
*/
|
||||||
typedef struct EventSource {
|
typedef struct event_source {
|
||||||
EventListener *es_next; /**< @brief First Event Listener
|
event_listener_t *es_next; /**< @brief First Event Listener
|
||||||
registered on the Event
|
registered on the Event
|
||||||
Source. */
|
Source. */
|
||||||
} EventSource;
|
} event_source_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Event Handler callback function.
|
* @brief Event Handler callback function.
|
||||||
|
@ -111,7 +109,7 @@ typedef void (*evhandler_t)(eventid_t);
|
||||||
*
|
*
|
||||||
* @param name the name of the event source variable
|
* @param name the name of the event source variable
|
||||||
*/
|
*/
|
||||||
#define EVENTSOURCE_DECL(name) EventSource name = _EVENTSOURCE_DATA(name)
|
#define EVENTSOURCE_DECL(name) event_source_t name = _EVENTSOURCE_DATA(name)
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* External declarations. */
|
/* External declarations. */
|
||||||
|
@ -120,18 +118,18 @@ typedef void (*evhandler_t)(eventid_t);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void chEvtRegisterMask(EventSource *esp,
|
void chEvtRegisterMask(event_source_t *esp,
|
||||||
EventListener *elp,
|
event_listener_t *elp,
|
||||||
eventmask_t mask);
|
eventmask_t mask);
|
||||||
void chEvtUnregister(EventSource *esp, EventListener *elp);
|
void chEvtUnregister(event_source_t *esp, event_listener_t *elp);
|
||||||
eventmask_t chEvtGetAndClearEvents(eventmask_t mask);
|
eventmask_t chEvtGetAndClearEvents(eventmask_t mask);
|
||||||
eventmask_t chEvtAddEvents(eventmask_t mask);
|
eventmask_t chEvtAddEvents(eventmask_t mask);
|
||||||
flagsmask_t chEvtGetAndClearFlags(EventListener *elp);
|
eventflags_t chEvtGetAndClearFlags(event_listener_t *elp);
|
||||||
flagsmask_t chEvtGetAndClearFlagsI(EventListener *elp);
|
eventflags_t chEvtGetAndClearFlagsI(event_listener_t *elp);
|
||||||
void chEvtSignal(thread_t *tp, eventmask_t mask);
|
void chEvtSignal(thread_t *tp, eventmask_t mask);
|
||||||
void chEvtSignalI(thread_t *tp, eventmask_t mask);
|
void chEvtSignalI(thread_t *tp, eventmask_t mask);
|
||||||
void chEvtBroadcastFlags(EventSource *esp, flagsmask_t flags);
|
void chEvtBroadcastFlags(event_source_t *esp, eventflags_t flags);
|
||||||
void chEvtBroadcastFlagsI(EventSource *esp, flagsmask_t flags);
|
void chEvtBroadcastFlagsI(event_source_t *esp, eventflags_t flags);
|
||||||
void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask);
|
void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask);
|
||||||
#if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT
|
#if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT
|
||||||
eventmask_t chEvtWaitOne(eventmask_t mask);
|
eventmask_t chEvtWaitOne(eventmask_t mask);
|
||||||
|
@ -160,15 +158,15 @@ extern "C" {
|
||||||
/**
|
/**
|
||||||
* @brief Initializes an Event Source.
|
* @brief Initializes an Event Source.
|
||||||
* @note This function can be invoked before the kernel is initialized
|
* @note This function can be invoked before the kernel is initialized
|
||||||
* because it just prepares a @p EventSource structure.
|
* because it just prepares a @p event_source_t structure.
|
||||||
*
|
*
|
||||||
* @param[in] esp pointer to the @p EventSource structure
|
* @param[in] esp pointer to the @p event_source_t structure
|
||||||
*
|
*
|
||||||
* @init
|
* @init
|
||||||
*/
|
*/
|
||||||
static inline void chEvtInit(EventSource *esp) {
|
static inline void chEvtInit(event_source_t *esp) {
|
||||||
|
|
||||||
esp->es_next = (EventListener *)(void *)esp;
|
esp->es_next = (event_listener_t *)(void *)esp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,8 +174,8 @@ static inline void chEvtInit(EventSource *esp) {
|
||||||
* @note Multiple Event Listeners can use the same event identifier, the
|
* @note Multiple Event Listeners can use the same event identifier, the
|
||||||
* listener will share the callback function.
|
* listener will share the callback function.
|
||||||
*
|
*
|
||||||
* @param[in] esp pointer to the @p EventSource structure
|
* @param[in] esp pointer to the @p event_source_t structure
|
||||||
* @param[out] elp pointer to the @p EventListener structure
|
* @param[out] elp pointer to the @p event_listener_t structure
|
||||||
* @param[in] eid numeric identifier assigned to the Event Listener. The
|
* @param[in] eid numeric identifier assigned to the Event Listener. The
|
||||||
* identifier is used as index for the event callback
|
* identifier is used as index for the event callback
|
||||||
* function.
|
* function.
|
||||||
|
@ -186,21 +184,21 @@ static inline void chEvtInit(EventSource *esp) {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
static inline void chEvtRegister(EventSource *esp,
|
static inline void chEvtRegister(event_source_t *esp,
|
||||||
EventListener *elp,
|
event_listener_t *elp,
|
||||||
eventid_t eid) {
|
eventid_t eid) {
|
||||||
|
|
||||||
chEvtRegisterMask(esp, elp, EVENT_MASK(eid));
|
chEvtRegisterMask(esp, elp, EVENT_MASK(eid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Verifies if there is at least one @p EventListener registered.
|
* @brief Verifies if there is at least one @p event_listener_t registered.
|
||||||
*
|
*
|
||||||
* @param[in] esp pointer to the @p EventSource structure
|
* @param[in] esp pointer to the @p event_source_t structure
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
static inline bool chEvtIsListeningI(EventSource *esp) {
|
static inline bool chEvtIsListeningI(event_source_t *esp) {
|
||||||
|
|
||||||
return (bool)((void *)esp != (void *)esp->es_next);
|
return (bool)((void *)esp != (void *)esp->es_next);
|
||||||
}
|
}
|
||||||
|
@ -209,11 +207,11 @@ static inline bool chEvtIsListeningI(EventSource *esp) {
|
||||||
* @brief Signals all the Event Listeners registered on the specified Event
|
* @brief Signals all the Event Listeners registered on the specified Event
|
||||||
* Source.
|
* Source.
|
||||||
*
|
*
|
||||||
* @param[in] esp pointer to the @p EventSource structure
|
* @param[in] esp pointer to the @p event_source_t structure
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
static inline void chEvtBroadcast(EventSource *esp) {
|
static inline void chEvtBroadcast(event_source_t *esp) {
|
||||||
|
|
||||||
chEvtBroadcastFlags(esp, 0);
|
chEvtBroadcastFlags(esp, 0);
|
||||||
}
|
}
|
||||||
|
@ -226,11 +224,11 @@ static inline void chEvtBroadcast(EventSource *esp) {
|
||||||
* interrupt handlers always reschedule on exit so an explicit
|
* interrupt handlers always reschedule on exit so an explicit
|
||||||
* reschedule must not be performed in ISRs.
|
* reschedule must not be performed in ISRs.
|
||||||
*
|
*
|
||||||
* @param[in] esp pointer to the @p EventSource structure
|
* @param[in] esp pointer to the @p event_source_t structure
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
static inline void chEvtBroadcastI(EventSource *esp) {
|
static inline void chEvtBroadcastI(event_source_t *esp) {
|
||||||
|
|
||||||
chEvtBroadcastFlagsI(esp, 0);
|
chEvtBroadcastFlagsI(esp, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,165 +0,0 @@
|
||||||
/*
|
|
||||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
|
||||||
2011,2012,2013 Giovanni Di Sirio.
|
|
||||||
|
|
||||||
This file is part of ChibiOS/RT.
|
|
||||||
|
|
||||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file chfiles.h
|
|
||||||
* @brief Data files.
|
|
||||||
* @details This header defines abstract interfaces useful to access generic
|
|
||||||
* data files in a standardized way.
|
|
||||||
*
|
|
||||||
* @addtogroup data_files
|
|
||||||
* @details This module define an abstract interface for generic data files by
|
|
||||||
* extending the @p BaseSequentialStream interface. Note that no code
|
|
||||||
* is present, data files are just abstract interface-like structures,
|
|
||||||
* you should look at the systems as to a set of abstract C++ classes
|
|
||||||
* (even if written in C). This system has the advantage to make the
|
|
||||||
* access to streams independent from the implementation logic.<br>
|
|
||||||
* The data files interface can be used as base class for high level
|
|
||||||
* object types such as an API for a File System implementation.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CHFILES_H_
|
|
||||||
#define _CHFILES_H_
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief No error return code.
|
|
||||||
*/
|
|
||||||
#define FILE_OK 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Error code from the file stream methods.
|
|
||||||
*/
|
|
||||||
#define FILE_ERROR 0xFFFFFFFFUL
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief File offset type.
|
|
||||||
*/
|
|
||||||
typedef uint32_t fileoffset_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief BaseFileStream specific methods.
|
|
||||||
*/
|
|
||||||
#define _base_file_stream_methods \
|
|
||||||
_base_sequential_stream_methods \
|
|
||||||
/* File close method.*/ \
|
|
||||||
uint32_t (*close)(void *instance); \
|
|
||||||
/* Get last error code method.*/ \
|
|
||||||
int (*geterror)(void *instance); \
|
|
||||||
/* File get size method.*/ \
|
|
||||||
fileoffset_t (*getsize)(void *instance); \
|
|
||||||
/* File get current position method.*/ \
|
|
||||||
fileoffset_t (*getposition)(void *instance); \
|
|
||||||
/* File seek method.*/ \
|
|
||||||
uint32_t (*lseek)(void *instance, fileoffset_t offset);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief @p BaseFileStream specific data.
|
|
||||||
* @note It is empty because @p BaseFileStream is only an interface
|
|
||||||
* without implementation.
|
|
||||||
*/
|
|
||||||
#define _base_file_stream_data \
|
|
||||||
_base_sequential_stream_data
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @extends BaseSequentialStreamVMT
|
|
||||||
*
|
|
||||||
* @brief @p BaseFileStream virtual methods table.
|
|
||||||
*/
|
|
||||||
struct BaseFileStreamVMT {
|
|
||||||
_base_file_stream_methods
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @extends BaseSequentialStream
|
|
||||||
*
|
|
||||||
* @brief Base file stream class.
|
|
||||||
* @details This class represents a generic file data stream.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
/** @brief Virtual Methods Table.*/
|
|
||||||
const struct BaseFileStreamVMT *vmt;
|
|
||||||
_base_file_stream_data
|
|
||||||
} BaseFileStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name Macro Functions (BaseFileStream)
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @brief Base file Stream close.
|
|
||||||
* @details The function closes a file stream.
|
|
||||||
*
|
|
||||||
* @param[in] ip pointer to a @p BaseFileStream or derived class
|
|
||||||
* @return The operation status.
|
|
||||||
* @retval FILE_OK no error.
|
|
||||||
* @retval FILE_ERROR operation failed.
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define chFileStreamClose(ip) ((ip)->vmt->close(ip))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns an implementation dependent error code.
|
|
||||||
*
|
|
||||||
* @param[in] ip pointer to a @p BaseFileStream or derived class
|
|
||||||
* @return Implementation dependent error code.
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define chFileStreamGetError(ip) ((ip)->vmt->geterror(ip))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the current file size.
|
|
||||||
*
|
|
||||||
* @param[in] ip pointer to a @p BaseFileStream or derived class
|
|
||||||
* @return The file size.
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define chFileStreamGetSize(ip) ((ip)->vmt->getsize(ip))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the current file pointer position.
|
|
||||||
*
|
|
||||||
* @param[in] ip pointer to a @p BaseFileStream or derived class
|
|
||||||
* @return The current position inside the file.
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define chFileStreamGetPosition(ip) ((ip)->vmt->getposition(ip))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Moves the file current pointer to an absolute position.
|
|
||||||
*
|
|
||||||
* @param[in] ip pointer to a @p BaseFileStream or derived class
|
|
||||||
* @param[in] offset new absolute position
|
|
||||||
* @return The operation status.
|
|
||||||
* @retval FILE_OK no error.
|
|
||||||
* @retval FILE_ERROR operation failed.
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define chFileStreamSeek(ip, offset) ((ip)->vmt->lseek(ip, offset))
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* _CHFILES_H_ */
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -31,18 +31,34 @@
|
||||||
|
|
||||||
#if CH_USE_HEAP || defined(__DOXYGEN__)
|
#if CH_USE_HEAP || defined(__DOXYGEN__)
|
||||||
|
|
||||||
/*
|
/*===========================================================================*/
|
||||||
* Module dependencies check.
|
/* Module constants. */
|
||||||
*/
|
/*===========================================================================*/
|
||||||
#if !CH_USE_MEMCORE && !CH_USE_MALLOC_HEAP
|
|
||||||
#error "CH_USE_HEAP requires CH_USE_MEMCORE or CH_USE_MALLOC_HEAP"
|
/*===========================================================================*/
|
||||||
|
/* Module pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if !CH_USE_MEMCORE
|
||||||
|
#error "CH_USE_HEAP requires CH_USE_MEMCORE"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !CH_USE_MUTEXES && !CH_USE_SEMAPHORES
|
#if !CH_USE_MUTEXES && !CH_USE_SEMAPHORES
|
||||||
#error "CH_USE_HEAP requires CH_USE_MUTEXES and/or CH_USE_SEMAPHORES"
|
#error "CH_USE_HEAP requires CH_USE_MUTEXES and/or CH_USE_SEMAPHORES"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct memory_heap MemoryHeap;
|
/*===========================================================================*/
|
||||||
|
/* Module data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a memory heap.
|
||||||
|
*/
|
||||||
|
typedef struct memory_heap memory_heap_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Memory heap block header.
|
* @brief Memory heap block header.
|
||||||
|
@ -52,7 +68,7 @@ union heap_header {
|
||||||
struct {
|
struct {
|
||||||
union {
|
union {
|
||||||
union heap_header *next; /**< @brief Next block in free list. */
|
union heap_header *next; /**< @brief Next block in free list. */
|
||||||
MemoryHeap *heap; /**< @brief Block owner heap. */
|
memory_heap_t *heap; /**< @brief Block owner heap. */
|
||||||
} u; /**< @brief Overlapped fields. */
|
} u; /**< @brief Overlapped fields. */
|
||||||
size_t size; /**< @brief Size of the memory block. */
|
size_t size; /**< @brief Size of the memory block. */
|
||||||
} h;
|
} h;
|
||||||
|
@ -66,26 +82,36 @@ struct memory_heap {
|
||||||
this heap. */
|
this heap. */
|
||||||
union heap_header h_free; /**< @brief Free blocks list header. */
|
union heap_header h_free; /**< @brief Free blocks list header. */
|
||||||
#if CH_USE_MUTEXES
|
#if CH_USE_MUTEXES
|
||||||
Mutex h_mtx; /**< @brief Heap access mutex. */
|
mutex_t h_mtx; /**< @brief Heap access mutex. */
|
||||||
#else
|
#else
|
||||||
Semaphore h_sem; /**< @brief Heap access semaphore. */
|
semaphore_t h_sem; /**< @brief Heap access semaphore. */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void _heap_init(void);
|
void _heap_init(void);
|
||||||
#if !CH_USE_MALLOC_HEAP
|
void chHeapInit(memory_heap_t *heapp, void *buf, size_t size);
|
||||||
void chHeapInit(MemoryHeap *heapp, void *buf, size_t size);
|
void *chHeapAlloc(memory_heap_t *heapp, size_t size);
|
||||||
#endif
|
|
||||||
void *chHeapAlloc(MemoryHeap *heapp, size_t size);
|
|
||||||
void chHeapFree(void *p);
|
void chHeapFree(void *p);
|
||||||
size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep);
|
size_t chHeapStatus(memory_heap_t *heapp, size_t *sizep);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module inline functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#endif /* CH_USE_HEAP */
|
#endif /* CH_USE_HEAP */
|
||||||
|
|
||||||
#endif /* _CHHEAP_H_ */
|
#endif /* _CHHEAP_H_ */
|
||||||
|
|
|
@ -31,13 +31,26 @@
|
||||||
|
|
||||||
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
|
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
|
||||||
|
|
||||||
/*
|
/*===========================================================================*/
|
||||||
* Module dependencies check.
|
/* Module constants. */
|
||||||
*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#if !CH_USE_SEMAPHORES
|
#if !CH_USE_SEMAPHORES
|
||||||
#error "CH_USE_MAILBOXES requires CH_USE_SEMAPHORES"
|
#error "CH_USE_MAILBOXES requires CH_USE_SEMAPHORES"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Structure representing a mailbox object.
|
* @brief Structure representing a mailbox object.
|
||||||
*/
|
*/
|
||||||
|
@ -52,79 +65,11 @@ typedef struct {
|
||||||
@p semaphore_t. */
|
@p semaphore_t. */
|
||||||
semaphore_t mb_emptysem; /**< @brief Empty counter
|
semaphore_t mb_emptysem; /**< @brief Empty counter
|
||||||
@p semaphore_t. */
|
@p semaphore_t. */
|
||||||
} Mailbox;
|
} mailbox_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/*===========================================================================*/
|
||||||
extern "C" {
|
/* Module macros. */
|
||||||
#endif
|
/*===========================================================================*/
|
||||||
void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n);
|
|
||||||
void chMBReset(Mailbox *mbp);
|
|
||||||
msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout);
|
|
||||||
msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t timeout);
|
|
||||||
msg_t chMBPostI(Mailbox *mbp, msg_t msg);
|
|
||||||
msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout);
|
|
||||||
msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t timeout);
|
|
||||||
msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg);
|
|
||||||
msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t timeout);
|
|
||||||
msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t timeout);
|
|
||||||
msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name Macro Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @brief Returns the mailbox buffer size.
|
|
||||||
*
|
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
#define chMBSizeI(mbp) \
|
|
||||||
((mbp)->mb_top - (mbp)->mb_buffer)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the number of free message slots into a mailbox.
|
|
||||||
* @note Can be invoked in any system state but if invoked out of a locked
|
|
||||||
* state then the returned value may change after reading.
|
|
||||||
* @note The returned value can be less than zero when there are waiting
|
|
||||||
* threads on the internal semaphore.
|
|
||||||
*
|
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
|
||||||
* @return The number of empty message slots.
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
#define chMBGetFreeCountI(mbp) chSemGetCounterI(&(mbp)->mb_emptysem)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the number of used message slots into a mailbox.
|
|
||||||
* @note Can be invoked in any system state but if invoked out of a locked
|
|
||||||
* state then the returned value may change after reading.
|
|
||||||
* @note The returned value can be less than zero when there are waiting
|
|
||||||
* threads on the internal semaphore.
|
|
||||||
*
|
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
|
||||||
* @return The number of queued messages.
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
#define chMBGetUsedCountI(mbp) chSemGetCounterI(&(mbp)->mb_fullsem)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the next message in the queue without removing it.
|
|
||||||
* @pre A message must be waiting in the queue for this function to work
|
|
||||||
* or it would return garbage. The correct way to use this macro is
|
|
||||||
* to use @p chMBGetFullCountI() and then use this macro, all within
|
|
||||||
* a lock state.
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
#define chMBPeekI(mbp) (*(mbp)->mb_rdptr)
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Data part of a static mailbox initializer.
|
* @brief Data part of a static mailbox initializer.
|
||||||
|
@ -154,7 +99,99 @@ extern "C" {
|
||||||
* @param[in] size size of the mailbox buffer area
|
* @param[in] size size of the mailbox buffer area
|
||||||
*/
|
*/
|
||||||
#define MAILBOX_DECL(name, buffer, size) \
|
#define MAILBOX_DECL(name, buffer, size) \
|
||||||
Mailbox name = _MAILBOX_DATA(name, buffer, size)
|
mailbox_t name = _MAILBOX_DATA(name, buffer, size)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void chMBInit(mailbox_t *mbp, msg_t *buf, cnt_t n);
|
||||||
|
void chMBReset(mailbox_t *mbp);
|
||||||
|
msg_t chMBPost(mailbox_t *mbp, msg_t msg, systime_t timeout);
|
||||||
|
msg_t chMBPostS(mailbox_t *mbp, msg_t msg, systime_t timeout);
|
||||||
|
msg_t chMBPostI(mailbox_t *mbp, msg_t msg);
|
||||||
|
msg_t chMBPostAhead(mailbox_t *mbp, msg_t msg, systime_t timeout);
|
||||||
|
msg_t chMBPostAheadS(mailbox_t *mbp, msg_t msg, systime_t timeout);
|
||||||
|
msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg);
|
||||||
|
msg_t chMBFetch(mailbox_t *mbp, msg_t *msgp, systime_t timeout);
|
||||||
|
msg_t chMBFetchS(mailbox_t *mbp, msg_t *msgp, systime_t timeout);
|
||||||
|
msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module inline functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the mailbox buffer size.
|
||||||
|
*
|
||||||
|
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline size_t chMBSizeI(mailbox_t *mbp) {
|
||||||
|
|
||||||
|
return (size_t)(mbp->mb_top - mbp->mb_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the number of free message slots into a mailbox.
|
||||||
|
* @note Can be invoked in any system state but if invoked out of a locked
|
||||||
|
* state then the returned value may change after reading.
|
||||||
|
* @note The returned value can be less than zero when there are waiting
|
||||||
|
* threads on the internal semaphore.
|
||||||
|
*
|
||||||
|
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||||
|
* @return The number of empty message slots.
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline cnt_t chMBGetFreeCountI(mailbox_t *mbp) {
|
||||||
|
|
||||||
|
chDbgCheckClassI();
|
||||||
|
|
||||||
|
return chSemGetCounterI(&mbp->mb_emptysem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the number of used message slots into a mailbox.
|
||||||
|
* @note Can be invoked in any system state but if invoked out of a locked
|
||||||
|
* state then the returned value may change after reading.
|
||||||
|
* @note The returned value can be less than zero when there are waiting
|
||||||
|
* threads on the internal semaphore.
|
||||||
|
*
|
||||||
|
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||||
|
* @return The number of queued messages.
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline cnt_t chMBGetUsedCountI(mailbox_t *mbp) {
|
||||||
|
|
||||||
|
chDbgCheckClassI();
|
||||||
|
|
||||||
|
return chSemGetCounterI(&mbp->mb_fullsem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the next message in the queue without removing it.
|
||||||
|
* @pre A message must be waiting in the queue for this function to work
|
||||||
|
* or it would return garbage. The correct way to use this macro is
|
||||||
|
* to use @p chMBGetFullCountI() and then use this macro, all within
|
||||||
|
* a lock state.
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline cnt_t chMBPeekI(mailbox_t *mbp) {
|
||||||
|
|
||||||
|
chDbgCheckClassI();
|
||||||
|
|
||||||
|
return *mbp->mb_rdptr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CH_USE_MAILBOXES */
|
#endif /* CH_USE_MAILBOXES */
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,24 @@
|
||||||
#ifndef _CHMEMCORE_H_
|
#ifndef _CHMEMCORE_H_
|
||||||
#define _CHMEMCORE_H_
|
#define _CHMEMCORE_H_
|
||||||
|
|
||||||
|
#if CH_USE_MEMCORE || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Memory get function.
|
* @brief Memory get function.
|
||||||
* @note This type must be assignment compatible with the @p chMemAlloc()
|
* @note This type must be assignment compatible with the @p chMemAlloc()
|
||||||
|
@ -36,6 +54,10 @@
|
||||||
*/
|
*/
|
||||||
typedef void *(*memgetfunc_t)(size_t size);
|
typedef void *(*memgetfunc_t)(size_t size);
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Alignment support macros
|
* @name Alignment support macros
|
||||||
*/
|
*/
|
||||||
|
@ -66,7 +88,9 @@ typedef void *(*memgetfunc_t)(size_t size);
|
||||||
#define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0)
|
#define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#if CH_USE_MEMCORE || defined(__DOXYGEN__)
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -79,6 +103,10 @@ extern "C" {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module inline functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#endif /* CH_USE_MEMCORE */
|
#endif /* CH_USE_MEMCORE */
|
||||||
|
|
||||||
#endif /* _CHMEMCORE_H_ */
|
#endif /* _CHMEMCORE_H_ */
|
||||||
|
|
|
@ -31,6 +31,26 @@
|
||||||
|
|
||||||
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
|
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if !CH_USE_MEMCORE
|
||||||
|
#error "CH_USE_MEMPOOLS requires CH_USE_MEMCORE"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Memory pool free object header.
|
* @brief Memory pool free object header.
|
||||||
*/
|
*/
|
||||||
|
@ -46,9 +66,13 @@ typedef struct {
|
||||||
struct pool_header *mp_next; /**< @brief Pointer to the header. */
|
struct pool_header *mp_next; /**< @brief Pointer to the header. */
|
||||||
size_t mp_object_size; /**< @brief Memory pool objects
|
size_t mp_object_size; /**< @brief Memory pool objects
|
||||||
size. */
|
size. */
|
||||||
memgetfunc_t mp_provider; /**< @brief Memory blocks provider for
|
memgetfunc_t mp_provider; /**< @brief Memory blocks provider
|
||||||
this pool. */
|
for this pool. */
|
||||||
} MemoryPool;
|
} memory_pool_t;
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Data part of a static memory pool initializer.
|
* @brief Data part of a static memory pool initializer.
|
||||||
|
@ -73,60 +97,71 @@ typedef struct {
|
||||||
* if the pool is not allowed to grow automatically
|
* if the pool is not allowed to grow automatically
|
||||||
*/
|
*/
|
||||||
#define MEMORYPOOL_DECL(name, size, provider) \
|
#define MEMORYPOOL_DECL(name, size, provider) \
|
||||||
MemoryPool name = _MEMORYPOOL_DATA(name, size, provider)
|
memory_pool_t name = _MEMORYPOOL_DATA(name, size, provider)
|
||||||
|
|
||||||
/**
|
/*===========================================================================*/
|
||||||
* @name Macro Functions
|
/* External declarations. */
|
||||||
* @{
|
/*===========================================================================*/
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @brief Adds an object to a memory pool.
|
|
||||||
* @pre The memory pool must be already been initialized.
|
|
||||||
* @pre The added object must be of the right size for the specified
|
|
||||||
* memory pool.
|
|
||||||
* @pre The added object must be memory aligned to the size of
|
|
||||||
* @p stkalign_t type.
|
|
||||||
* @note This function is just an alias for @p chPoolFree() and has been
|
|
||||||
* added for clarity.
|
|
||||||
*
|
|
||||||
* @param[in] mp pointer to a @p MemoryPool structure
|
|
||||||
* @param[in] objp the pointer to the object to be added
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define chPoolAdd(mp, objp) chPoolFree(mp, objp)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Adds an object to a memory pool.
|
|
||||||
* @pre The memory pool must be already been initialized.
|
|
||||||
* @pre The added object must be of the right size for the specified
|
|
||||||
* memory pool.
|
|
||||||
* @pre The added object must be memory aligned to the size of
|
|
||||||
* @p stkalign_t type.
|
|
||||||
* @note This function is just an alias for @p chPoolFree() and has been
|
|
||||||
* added for clarity.
|
|
||||||
*
|
|
||||||
* @param[in] mp pointer to a @p MemoryPool structure
|
|
||||||
* @param[in] objp the pointer to the object to be added
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
#define chPoolAddI(mp, objp) chPoolFreeI(mp, objp)
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider);
|
void chPoolInit(memory_pool_t *mp, size_t size, memgetfunc_t provider);
|
||||||
void chPoolLoadArray(MemoryPool *mp, void *p, size_t n);
|
void chPoolLoadArray(memory_pool_t *mp, void *p, size_t n);
|
||||||
void *chPoolAllocI(MemoryPool *mp);
|
void *chPoolAllocI(memory_pool_t *mp);
|
||||||
void *chPoolAlloc(MemoryPool *mp);
|
void *chPoolAlloc(memory_pool_t *mp);
|
||||||
void chPoolFreeI(MemoryPool *mp, void *objp);
|
void chPoolFreeI(memory_pool_t *mp, void *objp);
|
||||||
void chPoolFree(MemoryPool *mp, void *objp);
|
void chPoolFree(memory_pool_t *mp, void *objp);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module inline functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds an object to a memory pool.
|
||||||
|
* @pre The memory pool must be already been initialized.
|
||||||
|
* @pre The added object must be of the right size for the specified
|
||||||
|
* memory pool.
|
||||||
|
* @pre The added object must be memory aligned to the size of
|
||||||
|
* @p stkalign_t type.
|
||||||
|
* @note This function is just an alias for @p chPoolFree() and has been
|
||||||
|
* added for clarity.
|
||||||
|
*
|
||||||
|
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||||
|
* @param[in] objp the pointer to the object to be added
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
static inline void chPoolAdd(memory_pool_t *mp, void *objp) {
|
||||||
|
|
||||||
|
chPoolFree(mp, objp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds an object to a memory pool.
|
||||||
|
* @pre The memory pool must be already been initialized.
|
||||||
|
* @pre The added object must be of the right size for the specified
|
||||||
|
* memory pool.
|
||||||
|
* @pre The added object must be memory aligned to the size of
|
||||||
|
* @p stkalign_t type.
|
||||||
|
* @note This function is just an alias for @p chPoolFree() and has been
|
||||||
|
* added for clarity.
|
||||||
|
*
|
||||||
|
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||||
|
* @param[in] objp the pointer to the object to be added
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline void chPoolAddI(memory_pool_t *mp, void *objp) {
|
||||||
|
|
||||||
|
chDbgCheckClassI();
|
||||||
|
|
||||||
|
chPoolFreeI(mp, objp);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CH_USE_MEMPOOLS */
|
#endif /* CH_USE_MEMPOOLS */
|
||||||
|
|
||||||
#endif /* _CHMEMPOOLS_H_ */
|
#endif /* _CHMEMPOOLS_H_ */
|
||||||
|
|
|
@ -31,42 +31,29 @@
|
||||||
|
|
||||||
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
|
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
|
||||||
|
|
||||||
/**
|
/*===========================================================================*/
|
||||||
* @name Macro Functions
|
/* Module constants. */
|
||||||
* @{
|
/*===========================================================================*/
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @brief Evaluates to TRUE if the thread has pending messages.
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
#define chMsgIsPendingI(tp) \
|
|
||||||
((tp)->p_msgqueue.p_next != (thread_t *)&(tp)->p_msgqueue)
|
|
||||||
|
|
||||||
/**
|
/*===========================================================================*/
|
||||||
* @brief Returns the message carried by the specified thread.
|
/* Module pre-compile time settings. */
|
||||||
* @pre This function must be invoked immediately after exiting a call
|
/*===========================================================================*/
|
||||||
* to @p chMsgWait().
|
|
||||||
*
|
|
||||||
* @param[in] tp pointer to the thread
|
|
||||||
* @return The message carried by the sender.
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define chMsgGet(tp) ((tp)->p_msg)
|
|
||||||
|
|
||||||
/**
|
/*===========================================================================*/
|
||||||
* @brief Releases the thread waiting on top of the messages queue.
|
/* Derived constants and error checks. */
|
||||||
* @pre Invoke this function only after a message has been received
|
/*===========================================================================*/
|
||||||
* using @p chMsgWait().
|
|
||||||
*
|
/*===========================================================================*/
|
||||||
* @param[in] tp pointer to the thread
|
/* Module data structures and types. */
|
||||||
* @param[in] msg message to be returned to the sender
|
/*===========================================================================*/
|
||||||
*
|
|
||||||
* @sclass
|
/*===========================================================================*/
|
||||||
*/
|
/* Module macros. */
|
||||||
#define chMsgReleaseS(tp, msg) chSchWakeupS(tp, msg)
|
/*===========================================================================*/
|
||||||
/** @} */
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -78,6 +65,54 @@ extern "C" {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Evaluates to TRUE if the thread has pending messages.
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline bool chMsgIsPendingI(thread_t *tp) {
|
||||||
|
|
||||||
|
chDbgCheckClassI();
|
||||||
|
|
||||||
|
return (bool)(tp->p_msgqueue.p_next != (thread_t *)&tp->p_msgqueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the message carried by the specified thread.
|
||||||
|
* @pre This function must be invoked immediately after exiting a call
|
||||||
|
* to @p chMsgWait().
|
||||||
|
*
|
||||||
|
* @param[in] tp pointer to the thread
|
||||||
|
* @return The message carried by the sender.
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
static inline msg_t chMsgGet(thread_t *tp) {
|
||||||
|
|
||||||
|
return tp->p_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Releases the thread waiting on top of the messages queue.
|
||||||
|
* @pre Invoke this function only after a message has been received
|
||||||
|
* using @p chMsgWait().
|
||||||
|
*
|
||||||
|
* @param[in] tp pointer to the thread
|
||||||
|
* @param[in] msg message to be returned to the sender
|
||||||
|
*
|
||||||
|
* @sclass
|
||||||
|
*/
|
||||||
|
static inline void chMsgReleaseS(thread_t *tp, msg_t msg) {
|
||||||
|
|
||||||
|
chDbgCheckClassS();
|
||||||
|
|
||||||
|
chSchWakeupS(tp, msg);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CH_USE_MESSAGES */
|
#endif /* CH_USE_MESSAGES */
|
||||||
|
|
||||||
#endif /* _CHMSG_H_ */
|
#endif /* _CHMSG_H_ */
|
||||||
|
|
|
@ -31,32 +31,37 @@
|
||||||
|
|
||||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Mutex structure.
|
* @brief Mutex structure.
|
||||||
*/
|
*/
|
||||||
typedef struct Mutex {
|
typedef struct mutex {
|
||||||
threads_queue_t m_queue; /**< @brief Queue of the threads sleeping
|
threads_queue_t m_queue; /**< @brief Queue of the threads sleeping
|
||||||
on this Mutex. */
|
on this mutex. */
|
||||||
thread_t *m_owner; /**< @brief Owner @p thread_t pointer or
|
thread_t *m_owner; /**< @brief Owner @p thread_t pointer or
|
||||||
@p NULL. */
|
@p NULL. */
|
||||||
struct Mutex *m_next; /**< @brief Next @p Mutex into an
|
mutex_t *m_next; /**< @brief Next @p mutex_t into an
|
||||||
owner-list or @p NULL. */
|
owner-list or @p NULL. */
|
||||||
} Mutex;
|
} mutex_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/*===========================================================================*/
|
||||||
extern "C" {
|
/* Module macros. */
|
||||||
#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.
|
* @brief Data part of a static mutex initializer.
|
||||||
|
@ -74,20 +79,45 @@ extern "C" {
|
||||||
*
|
*
|
||||||
* @param[in] name the name of the mutex variable
|
* @param[in] name the name of the mutex variable
|
||||||
*/
|
*/
|
||||||
#define MUTEX_DECL(name) Mutex name = _MUTEX_DATA(name)
|
#define MUTEX_DECL(name) mutex_t name = _MUTEX_DATA(name)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void chMtxInit(mutex_t *mp);
|
||||||
|
void chMtxLock(mutex_t *mp);
|
||||||
|
void chMtxLockS(mutex_t *mp);
|
||||||
|
bool_t chMtxTryLock(mutex_t *mp);
|
||||||
|
bool_t chMtxTryLockS(mutex_t *mp);
|
||||||
|
mutex_t *chMtxUnlock(void);
|
||||||
|
mutex_t *chMtxUnlockS(void);
|
||||||
|
void chMtxUnlockAll(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module inline functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Macro Functions
|
* @brief Returns @p true if the mutex queue contains at least a waiting
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @brief Returns @p TRUE if the mutex queue contains at least a waiting
|
|
||||||
* thread.
|
* thread.
|
||||||
*
|
*
|
||||||
|
* @deprecated
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
#define chMtxQueueNotEmptyS(mp) queue_notempty(&(mp)->m_queue)
|
static inline bool chMtxQueueNotEmptyS(mutex_t *mp) {
|
||||||
/** @} */
|
|
||||||
|
chDbgCheckClassS();
|
||||||
|
|
||||||
|
return queue_notempty(&mp->m_queue);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CH_USE_MUTEXES */
|
#endif /* CH_USE_MUTEXES */
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,22 @@
|
||||||
|
|
||||||
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ChibiOS/RT memory signature record.
|
* @brief ChibiOS/RT memory signature record.
|
||||||
*/
|
*/
|
||||||
|
@ -57,39 +73,10 @@ typedef struct {
|
||||||
uint8_t cf_off_time; /**< @brief Offset of @p p_time field. */
|
uint8_t cf_off_time; /**< @brief Offset of @p p_time field. */
|
||||||
} chdebug_t;
|
} chdebug_t;
|
||||||
|
|
||||||
/**
|
/*===========================================================================*/
|
||||||
* @name Macro Functions
|
/* Module macros. */
|
||||||
* @{
|
/*===========================================================================*/
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @brief Sets the current thread name.
|
|
||||||
* @pre This function only stores the pointer to the name if the option
|
|
||||||
* @p CH_USE_REGISTRY is enabled else no action is performed.
|
|
||||||
*
|
|
||||||
* @param[in] p thread name as a zero terminated string
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define chRegSetThreadName(p) (currp->p_name = (p))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the name of the specified thread.
|
|
||||||
* @pre This function only returns the pointer to the name if the option
|
|
||||||
* @p CH_USE_REGISTRY is enabled else @p NULL is returned.
|
|
||||||
*
|
|
||||||
* @param[in] tp pointer to the thread
|
|
||||||
*
|
|
||||||
* @return Thread name as a zero terminated string.
|
|
||||||
* @retval NULL if the thread name has not been set.
|
|
||||||
*/
|
|
||||||
#define chRegGetThreadName(tp) ((tp)->p_name)
|
|
||||||
/** @} */
|
|
||||||
#else /* !CH_USE_REGISTRY */
|
|
||||||
#define chRegSetThreadName(p)
|
|
||||||
#define chRegGetThreadName(tp) NULL
|
|
||||||
#endif /* !CH_USE_REGISTRY */
|
|
||||||
|
|
||||||
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
|
||||||
/**
|
/**
|
||||||
* @brief Removes a thread from the registry list.
|
* @brief Removes a thread from the registry list.
|
||||||
* @note This macro is not meant for use in application code.
|
* @note This macro is not meant for use in application code.
|
||||||
|
@ -113,6 +100,10 @@ typedef struct {
|
||||||
(tp)->p_older->p_newer = rlist.r_older = (tp); \
|
(tp)->p_older->p_newer = rlist.r_older = (tp); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -123,6 +114,52 @@ extern "C" {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module inline functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the current thread name.
|
||||||
|
* @pre This function only stores the pointer to the name if the option
|
||||||
|
* @p CH_USE_REGISTRY is enabled else no action is performed.
|
||||||
|
*
|
||||||
|
* @param[in] p thread name as a zero terminated string
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
static inline void chRegSetThreadName(const char *name) {
|
||||||
|
|
||||||
|
#if CH_USE_REGISTRY
|
||||||
|
currp->p_name = name;
|
||||||
|
#else
|
||||||
|
(void)name;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the name of the specified thread.
|
||||||
|
* @pre This function only returns the pointer to the name if the option
|
||||||
|
* @p CH_USE_REGISTRY is enabled else @p NULL is returned.
|
||||||
|
*
|
||||||
|
* @param[in] tp pointer to the thread
|
||||||
|
*
|
||||||
|
* @return Thread name as a zero terminated string.
|
||||||
|
* @retval NULL if the thread name has not been set.
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline const char *chRegGetThreadNameI(thread_t *tp) {
|
||||||
|
|
||||||
|
chDbgCheckClassI();
|
||||||
|
|
||||||
|
#if CH_USE_REGISTRY
|
||||||
|
return tp->p_name;
|
||||||
|
#else
|
||||||
|
(void)tp;
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CH_USE_REGISTRY */
|
#endif /* CH_USE_REGISTRY */
|
||||||
|
|
||||||
#endif /* _CHREGISTRY_H_ */
|
#endif /* _CHREGISTRY_H_ */
|
||||||
|
|
|
@ -29,159 +29,25 @@
|
||||||
#ifndef _CHSYS_H_
|
#ifndef _CHSYS_H_
|
||||||
#define _CHSYS_H_
|
#define _CHSYS_H_
|
||||||
|
|
||||||
/**
|
/*===========================================================================*/
|
||||||
* @name Macro Functions
|
/* Module constants. */
|
||||||
* @{
|
/*===========================================================================*/
|
||||||
*/
|
|
||||||
#if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @brief Returns a pointer to the idle thread.
|
|
||||||
* @pre In order to use this function the option @p CH_NO_IDLE_THREAD
|
|
||||||
* must be disabled.
|
|
||||||
* @note The reference counter of the idle thread is not incremented but
|
|
||||||
* it is not strictly required being the idle thread a static
|
|
||||||
* object.
|
|
||||||
*
|
|
||||||
* @return Pointer to the idle thread.
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define chSysGetIdleThread() (rlist.r_queue.p_prev)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/*===========================================================================*/
|
||||||
* @brief Halts the system.
|
/* Module pre-compile time settings. */
|
||||||
* @details This function is invoked by the operating system when an
|
/*===========================================================================*/
|
||||||
* unrecoverable error is detected, for example because a programming
|
|
||||||
* error in the application code that triggers an assertion while
|
|
||||||
* in debug mode.
|
|
||||||
* @note Can be invoked from any system state.
|
|
||||||
*
|
|
||||||
* @special
|
|
||||||
*/
|
|
||||||
#if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
|
|
||||||
#define chSysHalt() port_halt()
|
|
||||||
#else
|
|
||||||
#define chSysHalt() { \
|
|
||||||
SYSTEM_HALT_HOOK(); \
|
|
||||||
port_halt(); \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/*===========================================================================*/
|
||||||
* @brief Performs a context switch.
|
/* Derived constants and error checks. */
|
||||||
* @note Not a user function, it is meant to be invoked by the scheduler
|
/*===========================================================================*/
|
||||||
* itself or from within the port layer.
|
|
||||||
*
|
|
||||||
* @param[in] ntp the thread to be switched in
|
|
||||||
* @param[in] otp the thread to be switched out
|
|
||||||
*
|
|
||||||
* @special
|
|
||||||
*/
|
|
||||||
#define chSysSwitch(ntp, otp) { \
|
|
||||||
dbg_trace(otp); \
|
|
||||||
THREAD_CONTEXT_SWITCH_HOOK(ntp, otp); \
|
|
||||||
port_switch(ntp, otp); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/*===========================================================================*/
|
||||||
* @brief Raises the system interrupt priority mask to the maximum level.
|
/* Module data structures and types. */
|
||||||
* @details All the maskable interrupt sources are disabled regardless their
|
/*===========================================================================*/
|
||||||
* hardware priority.
|
|
||||||
* @note Do not invoke this API from within a kernel lock.
|
|
||||||
*
|
|
||||||
* @special
|
|
||||||
*/
|
|
||||||
#define chSysDisable() { \
|
|
||||||
port_disable(); \
|
|
||||||
dbg_check_disable(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/*===========================================================================*/
|
||||||
* @brief Raises the system interrupt priority mask to system level.
|
/* Module macros. */
|
||||||
* @details The interrupt sources that should not be able to preempt the kernel
|
/*===========================================================================*/
|
||||||
* are disabled, interrupt sources with higher priority are still
|
|
||||||
* enabled.
|
|
||||||
* @note Do not invoke this API from within a kernel lock.
|
|
||||||
* @note This API is no replacement for @p chSysLock(), the @p chSysLock()
|
|
||||||
* could do more than just disable the interrupts.
|
|
||||||
*
|
|
||||||
* @special
|
|
||||||
*/
|
|
||||||
#define chSysSuspend() { \
|
|
||||||
port_suspend(); \
|
|
||||||
dbg_check_suspend(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Lowers the system interrupt priority mask to user level.
|
|
||||||
* @details All the interrupt sources are enabled.
|
|
||||||
* @note Do not invoke this API from within a kernel lock.
|
|
||||||
* @note This API is no replacement for @p chSysUnlock(), the
|
|
||||||
* @p chSysUnlock() could do more than just enable the interrupts.
|
|
||||||
*
|
|
||||||
* @special
|
|
||||||
*/
|
|
||||||
#define chSysEnable() { \
|
|
||||||
dbg_check_enable(); \
|
|
||||||
port_enable(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enters the kernel lock mode.
|
|
||||||
*
|
|
||||||
* @special
|
|
||||||
*/
|
|
||||||
#define chSysLock() { \
|
|
||||||
port_lock(); \
|
|
||||||
dbg_check_lock(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Leaves the kernel lock mode.
|
|
||||||
*
|
|
||||||
* @special
|
|
||||||
*/
|
|
||||||
#define chSysUnlock() { \
|
|
||||||
dbg_check_unlock(); \
|
|
||||||
port_unlock(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enters the kernel lock mode from within an interrupt handler.
|
|
||||||
* @note This API may do nothing on some architectures, it is required
|
|
||||||
* because on ports that support preemptable interrupt handlers
|
|
||||||
* it is required to raise the interrupt mask to the same level of
|
|
||||||
* the system mutual exclusion zone.<br>
|
|
||||||
* It is good practice to invoke this API before invoking any I-class
|
|
||||||
* syscall from an interrupt handler.
|
|
||||||
* @note This API must be invoked exclusively from interrupt handlers.
|
|
||||||
*
|
|
||||||
* @special
|
|
||||||
*/
|
|
||||||
#define chSysLockFromIsr() { \
|
|
||||||
port_lock_from_isr(); \
|
|
||||||
dbg_check_lock_from_isr(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Leaves the kernel lock mode from within an interrupt handler.
|
|
||||||
*
|
|
||||||
* @note This API may do nothing on some architectures, it is required
|
|
||||||
* because on ports that support preemptable interrupt handlers
|
|
||||||
* it is required to raise the interrupt mask to the same level of
|
|
||||||
* the system mutual exclusion zone.<br>
|
|
||||||
* It is good practice to invoke this API after invoking any I-class
|
|
||||||
* syscall from an interrupt handler.
|
|
||||||
* @note This API must be invoked exclusively from interrupt handlers.
|
|
||||||
*
|
|
||||||
* @special
|
|
||||||
*/
|
|
||||||
#define chSysUnlockFromIsr() { \
|
|
||||||
dbg_check_unlock_from_isr(); \
|
|
||||||
port_unlock_from_isr(); \
|
|
||||||
}
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name ISRs abstraction macros
|
* @name ISRs abstraction macros
|
||||||
|
@ -233,15 +99,146 @@
|
||||||
#define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
|
#define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void chSysInit(void);
|
void chSysInit(void);
|
||||||
|
void chSysHalt(void);
|
||||||
void chSysTimerHandlerI(void);
|
void chSysTimerHandlerI(void);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module inline functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
static inline void chSysSwitch(thread_t *ntp, thread_t *otp) {
|
||||||
|
|
||||||
|
dbg_trace(otp);
|
||||||
|
THREAD_CONTEXT_SWITCH_HOOK(ntp, otp);
|
||||||
|
port_switch(ntp, otp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raises the system interrupt priority mask to the maximum level.
|
||||||
|
* @details All the maskable interrupt sources are disabled regardless their
|
||||||
|
* hardware priority.
|
||||||
|
* @note Do not invoke this API from within a kernel lock.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
static inline void chSysDisable(void) {
|
||||||
|
|
||||||
|
port_disable();
|
||||||
|
dbg_check_disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raises the system interrupt priority mask to system level.
|
||||||
|
* @details The interrupt sources that should not be able to preempt the kernel
|
||||||
|
* are disabled, interrupt sources with higher priority are still
|
||||||
|
* enabled.
|
||||||
|
* @note Do not invoke this API from within a kernel lock.
|
||||||
|
* @note This API is no replacement for @p chSysLock(), the @p chSysLock()
|
||||||
|
* could do more than just disable the interrupts.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
static inline void chSysSuspend(void) {
|
||||||
|
|
||||||
|
port_suspend();
|
||||||
|
dbg_check_suspend();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lowers the system interrupt priority mask to user level.
|
||||||
|
* @details All the interrupt sources are enabled.
|
||||||
|
* @note Do not invoke this API from within a kernel lock.
|
||||||
|
* @note This API is no replacement for @p chSysUnlock(), the
|
||||||
|
* @p chSysUnlock() could do more than just enable the interrupts.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
static inline void chSysEnable(void) {
|
||||||
|
|
||||||
|
dbg_check_enable();
|
||||||
|
port_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enters the kernel lock mode.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
static inline void chSysLock(void) {
|
||||||
|
|
||||||
|
port_lock();
|
||||||
|
dbg_check_lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Leaves the kernel lock mode.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
static inline void chSysUnlock(void) {
|
||||||
|
|
||||||
|
dbg_check_unlock();
|
||||||
|
port_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enters the kernel lock mode from within an interrupt handler.
|
||||||
|
* @note This API may do nothing on some architectures, it is required
|
||||||
|
* because on ports that support preemptable interrupt handlers
|
||||||
|
* it is required to raise the interrupt mask to the same level of
|
||||||
|
* the system mutual exclusion zone.<br>
|
||||||
|
* It is good practice to invoke this API before invoking any I-class
|
||||||
|
* syscall from an interrupt handler.
|
||||||
|
* @note This API must be invoked exclusively from interrupt handlers.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
static inline void chSysLockFromIsr(void) {
|
||||||
|
|
||||||
|
port_lock_from_isr();
|
||||||
|
dbg_check_lock_from_isr();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Leaves the kernel lock mode from within an interrupt handler.
|
||||||
|
*
|
||||||
|
* @note This API may do nothing on some architectures, it is required
|
||||||
|
* because on ports that support preemptable interrupt handlers
|
||||||
|
* it is required to raise the interrupt mask to the same level of
|
||||||
|
* the system mutual exclusion zone.<br>
|
||||||
|
* It is good practice to invoke this API after invoking any I-class
|
||||||
|
* syscall from an interrupt handler.
|
||||||
|
* @note This API must be invoked exclusively from interrupt handlers.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
static inline void chSysUnlockFromIsr(void) {
|
||||||
|
|
||||||
|
dbg_check_unlock_from_isr();
|
||||||
|
port_unlock_from_isr();
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _CHSYS_H_ */
|
#endif /* _CHSYS_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
/* Forward declaration required by the mutexes stack structure present
|
/* Forward declaration required by the mutexes stack structure present
|
||||||
in every thread.*/
|
in every thread.*/
|
||||||
#if CH_USE_MUTEXES
|
#if CH_USE_MUTEXES
|
||||||
typedef struct Mutex Mutex;
|
typedef struct mutex mutex_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,7 +238,7 @@ typedef struct thread {
|
||||||
* @brief List of the mutexes owned by this thread.
|
* @brief List of the mutexes owned by this thread.
|
||||||
* @note The list is terminated by a @p NULL in this field.
|
* @note The list is terminated by a @p NULL in this field.
|
||||||
*/
|
*/
|
||||||
Mutex *p_mtxlist;
|
mutex_t *p_mtxlist;
|
||||||
/**
|
/**
|
||||||
* @brief Thread's own, non-inherited, priority.
|
* @brief Thread's own, non-inherited, priority.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -200,7 +200,7 @@ msg_t chCondWait(condition_variable_t *cp) {
|
||||||
*/
|
*/
|
||||||
msg_t chCondWaitS(condition_variable_t *cp) {
|
msg_t chCondWaitS(condition_variable_t *cp) {
|
||||||
thread_t *ctp = currp;
|
thread_t *ctp = currp;
|
||||||
Mutex *mp;
|
mutex_t *mp;
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
|
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
|
@ -285,7 +285,7 @@ msg_t chCondWaitTimeout(condition_variable_t *cp, systime_t time) {
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
msg_t chCondWaitTimeoutS(condition_variable_t *cp, systime_t time) {
|
msg_t chCondWaitTimeoutS(condition_variable_t *cp, systime_t time) {
|
||||||
Mutex *mp;
|
mutex_t *mp;
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
|
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
|
|
|
@ -144,7 +144,7 @@ void chThdRelease(thread_t *tp) {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
thread_t *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
|
thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size,
|
||||||
tprio_t prio, tfunc_t pf, void *arg) {
|
tprio_t prio, tfunc_t pf, void *arg) {
|
||||||
void *wsp;
|
void *wsp;
|
||||||
thread_t *tp;
|
thread_t *tp;
|
||||||
|
@ -193,7 +193,7 @@ thread_t *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
thread_t *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
|
thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, tprio_t prio,
|
||||||
tfunc_t pf, void *arg) {
|
tfunc_t pf, void *arg) {
|
||||||
void *wsp;
|
void *wsp;
|
||||||
thread_t *tp;
|
thread_t *tp;
|
||||||
|
|
|
@ -93,14 +93,16 @@
|
||||||
* @note Multiple Event Listeners can specify the same bits to be ORed to
|
* @note Multiple Event Listeners can specify the same bits to be ORed to
|
||||||
* different threads.
|
* different threads.
|
||||||
*
|
*
|
||||||
* @param[in] esp pointer to the @p EventSource structure
|
* @param[in] esp pointer to the @p event_source_t structure
|
||||||
* @param[in] elp pointer to the @p EventListener structure
|
* @param[in] elp pointer to the @p event_listener_t structure
|
||||||
* @param[in] mask the mask of event flags to be ORed to the thread when
|
* @param[in] mask the mask of event flags to be ORed to the thread when
|
||||||
* the event source is broadcasted
|
* the event source is broadcasted
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t mask) {
|
void chEvtRegisterMask(event_source_t *esp,
|
||||||
|
event_listener_t *elp,
|
||||||
|
eventmask_t mask) {
|
||||||
|
|
||||||
chDbgCheck((esp != NULL) && (elp != NULL), "chEvtRegisterMask");
|
chDbgCheck((esp != NULL) && (elp != NULL), "chEvtRegisterMask");
|
||||||
|
|
||||||
|
@ -121,19 +123,19 @@ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t mask) {
|
||||||
* operations in inverse order of the register operations (elements
|
* operations in inverse order of the register operations (elements
|
||||||
* are found on top of the list).
|
* are found on top of the list).
|
||||||
*
|
*
|
||||||
* @param[in] esp pointer to the @p EventSource structure
|
* @param[in] esp pointer to the @p event_source_t structure
|
||||||
* @param[in] elp pointer to the @p EventListener structure
|
* @param[in] elp pointer to the @p event_listener_t structure
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void chEvtUnregister(EventSource *esp, EventListener *elp) {
|
void chEvtUnregister(event_source_t *esp, event_listener_t *elp) {
|
||||||
EventListener *p;
|
event_listener_t *p;
|
||||||
|
|
||||||
chDbgCheck((esp != NULL) && (elp != NULL), "chEvtUnregister");
|
chDbgCheck((esp != NULL) && (elp != NULL), "chEvtUnregister");
|
||||||
|
|
||||||
p = (EventListener *)esp;
|
p = (event_listener_t *)esp;
|
||||||
chSysLock();
|
chSysLock();
|
||||||
while (p->el_next != (EventListener *)esp) {
|
while (p->el_next != (event_listener_t *)esp) {
|
||||||
if (p->el_next == elp) {
|
if (p->el_next == elp) {
|
||||||
p->el_next = elp->el_next;
|
p->el_next = elp->el_next;
|
||||||
break;
|
break;
|
||||||
|
@ -186,27 +188,27 @@ eventmask_t chEvtAddEvents(eventmask_t mask) {
|
||||||
* @brief Signals all the Event Listeners registered on the specified Event
|
* @brief Signals all the Event Listeners registered on the specified Event
|
||||||
* Source.
|
* Source.
|
||||||
* @details This function variants ORs the specified event flags to all the
|
* @details This function variants ORs the specified event flags to all the
|
||||||
* threads registered on the @p EventSource in addition to the event
|
* threads registered on the @p event_source_t in addition to the
|
||||||
* flags specified by the threads themselves in the
|
* event flags specified by the threads themselves in the
|
||||||
* @p EventListener objects.
|
* @p event_listener_t objects.
|
||||||
* @post This function does not reschedule so a call to a rescheduling
|
* @post This function does not reschedule so a call to a rescheduling
|
||||||
* function must be performed before unlocking the kernel. Note that
|
* function must be performed before unlocking the kernel. Note that
|
||||||
* interrupt handlers always reschedule on exit so an explicit
|
* interrupt handlers always reschedule on exit so an explicit
|
||||||
* reschedule must not be performed in ISRs.
|
* reschedule must not be performed in ISRs.
|
||||||
*
|
*
|
||||||
* @param[in] esp pointer to the @p EventSource structure
|
* @param[in] esp pointer to the @p event_source_t structure
|
||||||
* @param[in] flags the flags set to be added to the listener flags mask
|
* @param[in] flags the flags set to be added to the listener flags mask
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
void chEvtBroadcastFlagsI(EventSource *esp, flagsmask_t flags) {
|
void chEvtBroadcastFlagsI(event_source_t *esp, eventflags_t flags) {
|
||||||
EventListener *elp;
|
event_listener_t *elp;
|
||||||
|
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
chDbgCheck(esp != NULL, "chEvtBroadcastMaskI");
|
chDbgCheck(esp != NULL, "chEvtBroadcastMaskI");
|
||||||
|
|
||||||
elp = esp->es_next;
|
elp = esp->es_next;
|
||||||
while (elp != (EventListener *)esp) {
|
while (elp != (event_listener_t *)esp) {
|
||||||
elp->el_flags |= flags;
|
elp->el_flags |= flags;
|
||||||
chEvtSignalI(elp->el_listener, elp->el_mask);
|
chEvtSignalI(elp->el_listener, elp->el_mask);
|
||||||
elp = elp->el_next;
|
elp = elp->el_next;
|
||||||
|
@ -214,18 +216,18 @@ void chEvtBroadcastFlagsI(EventSource *esp, flagsmask_t flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the flags associated to an @p EventListener.
|
* @brief Returns the flags associated to an @p event_listener_t.
|
||||||
* @details The flags are returned and the @p EventListener flags mask is
|
* @details The flags are returned and the @p event_listener_t flags mask is
|
||||||
* cleared.
|
* cleared.
|
||||||
*
|
*
|
||||||
* @param[in] elp pointer to the @p EventListener structure
|
* @param[in] elp pointer to the @p event_listener_t structure
|
||||||
* @return The flags added to the listener by the associated
|
* @return The flags added to the listener by the associated
|
||||||
* event source.
|
* event source.
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
flagsmask_t chEvtGetAndClearFlags(EventListener *elp) {
|
eventflags_t chEvtGetAndClearFlags(event_listener_t *elp) {
|
||||||
flagsmask_t flags;
|
eventflags_t flags;
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
|
||||||
|
@ -284,16 +286,16 @@ void chEvtSignalI(thread_t *tp, eventmask_t mask) {
|
||||||
* @brief Signals all the Event Listeners registered on the specified Event
|
* @brief Signals all the Event Listeners registered on the specified Event
|
||||||
* Source.
|
* Source.
|
||||||
* @details This function variants ORs the specified event flags to all the
|
* @details This function variants ORs the specified event flags to all the
|
||||||
* threads registered on the @p EventSource in addition to the event
|
* threads registered on the @p event_source_t in addition to the
|
||||||
* flags specified by the threads themselves in the
|
* event flags specified by the threads themselves in the
|
||||||
* @p EventListener objects.
|
* @p event_listener_t objects.
|
||||||
*
|
*
|
||||||
* @param[in] esp pointer to the @p EventSource structure
|
* @param[in] esp pointer to the @p event_source_t structure
|
||||||
* @param[in] flags the flags set to be added to the listener flags mask
|
* @param[in] flags the flags set to be added to the listener flags mask
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void chEvtBroadcastFlags(EventSource *esp, flagsmask_t flags) {
|
void chEvtBroadcastFlags(event_source_t *esp, eventflags_t flags) {
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chEvtBroadcastFlagsI(esp, flags);
|
chEvtBroadcastFlagsI(esp, flags);
|
||||||
|
@ -302,18 +304,18 @@ void chEvtBroadcastFlags(EventSource *esp, flagsmask_t flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the flags associated to an @p EventListener.
|
* @brief Returns the flags associated to an @p event_listener_t.
|
||||||
* @details The flags are returned and the @p EventListener flags mask is
|
* @details The flags are returned and the @p event_listener_t flags mask is
|
||||||
* cleared.
|
* cleared.
|
||||||
*
|
*
|
||||||
* @param[in] elp pointer to the @p EventListener structure
|
* @param[in] elp pointer to the @p event_listener_t structure
|
||||||
* @return The flags added to the listener by the associated
|
* @return The flags added to the listener by the associated
|
||||||
* event source.
|
* event source.
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
flagsmask_t chEvtGetAndClearFlagsI(EventListener *elp) {
|
eventflags_t chEvtGetAndClearFlagsI(event_listener_t *elp) {
|
||||||
flagsmask_t flags;
|
eventflags_t flags;
|
||||||
|
|
||||||
flags = elp->el_flags;
|
flags = elp->el_flags;
|
||||||
elp->el_flags = 0;
|
elp->el_flags = 0;
|
||||||
|
@ -444,8 +446,8 @@ eventmask_t chEvtWaitAll(eventmask_t mask) {
|
||||||
* @details The function waits for one event among those specified in
|
* @details The function waits for one event among those specified in
|
||||||
* @p mask to become pending then the event is cleared and returned.
|
* @p mask to become pending then the event is cleared and returned.
|
||||||
* @note One and only one event is served in the function, the one with the
|
* @note One and only one event is served in the function, the one with the
|
||||||
* lowest event id. The function is meant to be invoked into a loop in
|
* lowest event id. The function is meant to be invoked into a loop
|
||||||
* order to serve all the pending events.<br>
|
* in order to serve all the pending events.<br>
|
||||||
* This means that Event Listeners with a lower event identifier have
|
* This means that Event Listeners with a lower event identifier have
|
||||||
* an higher priority.
|
* an higher priority.
|
||||||
*
|
*
|
||||||
|
|
|
@ -29,10 +29,6 @@
|
||||||
* are functionally equivalent to the usual @p malloc() and @p free()
|
* are functionally equivalent to the usual @p malloc() and @p free()
|
||||||
* library functions. The main difference is that the OS heap APIs
|
* library functions. The main difference is that the OS heap APIs
|
||||||
* are guaranteed to be thread safe.<br>
|
* are guaranteed to be thread safe.<br>
|
||||||
* By enabling the @p CH_USE_MALLOC_HEAP option the heap manager
|
|
||||||
* will use the runtime-provided @p malloc() and @p free() as
|
|
||||||
* back end for the heap APIs instead of the system provided
|
|
||||||
* allocator.
|
|
||||||
* @pre In order to use the heap APIs the @p CH_USE_HEAP option must
|
* @pre In order to use the heap APIs the @p CH_USE_HEAP option must
|
||||||
* be enabled in @p chconf.h.
|
* be enabled in @p chconf.h.
|
||||||
* @{
|
* @{
|
||||||
|
@ -42,7 +38,9 @@
|
||||||
|
|
||||||
#if CH_USE_HEAP || defined(__DOXYGEN__)
|
#if CH_USE_HEAP || defined(__DOXYGEN__)
|
||||||
|
|
||||||
#if !CH_USE_MALLOC_HEAP || defined(__DOXYGEN__)
|
/*===========================================================================*/
|
||||||
|
/* Module local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defaults on the best synchronization mechanism available.
|
* Defaults on the best synchronization mechanism available.
|
||||||
|
@ -55,10 +53,30 @@
|
||||||
#define H_UNLOCK(h) chSemSignal(&(h)->h_sem)
|
#define H_UNLOCK(h) chSemSignal(&(h)->h_sem)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default heap descriptor.
|
* @brief Default heap descriptor.
|
||||||
*/
|
*/
|
||||||
static MemoryHeap default_heap;
|
static memory_heap_t default_heap;
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the default heap.
|
* @brief Initializes the default heap.
|
||||||
|
@ -80,8 +98,6 @@ void _heap_init(void) {
|
||||||
* @brief Initializes a memory heap from a static memory area.
|
* @brief Initializes a memory heap from a static memory area.
|
||||||
* @pre Both the heap buffer base and the heap size must be aligned to
|
* @pre Both the heap buffer base and the heap size must be aligned to
|
||||||
* the @p stkalign_t type size.
|
* the @p stkalign_t type size.
|
||||||
* @pre In order to use this function the option @p CH_USE_MALLOC_HEAP
|
|
||||||
* must be disabled.
|
|
||||||
*
|
*
|
||||||
* @param[out] heapp pointer to the memory heap descriptor to be initialized
|
* @param[out] heapp pointer to the memory heap descriptor to be initialized
|
||||||
* @param[in] buf heap buffer base
|
* @param[in] buf heap buffer base
|
||||||
|
@ -89,7 +105,7 @@ void _heap_init(void) {
|
||||||
*
|
*
|
||||||
* @init
|
* @init
|
||||||
*/
|
*/
|
||||||
void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
|
void chHeapInit(memory_heap_t *heapp, void *buf, size_t size) {
|
||||||
union heap_header *hp;
|
union heap_header *hp;
|
||||||
|
|
||||||
chDbgCheck(MEM_IS_ALIGNED(buf) && MEM_IS_ALIGNED(size), "chHeapInit");
|
chDbgCheck(MEM_IS_ALIGNED(buf) && MEM_IS_ALIGNED(size), "chHeapInit");
|
||||||
|
@ -122,7 +138,7 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
|
void *chHeapAlloc(memory_heap_t *heapp, size_t size) {
|
||||||
union heap_header *qp, *hp, *fp;
|
union heap_header *qp, *hp, *fp;
|
||||||
|
|
||||||
if (heapp == NULL)
|
if (heapp == NULL)
|
||||||
|
@ -186,7 +202,7 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
|
||||||
*/
|
*/
|
||||||
void chHeapFree(void *p) {
|
void chHeapFree(void *p) {
|
||||||
union heap_header *qp, *hp;
|
union heap_header *qp, *hp;
|
||||||
MemoryHeap *heapp;
|
memory_heap_t *heapp;
|
||||||
|
|
||||||
chDbgCheck(p != NULL, "chHeapFree");
|
chDbgCheck(p != NULL, "chHeapFree");
|
||||||
|
|
||||||
|
@ -229,8 +245,6 @@ void chHeapFree(void *p) {
|
||||||
* @brief Reports the heap status.
|
* @brief Reports the heap status.
|
||||||
* @note This function is meant to be used in the test suite, it should
|
* @note This function is meant to be used in the test suite, it should
|
||||||
* not be really useful for the application code.
|
* not be really useful for the application code.
|
||||||
* @note This function is not implemented when the @p CH_USE_MALLOC_HEAP
|
|
||||||
* configuration option is used (it always returns zero).
|
|
||||||
*
|
*
|
||||||
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to
|
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to
|
||||||
* access the default heap.
|
* access the default heap.
|
||||||
|
@ -240,7 +254,7 @@ void chHeapFree(void *p) {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) {
|
size_t chHeapStatus(memory_heap_t *heapp, size_t *sizep) {
|
||||||
union heap_header *qp;
|
union heap_header *qp;
|
||||||
size_t n, sz;
|
size_t n, sz;
|
||||||
|
|
||||||
|
@ -259,60 +273,6 @@ size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CH_USE_MALLOC_HEAP */
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#if CH_USE_MUTEXES
|
|
||||||
#define H_LOCK() chMtxLock(&hmtx)
|
|
||||||
#define H_UNLOCK() chMtxUnlock()
|
|
||||||
static Mutex hmtx;
|
|
||||||
#elif CH_USE_SEMAPHORES
|
|
||||||
#define H_LOCK() chSemWait(&hsem)
|
|
||||||
#define H_UNLOCK() chSemSignal(&hsem)
|
|
||||||
static Semaphore hsem;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void _heap_init(void) {
|
|
||||||
|
|
||||||
#if CH_USE_MUTEXES
|
|
||||||
chMtxInit(&hmtx);
|
|
||||||
#else
|
|
||||||
chSemInit(&hsem, 1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
chDbgCheck(heapp == NULL, "chHeapAlloc");
|
|
||||||
|
|
||||||
H_LOCK();
|
|
||||||
p = malloc(size);
|
|
||||||
H_UNLOCK();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void chHeapFree(void *p) {
|
|
||||||
|
|
||||||
chDbgCheck(p != NULL, "chHeapFree");
|
|
||||||
|
|
||||||
H_LOCK();
|
|
||||||
free(p);
|
|
||||||
H_UNLOCK();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) {
|
|
||||||
|
|
||||||
chDbgCheck(heapp == NULL, "chHeapStatus");
|
|
||||||
|
|
||||||
if (sizep)
|
|
||||||
*sizep = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CH_USE_MALLOC_HEAP */
|
|
||||||
|
|
||||||
#endif /* CH_USE_HEAP */
|
#endif /* CH_USE_HEAP */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -53,16 +53,38 @@
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
|
||||||
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
|
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes a Mailbox object.
|
* @brief Initializes a @p mailbox_t object.
|
||||||
*
|
*
|
||||||
* @param[out] mbp the pointer to the Mailbox structure to be initialized
|
* @param[out] mbp the pointer to the @p mailbox_t structure to be
|
||||||
|
* initialized
|
||||||
* @param[in] buf pointer to the messages buffer as an array of @p msg_t
|
* @param[in] buf pointer to the messages buffer as an array of @p msg_t
|
||||||
* @param[in] n number of elements in the buffer array
|
* @param[in] n number of elements in the buffer array
|
||||||
*
|
*
|
||||||
* @init
|
* @init
|
||||||
*/
|
*/
|
||||||
void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) {
|
void chMBInit(mailbox_t *mbp, msg_t *buf, cnt_t n) {
|
||||||
|
|
||||||
chDbgCheck((mbp != NULL) && (buf != NULL) && (n > 0), "chMBInit");
|
chDbgCheck((mbp != NULL) && (buf != NULL) && (n > 0), "chMBInit");
|
||||||
|
|
||||||
|
@ -73,15 +95,15 @@ void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resets a Mailbox object.
|
* @brief Resets a @p mailbox_t object.
|
||||||
* @details All the waiting threads are resumed with status @p RDY_RESET and
|
* @details All the waiting threads are resumed with status @p RDY_RESET and
|
||||||
* the queued messages are lost.
|
* the queued messages are lost.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void chMBReset(Mailbox *mbp) {
|
void chMBReset(mailbox_t *mbp) {
|
||||||
|
|
||||||
chDbgCheck(mbp != NULL, "chMBReset");
|
chDbgCheck(mbp != NULL, "chMBReset");
|
||||||
|
|
||||||
|
@ -98,7 +120,7 @@ void chMBReset(Mailbox *mbp) {
|
||||||
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
||||||
* available or the specified time runs out.
|
* available or the specified time runs out.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
* @param[in] msg the message to be posted on the mailbox
|
* @param[in] msg the message to be posted on the mailbox
|
||||||
* @param[in] time the number of ticks before the operation timeouts,
|
* @param[in] time the number of ticks before the operation timeouts,
|
||||||
* the following special values are allowed:
|
* the following special values are allowed:
|
||||||
|
@ -112,7 +134,7 @@ void chMBReset(Mailbox *mbp) {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) {
|
msg_t chMBPost(mailbox_t *mbp, msg_t msg, systime_t time) {
|
||||||
msg_t rdymsg;
|
msg_t rdymsg;
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
@ -126,7 +148,7 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||||
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
||||||
* available or the specified time runs out.
|
* available or the specified time runs out.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
* @param[in] msg the message to be posted on the mailbox
|
* @param[in] msg the message to be posted on the mailbox
|
||||||
* @param[in] time the number of ticks before the operation timeouts,
|
* @param[in] time the number of ticks before the operation timeouts,
|
||||||
* the following special values are allowed:
|
* the following special values are allowed:
|
||||||
|
@ -140,7 +162,7 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) {
|
msg_t chMBPostS(mailbox_t *mbp, msg_t msg, systime_t time) {
|
||||||
msg_t rdymsg;
|
msg_t rdymsg;
|
||||||
|
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
|
@ -162,7 +184,7 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||||
* @details This variant is non-blocking, the function returns a timeout
|
* @details This variant is non-blocking, the function returns a timeout
|
||||||
* condition if the queue is full.
|
* condition if the queue is full.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
* @param[in] msg the message to be posted on the mailbox
|
* @param[in] msg the message to be posted on the mailbox
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval RDY_OK if a message has been correctly posted.
|
* @retval RDY_OK if a message has been correctly posted.
|
||||||
|
@ -171,7 +193,7 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
msg_t chMBPostI(Mailbox *mbp, msg_t msg) {
|
msg_t chMBPostI(mailbox_t *mbp, msg_t msg) {
|
||||||
|
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
chDbgCheck(mbp != NULL, "chMBPostI");
|
chDbgCheck(mbp != NULL, "chMBPostI");
|
||||||
|
@ -191,7 +213,7 @@ msg_t chMBPostI(Mailbox *mbp, msg_t msg) {
|
||||||
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
||||||
* available or the specified time runs out.
|
* available or the specified time runs out.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
* @param[in] msg the message to be posted on the mailbox
|
* @param[in] msg the message to be posted on the mailbox
|
||||||
* @param[in] time the number of ticks before the operation timeouts,
|
* @param[in] time the number of ticks before the operation timeouts,
|
||||||
* the following special values are allowed:
|
* the following special values are allowed:
|
||||||
|
@ -205,7 +227,7 @@ msg_t chMBPostI(Mailbox *mbp, msg_t msg) {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) {
|
msg_t chMBPostAhead(mailbox_t *mbp, msg_t msg, systime_t time) {
|
||||||
msg_t rdymsg;
|
msg_t rdymsg;
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
@ -219,7 +241,7 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||||
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
||||||
* available or the specified time runs out.
|
* available or the specified time runs out.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
* @param[in] msg the message to be posted on the mailbox
|
* @param[in] msg the message to be posted on the mailbox
|
||||||
* @param[in] time the number of ticks before the operation timeouts,
|
* @param[in] time the number of ticks before the operation timeouts,
|
||||||
* the following special values are allowed:
|
* the following special values are allowed:
|
||||||
|
@ -233,7 +255,7 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) {
|
msg_t chMBPostAheadS(mailbox_t *mbp, msg_t msg, systime_t time) {
|
||||||
msg_t rdymsg;
|
msg_t rdymsg;
|
||||||
|
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
|
@ -255,7 +277,7 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||||
* @details This variant is non-blocking, the function returns a timeout
|
* @details This variant is non-blocking, the function returns a timeout
|
||||||
* condition if the queue is full.
|
* condition if the queue is full.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
* @param[in] msg the message to be posted on the mailbox
|
* @param[in] msg the message to be posted on the mailbox
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval RDY_OK if a message has been correctly posted.
|
* @retval RDY_OK if a message has been correctly posted.
|
||||||
|
@ -264,7 +286,7 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) {
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg) {
|
msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg) {
|
||||||
|
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
chDbgCheck(mbp != NULL, "chMBPostAheadI");
|
chDbgCheck(mbp != NULL, "chMBPostAheadI");
|
||||||
|
@ -284,7 +306,7 @@ msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg) {
|
||||||
* @details The invoking thread waits until a message is posted in the mailbox
|
* @details The invoking thread waits until a message is posted in the mailbox
|
||||||
* or the specified time runs out.
|
* or the specified time runs out.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
* @param[out] msgp pointer to a message variable for the received message
|
* @param[out] msgp pointer to a message variable for the received message
|
||||||
* @param[in] time the number of ticks before the operation timeouts,
|
* @param[in] time the number of ticks before the operation timeouts,
|
||||||
* the following special values are allowed:
|
* the following special values are allowed:
|
||||||
|
@ -298,7 +320,7 @@ msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg) {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) {
|
msg_t chMBFetch(mailbox_t *mbp, msg_t *msgp, systime_t time) {
|
||||||
msg_t rdymsg;
|
msg_t rdymsg;
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
@ -312,7 +334,7 @@ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) {
|
||||||
* @details The invoking thread waits until a message is posted in the mailbox
|
* @details The invoking thread waits until a message is posted in the mailbox
|
||||||
* or the specified time runs out.
|
* or the specified time runs out.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
* @param[out] msgp pointer to a message variable for the received message
|
* @param[out] msgp pointer to a message variable for the received message
|
||||||
* @param[in] time the number of ticks before the operation timeouts,
|
* @param[in] time the number of ticks before the operation timeouts,
|
||||||
* the following special values are allowed:
|
* the following special values are allowed:
|
||||||
|
@ -326,7 +348,7 @@ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) {
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) {
|
msg_t chMBFetchS(mailbox_t *mbp, msg_t *msgp, systime_t time) {
|
||||||
msg_t rdymsg;
|
msg_t rdymsg;
|
||||||
|
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
|
@ -348,7 +370,7 @@ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) {
|
||||||
* @details This variant is non-blocking, the function returns a timeout
|
* @details This variant is non-blocking, the function returns a timeout
|
||||||
* condition if the queue is empty.
|
* condition if the queue is empty.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized Mailbox object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
* @param[out] msgp pointer to a message variable for the received message
|
* @param[out] msgp pointer to a message variable for the received message
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval RDY_OK if a message has been correctly fetched.
|
* @retval RDY_OK if a message has been correctly fetched.
|
||||||
|
@ -357,7 +379,7 @@ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) {
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp) {
|
msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp) {
|
||||||
|
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchI");
|
chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchI");
|
||||||
|
|
|
@ -48,9 +48,29 @@
|
||||||
|
|
||||||
#if CH_USE_MEMCORE || defined(__DOXYGEN__)
|
#if CH_USE_MEMCORE || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
static uint8_t *nextmem;
|
static uint8_t *nextmem;
|
||||||
static uint8_t *endmem;
|
static uint8_t *endmem;
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Low level memory manager initialization.
|
* @brief Low level memory manager initialization.
|
||||||
*
|
*
|
||||||
|
@ -60,10 +80,12 @@ void _core_init(void) {
|
||||||
#if CH_MEMCORE_SIZE == 0
|
#if CH_MEMCORE_SIZE == 0
|
||||||
extern uint8_t __heap_base__[];
|
extern uint8_t __heap_base__[];
|
||||||
extern uint8_t __heap_end__[];
|
extern uint8_t __heap_end__[];
|
||||||
|
|
||||||
nextmem = (uint8_t *)MEM_ALIGN_NEXT(__heap_base__);
|
nextmem = (uint8_t *)MEM_ALIGN_NEXT(__heap_base__);
|
||||||
endmem = (uint8_t *)MEM_ALIGN_PREV(__heap_end__);
|
endmem = (uint8_t *)MEM_ALIGN_PREV(__heap_end__);
|
||||||
#else
|
#else
|
||||||
static stkalign_t buffer[MEM_ALIGN_NEXT(CH_MEMCORE_SIZE)/MEM_ALIGN_SIZE];
|
static stkalign_t buffer[MEM_ALIGN_NEXT(CH_MEMCORE_SIZE)/MEM_ALIGN_SIZE];
|
||||||
|
|
||||||
nextmem = (uint8_t *)&buffer[0];
|
nextmem = (uint8_t *)&buffer[0];
|
||||||
endmem = (uint8_t *)&buffer[MEM_ALIGN_NEXT(CH_MEMCORE_SIZE)/MEM_ALIGN_SIZE];
|
endmem = (uint8_t *)&buffer[MEM_ALIGN_NEXT(CH_MEMCORE_SIZE)/MEM_ALIGN_SIZE];
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,10 +39,31 @@
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
|
||||||
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
|
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes an empty memory pool.
|
* @brief Initializes an empty memory pool.
|
||||||
*
|
*
|
||||||
* @param[out] mp pointer to a @p MemoryPool structure
|
* @param[out] mp pointer to a @p memory_pool_t structure
|
||||||
* @param[in] size the size of the objects contained in this memory pool,
|
* @param[in] size the size of the objects contained in this memory pool,
|
||||||
* the minimum accepted size is the size of a pointer to
|
* the minimum accepted size is the size of a pointer to
|
||||||
* void.
|
* void.
|
||||||
|
@ -52,7 +73,7 @@
|
||||||
*
|
*
|
||||||
* @init
|
* @init
|
||||||
*/
|
*/
|
||||||
void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) {
|
void chPoolInit(memory_pool_t *mp, size_t size, memgetfunc_t provider) {
|
||||||
|
|
||||||
chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit");
|
chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit");
|
||||||
|
|
||||||
|
@ -68,13 +89,13 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) {
|
||||||
* memory pool.
|
* memory pool.
|
||||||
* @post The memory pool contains the elements of the input array.
|
* @post The memory pool contains the elements of the input array.
|
||||||
*
|
*
|
||||||
* @param[in] mp pointer to a @p MemoryPool structure
|
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||||
* @param[in] p pointer to the array first element
|
* @param[in] p pointer to the array first element
|
||||||
* @param[in] n number of elements in the array
|
* @param[in] n number of elements in the array
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void chPoolLoadArray(MemoryPool *mp, void *p, size_t n) {
|
void chPoolLoadArray(memory_pool_t *mp, void *p, size_t n) {
|
||||||
|
|
||||||
chDbgCheck((mp != NULL) && (n != 0), "chPoolLoadArray");
|
chDbgCheck((mp != NULL) && (n != 0), "chPoolLoadArray");
|
||||||
|
|
||||||
|
@ -89,13 +110,13 @@ void chPoolLoadArray(MemoryPool *mp, void *p, size_t n) {
|
||||||
* @brief Allocates an object from a memory pool.
|
* @brief Allocates an object from a memory pool.
|
||||||
* @pre The memory pool must be already been initialized.
|
* @pre The memory pool must be already been initialized.
|
||||||
*
|
*
|
||||||
* @param[in] mp pointer to a @p MemoryPool structure
|
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||||
* @return The pointer to the allocated object.
|
* @return The pointer to the allocated object.
|
||||||
* @retval NULL if pool is empty.
|
* @retval NULL if pool is empty.
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
void *chPoolAllocI(MemoryPool *mp) {
|
void *chPoolAllocI(memory_pool_t *mp) {
|
||||||
void *objp;
|
void *objp;
|
||||||
|
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
|
@ -112,13 +133,13 @@ void *chPoolAllocI(MemoryPool *mp) {
|
||||||
* @brief Allocates an object from a memory pool.
|
* @brief Allocates an object from a memory pool.
|
||||||
* @pre The memory pool must be already been initialized.
|
* @pre The memory pool must be already been initialized.
|
||||||
*
|
*
|
||||||
* @param[in] mp pointer to a @p MemoryPool structure
|
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||||
* @return The pointer to the allocated object.
|
* @return The pointer to the allocated object.
|
||||||
* @retval NULL if pool is empty.
|
* @retval NULL if pool is empty.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void *chPoolAlloc(MemoryPool *mp) {
|
void *chPoolAlloc(memory_pool_t *mp) {
|
||||||
void *objp;
|
void *objp;
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
@ -134,12 +155,12 @@ void *chPoolAlloc(MemoryPool *mp) {
|
||||||
* memory pool.
|
* memory pool.
|
||||||
* @pre The object must be properly aligned to contain a pointer to void.
|
* @pre The object must be properly aligned to contain a pointer to void.
|
||||||
*
|
*
|
||||||
* @param[in] mp pointer to a @p MemoryPool structure
|
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||||
* @param[in] objp the pointer to the object to be released
|
* @param[in] objp the pointer to the object to be released
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
void chPoolFreeI(MemoryPool *mp, void *objp) {
|
void chPoolFreeI(memory_pool_t *mp, void *objp) {
|
||||||
struct pool_header *php = objp;
|
struct pool_header *php = objp;
|
||||||
|
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
|
@ -156,12 +177,12 @@ void chPoolFreeI(MemoryPool *mp, void *objp) {
|
||||||
* memory pool.
|
* memory pool.
|
||||||
* @pre The object must be properly aligned to contain a pointer to void.
|
* @pre The object must be properly aligned to contain a pointer to void.
|
||||||
*
|
*
|
||||||
* @param[in] mp pointer to a @p MemoryPool structure
|
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||||
* @param[in] objp the pointer to the object to be released
|
* @param[in] objp the pointer to the object to be released
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void chPoolFree(MemoryPool *mp, void *objp) {
|
void chPoolFree(memory_pool_t *mp, void *objp) {
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chPoolFreeI(mp, objp);
|
chPoolFreeI(mp, objp);
|
||||||
|
|
|
@ -48,12 +48,32 @@
|
||||||
|
|
||||||
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
|
#if CH_USE_MESSAGES || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#if CH_USE_MESSAGES_PRIORITY
|
#if CH_USE_MESSAGES_PRIORITY
|
||||||
#define msg_insert(tp, qp) prio_insert(tp, qp)
|
#define msg_insert(tp, qp) prio_insert(tp, qp)
|
||||||
#else
|
#else
|
||||||
#define msg_insert(tp, qp) queue_insert(tp, qp)
|
#define msg_insert(tp, qp) queue_insert(tp, qp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sends a message to the specified thread.
|
* @brief Sends a message to the specified thread.
|
||||||
* @details The sender is stopped until the receiver executes a
|
* @details The sender is stopped until the receiver executes a
|
||||||
|
|
|
@ -69,14 +69,34 @@
|
||||||
|
|
||||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes s @p Mutex structure.
|
* @brief Initializes s @p mutex_t structure.
|
||||||
*
|
*
|
||||||
* @param[out] mp pointer to a @p Mutex structure
|
* @param[out] mp pointer to a @p mutex_t structure
|
||||||
*
|
*
|
||||||
* @init
|
* @init
|
||||||
*/
|
*/
|
||||||
void chMtxInit(Mutex *mp) {
|
void chMtxInit(mutex_t *mp) {
|
||||||
|
|
||||||
chDbgCheck(mp != NULL, "chMtxInit");
|
chDbgCheck(mp != NULL, "chMtxInit");
|
||||||
|
|
||||||
|
@ -89,11 +109,11 @@ void chMtxInit(Mutex *mp) {
|
||||||
* @post The mutex is locked and inserted in the per-thread stack of owned
|
* @post The mutex is locked and inserted in the per-thread stack of owned
|
||||||
* mutexes.
|
* mutexes.
|
||||||
*
|
*
|
||||||
* @param[in] mp pointer to the @p Mutex structure
|
* @param[in] mp pointer to the @p mutex_t structure
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void chMtxLock(Mutex *mp) {
|
void chMtxLock(mutex_t *mp) {
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
|
||||||
|
@ -107,11 +127,11 @@ void chMtxLock(Mutex *mp) {
|
||||||
* @post The mutex is locked and inserted in the per-thread stack of owned
|
* @post The mutex is locked and inserted in the per-thread stack of owned
|
||||||
* mutexes.
|
* mutexes.
|
||||||
*
|
*
|
||||||
* @param[in] mp pointer to the @p Mutex structure
|
* @param[in] mp pointer to the @p mutex_t structure
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
void chMtxLockS(Mutex *mp) {
|
void chMtxLockS(mutex_t *mp) {
|
||||||
thread_t *ctp = currp;
|
thread_t *ctp = currp;
|
||||||
|
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
|
@ -123,18 +143,20 @@ void chMtxLockS(Mutex *mp) {
|
||||||
boosting the priority of all the affected threads to equal the priority
|
boosting the priority of all the affected threads to equal the priority
|
||||||
of the running thread requesting the mutex.*/
|
of the running thread requesting the mutex.*/
|
||||||
thread_t *tp = mp->m_owner;
|
thread_t *tp = mp->m_owner;
|
||||||
|
|
||||||
/* Does the running thread have higher priority than the mutex
|
/* Does the running thread have higher priority than the mutex
|
||||||
owning thread? */
|
owning thread? */
|
||||||
while (tp->p_prio < ctp->p_prio) {
|
while (tp->p_prio < ctp->p_prio) {
|
||||||
/* Make priority of thread tp match the running thread's priority.*/
|
/* Make priority of thread tp match the running thread's priority.*/
|
||||||
tp->p_prio = ctp->p_prio;
|
tp->p_prio = ctp->p_prio;
|
||||||
|
|
||||||
/* The following states need priority queues reordering.*/
|
/* The following states need priority queues reordering.*/
|
||||||
switch (tp->p_state) {
|
switch (tp->p_state) {
|
||||||
case THD_STATE_WTMTX:
|
case THD_STATE_WTMTX:
|
||||||
/* Re-enqueues the mutex owner with its new priority.*/
|
/* Re-enqueues the mutex owner with its new priority.*/
|
||||||
queue_prio_insert(queue_dequeue(tp),
|
queue_prio_insert(queue_dequeue(tp),
|
||||||
(threads_queue_t *)tp->p_u.wtobjp);
|
(threads_queue_t *)tp->p_u.wtobjp);
|
||||||
tp = ((Mutex *)tp->p_u.wtobjp)->m_owner;
|
tp = ((mutex_t *)tp->p_u.wtobjp)->m_owner;
|
||||||
continue;
|
continue;
|
||||||
#if CH_USE_CONDVARS | \
|
#if CH_USE_CONDVARS | \
|
||||||
(CH_USE_SEMAPHORES && CH_USE_SEMAPHORES_PRIORITY) | \
|
(CH_USE_SEMAPHORES && CH_USE_SEMAPHORES_PRIORITY) | \
|
||||||
|
@ -164,10 +186,12 @@ void chMtxLockS(Mutex *mp) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sleep on the mutex.*/
|
/* Sleep on the mutex.*/
|
||||||
queue_prio_insert(ctp, &mp->m_queue);
|
queue_prio_insert(ctp, &mp->m_queue);
|
||||||
ctp->p_u.wtobjp = mp;
|
ctp->p_u.wtobjp = mp;
|
||||||
chSchGoSleepS(THD_STATE_WTMTX);
|
chSchGoSleepS(THD_STATE_WTMTX);
|
||||||
|
|
||||||
/* It is assumed that the thread performing the unlock operation assigns
|
/* It is assumed that the thread performing the unlock operation assigns
|
||||||
the mutex to this thread.*/
|
the mutex to this thread.*/
|
||||||
chDbgAssert(mp->m_owner == ctp, "chMtxLockS(), #1", "not owner");
|
chDbgAssert(mp->m_owner == ctp, "chMtxLockS(), #1", "not owner");
|
||||||
|
@ -191,14 +215,14 @@ void chMtxLockS(Mutex *mp) {
|
||||||
* priority inheritance mechanism because it does not try to
|
* priority inheritance mechanism because it does not try to
|
||||||
* enter a sleep state.
|
* enter a sleep state.
|
||||||
*
|
*
|
||||||
* @param[in] mp pointer to the @p Mutex structure
|
* @param[in] mp pointer to the @p mutex_t structure
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval TRUE if the mutex has been successfully acquired
|
* @retval TRUE if the mutex has been successfully acquired
|
||||||
* @retval FALSE if the lock attempt failed.
|
* @retval FALSE if the lock attempt failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bool_t chMtxTryLock(Mutex *mp) {
|
bool_t chMtxTryLock(mutex_t *mp) {
|
||||||
bool_t b;
|
bool_t b;
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
@ -219,20 +243,21 @@ bool_t chMtxTryLock(Mutex *mp) {
|
||||||
* priority inheritance mechanism because it does not try to
|
* priority inheritance mechanism because it does not try to
|
||||||
* enter a sleep state.
|
* enter a sleep state.
|
||||||
*
|
*
|
||||||
* @param[in] mp pointer to the @p Mutex structure
|
* @param[in] mp pointer to the @p mutex_t structure
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval TRUE if the mutex has been successfully acquired
|
* @retval TRUE if the mutex has been successfully acquired
|
||||||
* @retval FALSE if the lock attempt failed.
|
* @retval FALSE if the lock attempt failed.
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
bool_t chMtxTryLockS(Mutex *mp) {
|
bool_t chMtxTryLockS(mutex_t *mp) {
|
||||||
|
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
chDbgCheck(mp != NULL, "chMtxTryLockS");
|
chDbgCheck(mp != NULL, "chMtxTryLockS");
|
||||||
|
|
||||||
if (mp->m_owner != NULL)
|
if (mp->m_owner != NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
mp->m_owner = currp;
|
mp->m_owner = currp;
|
||||||
mp->m_next = currp->p_mtxlist;
|
mp->m_next = currp->p_mtxlist;
|
||||||
currp->p_mtxlist = mp;
|
currp->p_mtxlist = mp;
|
||||||
|
@ -249,21 +274,24 @@ bool_t chMtxTryLockS(Mutex *mp) {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
Mutex *chMtxUnlock(void) {
|
mutex_t *chMtxUnlock(void) {
|
||||||
thread_t *ctp = currp;
|
thread_t *ctp = currp;
|
||||||
Mutex *ump, *mp;
|
mutex_t *ump, *mp;
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
|
|
||||||
chDbgAssert(ctp->p_mtxlist != NULL,
|
chDbgAssert(ctp->p_mtxlist != NULL,
|
||||||
"chMtxUnlock(), #1",
|
"chMtxUnlock(), #1",
|
||||||
"owned mutexes list empty");
|
"owned mutexes list empty");
|
||||||
chDbgAssert(ctp->p_mtxlist->m_owner == ctp,
|
chDbgAssert(ctp->p_mtxlist->m_owner == ctp,
|
||||||
"chMtxUnlock(), #2",
|
"chMtxUnlock(), #2",
|
||||||
"ownership failure");
|
"ownership failure");
|
||||||
/* Removes the top Mutex from the thread's owned mutexes list and marks it
|
|
||||||
|
/* Removes the top mutex from the thread's owned mutexes list and marks it
|
||||||
as not owned.*/
|
as not owned.*/
|
||||||
ump = ctp->p_mtxlist;
|
ump = ctp->p_mtxlist;
|
||||||
ctp->p_mtxlist = ump->m_next;
|
ctp->p_mtxlist = ump->m_next;
|
||||||
|
|
||||||
/* If a thread is waiting on the mutex then the fun part begins.*/
|
/* If a thread is waiting on the mutex then the fun part begins.*/
|
||||||
if (chMtxQueueNotEmptyS(ump)) {
|
if (chMtxQueueNotEmptyS(ump)) {
|
||||||
thread_t *tp;
|
thread_t *tp;
|
||||||
|
@ -280,9 +308,11 @@ Mutex *chMtxUnlock(void) {
|
||||||
newprio = mp->m_queue.p_next->p_prio;
|
newprio = mp->m_queue.p_next->p_prio;
|
||||||
mp = mp->m_next;
|
mp = mp->m_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assigns to the current thread the highest priority among all the
|
/* Assigns to the current thread the highest priority among all the
|
||||||
waiting threads.*/
|
waiting threads.*/
|
||||||
ctp->p_prio = newprio;
|
ctp->p_prio = newprio;
|
||||||
|
|
||||||
/* Awakens the highest priority thread waiting for the unlocked mutex and
|
/* Awakens the highest priority thread waiting for the unlocked mutex and
|
||||||
assigns the mutex to it.*/
|
assigns the mutex to it.*/
|
||||||
tp = queue_fifo_remove(&ump->m_queue);
|
tp = queue_fifo_remove(&ump->m_queue);
|
||||||
|
@ -309,9 +339,9 @@ Mutex *chMtxUnlock(void) {
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
Mutex *chMtxUnlockS(void) {
|
mutex_t *chMtxUnlockS(void) {
|
||||||
thread_t *ctp = currp;
|
thread_t *ctp = currp;
|
||||||
Mutex *ump, *mp;
|
mutex_t *ump, *mp;
|
||||||
|
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
chDbgAssert(ctp->p_mtxlist != NULL,
|
chDbgAssert(ctp->p_mtxlist != NULL,
|
||||||
|
@ -321,10 +351,11 @@ Mutex *chMtxUnlockS(void) {
|
||||||
"chMtxUnlockS(), #2",
|
"chMtxUnlockS(), #2",
|
||||||
"ownership failure");
|
"ownership failure");
|
||||||
|
|
||||||
/* Removes the top Mutex from the owned mutexes list and marks it as not
|
/* Removes the top mutex from the owned mutexes list and marks it as not
|
||||||
owned.*/
|
owned.*/
|
||||||
ump = ctp->p_mtxlist;
|
ump = ctp->p_mtxlist;
|
||||||
ctp->p_mtxlist = ump->m_next;
|
ctp->p_mtxlist = ump->m_next;
|
||||||
|
|
||||||
/* If a thread is waiting on the mutex then the fun part begins.*/
|
/* If a thread is waiting on the mutex then the fun part begins.*/
|
||||||
if (chMtxQueueNotEmptyS(ump)) {
|
if (chMtxQueueNotEmptyS(ump)) {
|
||||||
thread_t *tp;
|
thread_t *tp;
|
||||||
|
@ -339,9 +370,11 @@ Mutex *chMtxUnlockS(void) {
|
||||||
priority will have at least that priority.*/
|
priority will have at least that priority.*/
|
||||||
if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio))
|
if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio))
|
||||||
newprio = mp->m_queue.p_next->p_prio;
|
newprio = mp->m_queue.p_next->p_prio;
|
||||||
|
|
||||||
mp = mp->m_next;
|
mp = mp->m_next;
|
||||||
}
|
}
|
||||||
ctp->p_prio = newprio;
|
ctp->p_prio = newprio;
|
||||||
|
|
||||||
/* Awakens the highest priority thread waiting for the unlocked mutex and
|
/* Awakens the highest priority thread waiting for the unlocked mutex and
|
||||||
assigns the mutex to it.*/
|
assigns the mutex to it.*/
|
||||||
tp = queue_fifo_remove(&ump->m_queue);
|
tp = queue_fifo_remove(&ump->m_queue);
|
||||||
|
@ -372,7 +405,7 @@ void chMtxUnlockAll(void) {
|
||||||
chSysLock();
|
chSysLock();
|
||||||
if (ctp->p_mtxlist != NULL) {
|
if (ctp->p_mtxlist != NULL) {
|
||||||
do {
|
do {
|
||||||
Mutex *ump = ctp->p_mtxlist;
|
mutex_t *ump = ctp->p_mtxlist;
|
||||||
ctp->p_mtxlist = ump->m_next;
|
ctp->p_mtxlist = ump->m_next;
|
||||||
if (chMtxQueueNotEmptyS(ump)) {
|
if (chMtxQueueNotEmptyS(ump)) {
|
||||||
thread_t *tp = queue_fifo_remove(&ump->m_queue);
|
thread_t *tp = queue_fifo_remove(&ump->m_queue);
|
||||||
|
|
|
@ -50,9 +50,29 @@
|
||||||
|
|
||||||
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
#if CH_USE_REGISTRY || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#define _offsetof(st, m) \
|
#define _offsetof(st, m) \
|
||||||
((size_t)((char *)&((st *)0)->m - (char *)0))
|
((size_t)((char *)&((st *)0)->m - (char *)0))
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OS signature in ROM plus debug-related information.
|
* OS signature in ROM plus debug-related information.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -61,12 +61,32 @@
|
||||||
|
|
||||||
#if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
|
#if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#if CH_USE_SEMAPHORES_PRIORITY
|
#if CH_USE_SEMAPHORES_PRIORITY
|
||||||
#define sem_insert(tp, qp) prio_insert(tp, qp)
|
#define sem_insert(tp, qp) prio_insert(tp, qp)
|
||||||
#else
|
#else
|
||||||
#define sem_insert(tp, qp) queue_insert(tp, qp)
|
#define sem_insert(tp, qp) queue_insert(tp, qp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes a semaphore with the specified counter value.
|
* @brief Initializes a semaphore with the specified counter value.
|
||||||
*
|
*
|
||||||
|
|
|
@ -35,12 +35,30 @@
|
||||||
|
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
|
#if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Idle thread working area.
|
* @brief Idle thread working area.
|
||||||
*/
|
*/
|
||||||
WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE);
|
static WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE);
|
||||||
|
#endif /* CH_NO_IDLE_THREAD */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief This function implements the idle thread infinite loop.
|
* @brief This function implements the idle thread infinite loop.
|
||||||
* @details The function puts the processor in the lowest power mode capable
|
* @details The function puts the processor in the lowest power mode capable
|
||||||
|
@ -51,7 +69,7 @@ WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE);
|
||||||
*
|
*
|
||||||
* @param[in] p the thread parameter, unused in this scenario
|
* @param[in] p the thread parameter, unused in this scenario
|
||||||
*/
|
*/
|
||||||
void _idle_thread(void *p) {
|
static void _idle_thread(void *p) {
|
||||||
|
|
||||||
(void)p;
|
(void)p;
|
||||||
chRegSetThreadName("idle");
|
chRegSetThreadName("idle");
|
||||||
|
@ -62,6 +80,10 @@ void _idle_thread(void *p) {
|
||||||
}
|
}
|
||||||
#endif /* CH_NO_IDLE_THREAD */
|
#endif /* CH_NO_IDLE_THREAD */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Module exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ChibiOS/RT initialization.
|
* @brief ChibiOS/RT initialization.
|
||||||
* @details After executing this function the current instructions stream
|
* @details After executing this function the current instructions stream
|
||||||
|
@ -116,6 +138,29 @@ void chSysInit(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Halts the system.
|
||||||
|
* @details This function is invoked by the operating system when an
|
||||||
|
* unrecoverable error is detected, for example because a programming
|
||||||
|
* error in the application code that triggers an assertion while
|
||||||
|
* in debug mode.
|
||||||
|
* @note Can be invoked from any system state.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
void chSysHalt(void) {
|
||||||
|
|
||||||
|
chSysDisable();
|
||||||
|
|
||||||
|
#if defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
|
||||||
|
SYSTEM_HALT_HOOK();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Harmless infinite loop.*/
|
||||||
|
while (true)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles time ticks for round robin preemption and timer increments.
|
* @brief Handles time ticks for round robin preemption and timer increments.
|
||||||
* @details Decrements the remaining time quantum of the running thread
|
* @details Decrements the remaining time quantum of the running thread
|
||||||
|
|
|
@ -306,20 +306,6 @@
|
||||||
#define CH_USE_HEAP TRUE
|
#define CH_USE_HEAP TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief C-runtime allocator.
|
|
||||||
* @details If enabled the the heap allocator APIs just wrap the C-runtime
|
|
||||||
* @p malloc() and @p free() functions.
|
|
||||||
*
|
|
||||||
* @note The default is @p FALSE.
|
|
||||||
* @note Requires @p CH_USE_HEAP.
|
|
||||||
* @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
|
|
||||||
* appropriate documentation.
|
|
||||||
*/
|
|
||||||
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
|
||||||
#define CH_USE_MALLOC_HEAP FALSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Memory Pools Allocator APIs.
|
* @brief Memory Pools Allocator APIs.
|
||||||
* @details If enabled then the memory pools allocator APIs are included
|
* @details If enabled then the memory pools allocator APIs are included
|
||||||
|
|
|
@ -73,15 +73,20 @@ typedef uint32_t tprio_t;
|
||||||
typedef int32_t msg_t;
|
typedef int32_t msg_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Event Id, use fastest signed.
|
* @brief Numeric event identifier, use fastest signed.
|
||||||
*/
|
*/
|
||||||
typedef int32_t eventid_t;
|
typedef int32_t eventid_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Event Mask, recommended fastest unsigned.
|
* @brief Mask of event identifiers, recommended fastest unsigned.
|
||||||
*/
|
*/
|
||||||
typedef uint32_t eventmask_t;
|
typedef uint32_t eventmask_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mask of event flags, recommended fastest unsigned.
|
||||||
|
*/
|
||||||
|
typedef uint32_t eventflags_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief System Time, recommended fastest unsigned.
|
* @brief System Time, recommended fastest unsigned.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -66,12 +66,12 @@ extern "C" {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* CH_USE_XXX */
|
|
||||||
|
|
||||||
#endif /* _CHXXX_H_ */
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module inline functions. */
|
/* Module inline functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#endif /* CH_USE_XXX */
|
||||||
|
|
||||||
|
#endif /* _CHXXX_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -40,9 +40,9 @@ typedef uint8_t trefs_t; /**< Thread references counter. */
|
||||||
typedef uint8_t tslices_t; /**< Thread time slices counter. */
|
typedef uint8_t tslices_t; /**< Thread time slices counter. */
|
||||||
typedef uint32_t tprio_t; /**< Thread priority. */
|
typedef uint32_t tprio_t; /**< Thread priority. */
|
||||||
typedef int32_t msg_t; /**< Inter-thread message. */
|
typedef int32_t msg_t; /**< Inter-thread message. */
|
||||||
typedef int32_t eventid_t; /**< Event Id. */
|
typedef int32_t eventid_t; /**< Numeric event identifier. */
|
||||||
typedef uint32_t eventmask_t; /**< Event mask. */
|
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
|
||||||
typedef uint32_t flagsmask_t; /**< Event flags. */
|
typedef uint32_t eventflags_t; /**< Mask of event flags. */
|
||||||
typedef uint32_t systime_t; /**< System time. */
|
typedef uint32_t systime_t; /**< System time. */
|
||||||
typedef int32_t cnt_t; /**< Resources counter. */
|
typedef int32_t cnt_t; /**< Resources counter. */
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
static semaphore_t sem1;
|
static semaphore_t sem1;
|
||||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||||
static Mutex mtx1;
|
static mutex_t mtx1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static msg_t thread1(void *p) {
|
static msg_t thread1(void *p) {
|
||||||
|
@ -650,15 +650,15 @@ static void bmk13_execute(void) {
|
||||||
test_println(" bytes");
|
test_println(" bytes");
|
||||||
#if CH_USE_EVENTS || defined(__DOXYGEN__)
|
#if CH_USE_EVENTS || defined(__DOXYGEN__)
|
||||||
test_print("--- EventS: ");
|
test_print("--- EventS: ");
|
||||||
test_printn(sizeof(EventSource));
|
test_printn(sizeof(event_source_t));
|
||||||
test_println(" bytes");
|
test_println(" bytes");
|
||||||
test_print("--- EventL: ");
|
test_print("--- EventL: ");
|
||||||
test_printn(sizeof(EventListener));
|
test_printn(sizeof(event_listener_t));
|
||||||
test_println(" bytes");
|
test_println(" bytes");
|
||||||
#endif
|
#endif
|
||||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||||
test_print("--- Mutex : ");
|
test_print("--- Mutex : ");
|
||||||
test_printn(sizeof(Mutex));
|
test_printn(sizeof(mutex_t));
|
||||||
test_println(" bytes");
|
test_println(" bytes");
|
||||||
#endif
|
#endif
|
||||||
#if CH_USE_CONDVARS || defined(__DOXYGEN__)
|
#if CH_USE_CONDVARS || defined(__DOXYGEN__)
|
||||||
|
@ -673,7 +673,7 @@ static void bmk13_execute(void) {
|
||||||
#endif
|
#endif
|
||||||
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
|
#if CH_USE_MAILBOXES || defined(__DOXYGEN__)
|
||||||
test_print("--- MailB.: ");
|
test_print("--- MailB.: ");
|
||||||
test_printn(sizeof(Mailbox));
|
test_printn(sizeof(mailbox_t));
|
||||||
test_println(" bytes");
|
test_println(" bytes");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,10 +51,10 @@
|
||||||
|
|
||||||
#if CH_USE_DYNAMIC || defined(__DOXYGEN__)
|
#if CH_USE_DYNAMIC || defined(__DOXYGEN__)
|
||||||
#if (CH_USE_HEAP && !CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
#if (CH_USE_HEAP && !CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
||||||
static MemoryHeap heap1;
|
static memory_heap_t heap1;
|
||||||
#endif
|
#endif
|
||||||
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
|
#if CH_USE_MEMPOOLS || defined(__DOXYGEN__)
|
||||||
static MemoryPool mp1;
|
static memory_pool_t mp1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -83,7 +83,7 @@ static void h3(eventid_t id) {(void)id;test_emit_token('C');}
|
||||||
static ROMCONST evhandler_t evhndl[] = {h1, h2, h3};
|
static ROMCONST evhandler_t evhndl[] = {h1, h2, h3};
|
||||||
|
|
||||||
static void evt1_execute(void) {
|
static void evt1_execute(void) {
|
||||||
EventListener el1, el2;
|
event_listener_t el1, el2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Testing chEvtRegisterMask() and chEvtUnregister().
|
* Testing chEvtRegisterMask() and chEvtUnregister().
|
||||||
|
@ -148,7 +148,7 @@ static msg_t thread2(void *p) {
|
||||||
|
|
||||||
static void evt2_execute(void) {
|
static void evt2_execute(void) {
|
||||||
eventmask_t m;
|
eventmask_t m;
|
||||||
EventListener el1, el2;
|
event_listener_t el1, el2;
|
||||||
systime_t target_time;
|
systime_t target_time;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
#define SIZE 16
|
#define SIZE 16
|
||||||
|
|
||||||
static MemoryHeap test_heap;
|
static memory_heap_t test_heap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @page test_heap_001 Allocation and fragmentation test
|
* @page test_heap_001 Allocation and fragmentation test
|
||||||
|
|
|
@ -155,7 +155,7 @@ static void mbox1_execute(void) {
|
||||||
/*
|
/*
|
||||||
* Testing I-Class.
|
* Testing I-Class.
|
||||||
*/
|
*/
|
||||||
chSysLock()
|
chSysLock();
|
||||||
msg1 = chMBPostI(&mb1, 'A');
|
msg1 = chMBPostI(&mb1, 'A');
|
||||||
test_assert(22, msg1 == RDY_OK, "wrong wake-up message");
|
test_assert(22, msg1 == RDY_OK, "wrong wake-up message");
|
||||||
msg1 = chMBPostI(&mb1, 'B');
|
msg1 = chMBPostI(&mb1, 'B');
|
||||||
|
|
Loading…
Reference in New Issue