Index: App/Services/CommBuffers.c =================================================================== diff -u -ree310a2e5262c05bf0dc0eb0d84da0ee50bac7fe -rbbd766eed69a6ae143a42731965848da85fd4500 --- App/Services/CommBuffers.c (.../CommBuffers.c) (revision ee310a2e5262c05bf0dc0eb0d84da0ee50bac7fe) +++ App/Services/CommBuffers.c (.../CommBuffers.c) (revision bbd766eed69a6ae143a42731965848da85fd4500) @@ -28,12 +28,16 @@ // ********** private data ********** -static U32 commBufferStartPos[NUM_OF_COMM_BUFFERS][2]; // for each buffer, where is start? -static U32 commBufferEndPos[NUM_OF_COMM_BUFFERS][2]; // for each buffer, where is end? -static U32 commBufferByteCount[NUM_OF_COMM_BUFFERS][2]; // for each buffer, how many bytes? -static U32 activeDoubleBuffers[NUM_OF_COMM_BUFFERS][2]; // for each buffer, which double buffer is being fed? +static U32 commBufferByteCount[NUM_OF_COMM_BUFFERS][2]; // for each buffer, how many bytes does it contain? (also index to next available) +static U32 activeDoubleBuffers[NUM_OF_COMM_BUFFERS]; // for each buffer, which double buffer is being fed right now? static U08 commBuffers[NUM_OF_COMM_BUFFERS][2][COMM_BUFFER_LENGTH]; // each is double buffered to avoid thread contention +// ********** private function prototypes ********** + +static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ); +static U32 getRemainingByteCapacity( COMM_BUFFER_T buffer ); +static BOOL isCommBufferEmpty( COMM_BUFFER_T buffer ); + /************************************************************************* * @brief initCommBuffers * The initCommBuffers function initializes the CommBuffers module. @@ -50,12 +54,10 @@ // reset and zero out all buffers for ( b = 0; b < NUM_OF_COMM_BUFFERS; b++ ) { + activeDoubleBuffers[b] = 0; for ( d = 0; d < 2; d++ ) { - commBufferStartPos[b][d] = 0; - commBufferEndPos[b][d] = 0; commBufferByteCount[b][d] = 0; - activeDoubleBuffers[b][d] = 0; for ( l = 0; l < COMM_BUFFER_LENGTH; l++ ) { commBuffers[b][d][l] = 0; @@ -67,10 +69,13 @@ /************************************************************************* * @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. + * communication buffer. S/W fault if buffer too full to add data. \n + * Only one function in one thread should be calling this function. It is \n + * assumed that this thread will be higher priority than the thread calling \n + * the getFromCommBuffer() function so no thread protection is given. * @details - * Inputs : none - * Outputs : commBuffers[] + * Inputs : commBufferByteCount[], activeDoubleBuffers[] + * Outputs : commBuffers[], commBufferByteCount[] * @param buffer : which comm buffer to add data to * @param data : pointer to byte array containing data to add * @param len : length of data (in bytes) @@ -79,24 +84,174 @@ BOOL addToCommBuffer( COMM_BUFFER_T buffer, U08* data, U32 len ) { BOOL result = FALSE; + U32 activeBuffer = activeDoubleBuffers[buffer]; + // verify given buffer + if ( buffer < NUM_OF_COMM_BUFFERS ) + { + // check to make sure buffer is not too full to service this add + if ( len <= getRemainingByteCapacity( buffer ) ) + { + 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]; + // 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++; + } + // adjust buffer count per this data add + commBufferByteCount[buffer][activeBuffer] += len; + } + else // buffer too full to add this much data + { + // TODO - s/w fault? + } + } + else // invalid buffer given + { + // TODO - s/w fault + } + return result; } /************************************************************************* * @brief getFromCommBuffer * The getFromCommBuffer function fills a given byte array with data from \n - * a given buffer and returns the number of bytes retrieved from the buffer. + * a given buffer and returns the number of bytes retrieved from the buffer. \n + * Only one function in one thread should be calling this function. * @details - * Inputs : none - * Outputs : none - * @param none + * Inputs : commBuffers[], commBufferByteCount[] + * Outputs : commBufferByteCount[], activeDoubleBuffers[] + * @param buffer : which comm buffer to retrieve data from + * @param data : pointer to byte array to stuff data into + * @param maxLen : maximum # of bytes to retrieve into given data array. * @return the number of bytes retrieved. *************************************************************************/ U32 getFromCommBuffer( COMM_BUFFER_T buffer, U08* data, U32 maxLen ) { U32 result = 0; + // verify given buffer + if ( buffer < NUM_OF_COMM_BUFFERS ) + { + // check to see if anything in buffer + if ( FALSE == isCommBufferEmpty( buffer ) ) + { + // switch double buffer (now we'll read from what was active buffer and Rx interrupts will feed new active buffer) + U32 activeBuffer = switchDoubleBuffer( buffer ); + U32 inactiveBuffer = ( activeBuffer == 0 ? 1 : 0 ); + U32 bytesRetrieved = commBufferByteCount[buffer][inactiveBuffer]; + + // ensure caller's data buffer can hold the data we have to retrieve + if ( bytesRetrieved <= maxLen ) + { + U08 *buffPtr; // buffer source for retrieved data + U08 *dstPtr; // buffer destination for retrieved data + U32 i; + + // get source pointer to start of comm buffer + buffPtr = &commBuffers[buffer][inactiveBuffer][0]; + // get destination pointer to start of given data array + dstPtr = data; + // copy source data to destination buffer + for ( i = 0; i < bytesRetrieved; i++ ) + { + *dstPtr++ = *buffPtr++; + } + // reset inactive buffer after data retrieved from it + commBufferByteCount[buffer][inactiveBuffer] = 0; + } + else // not enough space in caller's buffer + { + // TODO - s/w fault? + } + } + else // buffer is empty + { + // result already set to zero + } + } + else // invalid buffer given + { + // TODO - s/w fault + } + return result; } +/************************************************************************* + * @brief switchDoubleBuffer + * The switchDoubleBuffer function switches the active and inactive buffers \n + * for the given buffer. + * @details + * Inputs : activeDoubleBuffers[] + * Outputs : activeDoubleBuffers[], commBufferByteCount[] + * @param buffer : which comm buffer to switch double buffers on + * @return the new active buffer for the given buffer. + *************************************************************************/ +static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ) +{ + U32 activeBuffer = activeDoubleBuffers[buffer]; + U32 inactiveBuffer = ( activeBuffer == 0 ? 1 : 0 ); + + // ensure inactive buffer is reset before making active + commBufferByteCount[buffer][inactiveBuffer] = 0; + // switch buffers + activeDoubleBuffers[buffer] = inactiveBuffer; + + // return the new active buffer (was just inactive) + return inactiveBuffer; +} + +/************************************************************************* + * @brief getRemainingByteCapacity + * The getRemainingByteCapacity function determines the remaining capacity \n + * of the given buffer. + * @details + * Inputs : commBufferByteCount[], activeDoubleBuffers[] + * 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 = activeDoubleBuffers[buffer]; + + result = COMM_BUFFER_LENGTH - commBufferByteCount[buffer][activeBuffer]; + + return result; +} + +/************************************************************************* + * @brief isCommBufferEmpty + * The isCommBufferEmpty function determines whether a given comm buffer \n + * is empty. + * @details + * Inputs : commBufferByteCount[], activeDoubleBuffers[] + * Outputs : none + * @param buffer : which comm buffer to check for empty + * @return TRUE if the given comm buffer is empty, FALSE if not + *************************************************************************/ +static BOOL isCommBufferEmpty( COMM_BUFFER_T buffer ) +{ + BOOL result = FALSE; + U32 activeBuffer = activeDoubleBuffers[buffer]; + + if ( commBufferByteCount[buffer][activeBuffer] == 0 ) + { + result = TRUE; + } + + return result; +} +