Index: firmware/App/Services/CommBuffers.c =================================================================== diff -u -r2112e3143003eaf9584d4be068f7ca89b33c941a -ra60ec05d359c0d3f014015e9080b6dbcef0fea28 --- firmware/App/Services/CommBuffers.c (.../CommBuffers.c) (revision 2112e3143003eaf9584d4be068f7ca89b33c941a) +++ firmware/App/Services/CommBuffers.c (.../CommBuffers.c) (revision a60ec05d359c0d3f014015e9080b6dbcef0fea28) @@ -24,26 +24,31 @@ #include // for memcpy() #include "CommBuffers.h" +#include "SystemCommMessages.h" +#include "Timers.h" // ********** private definitions ********** #define COMM_BUFFER_LENGTH 512 // max bytes in each comm buffer (double if you count double buffers) #define DOUBLE_BUFFERS 2 // need 2 buffers for double buffering +#define BUFFER_OVERFLOW_PERSISTENCE_MS 5000 // how many ms buffer overflows must persist before fault // ********** private data ********** static volatile U32 commBufferByteCount[ NUM_OF_COMM_BUFFERS ][ DOUBLE_BUFFERS ]; // for each buffer, how many bytes does it contain? (also index to next available) static volatile U32 activeDoubleBuffer[ NUM_OF_COMM_BUFFERS ]; // for each buffer, which double buffer is being fed right now? static U08 commBuffers[ NUM_OF_COMM_BUFFERS ][ DOUBLE_BUFFERS ][ COMM_BUFFER_LENGTH ]; // each is double buffered to avoid thread contention static volatile BOOL bufferGetLock[ NUM_OF_COMM_BUFFERS ]; // prevent getter from accessing active buffer while add in progress +static U32 firstBufferOverflowTimeStamp = 0; // time stamp of a prior overflow event - allows for an overflow persistence check // ********** private function prototypes ********** +static void clearBuffer( COMM_BUFFER_T buffer ); static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ); static void getDataFromInactiveBuffer( COMM_BUFFER_T buffer, U08 *data, U32 len ); /************************************************************************* - * @brief initCommBuffers + * @brief * The initCommBuffers function initializes the CommBuffers module. * @details * Inputs : none @@ -53,25 +58,46 @@ *************************************************************************/ void initCommBuffers( void ) { - S32 b,d,i; + S32 b; // reset and zero out all buffers for ( b = 0; b < NUM_OF_COMM_BUFFERS; b++ ) { - activeDoubleBuffer[ b ] = 0; + clearBuffer( (COMM_BUFFER_T)b ); + } +} + +/************************************************************************* + * @brief + * The clearBuffer function clears (empties) a given buffer. \n + * Caller should ensure buffer won't be used while this function is clearing \n + * the buffer. + * @details + * Inputs : none + * Outputs : given buffer is cleared. + * @param buffer : the buffer to clear + * @return none + *************************************************************************/ +static void clearBuffer( COMM_BUFFER_T buffer ) +{ + if ( buffer < NUM_OF_COMM_BUFFERS ) + { + S32 d,i; + + activeDoubleBuffer[ buffer ] = 0; for ( d = 0; d < DOUBLE_BUFFERS; d++ ) { - commBufferByteCount[ b ][ d ] = 0; + commBufferByteCount[ buffer ][ d ] = 0; for ( i = 0; i < COMM_BUFFER_LENGTH; i++ ) { - commBuffers[ b ][ d ][ i ] = 0; + commBuffers[ buffer ][ d ][ i ] = 0; } } } } /************************************************************************* - * @brief addToCommBuffer + * @brief * 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 * This function will always add to the active double buffer. \n @@ -123,15 +149,43 @@ else // buffer too full to add this much data { bufferFull = TRUE; + clearBuffer( buffer ); } // release thread protection bufferGetLock[ buffer ] = FALSE; _enable_IRQ(); - // if buffer was full, trigger s/w fault + // if buffer was full, check persistence - trigger s/w fault if persists if ( TRUE == bufferFull ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_ADD_TOO_MUCH_DATA, len ) + // not first overflow? + if ( firstBufferOverflowTimeStamp != 0 ) + { + // if buffer overflows persists, fault + if ( calcTimeSince( firstBufferOverflowTimeStamp ) > BUFFER_OVERFLOW_PERSISTENCE_MS ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_ADD_TOO_MUCH_DATA, len ) + } + } + else // first overflow - set time stamp for persistence check + { + firstBufferOverflowTimeStamp = getMSTimerCount(); + } +#ifdef DEBUG_ENABLED + { + // TODO - temporary debug code - remove later + char debugStr[ 256 ]; + sprintf( debugStr, "Comm Buffer Overflow:%5d \n", (U32)buffer ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + } +#endif } + else + { // if good for persistence time period, reset persistence check + if ( ( firstBufferOverflowTimeStamp != 0 ) && ( calcTimeSince( firstBufferOverflowTimeStamp ) > BUFFER_OVERFLOW_PERSISTENCE_MS ) ) + { + firstBufferOverflowTimeStamp = 0; + } + } } else // invalid buffer given { @@ -142,7 +196,7 @@ } /************************************************************************* - * @brief getFromCommBuffer + * @brief * The getFromCommBuffer function fills a given byte array with a given \n * 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 @@ -203,7 +257,7 @@ } /************************************************************************* - * @brief peekFromCommBuffer + * @brief * The peekFromCommBuffer function fills a given byte array with a given \n * number of bytes from a given buffer. This function does NOT consume \n * the bytes - it only peeks at them. A call to numberOfBytesInCommBuffer() \n @@ -261,7 +315,7 @@ } /************************************************************************* - * @brief numberOfBytesInCommBuffer + * @brief * The numberOfBytesInCommBuffer function determines how many bytes \n * are currently contained in a given comm buffer. Both double buffers \n * are considered for this. @@ -299,7 +353,7 @@ } /************************************************************************* - * @brief switchDoubleBuffer + * @brief * The switchDoubleBuffer function switches the active and inactive buffers \n * for the given buffer. \n * This function should only be called when the current inactive buffer has \n @@ -325,7 +379,7 @@ } /************************************************************************* - * @brief getDataFromInactiveBuffer + * @brief * The getDataFromInactiveBuffer function retrieves a given number of bytes \n * from the inactive buffer of a given buffer. This function should only be \n * called by getFromCommBuffer(). Params will be pre-validated there.