Add Stream Batching Buffer (#916)

The difference between a stream buffer and a stream batching buffer is when
a task performs read on a non-empty buffer:
- The task reading from a non-empty stream buffer returns immediately
   regardless of the amount of data in the buffer.
- The task reading from a non-empty steam batching buffer blocks until the
   amount of data in the buffer exceeds the trigger level or the block time
   expires.
diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h
index 662c5ea..f7a59a7 100644
--- a/include/FreeRTOS.h
+++ b/include/FreeRTOS.h
@@ -982,15 +982,15 @@
 #endif
 
 #ifndef traceSTREAM_BUFFER_CREATE_FAILED
-    #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
+    #define traceSTREAM_BUFFER_CREATE_FAILED( xStreamBufferType )
 #endif
 
 #ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED
-    #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer )
+    #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xStreamBufferType )
 #endif
 
 #ifndef traceSTREAM_BUFFER_CREATE
-    #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer )
+    #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xStreamBufferType )
 #endif
 
 #ifndef traceSTREAM_BUFFER_DELETE
@@ -2402,7 +2402,7 @@
 #endif
 
 #ifndef traceENTER_xStreamBufferGenericCreate
-    #define traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback )
+    #define traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xStreamBufferType, pxSendCompletedCallback, pxReceiveCompletedCallback )
 #endif
 
 #ifndef traceRETURN_xStreamBufferGenericCreate
@@ -2410,7 +2410,7 @@
 #endif
 
 #ifndef traceENTER_xStreamBufferGenericCreateStatic
-    #define traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback )
+    #define traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xStreamBufferType, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback )
 #endif
 
 #ifndef traceRETURN_xStreamBufferGenericCreateStatic
diff --git a/include/message_buffer.h b/include/message_buffer.h
index b58f33f..975a7e3 100644
--- a/include/message_buffer.h
+++ b/include/message_buffer.h
@@ -158,11 +158,11 @@
  * \ingroup MessageBufferManagement
  */
 #define xMessageBufferCreate( xBufferSizeBytes ) \
-    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, NULL, NULL )
+    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, sbTYPE_MESSAGE_BUFFER, NULL, NULL )
 
 #if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
     #define xMessageBufferCreateWithCallback( xBufferSizeBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
-    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
+    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, sbTYPE_MESSAGE_BUFFER, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
 #endif
 
 /**
@@ -243,11 +243,11 @@
  * \ingroup MessageBufferManagement
  */
 #define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \
-    xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL )
+    xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, sbTYPE_MESSAGE_BUFFER, ( 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, sbTYPE_MESSAGE_BUFFER, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
 #endif
 
 /**
diff --git a/include/mpu_prototypes.h b/include/mpu_prototypes.h
index 10da35b..d51547c 100644
--- a/include/mpu_prototypes.h
+++ b/include/mpu_prototypes.h
@@ -357,12 +357,12 @@
  * with all the APIs. */
 StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
                                                      size_t xTriggerLevelBytes,
-                                                     BaseType_t xIsMessageBuffer,
+                                                     BaseType_t xStreamBufferType,
                                                      StreamBufferCallbackFunction_t pxSendCompletedCallback,
                                                      StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
 StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
                                                            size_t xTriggerLevelBytes,
-                                                           BaseType_t xIsMessageBuffer,
+                                                           BaseType_t xStreamBufferType,
                                                            uint8_t * const pucStreamBufferStorageArea,
                                                            StaticStreamBuffer_t * const pxStaticStreamBuffer,
                                                            StreamBufferCallbackFunction_t pxSendCompletedCallback,
diff --git a/include/stream_buffer.h b/include/stream_buffer.h
index dca9851..9b15c8a 100644
--- a/include/stream_buffer.h
+++ b/include/stream_buffer.h
@@ -63,6 +63,13 @@
 /* *INDENT-ON* */
 
 /**
+ * Type of stream buffer. For internal use only.
+ */
+#define sbTYPE_STREAM_BUFFER             ( ( BaseType_t ) 0 )
+#define sbTYPE_MESSAGE_BUFFER            ( ( BaseType_t ) 1 )
+#define sbTYPE_STREAM_BATCHING_BUFFER    ( ( BaseType_t ) 2 )
+
+/**
  * Type by which stream buffers are referenced.  For example, a call to
  * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can
  * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(),
@@ -157,11 +164,11 @@
  */
 
 #define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) \
-    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, NULL, NULL )
+    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BUFFER, NULL, NULL )
 
 #if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
     #define xStreamBufferCreateWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
