mirror of
				https://github.com/0xFEEDC0DE64/arduino-esp32.git
				synced 2025-11-03 23:51: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__
							 | 
						||
| 
								 | 
							
								
							 |