@@ -103,6 +103,20 @@ static void prvInterruptSimulatorTask( void * pvParameters );
103103 */
104104static void prvCreateThreadSafeBuffers ( void );
105105
106+ /*
107+ * This function is equivalent to uxStreamBufferAdd from
108+ * FreeRTOS_Stream_Buffer.c in the case that the stream buffer is being used
109+ * as a normal circular buffer (i.e. only the tail and head pointers are
110+ * needed). Thus, this function does not take the offset argument, and does not
111+ * update the front pointer of the stream buffer. This allows the removal of
112+ * the calls to vTaskSuspendAll and xTaskResumeAll, as the head and front
113+ * pointer no longer need to be atomically updated, allowing this function to be
114+ * safely used by a Windows thread.
115+ */
116+ static size_t prvStreamBufferAdd ( StreamBuffer_t * pxBuffer ,
117+ const uint8_t * pucData ,
118+ size_t uxByteCount );
119+
106120/*
107121 * Utility function used to format print messages only.
108122 */
@@ -189,6 +203,59 @@ static void prvCreateThreadSafeBuffers( void )
189203 xRecvBuffer -> LENGTH = xRECV_BUFFER_SIZE + 1 ;
190204 }
191205}
206+
207+ /*-----------------------------------------------------------*/
208+
209+ static size_t prvStreamBufferAdd ( StreamBuffer_t * pxBuffer ,
210+ const uint8_t * pucData ,
211+ size_t uxByteCount )
212+ {
213+ size_t uxSpace , uxNextHead , uxFirst ;
214+ size_t uxCount = uxByteCount ;
215+
216+ uxSpace = uxStreamBufferGetSpace ( pxBuffer );
217+
218+ /* The number of bytes that can be written is the minimum of the number of
219+ * bytes requested and the number available. */
220+ uxCount = FreeRTOS_min_size_t ( uxSpace , uxCount );
221+
222+ if ( uxCount != 0U )
223+ {
224+ uxNextHead = pxBuffer -> uxHead ;
225+
226+ if ( pucData != NULL )
227+ {
228+ /* Calculate the number of bytes that can be added in the first
229+ * write - which may be less than the total number of bytes that need
230+ * to be added if the buffer will wrap back to the beginning. */
231+ uxFirst = FreeRTOS_min_size_t ( pxBuffer -> LENGTH - uxNextHead , uxCount );
232+
233+ /* Write as many bytes as can be written in the first write. */
234+ ( void ) memcpy ( & ( pxBuffer -> ucArray [ uxNextHead ] ), pucData , uxFirst );
235+
236+ /* If the number of bytes written was less than the number that
237+ * could be written in the first write... */
238+ if ( uxCount > uxFirst )
239+ {
240+ /* ...then write the remaining bytes to the start of the
241+ * buffer. */
242+ ( void ) memcpy ( pxBuffer -> ucArray , & ( pucData [ uxFirst ] ), uxCount - uxFirst );
243+ }
244+ }
245+
246+ uxNextHead += uxCount ;
247+
248+ if ( uxNextHead >= pxBuffer -> LENGTH )
249+ {
250+ uxNextHead -= pxBuffer -> LENGTH ;
251+ }
252+
253+ pxBuffer -> uxHead = uxNextHead ;
254+ }
255+
256+ return uxCount ;
257+ }
258+
192259/*-----------------------------------------------------------*/
193260
194261BaseType_t xNetworkInterfaceOutput ( NetworkBufferDescriptor_t * const pxNetworkBuffer ,
@@ -255,7 +322,7 @@ static pcap_if_t * prvPrintAvailableNetworkInterfaces( void )
255322 {
256323 /* Print out the list of network interfaces. The first in the list
257324 * is interface '1', not interface '0'. */
258- for ( xInterface = pxAllNetworkInterfaces ; xInterface != NULL ; xInterface = xInterface -> next )
325+ for (xInterface = pxAllNetworkInterfaces ; xInterface != NULL ; xInterface = xInterface -> next )
259326 {
260327 /* The descriptions of the devices can be full of spaces, clean them
261328 * a little. printf() can only be used here because the network is not
@@ -350,7 +417,7 @@ static void prvOpenSelectedNetworkInterface( pcap_if_t * pxAllNetworkInterfaces
350417 /* Walk the list of devices until the selected device is located. */
351418 pxInterface = pxAllNetworkInterfaces ;
352419
353- for ( x = 0L ; x < ( xConfigNetworkInterfaceToUse - 1L ); x ++ )
420+ for (x = 0L ; x < ( xConfigNetworkInterfaceToUse - 1L ); x ++ )
354421 {
355422 pxInterface = pxInterface -> next ;
356423 }
@@ -459,8 +526,16 @@ void pcap_callback( u_char * user,
459526 * Otherwise, there is no action. */
460527 iptraceDUMP_PACKET ( ( const uint8_t * ) pkt_data , ( size_t ) pkt_header -> caplen , pdTRUE );
461528
462- uxStreamBufferAdd ( xRecvBuffer , 0 , ( const uint8_t * ) pkt_header , sizeof ( * pkt_header ) );
463- uxStreamBufferAdd ( xRecvBuffer , 0 , ( const uint8_t * ) pkt_data , ( size_t ) pkt_header -> caplen );
529+ /* NOTE. The prvStreamBufferAdd function is used here in place of
530+ * uxStreamBufferAdd since the uxStreamBufferAdd call will suspend
531+ * the FreeRTOS scheduler to atomically update the head and front
532+ * of the stream buffer. Since xRecvBuffer is being used as a regular
533+ * circular buffer (i.e. only the head and tail are needed), this call
534+ * only updates the head of the buffer, removing the need to suspend
535+ * the scheduler, and allowing this function to be safely called from
536+ * a Windows thread. */
537+ prvStreamBufferAdd ( xRecvBuffer , ( const uint8_t * ) pkt_header , sizeof ( * pkt_header ) );
538+ prvStreamBufferAdd ( xRecvBuffer , ( const uint8_t * ) pkt_data , ( size_t ) pkt_header -> caplen );
464539 }
465540}
466541/*-----------------------------------------------------------*/
@@ -704,7 +779,7 @@ void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkB
704779 }
705780 else
706781 {
707- for ( uxIndex = 0 ; uxIndex < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ; uxIndex ++ )
782+ for (uxIndex = 0 ; uxIndex < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ; uxIndex ++ )
708783 {
709784 size_t uxOffset = uxIndex * BUFFER_SIZE_ROUNDED_UP ;
710785 NetworkBufferDescriptor_t * * ppDescriptor ;
0 commit comments