Index: App/Services/CommBuffers.c =================================================================== diff -u -r6dde2145782d8f68eb66e053f1db8f8847b15980 -ra87b6b9e253c6c0fcc84bca6f5de71959ce18bcc --- App/Services/CommBuffers.c (.../CommBuffers.c) (revision 6dde2145782d8f68eb66e053f1db8f8847b15980) +++ App/Services/CommBuffers.c (.../CommBuffers.c) (revision a87b6b9e253c6c0fcc84bca6f5de71959ce18bcc) @@ -38,7 +38,6 @@ static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ); static void getDataFromInactiveBuffer( COMM_BUFFER_T buffer, U08 *data, U32 len ); -static U32 getRemainingByteCapacity( COMM_BUFFER_T buffer ); /************************************************************************* * @brief initCommBuffers @@ -72,8 +71,7 @@ * @brief addToCommBuffer * The addToCommBuffer function adds data of specified length to a specified \n * communication buffer. S/W fault if buffer too full to add data. \n - * Only one function in one thread should be calling this function for a \n - * given buffer. This function will always add to the active double buffer. + * This function will always add to the active double buffer. \n * @details * Inputs : commBufferByteCount[], activeDoubleBuffer[] * Outputs : commBuffers[], commBufferByteCount[] @@ -90,31 +88,38 @@ // verify given buffer if ( buffer < NUM_OF_COMM_BUFFERS ) { + U32 currentActiveBufCount; // where to start adding new data to buffer (after existing data) + + // add requires brief thread protection because there may be multiple sources for transmits trying to add data to a buffer. + _disable_IRQ(); + + currentActiveBufCount = commBufferByteCount[buffer][activeBuffer]; + // check to make sure buffer is not too full to service this add - if ( len <= getRemainingByteCapacity( buffer ) ) + if ( len <= ( COMM_BUFFER_LENGTH - currentActiveBufCount ) ) { U08 *buffPtr; // buffer destination for added data U08 *srcPtr; // data source - U32 dstIndex; // where to start adding bytes in destination buffer - U32 i; - // get destination pointer to first available byte in buffer - dstIndex = commBufferByteCount[buffer][activeBuffer]; - buffPtr = &commBuffers[buffer][activeBuffer][dstIndex]; + // adjust buffer count per this data add (also reserves space to add data before releasing thread protection) + commBufferByteCount[buffer][activeBuffer] += len; + // release thread protection + _enable_IRQ(); + // set destination pointer to end of active buffer data + buffPtr = &commBuffers[buffer][activeBuffer][currentActiveBufCount]; // get source pointer to start of given data array srcPtr = data; // copy source data to destination buffer - for ( i = 0; i < len; i++ ) - { - *buffPtr++ = *srcPtr++; - } + memcpy( buffPtr, srcPtr, len ); // adjust buffer count per this data add commBufferByteCount[buffer][activeBuffer] += len; // data successfully added to buffer result = TRUE; } else // buffer too full to add this much data { + // release thread protection + _enable_IRQ(); // TODO - s/w fault? } } @@ -132,7 +137,7 @@ * number of bytes from a given buffer and returns the number of bytes \n * retrieved from the buffer. This function will draw from the inactive \n * double buffer first and, if needed, switch double buffers to draw the \n - * reset of the requested data. + * rest of the requested data. * Only one function in one thread should be calling this function for a given \n * buffer. * @details @@ -245,7 +250,6 @@ return numOfBytesPeeked; } - /************************************************************************* * @brief numberOfBytesInCommBuffer * The numberOfBytesInCommBuffer function determines how many bytes \n @@ -336,23 +340,4 @@ } } -/************************************************************************* - * @brief getRemainingByteCapacity - * The getRemainingByteCapacity function determines the remaining capacity \n - * of the given buffer. - * @details - * Inputs : commBufferByteCount[], activeDoubleBuffer[] - * Outputs : none - * @param buffer : which comm buffer to check the capacity of - * @return the number of bytes of capacity remaining in the buffer. - *************************************************************************/ -static U32 getRemainingByteCapacity( COMM_BUFFER_T buffer ) -{ - U32 result; - U32 activeBuffer = activeDoubleBuffer[buffer]; - result = COMM_BUFFER_LENGTH - commBufferByteCount[buffer][activeBuffer]; - - return result; -} - Index: App/Services/CommBuffers.h =================================================================== diff -u -r833095dbbe2b21a989b05f48bd7ddc390ad964cb -ra87b6b9e253c6c0fcc84bca6f5de71959ce18bcc --- App/Services/CommBuffers.h (.../CommBuffers.h) (revision 833095dbbe2b21a989b05f48bd7ddc390ad964cb) +++ App/Services/CommBuffers.h (.../CommBuffers.h) (revision a87b6b9e253c6c0fcc84bca6f5de71959ce18bcc) @@ -23,7 +23,7 @@ typedef enum Comm_Buffers { - COMM_BUFFER_NOT_USED_1 = 0, // CAN message boxes start at 1 + COMM_BUFFER_NOT_USED = 0, // CAN message boxes start at 1 COMM_BUFFER_OUT_CAN_HD_ALARM, COMM_BUFFER_IN_CAN_DG_ALARM, COMM_BUFFER_IN_CAN_UI_ALARM, Index: App/Services/MsgQueues.c =================================================================== diff -u -r833095dbbe2b21a989b05f48bd7ddc390ad964cb -ra87b6b9e253c6c0fcc84bca6f5de71959ce18bcc --- App/Services/MsgQueues.c (.../MsgQueues.c) (revision 833095dbbe2b21a989b05f48bd7ddc390ad964cb) +++ App/Services/MsgQueues.c (.../MsgQueues.c) (revision a87b6b9e253c6c0fcc84bca6f5de71959ce18bcc) @@ -10,7 +10,10 @@ * @date 08-Oct-2019 * @author S. Nash * - * @brief MsgQueues service module. Provides message queue functionality. + * @brief MsgQueues service module. Provides message queue functionality. \n + * These queues are NOT thread safe. However, these queue functions are \n + * intended to be called from the General Task thread so no thread safety \n + * is required. * **************************************************************************/ @@ -59,10 +62,10 @@ /************************************************************************* * @brief addToMsgQueue * The addToMsgQueue function adds a message to a given message queue. \n - * A CRC is calculated for the message and included in the message wrapper. + * This function should only be called from the General Task. * @details * Inputs : none - * Outputs : none + * Outputs : message added to queue * @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 @@ -74,39 +77,17 @@ // verify given message queue if ( queue < NUM_OF_MSG_QUEUES ) { - U32 next; - U32 count; - BOOL full = FALSE; - - // thread protection - // TODO - disable interrupts (selectively if possible) - - // reserve next available queue space while under thread protection - next = msgQueueNexts[queue]; - count = msgQueueCounts[queue]; - if ( count < MAX_MSG_QUEUE_SIZE ) - { // increment queue count and next queue indexes while under thread protection - msgQueueCounts[queue]++; - msgQueueNexts[queue] = INC_WRAP(next,0,MAX_MSG_QUEUE_SIZE); - } - else + if ( FALSE == isMsgQueueFull( queue ) ) { - full = TRUE; - } - - // end thread protection - // TODO - re-enable interrupts - - // make sure queue is not full - if ( FALSE == full ) - { + result = TRUE; // add message to queue - msgQueues[queue][next] = *msg; - - // TODO - calculate CRC for given message (just zero for now) - msgQueues[queue][next].crc = 0x0; + msgQueues[queue][msgQueueNexts[queue]] = *msg; + // increment next index to add to + msgQueueNexts[queue] = INC_WRAP(msgQueueNexts[queue],0,MAX_MSG_QUEUE_SIZE); + // increment queue count + msgQueueCounts[queue]++; } - else // message queue is full + else // msg queue is full { // TODO - s/w fault? } @@ -122,12 +103,13 @@ /************************************************************************* * @brief getFromMsgQueue * The getFromMsgQueue function retrieves the next message from a given \n - * message queue. + * message queue. This function should only be called from the General Task. * @details - * Inputs : none - * Outputs : none + * Inputs : queue + * Outputs : message retrieved from the queue * @param queue : the message queue to retrieve from - * @param msg : a pointer to a message structure to stuff + * @param msg : a pointer to a message structure to populate with the retrieved \n + * message. * @return TRUE if a message was found to retrieve, FALSE if not *************************************************************************/ BOOL getFromMsgQueue( MSG_QUEUE_T queue, MESSAGE_WRAPPER_T *msg ) @@ -137,40 +119,19 @@ // verify given message queue if ( queue < NUM_OF_MSG_QUEUES ) { - U32 first; - U32 count; - BOOL empty = FALSE; - - // thread protection - // TODO - disable interrupts (selectively if possible) - - // reserve next available queue space while under thread protection - first = msgQueueStarts[queue]; - count = msgQueueCounts[queue]; - if ( count > 0 ) - { // decrement queue count and increment start queue index while under thread protection - msgQueueCounts[queue]--; - msgQueueStarts[queue] = INC_WRAP(first,0,MAX_MSG_QUEUE_SIZE); - } - else + if ( FALSE == isMsgQueueEmpty( queue ) ) { - empty = TRUE; - } - - // end thread protection - // TODO - re-enable interrupts - - // make sure queue is not empty - if ( FALSE == empty ) - { - // get message from queue - *msg = msgQueues[queue][first]; - 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); + // decrement queue count + msgQueueCounts[queue]--; } - else // message queue is full + else // message queue is empty { - // TODO - s/w fault? + // result already set to FALSE } } else // invalid message queue Index: App/Services/SystemComm.c =================================================================== diff -u -r29f1ba03faefd982327916590818a260a3e4aa48 -ra87b6b9e253c6c0fcc84bca6f5de71959ce18bcc --- App/Services/SystemComm.c (.../SystemComm.c) (revision 29f1ba03faefd982327916590818a260a3e4aa48) +++ App/Services/SystemComm.c (.../SystemComm.c) (revision a87b6b9e253c6c0fcc84bca6f5de71959ce18bcc) @@ -243,11 +243,11 @@ * Outputs : none * @param msg : none * @return buffer with highest priority CAN packet to transmit, \n - * COMM_BUFFER_NOT_USED_1 if not CAN packets pending transmit found + * COMM_BUFFER_NOT_USED if not CAN packets pending transmit found *************************************************************************/ static COMM_BUFFER_T findNextHighestPriorityCANPacketToTransmit( void ) { - COMM_BUFFER_T result = COMM_BUFFER_NOT_USED_1; + COMM_BUFFER_T result = COMM_BUFFER_NOT_USED; U32 i; // search for next priority CAN packet to transmit @@ -278,7 +278,7 @@ COMM_BUFFER_T buffer = findNextHighestPriorityCANPacketToTransmit(); // if a buffer is found with a packet to transmit, get packet from buffer and transmit it - if ( buffer != COMM_BUFFER_NOT_USED_1 ) + if ( buffer != COMM_BUFFER_NOT_USED ) { U08 data[CAN_MESSAGE_CARGO_SIZE]; U32 dataSize = getFromCommBuffer( buffer, data, CAN_MESSAGE_CARGO_SIZE ); @@ -351,43 +351,52 @@ U08 data[sizeof(MESSAGE_WRAPPER_T)+1]; U32 i; - // TODO - remove this later - this should be called by CAN receive interrupt handler when implemented -// handleCANPacketReceivedInt( COMM_BUFFER_IN_CAN_UI_2_HD ); - // queue any received CAN messages for ( i = 0; i < NUM_OF_CAN_IN_BUFFERS; i++ ) { - U32 numOfBytesInBuffer; + BOOL messagesInBuffer = TRUE; // assume true at first to get into while loop - // since messages can have CAN padding left unconsumed by last get, get padding out of buffer - consumeBufferPaddingBeforeSync( CAN_IN_BUFFERS[i] ); - // do we have enough bytes in buffer for smallest message? - numOfBytesInBuffer = numberOfBytesInCommBuffer( CAN_IN_BUFFERS[i] ); - if ( numOfBytesInBuffer >= MESSAGE_OVERHEAD_SIZE ) - { // peek at minimum of all bytes available or max message size (+1 for sync byte) - U32 bytesPeeked = peekFromCommBuffer( CAN_IN_BUFFERS[i], data, MIN(numOfBytesInBuffer,sizeof(MESSAGE_WRAPPER_T)+1) ); - U32 msgSize = parseMessageFromBuffer( data, bytesPeeked ); + while ( TRUE == messagesInBuffer ) + { + U32 numOfBytesInBuffer; - if ( msgSize > 0 ) - { // consume message (+sync byte) - msgSize = getFromCommBuffer( CAN_IN_BUFFERS[i], data, msgSize+1 ); - if ( msgSize > MESSAGE_OVERHEAD_SIZE ) + // assume false so we don't get stuck in loop - only set to true if we find another complete message in buffer + messagesInBuffer = FALSE; + + // since messages can have CAN padding left unconsumed by last get, get padding out of buffer + consumeBufferPaddingBeforeSync( CAN_IN_BUFFERS[i] ); + // do we have enough bytes in buffer for smallest message? + numOfBytesInBuffer = numberOfBytesInCommBuffer( CAN_IN_BUFFERS[i] ); + if ( numOfBytesInBuffer >= MESSAGE_OVERHEAD_SIZE ) + { // peek at minimum of all bytes available or max message size (+1 for sync byte) + U32 bytesPeeked = peekFromCommBuffer( CAN_IN_BUFFERS[i], data, MIN(numOfBytesInBuffer,sizeof(MESSAGE_WRAPPER_T)+1) ); + U32 msgSize = parseMessageFromBuffer( data, bytesPeeked ); + + if ( msgSize > 0 ) { - MESSAGE_WRAPPER_T rcvMsg; - U08 *dataPtr = data+1; // skip over sync byte + // consume message (+sync byte) + msgSize = getFromCommBuffer( CAN_IN_BUFFERS[i], data, msgSize+1 ); + if ( msgSize > MESSAGE_OVERHEAD_SIZE ) + { + MESSAGE_WRAPPER_T rcvMsg; + U08 *dataPtr = data+1; // skip over sync byte - // convert received message data to a message and add to message queue - blankMessageInWrapper( &rcvMsg ); - memcpy( &(rcvMsg.msg.hdr), dataPtr, sizeof(MESSAGE_HEADER_T) ); - dataPtr += sizeof(MESSAGE_HEADER_T); - memcpy( &(rcvMsg.msg.cargo), dataPtr, rcvMsg.msg.hdr.cargoLen ); - dataPtr += rcvMsg.msg.hdr.cargoLen; - rcvMsg.crc = *dataPtr; - addToMsgQueue( MSG_Q_IN_CAN, &rcvMsg ); - } - } - } - } + messagesInBuffer = TRUE; + // convert received message data to a message and add to message queue + blankMessageInWrapper( &rcvMsg ); + memcpy( &(rcvMsg.msg.hdr), dataPtr, sizeof(MESSAGE_HEADER_T) ); + dataPtr += sizeof(MESSAGE_HEADER_T); + memcpy( &(rcvMsg.msg.cargo), dataPtr, rcvMsg.msg.hdr.cargoLen ); + dataPtr += rcvMsg.msg.hdr.cargoLen; + rcvMsg.crc = *dataPtr; + addToMsgQueue( MSG_Q_IN_CAN, &rcvMsg ); + } // message is at least as large as minimum size + } // looks like there is a complete message in the comm buffer + } // enough data left in comm buffer to possibly be a complete message + } // while loop to get all complete messages for each comm buffer + } // for loop to check all comm buffers for messages + + // TODO - queue any received UART messages } /************************************************************************* @@ -424,13 +433,13 @@ /************************************************************************* * @brief parseMessageFromBuffer * The parseMessageFromBuffer function looks for a complete message in a \n - * given comm buffer. If found, the given buffer is populated with the \n - * message and its size is returned. + * given buffer. If a message is found, its size is returned. * @details - * Inputs : Comm Buffer + * Inputs : none * Outputs : none - * @param msg : data : pointer to byte array to populate with a message if found - * @return size of message, zero if no complete message found. + * @param data : pointer to byte array to search for a message + * @param len : # of bytes in the data to search + * @return size of message if found, zero if no complete message found. *************************************************************************/ static U32 parseMessageFromBuffer( U08 *data, U32 len ) { @@ -477,22 +486,25 @@ *************************************************************************/ static void processReceivedMessages( void ) { - BOOL isThereMsgRcvd; + BOOL isThereMsgRcvd = TRUE; // assume TRUE at first to get into while loop MESSAGE_WRAPPER_T message; - // see if any messages received - isThereMsgRcvd = getFromMsgQueue( MSG_Q_IN_CAN, &message ); - if ( TRUE == isThereMsgRcvd ) + while ( TRUE == isThereMsgRcvd ) { - // TODO - check CRC before processing a message - if ( 1 ) + // see if any messages received + isThereMsgRcvd = getFromMsgQueue( MSG_Q_IN_CAN, &message ); + if ( TRUE == isThereMsgRcvd ) { - processReceivedMessage( &message.msg ); + // TODO - check CRC before processing a message + if ( 1 ) + { + processReceivedMessage( &message.msg ); + } + else // CRC failed + { + // TODO - probably wouldn't want to fault on this. ignore? + } } - else // CRC failed - { - // TODO - probably wouldn't want to fault on this. ignore? - } } // TODO - process UART (script) messages too Index: App/Services/SystemCommMessages.c =================================================================== diff -u -r83de6e3e3de4767fd50713e18b0bd75a06479fc7 -ra87b6b9e253c6c0fcc84bca6f5de71959ce18bcc --- App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 83de6e3e3de4767fd50713e18b0bd75a06479fc7) +++ App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision a87b6b9e253c6c0fcc84bca6f5de71959ce18bcc) @@ -84,6 +84,10 @@ return msgSize; } +// *********************************************************************** +// ********************* MSG_ID_OFF_BUTTON_PRESS ************************* +// *********************************************************************** + /************************************************************************* * @brief sendOffButtonMsgToUI * The sendOffButtonMsgToUI function constructs an off button msg to the UI \n Index: App/Services/SystemCommMessages.h =================================================================== diff -u -r29f1ba03faefd982327916590818a260a3e4aa48 -ra87b6b9e253c6c0fcc84bca6f5de71959ce18bcc --- App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 29f1ba03faefd982327916590818a260a3e4aa48) +++ App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision a87b6b9e253c6c0fcc84bca6f5de71959ce18bcc) @@ -24,13 +24,14 @@ typedef enum Msg_IDs { - MSG_ID_TEST = 0, + MSG_ID_UNUSED = 0, MSG_ID_OFF_BUTTON_PRESS, NUM_OF_MSG_IDS } MSG_ID_T; // ********** public function prototypes ********** +// MSG_ID_OFF_BUTTON_PRESS BOOL sendOffButtonMsgToUI( void ); void handleOffButtonConfirmMsgFromUI( MESSAGE_T *message ); Index: App/Tasks/TaskGeneral.c =================================================================== diff -u -r29f1ba03faefd982327916590818a260a3e4aa48 -ra87b6b9e253c6c0fcc84bca6f5de71959ce18bcc --- App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision 29f1ba03faefd982327916590818a260a3e4aa48) +++ App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision a87b6b9e253c6c0fcc84bca6f5de71959ce18bcc) @@ -59,6 +59,9 @@ } #endif + // check in with watchdog manager + checkInWithWatchdogMgmt( TASK_GENERAL ); // do this first to keep timing consistent with watchdog management + // manage data received from other sub-systems execSystemCommRx(); @@ -71,9 +74,6 @@ // manage data to be transmitted to other sub-systems execSystemCommTx(); - // check in with watchdog manager - checkInWithWatchdogMgmt( TASK_GENERAL ); - // toggle GPIO to indicate general task has executed // gioToggleBit( gioPORTB, 1 ); }