stream_buffer.c
Go to the documentation of this file.
1 /*
2  * FreeRTOS Kernel V10.0.0
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software. If you wish to use our Amazon
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * http://www.FreeRTOS.org
24  * http://aws.amazon.com/freertos
25  *
26  * 1 tab == 4 spaces!
27  */
28 
29 /* Standard includes. */
30 #include <stdint.h>
31 #include <string.h>
32 
33 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
34 all the API functions to use the MPU wrappers. That should only be done when
35 task.h is included from an application file. */
36 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
37 
38 /* FreeRTOS includes. */
39 #include "FreeRTOS.h"
40 #include "task.h"
41 #include "stream_buffer.h"
42 
43 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
44 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
45 header files above, but not in this file, in order to generate the correct
46 privileged Vs unprivileged linkage and placement. */
47 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
48 
49 /* If the user has not provided application specific Rx notification macros,
50 or #defined the notification macros away, them provide default implementations
51 that uses task notifications. */
52 /*lint -save -e9026 Function like macros allowed and needed here so they can be overidden. */
53 #ifndef sbRECEIVE_COMPLETED
54  #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \
55  vTaskSuspendAll(); \
56  { \
57  if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
58  { \
59  ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \
60  ( uint32_t ) 0, \
61  eNoAction ); \
62  ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \
63  } \
64  } \
65  ( void ) xTaskResumeAll();
66 #endif /* sbRECEIVE_COMPLETED */
67 
68 #ifndef sbRECEIVE_COMPLETED_FROM_ISR
69  #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \
70  pxHigherPriorityTaskWoken ) \
71  { \
72  UBaseType_t uxSavedInterruptStatus; \
73  \
74  uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \
75  { \
76  if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
77  { \
78  ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \
79  ( uint32_t ) 0, \
80  eNoAction, \
81  pxHigherPriorityTaskWoken ); \
82  ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \
83  } \
84  } \
85  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
86  }
87 #endif /* sbRECEIVE_COMPLETED_FROM_ISR */
88 
89 /* If the user has not provided an application specific Tx notification macro,
90 or #defined the notification macro away, them provide a default implementation
91 that uses task notifications. */
92 #ifndef sbSEND_COMPLETED
93  #define sbSEND_COMPLETED( pxStreamBuffer ) \
94  vTaskSuspendAll(); \
95  { \
96  if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \
97  { \
98  ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \
99  ( uint32_t ) 0, \
100  eNoAction ); \
101  ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \
102  } \
103  } \
104  ( void ) xTaskResumeAll();
105 #endif /* sbSEND_COMPLETED */
106 
107 #ifndef sbSEND_COMPLETE_FROM_ISR
108  #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
109  { \
110  UBaseType_t uxSavedInterruptStatus; \
111  \
112  uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \
113  { \
114  if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \
115  { \
116  ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \
117  ( uint32_t ) 0, \
118  eNoAction, \
119  pxHigherPriorityTaskWoken ); \
120  ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \
121  } \
122  } \
123  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
124  }
125 #endif /* sbSEND_COMPLETE_FROM_ISR */
126 /*lint -restore (9026) */
127 
128 /* The number of bytes used to hold the length of a message in the buffer. */
129 #define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( size_t ) )
130 
131 /* Bits stored in the ucFlags field of the stream buffer. */
132 #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. */
133 #define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */
134 
135 /*-----------------------------------------------------------*/
136 
137 /* Structure that hold state information on the buffer. */
138 typedef struct xSTREAM_BUFFER /*lint !e9058 Style convention uses tag. */
139 {
140  volatile size_t xTail; /* Index to the next item to read within the buffer. */
141  volatile size_t xHead; /* Index to the next item to write within the buffer. */
142  size_t xLength; /* The length of the buffer pointed to by pucBuffer. */
143  size_t xTriggerLevelBytes; /* The number of bytes that must be in the stream buffer before a task that is waiting for data is unblocked. */
144  volatile TaskHandle_t xTaskWaitingToReceive; /* Holds the handle of a task waiting for data, or NULL if no tasks are waiting. */
145  volatile TaskHandle_t xTaskWaitingToSend; /* Holds the handle of a task waiting to send data to a message buffer that is full. */
146  uint8_t *pucBuffer; /* Points to the buffer itself - that is - the RAM that stores the data passed through the buffer. */
147  uint8_t ucFlags;
148 
149  #if ( configUSE_TRACE_FACILITY == 1 )
150  UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */
151  #endif
153 
154 /*
155  * The number of bytes available to be read from the buffer.
156  */
157 static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION;
158 
159 /*
160  * Add xCount bytes from pucData into the pxStreamBuffer message buffer.
161  * Returns the number of bytes written, which will either equal xCount in the
162  * success case, or 0 if there was not enough space in the buffer (in which case
163  * no data is written into the buffer).
164  */
165 static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount ) PRIVILEGED_FUNCTION;
166 
167 /*
168  * If the stream buffer is being used as a message buffer, then reads an entire
169  * message out of the buffer. If the stream buffer is being used as a stream
170  * buffer then read as many bytes as possible from the buffer.
171  * prvReadBytesFromBuffer() is called to actually extract the bytes from the
172  * buffer's data storage area.
173  */
174 static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer,
175  void *pvRxData,
176  size_t xBufferLengthBytes,
177  size_t xBytesAvailable,
178  size_t xBytesToStoreMessageLength ) PRIVILEGED_FUNCTION;
179 
180 /*
181  * If the stream buffer is being used as a message buffer, then writes an entire
182  * message to the buffer. If the stream buffer is being used as a stream
183  * buffer then write as many bytes as possible to the buffer.
184  * prvWriteBytestoBuffer() is called to actually send the bytes to the buffer's
185  * data storage area.
186  */
187 static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
188  const void * pvTxData,
189  size_t xDataLengthBytes,
190  size_t xSpace,
191  size_t xRequiredSpace ) PRIVILEGED_FUNCTION;
192 
193 /*
194  * Read xMaxCount bytes from the pxStreamBuffer message buffer and write them
195  * to pucData.
196  */
197 static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer,
198  uint8_t *pucData,
199  size_t xMaxCount,
200  size_t xBytesAvailable ); PRIVILEGED_FUNCTION
201 
202 /*
203  * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to
204  * initialise the members of the newly created stream buffer structure.
205  */
206 static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
207  uint8_t * const pucBuffer,
208  size_t xBufferSizeBytes,
209  size_t xTriggerLevelBytes,
210  BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION;
211 
212 /*-----------------------------------------------------------*/
213 
214 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
215 
216  StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer )
217  {
218  uint8_t *pucAllocatedMemory;
219 
220  /* In case the stream buffer is going to be used as a message buffer
221  (that is, it will hold discrete messages with a little meta data that
222  says how big the next message is) check the buffer will be large enough
223  to hold at least one message. */
224  configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
225  configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
226 
227  /* A trigger level of 0 would cause a waiting task to unblock even when
228  the buffer was empty. */
229  if( xTriggerLevelBytes == ( size_t ) 0 )
230  {
231  xTriggerLevelBytes = ( size_t ) 1; /*lint !e9044 Parameter modified to ensure it doesn't have a dangerous value. */
232  }
233 
234  /* A stream buffer requires a StreamBuffer_t structure and a buffer.
235  Both are allocated in a single call to pvPortMalloc(). The
236  StreamBuffer_t structure is placed at the start of the allocated memory
237  and the buffer follows immediately after. The requested size is
238  incremented so the free space is returned as the user would expect -
239  this is a quirk of the implementation that means otherwise the free
240  space would be reported as one byte smaller than would be logically
241  expected. */
242  xBufferSizeBytes++;
243  pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */
244 
245  if( pucAllocatedMemory != NULL )
246  {
247  prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) (void*)pucAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */
248  pucAllocatedMemory + sizeof( StreamBuffer_t ), /* Storage area follows. */ /*lint !e9016 Indexing past structure valid for uint8_t pointer, also storage area has no alignment requirement. */
249  xBufferSizeBytes,
250  xTriggerLevelBytes,
251  xIsMessageBuffer );
252 
253  traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pucAllocatedMemory ), xIsMessageBuffer );
254  }
255  else
256  {
257  traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer );
258  }
259 
260  return ( StreamBufferHandle_t * ) (void*)pucAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */
261  }
262 
263 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
264 /*-----------------------------------------------------------*/
265 
266 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
267 
269  size_t xTriggerLevelBytes,
270  BaseType_t xIsMessageBuffer,
271  uint8_t * const pucStreamBufferStorageArea,
272  StaticStreamBuffer_t * const pxStaticStreamBuffer )
273  {
274  StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */
275  StreamBufferHandle_t xReturn;
276 
277  configASSERT( pucStreamBufferStorageArea );
278  configASSERT( pxStaticStreamBuffer );
279  configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
280 
281  /* A trigger level of 0 would cause a waiting task to unblock even when
282  the buffer was empty. */
283  if( xTriggerLevelBytes == ( size_t ) 0 )
284  {
285  xTriggerLevelBytes = ( size_t ) 1; /*lint !e9044 Function parameter deliberately modified to ensure it is in range. */
286  }
287 
288  /* In case the stream buffer is going to be used as a message buffer
289  (that is, it will hold discrete messages with a little meta data that
290  says how big the next message is) check the buffer will be large enough
291  to hold at least one message. */
292  configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
293 
294  #if( configASSERT_DEFINED == 1 )
295  {
296  /* Sanity check that the size of the structure used to declare a
297  variable of type StaticStreamBuffer_t equals the size of the real
298  message buffer structure. */
299  volatile size_t xSize = sizeof( StaticStreamBuffer_t );
300  configASSERT( xSize == sizeof( StreamBuffer_t ) );
301  }
302  #endif /* configASSERT_DEFINED */
303 
304  if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) )
305  {
306  prvInitialiseNewStreamBuffer( pxStreamBuffer,
307  pucStreamBufferStorageArea,
308  xBufferSizeBytes,
309  xTriggerLevelBytes,
310  xIsMessageBuffer );
311 
312  /* Remember this was statically allocated in case it is ever deleted
313  again. */
314  pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED;
315 
316  traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer );
317 
318  xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */
319  }
320  else
321  {
322  xReturn = NULL;
323  traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );
324  }
325 
326  return xReturn;
327  }
328 
329 #endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
330 /*-----------------------------------------------------------*/
331 
333 {
334 StreamBuffer_t * pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
335 
336  configASSERT( pxStreamBuffer );
337 
338  traceSTREAM_BUFFER_DELETE( xStreamBuffer );
339 
340  if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE )
341  {
342  #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
343  {
344  /* Both the structure and the buffer were allocated using a single call
345  to pvPortMalloc(), hence only one call to vPortFree() is required. */
346  vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */
347  }
348  #else
349  {
350  /* Should not be possible to get here, ucFlags must be corrupt.
351  Force an assert. */
352  configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 );
353  }
354  #endif
355  }
356  else
357  {
358  /* The structure and buffer were not allocated dynamically and cannot be
359  freed - just scrub the structure so future use will assert. */
360  memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) );
361  }
362 }
363 /*-----------------------------------------------------------*/
364 
366 {
367 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
368 BaseType_t xReturn = pdFAIL, xIsMessageBuffer;
369 
370 #if( configUSE_TRACE_FACILITY == 1 )
371  UBaseType_t uxStreamBufferNumber;
372 #endif
373 
374  configASSERT( pxStreamBuffer );
375 
376  #if( configUSE_TRACE_FACILITY == 1 )
377  {
378  /* Store the stream buffer number so it can be restored after the
379  reset. */
380  uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber;
381  }
382  #endif
383 
384  /* Can only reset a message buffer if there are no tasks blocked on it. */
385  if( pxStreamBuffer->xTaskWaitingToReceive == NULL )
386  {
387  if( pxStreamBuffer->xTaskWaitingToSend == NULL )
388  {
389  if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
390  {
391  xIsMessageBuffer = pdTRUE;
392  }
393  else
394  {
395  xIsMessageBuffer = pdFALSE;
396  }
397 
398  prvInitialiseNewStreamBuffer( pxStreamBuffer,
399  pxStreamBuffer->pucBuffer,
400  pxStreamBuffer->xLength,
401  pxStreamBuffer->xTriggerLevelBytes,
402  xIsMessageBuffer );
403  xReturn = pdPASS;
404 
405  #if( configUSE_TRACE_FACILITY == 1 )
406  {
407  pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
408  }
409  #endif
410 
411  traceSTREAM_BUFFER_RESET( xStreamBuffer );
412  }
413  }
414 
415  return xReturn;
416 }
417 /*-----------------------------------------------------------*/
418 
419 BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel )
420 {
421 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
422 BaseType_t xReturn;
423 
424  configASSERT( pxStreamBuffer );
425 
426  /* It is not valid for the trigger level to be 0. */
427  if( xTriggerLevel == ( size_t ) 0 )
428  {
429  xTriggerLevel = ( size_t ) 1; /*lint !e9044 Parameter modified to ensure it doesn't have a dangerous value. */
430  }
431 
432  /* The trigger level is the number of bytes that must be in the stream
433  buffer before a task that is waiting for data is unblocked. */
434  if( xTriggerLevel <= pxStreamBuffer->xLength )
435  {
436  pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel;
437  xReturn = pdPASS;
438  }
439  else
440  {
441  xReturn = pdFALSE;
442  }
443 
444  return xReturn;
445 }
446 /*-----------------------------------------------------------*/
447 
449 {
450 const StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
451 size_t xSpace;
452 
453  configASSERT( pxStreamBuffer );
454 
455  xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail;
456  xSpace -= pxStreamBuffer->xHead;
457  xSpace -= ( size_t ) 1;
458 
459  if( xSpace >= pxStreamBuffer->xLength )
460  {
461  xSpace -= pxStreamBuffer->xLength;
462  }
463  else
464  {
466  }
467 
468  return xSpace;
469 }
470 /*-----------------------------------------------------------*/
471 
473 {
474 const StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
475 size_t xReturn;
476 
477  configASSERT( pxStreamBuffer );
478 
479  xReturn = prvBytesInBuffer( pxStreamBuffer );
480  return xReturn;
481 }
482 /*-----------------------------------------------------------*/
483 
485  const void *pvTxData,
486  size_t xDataLengthBytes,
487  TickType_t xTicksToWait )
488 {
489 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
490 size_t xReturn, xSpace = 0;
491 size_t xRequiredSpace = xDataLengthBytes;
492 TimeOut_t xTimeOut;
493 
494  configASSERT( pvTxData );
495  configASSERT( pxStreamBuffer );
496 
497  /* This send function is used to write to both message buffers and stream
498  buffers. If this is a message buffer then the space needed must be
499  increased by the amount of bytes needed to store the length of the
500  message. */
501  if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
502  {
503  xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
504  }
505  else
506  {
508  }
509 
510  if( xTicksToWait != ( TickType_t ) 0 )
511  {
512  vTaskSetTimeOutState( &xTimeOut );
513 
514  do
515  {
516  /* Wait until the required number of bytes are free in the message
517  buffer. */
519  {
520  xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
521 
522  if( xSpace < xRequiredSpace )
523  {
524  /* Clear notification state as going to wait for space. */
525  ( void ) xTaskNotifyStateClear( NULL );
526 
527  /* Should only be one writer. */
528  configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL );
529  pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle();
530  }
531  else
532  {
534  break;
535  }
536  }
538 
539  traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer );
540  ( void ) xTaskNotifyWait( ( uint32_t ) 0, UINT32_MAX, NULL, xTicksToWait );
541  pxStreamBuffer->xTaskWaitingToSend = NULL;
542 
543  } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE );
544  }
545  else
546  {
548  }
549 
550  if( xSpace == ( size_t ) 0 )
551  {
552  xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
553  }
554  else
555  {
557  }
558 
559  xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
560 
561  if( xReturn > ( size_t ) 0 )
562  {
563  traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn );
564 
565  /* Was a task waiting for the data? */
566  if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
567  {
568  sbSEND_COMPLETED( pxStreamBuffer );
569  }
570  else
571  {
573  }
574  }
575  else
576  {
578  traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer );
579  }
580 
581  return xReturn;
582 }
583 /*-----------------------------------------------------------*/
584 
586  const void *pvTxData,
587  size_t xDataLengthBytes,
588  BaseType_t * const pxHigherPriorityTaskWoken )
589 {
590 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
591 size_t xReturn, xSpace;
592 size_t xRequiredSpace = xDataLengthBytes;
593 
594  configASSERT( pvTxData );
595  configASSERT( pxStreamBuffer );
596 
597  /* This send function is used to write to both message buffers and stream
598  buffers. If this is a message buffer then the space needed must be
599  increased by the amount of bytes needed to store the length of the
600  message. */
601  if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
602  {
603  xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
604  }
605  else
606  {
608  }
609 
610  xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
611  xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
612 
613  if( xReturn > ( size_t ) 0 )
614  {
615  /* Was a task waiting for the data? */
616  if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
617  {
618  sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
619  }
620  else
621  {
623  }
624  }
625  else
626  {
628  }
629 
630  traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn );
631 
632  return xReturn;
633 }
634 /*-----------------------------------------------------------*/
635 
636 static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
637  const void * pvTxData,
638  size_t xDataLengthBytes,
639  size_t xSpace,
640  size_t xRequiredSpace )
641 {
642  BaseType_t xShouldWrite;
643  size_t xReturn;
644 
645  if( xSpace == ( size_t ) 0 )
646  {
647  /* Doesn't matter if this is a stream buffer or a message buffer, there
648  is no space to write. */
649  xShouldWrite = pdFALSE;
650  }
651  else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) == ( uint8_t ) 0 )
652  {
653  /* This is a stream buffer, as opposed to a message buffer, so writing a
654  stream of bytes rather than discrete messages. Write as many bytes as
655  possible. */
656  xShouldWrite = pdTRUE;
657  xDataLengthBytes = configMIN( xDataLengthBytes, xSpace ); /*lint !e9044 Function parameter modified to ensure it is capped to available space. */
658  }
659  else if( xSpace >= xRequiredSpace )
660  {
661  /* This is a message buffer, as opposed to a stream buffer, and there
662  is enough space to write both the message length and the message itself
663  into the buffer. Start by writing the length of the data, the data
664  itself will be written later in this function. */
665  xShouldWrite = pdTRUE;
666  ( void ) prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH );
667  }
668  else
669  {
670  /* There is space available, but not enough space. */
671  xShouldWrite = pdFALSE;
672  }
673 
674  if( xShouldWrite != pdFALSE )
675  {
676  /* Writes the data itself. */
677  xReturn = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alighment and access. */
678  }
679  else
680  {
681  xReturn = 0;
682  }
683 
684  return xReturn;
685 }
686 /*-----------------------------------------------------------*/
687 
689  void *pvRxData,
690  size_t xBufferLengthBytes,
691  TickType_t xTicksToWait )
692 {
693 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
694 size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
695 
696  configASSERT( pvRxData );
697  configASSERT( pxStreamBuffer );
698 
699  /* This receive function is used by both message buffers, which store
700  discrete messages, and stream buffers, which store a continuous stream of
701  bytes. Discrete messages include an additional
702  sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the
703  message. */
704  if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
705  {
706  xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
707  }
708  else
709  {
710  xBytesToStoreMessageLength = 0;
711  }
712 
713  if( xTicksToWait != ( TickType_t ) 0 )
714  {
715  /* Checking if there is data and clearing the notification state must be
716  performed atomically. */
718  {
719  xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
720 
721  /* If this function was invoked by a message buffer read then
722  xBytesToStoreMessageLength holds the number of bytes used to hold
723  the length of the next discrete message. If this function was
724  invoked by a stream buffer read then xBytesToStoreMessageLength will
725  be 0. */
726  if( xBytesAvailable <= xBytesToStoreMessageLength )
727  {
728  /* Clear notification state as going to wait for data. */
729  ( void ) xTaskNotifyStateClear( NULL );
730 
731  /* Should only be one reader. */
732  configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL );
734  }
735  else
736  {
738  }
739  }
741 
742  if( xBytesAvailable <= xBytesToStoreMessageLength )
743  {
744  /* Wait for data to be available. */
746  ( void ) xTaskNotifyWait( ( uint32_t ) 0, UINT32_MAX, NULL, xTicksToWait );
747  pxStreamBuffer->xTaskWaitingToReceive = NULL;
748 
749  /* Recheck the data available after blocking. */
750  xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
751  }
752  else
753  {
755  }
756  }
757  else
758  {
759  xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
760  }
761 
762  /* Whether receiving a discrete message (where xBytesToStoreMessageLength
763  holds the number of bytes used to store the message length) or a stream of
764  bytes (where xBytesToStoreMessageLength is zero), the number of bytes
765  available must be greater than xBytesToStoreMessageLength to be able to
766  read bytes from the buffer. */
767  if( xBytesAvailable > xBytesToStoreMessageLength )
768  {
769  xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
770 
771  /* Was a task waiting for space in the buffer? */
772  if( xReceivedLength != ( size_t ) 0 )
773  {
774  traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength );
775  sbRECEIVE_COMPLETED( pxStreamBuffer );
776  }
777  else
778  {
780  }
781  }
782  else
783  {
784  traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer );
786  }
787 
788  return xReceivedLength;
789 }
790 /*-----------------------------------------------------------*/
791 
793  void *pvRxData,
794  size_t xBufferLengthBytes,
795  BaseType_t * const pxHigherPriorityTaskWoken )
796 {
797 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
798 size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
799 
800  configASSERT( pvRxData );
801  configASSERT( pxStreamBuffer );
802 
803  /* This receive function is used by both message buffers, which store
804  discrete messages, and stream buffers, which store a continuous stream of
805  bytes. Discrete messages include an additional
806  sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the
807  message. */
808  if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
809  {
810  xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
811  }
812  else
813  {
814  xBytesToStoreMessageLength = 0;
815  }
816 
817  xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
818 
819  /* Whether receiving a discrete message (where xBytesToStoreMessageLength
820  holds the number of bytes used to store the message length) or a stream of
821  bytes (where xBytesToStoreMessageLength is zero), the number of bytes
822  available must be greater than xBytesToStoreMessageLength to be able to
823  read bytes from the buffer. */
824  if( xBytesAvailable > xBytesToStoreMessageLength )
825  {
826  xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
827 
828  /* Was a task waiting for space in the buffer? */
829  if( xReceivedLength != ( size_t ) 0 )
830  {
831  sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
832  }
833  else
834  {
836  }
837  }
838  else
839  {
841  }
842 
843  traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength );
844 
845  return xReceivedLength;
846 }
847 /*-----------------------------------------------------------*/
848 
849 static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer,
850  void *pvRxData,
851  size_t xBufferLengthBytes,
852  size_t xBytesAvailable,
853  size_t xBytesToStoreMessageLength )
854 {
855 size_t xOriginalTail, xReceivedLength, xNextMessageLength;
856 
857  if( xBytesToStoreMessageLength != ( size_t ) 0 )
858  {
859  /* A discrete message is being received. First receive the length
860  of the message. A copy of the tail is stored so the buffer can be
861  returned to its prior state if the length of the message is too
862  large for the provided buffer. */
863  xOriginalTail = pxStreamBuffer->xTail;
864  ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable );
865 
866  /* Reduce the number of bytes available by the number of bytes just
867  read out. */
868  xBytesAvailable -= xBytesToStoreMessageLength;
869 
870  /* Check there is enough space in the buffer provided by the
871  user. */
872  if( xNextMessageLength > xBufferLengthBytes )
873  {
874  /* The user has provided insufficient space to read the message
875  so return the buffer to its previous state (so the length of
876  the message is in the buffer again). */
877  pxStreamBuffer->xTail = xOriginalTail;
878  xNextMessageLength = 0;
879  }
880  else
881  {
883  }
884  }
885  else
886  {
887  /* A stream of bytes is being received (as opposed to a discrete
888  message), so read as many bytes as possible. */
889  xNextMessageLength = xBufferLengthBytes;
890  }
891 
892  /* Read the actual data. */
893  xReceivedLength = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xNextMessageLength, xBytesAvailable ); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */
894 
895  return xReceivedLength;
896 }
897 /*-----------------------------------------------------------*/
898 
900 {
901 const StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
902 BaseType_t xReturn;
903 size_t xTail;
904 
905  configASSERT( pxStreamBuffer );
906 
907  /* True if no bytes are available. */
908  xTail = pxStreamBuffer->xTail;
909  if( pxStreamBuffer->xHead == xTail )
910  {
911  xReturn = pdTRUE;
912  }
913  else
914  {
915  xReturn = pdFALSE;
916  }
917 
918  return xReturn;
919 }
920 /*-----------------------------------------------------------*/
921 
923 {
924 BaseType_t xReturn;
925 size_t xBytesToStoreMessageLength;
926 const StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
927 
928  configASSERT( pxStreamBuffer );
929 
930  /* This generic version of the receive function is used by both message
931  buffers, which store discrete messages, and stream buffers, which store a
932  continuous stream of bytes. Discrete messages include an additional
933  sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */
934  if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
935  {
936  xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
937  }
938  else
939  {
940  xBytesToStoreMessageLength = 0;
941  }
942 
943  /* True if the available space equals zero. */
944  if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength )
945  {
946  xReturn = pdTRUE;
947  }
948  else
949  {
950  xReturn = pdFALSE;
951  }
952 
953  return xReturn;
954 }
955 /*-----------------------------------------------------------*/
956 
958 {
959 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
960 BaseType_t xReturn;
961 UBaseType_t uxSavedInterruptStatus;
962 
963  configASSERT( pxStreamBuffer );
964 
965  uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();
966  {
967  if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )
968  {
969  ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive,
970  ( uint32_t ) 0,
971  eNoAction,
972  pxHigherPriorityTaskWoken );
973  ( pxStreamBuffer )->xTaskWaitingToReceive = NULL;
974  xReturn = pdTRUE;
975  }
976  else
977  {
978  xReturn = pdFALSE;
979  }
980  }
981  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
982 
983  return xReturn;
984 }
985 /*-----------------------------------------------------------*/
986 
988 {
989 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
990 BaseType_t xReturn;
991 UBaseType_t uxSavedInterruptStatus;
992 
993  configASSERT( pxStreamBuffer );
994 
995  uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();
996  {
997  if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )
998  {
999  ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend,
1000  ( uint32_t ) 0,
1001  eNoAction,
1002  pxHigherPriorityTaskWoken );
1003  ( pxStreamBuffer )->xTaskWaitingToSend = NULL;
1004  xReturn = pdTRUE;
1005  }
1006  else
1007  {
1008  xReturn = pdFALSE;
1009  }
1010  }
1011  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
1012 
1013  return xReturn;
1014 }
1015 /*-----------------------------------------------------------*/
1016 
1017 static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount )
1018 {
1019 size_t xNextHead, xFirstLength;
1020 
1021  configASSERT( xCount > ( size_t ) 0 );
1022 
1023  xNextHead = pxStreamBuffer->xHead;
1024 
1025  /* Calculate the number of bytes that can be added in the first write -
1026  which may be less than the total number of bytes that need to be added if
1027  the buffer will wrap back to the beginning. */
1028  xFirstLength = configMIN( pxStreamBuffer->xLength - xNextHead, xCount );
1029 
1030  /* Write as many bytes as can be written in the first write. */
1031  configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength );
1032  memcpy( ( void* ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */
1033 
1034  /* If the number of bytes written was less than the number that could be
1035  written in the first write... */
1036  if( xCount > xFirstLength )
1037  {
1038  /* ...then write the remaining bytes to the start of the buffer. */
1039  configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength );
1040  memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
1041  }
1042  else
1043  {
1045  }
1046 
1047  xNextHead += xCount;
1048  if( xNextHead >= pxStreamBuffer->xLength )
1049  {
1050  xNextHead -= pxStreamBuffer->xLength;
1051  }
1052  else
1053  {
1055  }
1056 
1057  pxStreamBuffer->xHead = xNextHead;
1058 
1059  return xCount;
1060 }
1061 /*-----------------------------------------------------------*/
1062 
1063 static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, uint8_t *pucData, size_t xMaxCount, size_t xBytesAvailable )
1064 {
1065 size_t xCount, xFirstLength, xNextTail;
1066 
1067  /* Use the minimum of the wanted bytes and the available bytes. */
1068  xCount = configMIN( xBytesAvailable, xMaxCount );
1069 
1070  if( xCount > ( size_t ) 0 )
1071  {
1072  xNextTail = pxStreamBuffer->xTail;
1073 
1074  /* Calculate the number of bytes that can be read - which may be
1075  less than the number wanted if the data wraps around to the start of
1076  the buffer. */
1077  xFirstLength = configMIN( pxStreamBuffer->xLength - xNextTail, xCount );
1078 
1079  /* Obtain the number of bytes it is possible to obtain in the first
1080  read. Asserts check bounds of read and write. */
1081  configASSERT( xFirstLength <= xMaxCount );
1082  configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength );
1083  memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */
1084 
1085  /* If the total number of wanted bytes is greater than the number
1086  that could be read in the first read... */
1087  if( xCount > xFirstLength )
1088  {
1089  /*...then read the remaining bytes from the start of the buffer. */
1090  configASSERT( xCount <= xMaxCount );
1091  memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
1092  }
1093  else
1094  {
1096  }
1097 
1098  /* Move the tail pointer to effectively remove the data read from
1099  the buffer. */
1100  xNextTail += xCount;
1101 
1102  if( xNextTail >= pxStreamBuffer->xLength )
1103  {
1104  xNextTail -= pxStreamBuffer->xLength;
1105  }
1106 
1107  pxStreamBuffer->xTail = xNextTail;
1108  }
1109  else
1110  {
1112  }
1113 
1114  return xCount;
1115 }
1116 /*-----------------------------------------------------------*/
1117 
1118 static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer )
1119 {
1120 /* Returns the distance between xTail and xHead. */
1121 size_t xCount;
1122 
1123  xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead;
1124  xCount -= pxStreamBuffer->xTail;
1125  if ( xCount >= pxStreamBuffer->xLength )
1126  {
1127  xCount -= pxStreamBuffer->xLength;
1128  }
1129  else
1130  {
1132  }
1133 
1134  return xCount;
1135 }
1136 /*-----------------------------------------------------------*/
1137 
1138 static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
1139  uint8_t * const pucBuffer,
1140  size_t xBufferSizeBytes,
1141  size_t xTriggerLevelBytes,
1142  BaseType_t xIsMessageBuffer )
1143 {
1144  /* Assert here is deliberately writing to the entire buffer to ensure it can
1145  be written to without generating exceptions, and is setting the buffer to a
1146  known value to assist in development/debugging. */
1147  #if( configASSERT_DEFINED == 1 )
1148  {
1149  /* The value written just has to be identifiable when looking at the
1150  memory. Don't use 0xA5 as that is the stack fill value and could
1151  result in confusion as to what is actually being observed. */
1152  const BaseType_t xWriteValue = 0x55;
1153  configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer );
1154  }
1155  #endif
1156 
1157  memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */
1158  pxStreamBuffer->pucBuffer = pucBuffer;
1159  pxStreamBuffer->xLength = xBufferSizeBytes;
1160  pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes;
1161 
1162  if( xIsMessageBuffer != pdFALSE )
1163  {
1164  pxStreamBuffer->ucFlags |= sbFLAGS_IS_MESSAGE_BUFFER;
1165  }
1166 }
1167 
1168 #if ( configUSE_TRACE_FACILITY == 1 )
1169 
1170  UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer )
1171  {
1172  return ( ( StreamBuffer_t * ) xStreamBuffer )->uxStreamBufferNumber;
1173  }
1174 
1175 #endif /* configUSE_TRACE_FACILITY */
1176 /*-----------------------------------------------------------*/
1177 
1178 #if ( configUSE_TRACE_FACILITY == 1 )
1179 
1180  void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber )
1181  {
1182  ( ( StreamBuffer_t * ) xStreamBuffer )->uxStreamBufferNumber = uxStreamBufferNumber;
1183  }
1184 
1185 #endif /* configUSE_TRACE_FACILITY */
1186 /*-----------------------------------------------------------*/
1187 
1188 #if ( configUSE_TRACE_FACILITY == 1 )
1189 
1190  uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer )
1191  {
1192  return ( ( StreamBuffer_t * )xStreamBuffer )->ucFlags | sbFLAGS_IS_MESSAGE_BUFFER;
1193  }
1194 
1195 #endif /* configUSE_TRACE_FACILITY */
1196 /*-----------------------------------------------------------*/
#define pdTRUE
Definition: projdefs.h:46
size_t xStreamBufferSendFromISR(StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, BaseType_t *const pxHigherPriorityTaskWoken)
volatile TaskHandle_t xTaskWaitingToReceive
void vPortFree(void *pv) PRIVILEGED_FUNCTION
Definition: heap_4.c:311
size_t xStreamBufferReceive(StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait)
Definition: task.h:84
TaskHandle_t xTaskGetCurrentTaskHandle(void) PRIVILEGED_FUNCTION
#define traceBLOCKING_ON_STREAM_BUFFER_SEND(xStreamBuffer)
Definition: FreeRTOS.h:661
#define sbRECEIVE_COMPLETED(pxStreamBuffer)
Definition: stream_buffer.c:54
size_t xStreamBufferSpacesAvailable(StreamBufferHandle_t xStreamBuffer)
BaseType_t xStreamBufferReceiveCompletedFromISR(StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken)
#define sbFLAGS_IS_MESSAGE_BUFFER
#define taskEXIT_CRITICAL()
Definition: task.h:194
BaseType_t xStreamBufferIsEmpty(StreamBufferHandle_t xStreamBuffer)
struct xSTATIC_STREAM_BUFFER StaticStreamBuffer_t
void * pvPortMalloc(size_t xSize) PRIVILEGED_FUNCTION
Definition: heap_4.c:155
struct xSTREAM_BUFFER StreamBuffer_t
#define NULL
Definition: nm_bsp.h:52
#define traceSTREAM_BUFFER_RECEIVE(xStreamBuffer, xReceivedLength)
Definition: FreeRTOS.h:681
size_t xStreamBufferReceiveFromISR(StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, BaseType_t *const pxHigherPriorityTaskWoken)
static PRIVILEGED_FUNCTION void prvInitialiseNewStreamBuffer(StreamBuffer_t *const pxStreamBuffer, uint8_t *const pucBuffer, size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer) PRIVILEGED_FUNCTION
#define xTaskNotifyFromISR(xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken)
Definition: task.h:1858
unsigned long UBaseType_t
Definition: portmacro.h:58
uint32_t TickType_t
Definition: portmacro.h:64
size_t xStreamBufferBytesAvailable(StreamBufferHandle_t xStreamBuffer)
#define traceSTREAM_BUFFER_RECEIVE_FAILED(xStreamBuffer)
Definition: FreeRTOS.h:685
static size_t prvReadMessageFromBuffer(StreamBuffer_t *pxStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, size_t xBytesAvailable, size_t xBytesToStoreMessageLength) PRIVILEGED_FUNCTION
#define portSET_INTERRUPT_MASK_FROM_ISR()
Definition: FreeRTOS.h:259
size_t xStreamBufferSend(StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait)
BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait) PRIVILEGED_FUNCTION
Definition: task.h:94
#define configASSERT(x)
Definition: FreeRTOS.h:235
#define traceSTREAM_BUFFER_SEND_FROM_ISR(xStreamBuffer, xBytesSent)
Definition: FreeRTOS.h:673
#define sbSEND_COMPLETE_FROM_ISR(pxStreamBuffer, pxHigherPriorityTaskWoken)
#define sbSEND_COMPLETED(pxStreamBuffer)
Definition: stream_buffer.c:93
#define traceSTREAM_BUFFER_DELETE(xStreamBuffer)
Definition: FreeRTOS.h:653
#define configMIN(a, b)
Definition: FreeRTOS.h:895
#define pdFAIL
Definition: projdefs.h:49
long BaseType_t
Definition: portmacro.h:57
#define pdPASS
Definition: projdefs.h:48
size_t xTriggerLevelBytes
#define traceSTREAM_BUFFER_SEND(xStreamBuffer, xBytesSent)
Definition: FreeRTOS.h:665
void * TaskHandle_t
Definition: task.h:62
BaseType_t xStreamBufferSetTriggerLevel(StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel)
#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE(xStreamBuffer)
Definition: FreeRTOS.h:677
#define sbBYTES_TO_STORE_MESSAGE_LENGTH
static size_t prvReadBytesFromBuffer(StreamBuffer_t *pxStreamBuffer, uint8_t *pucData, size_t xMaxCount, size_t xBytesAvailable)
BaseType_t xStreamBufferIsFull(StreamBufferHandle_t xStreamBuffer)
#define traceSTREAM_BUFFER_CREATE(pxStreamBuffer, xIsMessageBuffer)
Definition: FreeRTOS.h:649
BaseType_t xTaskNotifyStateClear(TaskHandle_t xTask)
volatile size_t xTail
#define pdFALSE
Definition: projdefs.h:45
#define sbFLAGS_IS_STATICALLY_ALLOCATED
#define taskENTER_CRITICAL()
Definition: task.h:179
volatile TaskHandle_t xTaskWaitingToSend
static size_t prvWriteMessageToBuffer(StreamBuffer_t *const pxStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, size_t xSpace, size_t xRequiredSpace) PRIVILEGED_FUNCTION
BaseType_t xStreamBufferSendCompletedFromISR(StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken)
void vTaskSetTimeOutState(TimeOut_t *const pxTimeOut) PRIVILEGED_FUNCTION
Definition: tasks.c:3088
BaseType_t xStreamBufferReset(StreamBufferHandle_t xStreamBuffer)
static size_t prvWriteBytesToBuffer(StreamBuffer_t *const pxStreamBuffer, const uint8_t *pucData, size_t xCount) PRIVILEGED_FUNCTION
#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR(xStreamBuffer, xReceivedLength)
Definition: FreeRTOS.h:689
#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED(xReturn, xIsMessageBuffer)
Definition: FreeRTOS.h:645
void * StreamBufferHandle_t
Definition: stream_buffer.h:65
#define PRIVILEGED_FUNCTION
Definition: mpu_wrappers.h:174
void vStreamBufferDelete(StreamBufferHandle_t xStreamBuffer)
StreamBufferHandle_t xStreamBufferGenericCreateStatic(size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t *const pucStreamBufferStorageArea, StaticStreamBuffer_t *const pxStaticStreamBuffer) PRIVILEGED_FUNCTION
#define mtCOVERAGE_TEST_MARKER()
Definition: FreeRTOS.h:787
BaseType_t xTaskCheckForTimeOut(TimeOut_t *const pxTimeOut, TickType_t *const pxTicksToWait) PRIVILEGED_FUNCTION
Definition: tasks.c:3108
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue)
Definition: FreeRTOS.h:263
#define traceSTREAM_BUFFER_RESET(xStreamBuffer)
Definition: FreeRTOS.h:657
StreamBufferHandle_t xStreamBufferGenericCreate(size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer) PRIVILEGED_FUNCTION
#define traceSTREAM_BUFFER_SEND_FAILED(xStreamBuffer)
Definition: FreeRTOS.h:669
uint8_t * pucBuffer
#define traceSTREAM_BUFFER_CREATE_FAILED(xIsMessageBuffer)
Definition: FreeRTOS.h:641
volatile size_t xHead
#define sbRECEIVE_COMPLETED_FROM_ISR(pxStreamBuffer, pxHigherPriorityTaskWoken)
Definition: stream_buffer.c:69
static size_t prvBytesInBuffer(const StreamBuffer_t *const pxStreamBuffer) PRIVILEGED_FUNCTION


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:58