-    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
+    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BUFFER, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
 #endif
 
 /**
@@ -257,11 +264,199 @@
  */
 
 #define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \
-    xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL )
+    xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BUFFER, ( 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 ), sbTYPE_STREAM_BUFFER, ( 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.
+ *
+ * The difference between a stream buffer and a stream batching buffer is when
+ * a task performs read on a non-empty buffer:
+ * - The task reading from a non-empty stream buffer returns immediately
+ *   regardless of the amount of data in the buffer.
+ * - The task reading from a non-empty steam batching buffer blocks until the
+ *   amount of data in the buffer exceeds the trigger level or the block time
+ *   expires.
+ *
+ * @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 ), sbTYPE_STREAM_BATCHING_BUFFER, NULL, NULL )
+
+#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
+    #define xStreamBatchingBufferCreateWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
+    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BATCHING_BUFFER, ( 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.
+ *
+ * The difference between a stream buffer and a stream batching buffer is when
+ * a task performs read on a non-empty buffer:
+ * - The task reading from a non-empty stream buffer returns immediately
+ *   regardless of the amount of data in the buffer.
+ * - The task reading from a non-empty steam batching buffer blocks until the
+ *   amount of data in the buffer exceeds the trigger level or the block time
+ *   expires.
+ *
+ * @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 ), sbTYPE_STREAM_BATCHING_BUFFER, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL )
+
+#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
+    #define xStreamBatchingBufferCreateStaticWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
+    xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BATCHING_BUFFER, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
 #endif
 
 /**
@@ -1053,14 +1248,14 @@
 /* Functions below here are not part of the public API. */
 StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
                                                  size_t xTriggerLevelBytes,
-                                                 BaseType_t xIsMessageBuffer,
+                                                 BaseType_t xStreamBufferType,
                                                  StreamBufferCallbackFunction_t pxSendCompletedCallback,
                                                  StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
 
 #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
     StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
                                                            size_t xTriggerLevelBytes,
-                                                           BaseType_t xIsMessageBuffer,
+                                                           BaseType_t xStreamBufferType,
                                                            uint8_t * const pucStreamBufferStorageArea,
                                                            StaticStreamBuffer_t * const pxStaticStreamBuffer,
                                                            StreamBufferCallbackFunction_t pxSendCompletedCallback,
diff --git a/portable/Common/mpu_wrappers.c b/portable/Common/mpu_wrappers.c
index 85facbd..be1a995 100644
--- a/portable/Common/mpu_wrappers.c
+++ b/portable/Common/mpu_wrappers.c
@@ -2404,14 +2404,14 @@
     #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) )
         StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
                                                              size_t xTriggerLevelBytes,
-                                                             BaseType_t xIsMessageBuffer,
+                                                             BaseType_t xStreamBufferType,
                                                              StreamBufferCallbackFunction_t pxSendCompletedCallback,
                                                              StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* FREERTOS_SYSTEM_CALL */
         {
             StreamBufferHandle_t xReturn;
 
             /**
-             * Streambuffer application level callback functionality is disabled for MPU
+             * Stream buffer application level callback functionality is disabled for MPU
              * enabled ports.
              */
             configASSERT( ( pxSendCompletedCallback == NULL ) &&
@@ -2427,7 +2427,7 @@
 
                     xReturn = xStreamBufferGenericCreate( xBufferSizeBytes,
                                                           xTriggerLevelBytes,
-                                                          xIsMessageBuffer,
+                                                          xStreamBufferType,
                                                           NULL,
                                                           NULL );
                     portMEMORY_BARRIER();
@@ -2439,14 +2439,14 @@
                 {
                     xReturn = xStreamBufferGenericCreate( xBufferSizeBytes,
                                                           xTriggerLevelBytes,
-                                                          xIsMessageBuffer,
+                                                          xStreamBufferType,
                                                           NULL,
                                                           NULL );
                 }
             }
             else
             {
-                traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer );
+                traceSTREAM_BUFFER_CREATE_FAILED( xStreamBufferType );
                 xReturn = NULL;
             }
 
