mirror of
				https://github.com/0xFEEDC0DE64/arduino-esp32.git
				synced 2025-10-31 22:21:39 +01:00 
			
		
		
		
	
		
			
	
	
		
			279 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			279 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /** @file */ | ||
|  | 
 | ||
|  | // xos_msgq.h - XOS Message Queue API and data structures.
 | ||
|  | 
 | ||
|  | // Copyright (c) 2003-2015 Cadence Design Systems, Inc.
 | ||
|  | //
 | ||
|  | // Permission is hereby granted, free of charge, to any person obtaining
 | ||
|  | // a copy of this software and associated documentation files (the
 | ||
|  | // "Software"), to deal in the Software without restriction, including
 | ||
|  | // without limitation the rights to use, copy, modify, merge, publish,
 | ||
|  | // distribute, sublicense, and/or sell copies of the Software, and to
 | ||
|  | // permit persons to whom the Software is furnished to do so, subject to
 | ||
|  | // the following conditions:
 | ||
|  | //
 | ||
|  | // The above copyright notice and this permission notice shall be included
 | ||
|  | // in all copies or substantial portions of the Software.
 | ||
|  | //
 | ||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | ||
|  | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | ||
|  | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | ||
|  | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | ||
|  | // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | ||
|  | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | ||
|  | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | ||
|  | 
 | ||
|  | // NOTE: Do not include this file directly in your application. Including
 | ||
|  | // xos.h will automatically include this file.
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #ifndef __XOS_MSGQ_H__
 | ||
|  | #define __XOS_MSGQ_H__
 | ||
|  | 
 | ||
