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:
gdisirio 2013-07-19 14:51:35 +00:00
parent d58064a533
commit 25ddb1c801
37 changed files with 999 additions and 812 deletions

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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_ */

View File

@ -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

View File

@ -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);
} }

View File

@ -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_ */
/** @} */

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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_ */
/** @} */ /** @} */

View File

@ -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.
*/ */

View File

@ -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();

View File

@ -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;

View File

@ -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.
* *

View File

@ -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 */
/** @} */ /** @} */

View File

@ -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");

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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.
*/ */

View File

@ -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.
* *

View File

@ -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

View File

@ -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

View File

@ -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.
*/ */

View File

@ -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_ */
/** @} */ /** @} */

View File

@ -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. */

View File

@ -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
} }

View File

@ -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
/** /**

View File

@ -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;
/* /*

View File

@ -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

View File

@ -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');