@@ -2458,7 +2458,7 @@
     #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) )
         StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
                                                                    size_t xTriggerLevelBytes,
-                                                                   BaseType_t xIsMessageBuffer,
+                                                                   BaseType_t xStreamBufferType,
                                                                    uint8_t * const pucStreamBufferStorageArea,
                                                                    StaticStreamBuffer_t * const pxStaticStreamBuffer,
                                                                    StreamBufferCallbackFunction_t pxSendCompletedCallback,
@@ -2467,7 +2467,7 @@
             StreamBufferHandle_t xReturn;
 
             /**
-             * Streambuffer application level callback functionality is disabled for MPU
+             * Stream buffer application level callback functionality is disabled for MPU
              * enabled ports.
              */
             configASSERT( ( pxSendCompletedCallback == NULL ) &&
@@ -2483,7 +2483,7 @@
 
                     xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes,
                                                                 xTriggerLevelBytes,
-                                                                xIsMessageBuffer,
+                                                                xStreamBufferType,
                                                                 pucStreamBufferStorageArea,
                                                                 pxStaticStreamBuffer,
                                                                 NULL,
@@ -2497,7 +2497,7 @@
                 {
                     xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes,
                                                                 xTriggerLevelBytes,
-                                                                xIsMessageBuffer,
+                                                                xStreamBufferType,
                                                                 pucStreamBufferStorageArea,
                                                                 pxStaticStreamBuffer,
                                                                 NULL,
@@ -2506,7 +2506,7 @@
             }
             else
             {
-                traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );
+                traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xStreamBufferType );
                 xReturn = NULL;
             }
 
diff --git a/portable/Common/mpu_wrappers_v2.c b/portable/Common/mpu_wrappers_v2.c
index f8d14b1..2dc36b3 100644
--- a/portable/Common/mpu_wrappers_v2.c
+++ b/portable/Common/mpu_wrappers_v2.c
@@ -4662,7 +4662,7 @@
 
         StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
                                                              size_t xTriggerLevelBytes,
-                                                             BaseType_t xIsMessageBuffer,
+                                                             BaseType_t xStreamBufferType,
                                                              StreamBufferCallbackFunction_t pxSendCompletedCallback,
                                                              StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* PRIVILEGED_FUNCTION */
         {
@@ -4686,7 +4686,7 @@
                 {
                     xInternalStreamBufferHandle = xStreamBufferGenericCreate( xBufferSizeBytes,
                                                                               xTriggerLevelBytes,
-                                                                              xIsMessageBuffer,
+                                                                              xStreamBufferType,
                                                                               NULL,
                                                                               NULL );
 
@@ -4703,7 +4703,7 @@
             }
             else
             {
-                traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer );
+                traceSTREAM_BUFFER_CREATE_FAILED( xStreamBufferType );
                 xExternalStreamBufferHandle = NULL;
             }
 
@@ -4717,7 +4717,7 @@
 
         StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
                                                                    size_t xTriggerLevelBytes,
-                                                                   BaseType_t xIsMessageBuffer,
+                                                                   BaseType_t xStreamBufferType,
                                                                    uint8_t * const pucStreamBufferStorageArea,
                                                                    StaticStreamBuffer_t * const pxStaticStreamBuffer,
                                                                    StreamBufferCallbackFunction_t pxSendCompletedCallback,
@@ -4743,7 +4743,7 @@
                 {
                     xInternalStreamBufferHandle = xStreamBufferGenericCreateStatic( xBufferSizeBytes,
                                                                                     xTriggerLevelBytes,
-                                                                                    xIsMessageBuffer,
+                                                                                    xStreamBufferType,
                                                                                     pucStreamBufferStorageArea,
                                                                                     pxStaticStreamBuffer,
                                                                                     NULL,
@@ -4762,7 +4762,7 @@
             }
             else
             {
-                traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );
+                traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xStreamBufferType );
                 xExternalStreamBufferHandle = NULL;
             }
 
diff --git a/stream_buffer.c b/stream_buffer.c
index 17a898d..4471b4f 100644
--- a/stream_buffer.c
+++ b/stream_buffer.c
@@ -224,6 +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_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. */
 
 /*-----------------------------------------------------------*/
 