|  | #include "xos_types.h"
 | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | extern "C" { | ||
|  | #endif
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | //  XosMsgQueue is a multi-writer multi-reader message queue implementation.
 | ||
|  | //  It is completely thread-safe and can be used by interrupt handlers.
 | ||
|  | //  Interrupt handlers are guaranteed not to block when trying to send or
 | ||
|  | //  receive a message. Messages are copied into the queue. The queue contains
 | ||
|  | //  storage for a fixed number of messages defined at queue creation time.
 | ||
|  | //  Messages must be a multiple of 4 bytes long (padded if necessary) and the
 | ||
|  | //  message buffers must be 4-byte aligned.
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | //  Message Queue flags.
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | #define XOS_MSGQ_WAIT_PRIORITY  0x0000  ///< Wake waiters in priority order (default)
 | ||
|  | #define XOS_MSGQ_WAIT_FIFO      0x0001  ///< Wake waiters in FIFO order
 | ||
|  | #define XOS_MSGQ_FULL           0x0002  // Queue is full
 | ||
|  | #define XOS_MSGQ_DELETED        0x8000  // Queue is deleted
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  XosMsgQueue object.
 | ||
|  | ///
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | typedef struct XosMsgQueue { | ||
|  |     uint16_t            flags;          ///< queue flags
 | ||
|  |     uint16_t            count;          ///< # of messages queue can hold
 | ||
|  |     uint32_t            msize;          ///< message size in bytes
 | ||
|  |     uint16_t            head;           ///< write pointer
 | ||
|  |     uint16_t            tail;           ///< read pointer
 | ||
|  |     XosThreadQueue      readq;          ///< reader wait queue
 | ||
|  |     XosThreadQueue      writeq;         ///< writer wait queue
 | ||
|  | #if XOS_MSGQ_DEBUG
 | ||
|  |     uint32_t            sig;            // debug signature
 | ||
|  | #endif
 | ||
|  | #if XOS_OPT_MSGQ_STATS
 | ||
|  |     uint32_t            num_send;       ///< # of messages put to queue
 | ||
|  |     uint32_t            num_recv;       ///< # of messages taken from queue
 | ||
|  |     uint32_t            num_send_blks;  ///< # of times thread blocked on send
 | ||
|  |     uint32_t            num_recv_blks;  ///< # of times thread blocked on recv
 | ||
|  | #endif
 | ||
|  |     uint32_t            msg[1];         ///< first word of message buffer
 | ||
|  | } XosMsgQueue; | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Use these macros to statically or dynamically allocate a message queue.
 | ||
|  | ///  XOS_MSGQ_ALLOC allocates a static queue, while XOS_MSGQ_SIZE can be used
 | ||
|  | ///  to allocate memory via malloc() etc.
 | ||
|  | ///
 | ||
|  | ///  Static: this allocates a queue named "testq", containing 10 messages,
 | ||
|  | ///  each 16 bytes long.
 | ||
|  | ///
 | ||
|  | ///      XOS_MSGQ_ALLOC(testq, 10, 16);
 | ||
|  | ///
 | ||
|  | ///  Dynamic: this allocates a queue named "testq", containing 10 messages,
 | ||
|  | ///  each 16 bytes long.
 | ||
|  | ///
 | ||
|  | ///      XosMsgQueue * testq = malloc( XOS_MSGQ_SIZE(10, 16) );
 | ||
|  | ///
 | ||
|  | ///  \param     name            The queue name, i.e. the name of the pointer
 | ||
|  | ///                             to the queue. Used as the queue handle in
 | ||
|  | ///                             queue API calls.
 | ||
|  | ///
 | ||
|  | ///  \param     num             Number of messages to allocate in queue. Must be > 0.
 | ||
|  | ///
 | ||
|  | ///  \param     size            Message size in bytes. Must be > 0 and multiple of 4.
 | ||
|  | ///
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | 
 | ||
|  | #define XOS_MSGQ_ALLOC(name, num, size) \
 | ||
|  |     static uint8_t name ## _buf[ sizeof(XosMsgQueue) + ((num) * (size)) ]; \ | ||
|  |     XosMsgQueue * name = (XosMsgQueue *) name ## _buf; | ||
|  | 
 | ||
|  | #define XOS_MSGQ_SIZE(num, size) \
 | ||
|  |     (sizeof(XosMsgQueue) + ((num) * (size))) | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Create the message queue object. Memory for the queue must be allocated by
 | ||
|  | ///  the caller, either statically or via dynamic allocation. See the macros
 | ||
|  | ///  XOS_MSGQ_ALLOC and XOS_MSGQ_SIZE for examples.
 | ||
|  | ///
 | ||
|  | ///  \param     msgq            Handle (pointer) to message queue.
 | ||
|  | ///
 | ||
|  | ///  \param     num             Number of messages allocated in queue. Must be > 0.
 | ||
|  | ///
 | ||
|  | ///  \param     size            Message size in bytes. Must be > 0 and multiple of 4.
 | ||
|  | ///
 | ||
|  | ///  \param     flags           Queue flags:
 | ||
|  | ///                             - XOS_MSGQ_WAIT_FIFO - blocked threads will be
 | ||
|  | ///                               woken in FIFO order.
 | ||
|  | ///                             - XOS_MSGQ_WAIT_PRIORITY - blocked threads will
 | ||
|  | ///                               be woken in priority order (default).
 | ||
|  | ///
 | ||
|  | ///  \return    Returns XOS_OK on success, else error code.
 | ||
|  | ///
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | int32_t | ||
|  | xos_msgq_create(XosMsgQueue * msgq, uint16_t num, uint32_t size, uint16_t flags); | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Destroys the specified queue. Any waiting threads are unblocked with an 
 | ||
|  | ///  error return. Any messages in the queue will be lost.
 | ||
|  | ///
 | ||
|  | ///  \param     msgq            Pointer to message queue.
 | ||
|  | ///
 | ||
|  | ///  \return    Returns XOS_OK on success, else error code.
 | ||
|  | ///
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | int32_t | ||
|  | xos_msgq_delete(XosMsgQueue * msgq); | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Put a message into the queue. The message contents are copied into the next
 | ||
|  | ///  available message slot. If no space is available, this function will block
 | ||
|  | ///  if called from a thread, but will return immediately if called from an
 | ||
|  | ///  interrupt handler.
 | ||
|  | ///
 | ||
|  | ///  \param     msgq            Pointer to message queue.
 | ||
|  | ///
 | ||
|  | ///  \param     msg             Pointer to message buffer.
 | ||
|  | ///
 | ||
|  | ///  \return    Returns XOS_OK on success, else error code.
 | ||
|  | ///
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | int32_t | ||
|  | xos_msgq_put(XosMsgQueue * msgq, const uint32_t * msg); | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Put a message into the queue. The message contents are copied into the next
 | ||
|  | ///  available message slot. If no space is available, this function will block
 | ||
|  | ///  if called from a thread, but will return immediately if called from an
 | ||
|  | ///  interrupt handler. The thread will be unblocked when space frees up in the
 | ||
|  | ///  queue or the timeout expires.
 | ||
|  | ///
 | ||
|  | ///  \param     msgq            Pointer to message queue.
 | ||
|  | ///
 | ||
|  | ///  \param     msg             Pointer to message buffer.
 | ||
|  | ///
 | ||
|  | ///  \param     to_cycles       Timeout in cycles. Convert from time to cycles
 | ||
|  | ///                             using the helper functions provided in xos_timer.
 | ||
|  | ///                             A value of zero indicates no timeout.
 | ||
|  | ///
 | ||
|  | ///  \return    Returns XOS_OK on success, XOS_ERR_TIMEOUT on timeout, else error code.
 | ||
|  | ///
 | ||
|  | ///  NOTE: If XOS_OPT_WAIT_TIMEOUT is not enabled, then the timeout value is
 | ||
|  | ///  ignored, and no timeout will occur.
 | ||
|  | ///
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | int32_t | ||
|  | xos_msgq_put_timeout(XosMsgQueue * msgq, const uint32_t * msg, uint64_t to_cycles); | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Get a message from the queue. The message contents are copied into the 
 | ||
|  | ///  buffer that must be provided. If no message is available, this function
 | ||
|  | ///  will block if called from a thread, but will return immediately if called
 | ||
|  | ///  from an interrupt handler.
 | ||
|  | ///
 | ||
|  | ///  \param     msgq            Pointer to message queue.
 | ||
|  | ///
 | ||
|  | ///  \param     msg             Pointer to message buffer.
 | ||
|  | ///
 | ||
|  | ///  \return    Returns XOS_OK on success, else error code.
 | ||
|  | ///
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | int32_t | ||
|  | xos_msgq_get(XosMsgQueue * msgq, uint32_t * msg); | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Get a message from the queue. The message contents are copied into the 
 | ||
|  | ///  buffer that must be provided. If no message is available, this function
 | ||
|  | ///  will block if called from a thread, but will return immediately if called
 | ||
|  | ///  from an interrupt handler. The thread will be unblocked when a message
 | ||
|  | ///  arrives in the queue or the timeout expires.
 | ||
|  | ///
 | ||
|  | ///  \param     msgq            Pointer to message queue.
 | ||
|  | ///
 | ||
|  | ///  \param     msg             Pointer to message buffer.
 | ||
|  | ///
 | ||
|  | ///  \param     to_cycles       Timeout in cycles. Convert from time to cycles
 | ||
|  | ///                             using the helper functions provided in xos_timer.
 | ||
|  | ///                             A value of zero indicates no timeout.
 | ||
|  | ///
 | ||
|  | ///  \return    Returns XOS_OK on success, XOS_ERR_TIMEOUT on timeout, else error code.
 | ||
|  | ///
 | ||
|  | ///  NOTE: If XOS_OPT_WAIT_TIMEOUT is not enabled, then the timeout value is
 | ||
|  | ///  ignored, and no timeout will occur.
 | ||
|  | ///
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | int32_t | ||
|  | xos_msgq_get_timeout(XosMsgQueue * msgq, uint32_t * msg, uint64_t to_cycles); | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Check if the queue is empty.
 | ||
|  | ///
 | ||
|  | ///  \param     msgq            Pointer to message queue.
 | ||
|  | ///
 | ||
|  | ///  \return    Returns nonzero if queue is empty, zero if queue is not empty.
 | ||
|  | ///
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | int32_t | ||
|  | xos_msgq_empty(XosMsgQueue * msgq); | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Check if the queue is full.
 | ||
|  | ///
 | ||
|  | ///  \param     msgq            Pointer to message queue.
 | ||
|  | ///
 | ||
|  | ///  \return    Returns nonzero if queue is full, zero if queue is not full.
 | ||
|  | ///
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | int32_t | ||
|  | xos_msgq_full(XosMsgQueue * msgq); | ||
|  | 
 | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | } | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #endif // __XOS_MSGQ_H__
 | ||
|  | 
 |