/************************************************************************** * * Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file MsgQueues.c * * @author (last) Vinayakam Mani * @date (last) 06-Aug-2024 * * @author (original) Vinayakam Mani * @date (original) 05-Aug-2024 * ***************************************************************************/ #include "MsgQueues.h" /** * @addtogroup MsgQueues * @{ */ // ********** private definitions ********** #define MAX_MSG_QUEUE_SIZE 100 ///< Maximum message queue size // ********** private data ********** static U32 msgQueueCounts[ NUM_OF_MSG_QUEUES ]; ///< Message queue count static U32 msgQueueStarts[ NUM_OF_MSG_QUEUES ]; ///< Start index of a queue static U32 msgQueueNexts[ NUM_OF_MSG_QUEUES ]; ///< Index to add new message to a queue static MESSAGE_WRAPPER_T msgQueues[ NUM_OF_MSG_QUEUES ][ MAX_MSG_QUEUE_SIZE ]; ///< Message queues // ********** private function prototypes ********** /*********************************************************************//** * @brief * The initMsgQueues function initializes the MsgQueues unit. * @details \b Inputs: none * @details \b Outputs: MsgQueues unit initialized * @return none *************************************************************************/ void initMsgQueues( void ) { U32 q, m; // reset message queues for ( q = 0; q < NUM_OF_MSG_QUEUES; q++ ) { msgQueueCounts[ q ] = 0; msgQueueStarts[ q ] = 0; msgQueueNexts[ q ] = 0; for ( m = 0; m < MAX_MSG_QUEUE_SIZE; m++ ) { blankMessageInWrapper( &msgQueues[ q ][ m ] ); } } } /*********************************************************************//** * @brief * The addToMsgQueue function adds a message to a given message queue. * * @details \b Inputs: none * @details \b Outputs: message added to queue * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when message queue is full * or invalid queue passed * @param queue the message queue to add to * @param msg a pointer to a message structure to add to the queue * @return TRUE if message added to queue, FALSE if could not * @warning This function should only be called from the general task. *************************************************************************/ BOOL addToMsgQueue( MSG_QUEUE_T queue, MESSAGE_WRAPPER_T *msg ) { BOOL result = FALSE; // verify given message queue if ( queue < NUM_OF_MSG_QUEUES ) { if ( FALSE == isMsgQueueFull( queue ) ) { result = TRUE; // add message to queue msgQueues[ queue ][ msgQueueNexts[ queue ] ] = *msg; // increment next index to add to msgQueueNexts[ queue ] = INC_WRAP( msgQueueNexts[ queue ], 0, MAX_MSG_QUEUE_SIZE - 1 ); // increment queue count msgQueueCounts[ queue ]++; } else // msg queue is full { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_MSG_QUEUES_ADD_QUEUE_FULL ) } } else // invalid message queue { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_MSG_QUEUES_ADD_INVALID_QUEUE, queue ) } return result; } /*********************************************************************//** * @brief * The getFromMsgQueue function retrieves the next message from a given * message queue. * @details \b Inputs: queue * @details \b Outputs: message retrieved from the queue * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when invalid queue used to * retrieve the message. * @param queue the message queue to retrieve from * @param msg a pointer to a message structure to populate with the retrieved message. * @return TRUE if a message was found to retrieve, FALSE if not * @warning This function should only be called from the general task. *************************************************************************/ BOOL getFromMsgQueue( MSG_QUEUE_T queue, MESSAGE_WRAPPER_T *msg ) { BOOL result = FALSE; // verify given message queue if ( queue < NUM_OF_MSG_QUEUES ) { if ( FALSE == isMsgQueueEmpty( queue ) ) { result = TRUE; // get message from queue *msg = msgQueues[ queue ][ msgQueueStarts[ queue ] ]; // increment queue next index to get from msgQueueStarts[ queue ] = INC_WRAP( msgQueueStarts[ queue ], 0, MAX_MSG_QUEUE_SIZE - 1 ); // decrement queue count msgQueueCounts[ queue ]--; } else // message queue is empty { // result already set to FALSE } } else // invalid message queue { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_MSG_QUEUES_GET_INVALID_QUEUE, queue ) } return result; } /*********************************************************************//** * @brief * The isMsgQueueEmpty function determines whether a given message queue is empty. * @details \b Inputs: msgQueueCounts[] * @details \b Outputs: none * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when invalid message queue being * passed. * @param queue the message queue to check * @return TRUE if a given message queue is empty, FALSE if not *************************************************************************/ BOOL isMsgQueueEmpty( MSG_QUEUE_T queue ) { BOOL result = FALSE; // verify given message queue if ( queue < NUM_OF_MSG_QUEUES ) { if ( msgQueueCounts[ queue ] == 0 ) { result = TRUE; } } else // invalid message queue { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_MSG_QUEUES_IS_EMPTY_INVALID_QUEUE, queue ) } return result; } /*********************************************************************//** * @brief * The isMsgQueueFull function determines whether a given message queue is full. * @details \b Inputs: msgQueueCounts[] * @details \b Outputs: none * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when invalid message queue being * passed. * @param queue the message queue to check * @return TRUE if the given message queue is full, FALSE if not *************************************************************************/ BOOL isMsgQueueFull( MSG_QUEUE_T queue ) { BOOL result = TRUE; // verify given message queue if ( queue < NUM_OF_MSG_QUEUES ) { if ( msgQueueCounts[ queue ] < MAX_MSG_QUEUE_SIZE ) { result = FALSE; } } else // invalid message queue { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_MSG_QUEUES_IS_FULL_INVALID_QUEUE, queue ) } return result; } /*********************************************************************//** * @brief * The blankMessage function blanks a given message. * @details \b Inputs: none * @details \b Outputs: Zeroed out the message * @param message Pointer to the message to blank * @return none *************************************************************************/ void blankMessage( MESSAGE_T *message ) { U32 i; U32 msgSize = sizeof(MESSAGE_T); U08 *msgContent = (U08*)message; // zero out the message for ( i = 0; i < msgSize; i++ ) { *msgContent++ = 0x0; } } /*********************************************************************//** * @brief * The blankMessageInWrapper function blanks a given message in a wrapper. * @details \b Inputs: none * @details \b Outputs: Zeroed out the message in wrapper * @param message pointer to the message in a wrapper to blank * @return none *************************************************************************/ void blankMessageInWrapper( MESSAGE_WRAPPER_T *message ) { U32 i; U32 msgSize = sizeof(MESSAGE_T); U08 *msgContent = (U08*)message; // zero out the message for ( i = 0; i < msgSize; i++ ) { *msgContent++ = 0x0; } // set msg ID out of bounds in case blank message goes somewhere message->msg.hdr.msgID = 0xFFFF; } /**@}*/