diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 69611842a..bda2f1f34 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -2398,7 +2398,7 @@ #endif #ifndef traceENTER_xStreamBufferGenericCreate - #define traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) + #define traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, xIsBatchingBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) #endif #ifndef traceRETURN_xStreamBufferGenericCreate @@ -2406,7 +2406,7 @@ #endif #ifndef traceENTER_xStreamBufferGenericCreateStatic - #define traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) + #define traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, xIsBatchingBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) #endif #ifndef traceRETURN_xStreamBufferGenericCreateStatic diff --git a/include/message_buffer.h b/include/message_buffer.h index b8c080b6b..9ab1d3616 100644 --- a/include/message_buffer.h +++ b/include/message_buffer.h @@ -162,7 +162,7 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xMessageBufferCreateWithCallback( xBufferSizeBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ - xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, pdFALSE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** @@ -243,11 +243,11 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * \ingroup MessageBufferManagement */ #define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \ - xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL ) + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, pdFALSE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL ) #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xMessageBufferCreateStaticWithCallback( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ - xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, pdFALSE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** diff --git a/include/stream_buffer.h b/include/stream_buffer.h index 5441f6972..e1508ac17 100644 --- a/include/stream_buffer.h +++ b/include/stream_buffer.h @@ -161,7 +161,7 @@ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuf #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xStreamBufferCreateWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ - xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, pdFALSE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** @@ -257,11 +257,183 @@ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuf */ #define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \ - xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL ) + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL ) #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xStreamBufferCreateStaticWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ - xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) +#endif + +/** + * stream_buffer.h + * + * @code{c} + * StreamBufferHandle_t xStreamBatchingBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes ); + * @endcode + * + * Creates a new stream batching buffer using dynamically allocated memory. See + * xStreamBatchingBufferCreateStatic() for a version that uses statically + * allocated memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xStreamBatchingBufferCreate() to be available. + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBatchingBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes the stream batching buffer + * will be able to hold at any one time. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * batching buffer to unblock a task calling xStreamBufferReceive before the + * block time expires. + * + * @param pxSendCompletedCallback Callback invoked when number of bytes at least + * equal to trigger level is sent to the stream batching buffer. If the + * parameter is NULL, it will use the default implementation provided by + * sbSEND_COMPLETED macro. To enable the callback, configUSE_SB_COMPLETED_CALLBACK + * must be set to 1 in FreeRTOSConfig.h. + * + * @param pxReceiveCompletedCallback Callback invoked when more than zero bytes + * are read from a stream batching buffer. If the parameter is NULL, it will use + * the default implementation provided by sbRECEIVE_COMPLETED macro. To enable + * the callback, configUSE_SB_COMPLETED_CALLBACK must be set to 1 in + * FreeRTOSConfig.h. + * + * @return If NULL is returned, then the stream batching buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the stream batching buffer data structures and storage area. A non-NULL value + * being returned indicates that the stream batching buffer has been created + * successfully - the returned value should be stored as the handle to the + * created stream batching buffer. + * + * Example use: + * @code{c} + * + * void vAFunction( void ) + * { + * StreamBufferHandle_t xStreamBatchingBuffer; + * const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10; + * + * // Create a stream batching buffer that can hold 100 bytes. The memory used + * // to hold both the stream batching buffer structure and the data in the stream + * // batching buffer is allocated dynamically. + * xStreamBatchingBuffer = xStreamBatchingBufferCreate( xStreamBufferSizeBytes, xTriggerLevel ); + * + * if( xStreamBatchingBuffer == NULL ) + * { + * // There was not enough heap memory space available to create the + * // stream batching buffer. + * } + * else + * { + * // The stream batching buffer was created successfully and can now be used. + * } + * } + * @endcode + * \defgroup xStreamBatchingBufferCreate xStreamBatchingBufferCreate + * \ingroup StreamBatchingBufferManagement + */ + +#define xStreamBatchingBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) \ + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, pdTRUE, NULL, NULL ) + +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define xStreamBatchingBufferCreateWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, pdTRUE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) +#endif + +/** + * stream_buffer.h + * + * @code{c} + * StreamBufferHandle_t xStreamBatchingBufferCreateStatic( size_t xBufferSizeBytes, + * size_t xTriggerLevelBytes, + * uint8_t *pucStreamBufferStorageArea, + * StaticStreamBuffer_t *pxStaticStreamBuffer ); + * @endcode + * Creates a new stream batching buffer using statically allocated memory. See + * xStreamBatchingBufferCreate() for a version that uses dynamically allocated + * memory. + * + * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for + * xStreamBatchingBufferCreateStatic() to be available. configUSE_STREAM_BUFFERS + * must be set to 1 in for FreeRTOSConfig.h for xStreamBatchingBufferCreateStatic() + * to be available. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucStreamBufferStorageArea parameter. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * batching buffer to unblock a task calling xStreamBufferReceive before the + * block time expires. + * + * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes big. This is the array to which streams are + * copied when they are written to the stream batching buffer. + * + * @param pxStaticStreamBuffer Must point to a variable of type + * StaticStreamBuffer_t, which will be used to hold the stream batching buffer's + * data structure. + * + * @param pxSendCompletedCallback Callback invoked when number of bytes at least + * equal to trigger level is sent to the stream batching buffer. If the parameter + * is NULL, it will use the default implementation provided by sbSEND_COMPLETED + * macro. To enable the callback, configUSE_SB_COMPLETED_CALLBACK must be set to + * 1 in FreeRTOSConfig.h. + * + * @param pxReceiveCompletedCallback Callback invoked when more than zero bytes + * are read from a stream batching buffer. If the parameter is NULL, it will use + * the default implementation provided by sbRECEIVE_COMPLETED macro. To enable + * the callback, configUSE_SB_COMPLETED_CALLBACK must be set to 1 in + * FreeRTOSConfig.h. + * + * @return If the stream batching buffer is created successfully then a handle + * to the created stream batching buffer is returned. If either pucStreamBufferStorageArea + * or pxStaticstreamBuffer are NULL then NULL is returned. + * + * Example use: + * @code{c} + * + * // Used to dimension the array used to hold the streams. The available space + * // will actually be one less than this, so 999. + * #define STORAGE_SIZE_BYTES 1000 + * + * // Defines the memory that will actually hold the streams within the stream + * // batching buffer. + * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; + * + * // The variable used to hold the stream batching buffer structure. + * StaticStreamBuffer_t xStreamBufferStruct; + * + * void MyFunction( void ) + * { + * StreamBufferHandle_t xStreamBatchingBuffer; + * const size_t xTriggerLevel = 1; + * + * xStreamBatchingBuffer = xStreamBatchingBufferCreateStatic( sizeof( ucStorageBuffer ), + * xTriggerLevel, + * ucStorageBuffer, + * &xStreamBufferStruct ); + * + * // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer + * // parameters were NULL, xStreamBatchingBuffer will not be NULL, and can be + * // used to reference the created stream batching buffer in other stream + * // buffer API calls. + * + * // Other code that uses the stream batching buffer can go here. + * } + * + * @endcode + * \defgroup xStreamBatchingBufferCreateStatic xStreamBatchingBufferCreateStatic + * \ingroup StreamBatchingBufferManagement + */ + +#define xStreamBatchingBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \ + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, pdTRUE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL ) + +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define xStreamBatchingBufferCreateStaticWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, pdTRUE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** @@ -1018,7 +1190,7 @@ void vStreamBufferSetStreamBufferNotificationIndex( StreamBufferHandle_t xStream StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, - BaseType_t xIsBlockingBuffer, + BaseType_t xIsBatchingBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; @@ -1026,6 +1198,7 @@ StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, + BaseType_t xIsBatchingBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, diff --git a/stream_buffer.c b/stream_buffer.c index c682a402c..e3ff7a1a4 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -224,7 +224,7 @@ /* Bits stored in the ucFlags field of the stream buffer. */ #define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */ #define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */ - #define sbFLAGS_IS_BLOCKING_BUFFER ( ( uint8_t ) 4 ) /* Set if the stream buffer was created as a streaming buffer, meaning it will only unblock when the trigger level has been exceeded. */ + #define sbFLAGS_IS_BATCHING_BUFFER ( ( uint8_t ) 4 ) /* Set if the stream buffer was created as a batching buffer, meaning the receiver task will only unblock when the trigger level exceededs. */ /*-----------------------------------------------------------*/ @@ -331,14 +331,14 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, - BaseType_t xIsBlockingBuffer, + BaseType_t xIsBatchingBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) { void * pvAllocatedMemory; uint8_t ucFlags; - traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ); + traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, xIsBatchingBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ); /* In case the stream buffer is going to be used as a message buffer * (that is, it will hold discrete messages with a little meta data that @@ -350,10 +350,10 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, ucFlags = sbFLAGS_IS_MESSAGE_BUFFER; configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); } - else if( xIsBlockingBuffer == pdTRUE ) + else if( xIsBatchingBuffer == pdTRUE ) { - /* Is a blocking buffer but not statically allocated. */ - ucFlags = sbFLAGS_IS_BLOCKING_BUFFER; + /* Is a batching buffer but not statically allocated. */ + ucFlags = sbFLAGS_IS_BATCHING_BUFFER; configASSERT( xBufferSizeBytes > 0 ); } else @@ -428,6 +428,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, + BaseType_t xIsBatchingBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, @@ -440,7 +441,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, StreamBufferHandle_t xReturn; uint8_t ucFlags; - traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ); + traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, xIsBatchingBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ); configASSERT( pucStreamBufferStorageArea ); configASSERT( pxStaticStreamBuffer ); @@ -464,6 +465,12 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED; configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); } + else if( xIsBatchingBuffer != pdFALSE ) + { + /* Statically allocated batching buffer. */ + ucFlags = sbFLAGS_IS_BATCHING_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED; + configASSERT( xBufferSizeBytes > 0 ); + } else { /* Statically allocated stream buffer. */ @@ -999,9 +1006,10 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, { xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; } - else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_BLOCKING_BUFFER ) != ( uint8_t ) 0 ) + else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_BATCHING_BUFFER ) != ( uint8_t ) 0 ) { - /* force task to block if the buffer contains less bytes than trigger level */ + /* Force task to block if the batching buffer contains less bytes than + * the trigger level. */ xBytesToStoreMessageLength = pxStreamBuffer->xTriggerLevelBytes; } else @@ -1021,7 +1029,9 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, * xBytesToStoreMessageLength holds the number of bytes used to hold * the length of the next discrete message. If this function was * invoked by a stream buffer read then xBytesToStoreMessageLength will - * be 0. */ + * be 0. If this function was invoked by a stream batch buffer read + * then xBytesToStoreMessageLength will be xTriggerLevelBytes value + * for the buffer.*/ if( xBytesAvailable <= xBytesToStoreMessageLength ) { /* Clear notification state as going to wait for data. */