@@ -329,25 +330,31 @@
     #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
     StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
                                                      size_t xTriggerLevelBytes,
-                                                     BaseType_t xIsMessageBuffer,
+                                                     BaseType_t xStreamBufferType,
                                                      StreamBufferCallbackFunction_t pxSendCompletedCallback,
                                                      StreamBufferCallbackFunction_t pxReceiveCompletedCallback )
     {
         void * pvAllocatedMemory;
         uint8_t ucFlags;
 
-        traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback );
+        traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xStreamBufferType, 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
          * says how big the next message is) check the buffer will be large enough
          * to hold at least one message. */
-        if( xIsMessageBuffer == pdTRUE )
+        if( xStreamBufferType == sbTYPE_MESSAGE_BUFFER )
         {
             /* Is a message buffer but not statically allocated. */
             ucFlags = sbFLAGS_IS_MESSAGE_BUFFER;
             configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
         }
+        else if( xStreamBufferType == sbTYPE_STREAM_BATCHING_BUFFER )
+        {
+            /* Is a batching buffer but not statically allocated. */
+            ucFlags = sbFLAGS_IS_BATCHING_BUFFER;
+            configASSERT( xBufferSizeBytes > 0 );
+        }
         else
         {
             /* Not a message buffer and not statically allocated. */
@@ -398,11 +405,11 @@
                                           pxSendCompletedCallback,
                                           pxReceiveCompletedCallback );
 
-            traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pvAllocatedMemory ), xIsMessageBuffer );
+            traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pvAllocatedMemory ), xStreamBufferType );
         }
         else
         {
-            traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer );
+            traceSTREAM_BUFFER_CREATE_FAILED( xStreamBufferType );
         }
 
         traceRETURN_xStreamBufferGenericCreate( pvAllocatedMemory );
@@ -419,7 +426,7 @@
 
     StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
                                                            size_t xTriggerLevelBytes,
-                                                           BaseType_t xIsMessageBuffer,
+                                                           BaseType_t xStreamBufferType,
                                                            uint8_t * const pucStreamBufferStorageArea,
                                                            StaticStreamBuffer_t * const pxStaticStreamBuffer,
                                                            StreamBufferCallbackFunction_t pxSendCompletedCallback,
@@ -432,7 +439,7 @@
         StreamBufferHandle_t xReturn;
         uint8_t ucFlags;
 
-        traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback );
+        traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xStreamBufferType, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback );
 
         configASSERT( pucStreamBufferStorageArea );
         configASSERT( pxStaticStreamBuffer );
@@ -450,12 +457,18 @@
          * says how big the next message is) check the buffer will be large enough
          * to hold at least one message. */
 
-        if( xIsMessageBuffer != pdFALSE )
+        if( xStreamBufferType == sbTYPE_MESSAGE_BUFFER )
         {
             /* Statically allocated message buffer. */
             ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED;
             configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
         }
+        else if( xStreamBufferType == sbTYPE_STREAM_BATCHING_BUFFER )
+        {
+            /* Statically allocated batching buffer. */
+            ucFlags = sbFLAGS_IS_BATCHING_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED;
+            configASSERT( xBufferSizeBytes > 0 );
+        }
         else
         {
             /* Statically allocated stream buffer. */
@@ -486,7 +499,7 @@
              * again. */
             pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED;
 
-            traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer );
+            traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xStreamBufferType );
 
             /* MISRA Ref 11.3.1 [Misaligned access] */
             /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
@@ -496,7 +509,7 @@
         else
         {
             xReturn = NULL;
-            traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );
+            traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xStreamBufferType );
         }
 
         traceRETURN_xStreamBufferGenericCreateStatic( xReturn );
@@ -1053,6 +1066,12 @@
     {
         xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
     }
+    else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_BATCHING_BUFFER ) != ( uint8_t ) 0 )
+    {
+        /* Force task to block if the batching buffer contains less bytes than
+         * the trigger level. */
+        xBytesToStoreMessageLength = pxStreamBuffer->xTriggerLevelBytes;
+    }
     else
     {
         xBytesToStoreMessageLength = 0;
@@ -1070,7 +1089,9 @@
              * 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. */