USB-LED-Fader/firmware/message_queue.c

96 lines
2.5 KiB
C

/**
* \file message_queue.c
* \brief A message queue used to exchange messages between two concurrent threads.
* \author Thomas Stegemann
* \version $Id: message_queue.c,v 1.2 2006/09/29 22:30:03 rschaten Exp $
*
* License: See documentation.
*/
#include <stdint.h>
#include "message_queue.h"
#include "config_message_queue_impl.h"
/** Structure of the global data of the queue */
typedef struct S_messageQueue_GlobalData {
messageQueue_QueuedMessage queue[messageQueue_Size]; /**< the data elements of the queue */
messageQueue_SizeType begin; /**< the current start of the queue */
messageQueue_SizeType end; /**< the current end of the queue, behind the last element */
} messageQueue_GlobalData;
/** Global data of the queue */
static volatile messageQueue_GlobalData m_data;
/**
* increments an messageQueue index
* \param value position within the messageQueue
* \return the following position within the messageQueue
*/
static inline messageQueue_SizeType messageQueue_next(messageQueue_SizeType value) {
value++;
if(value >= messageQueue_Size) {
/* messageQueue is used circular */
value= 0;
}
return value;
}
/**
* Initialize the queue.
*/
void messageQueue_init(void) {
m_data.begin= 0;
m_data.end= 0;
}
/**
* Clean up the queue. Currently this does nothing.
*/
void messageQueue_cleanup(void)
{}
/**
* Test if the queue is empty.
* \return True if it is empty, otherwise false.
*/
Boolean messageQueue_isEmpty(void) {
return boolean(m_data.begin == m_data.end);
}
/**
* Test if the queue is full.
* \return True if it is full, otherwise false.
*/
Boolean messageQueue_isFull(void) {
return boolean(messageQueue_next(m_data.end) == m_data.begin);
}
/**
* Read a message from the queue.
* \param pMessage Pointer to a message variable that should be set to the
* message.
* \return True if an entry could be read, otherwise false.
*/
Boolean messageQueue_read(messageQueue_QueuedMessage* pMessage) {
Boolean success= !messageQueue_isEmpty();
if(success) {
*pMessage= m_data.queue[m_data.begin];
m_data.begin= messageQueue_next(m_data.begin);
}
return success;
}
/**
* Write a message to the queue.
* \param message The message to append.
* \return True if the message could be appended, otherwise false.
*/
Boolean messageQueue_write(messageQueue_QueuedMessage message) {
Boolean success= !messageQueue_isFull();
if(success) {
m_data.queue[m_data.end]= message;
m_data.end= messageQueue_next(m_data.end);
}
return success;
}