Introduce xMessageBufferNextLengthBytes() and tests for the same.

Add call to traceTASK_SWITCHED_IN() in vTaskStartScheduler() so trace tools can see the first task to run.
This commit is contained in:
Richard Barry 2018-03-04 19:25:14 +00:00
parent 9ed3a9fe18
commit f9bef06ec0
9 changed files with 121 additions and 3 deletions

View File

@ -156,7 +156,7 @@ MessageBufferHandle_t xMessageBuffer;
static void prvSingleTaskTests( MessageBufferHandle_t xMessageBuffer )
{
size_t xReturned, xItem, xExpectedSpace;
size_t xReturned, xItem, xExpectedSpace, xNextLength;
const size_t xMax6ByteMessages = mbMESSAGE_BUFFER_LENGTH_BYTES / ( 6 + mbBYTES_TO_STORE_MESSAGE_LENGTH );
const size_t x6ByteLength = 6, x17ByteLength = 17;
uint8_t *pucFullBuffer, *pucData, *pucReadData;
@ -177,11 +177,15 @@ UBaseType_t uxOriginalPriority;
pucReadData = pucData + x17ByteLength;
/* Nothing has been added or removed yet, so expect the free space to be
exactly as created. */
exactly as created and the length of the next message to be 0. */
xExpectedSpace = xMessageBufferSpaceAvailable( xMessageBuffer );
configASSERT( xExpectedSpace == mbMESSAGE_BUFFER_LENGTH_BYTES );
configASSERT( xMessageBufferIsEmpty( xMessageBuffer ) == pdTRUE );
xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer );
configASSERT( xNextLength == 0 );
/* In case configASSERT() is not define. */
( void ) xExpectedSpace;
( void ) xNextLength;
/* The buffer is 50 bytes long. When an item is added to the buffer an
additional 4 bytes are added to hold the item's size. That means adding
@ -215,6 +219,11 @@ UBaseType_t uxOriginalPriority;
xReturned = xMessageBufferSpaceAvailable( xMessageBuffer );
configASSERT( xReturned == xExpectedSpace );
( void ) xReturned; /* In case configASSERT() is not defined. */
/* Only 6 byte messages are written. */
xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer );
configASSERT( xNextLength == x6ByteLength );
( void ) xNextLength; /* In case configASSERT() is not defined. */
}
/* Now the buffer should be full, and attempting to add anything will should
@ -255,6 +264,11 @@ UBaseType_t uxOriginalPriority;
configASSERT( xReturned == 0 );
( void ) xReturned; /* In case configASSERT() is not defined. */
/* Should still be at least one 6 byte message still available. */
xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer );
configASSERT( xNextLength == x6ByteLength );
( void ) xNextLength; /* In case configASSERT() is not defined. */
/* Read the next 6 bytes out. The 'FromISR' version is used to give it
some exercise as a block time is not used. THa requires the code to be
in a critical section so this test can be run with FreeRTOS ports that
@ -284,6 +298,11 @@ UBaseType_t uxOriginalPriority;
configASSERT( xMessageBufferIsEmpty( xMessageBuffer ) == pdTRUE );
xExpectedSpace = xMessageBufferSpaceAvailable( xMessageBuffer );
configASSERT( xExpectedSpace == mbMESSAGE_BUFFER_LENGTH_BYTES );
( void ) xExpectedSpace; /* In case configASSERT() is not defined. */
xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer );
configASSERT( xNextLength == 0 );
( void ) xNextLength; /* In case configASSERT() is not defined. */
/* Reading with a timeout should also fail after the appropriate time. The
priority is temporarily boosted in this part of the test to keep the
@ -320,6 +339,11 @@ UBaseType_t uxOriginalPriority;
configASSERT( xReturned == x17ByteLength );
( void ) xReturned; /* In case configASSERT() is not defined. */
/* Only 17 byte messages are written. */
xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer );
configASSERT( xNextLength == x17ByteLength );
( void ) xNextLength; /* In case configASSERT() is not defined. */
/* The space in the buffer will have reduced by the amount of user data
written into the buffer and the amount of space used to store the length
of the data written into the buffer. */
@ -334,6 +358,12 @@ UBaseType_t uxOriginalPriority;
/* Does the data read out match that expected? */
configASSERT( memcmp( ( void * ) pucData, ( void * ) pucReadData, x17ByteLength ) == 0 );
/* Don't expect any messages to be available as the data was read out
again. */
xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer );
configASSERT( xNextLength == 0 );
( void ) xNextLength; /* In case configASSERT() is not defined. */
}
/* The buffer should be empty again. */
@ -357,10 +387,19 @@ UBaseType_t uxOriginalPriority;
configASSERT( xReturned == 0 );
( void ) xReturned; /* In case configASSERT() is not defined. */
/* Don't expect any messages to be available as the above were too large to
get written. */
xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer );
configASSERT( xNextLength == 0 );
( void ) xNextLength; /* In case configASSERT() is not defined. */
/* Can write mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) bytes though. */
xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ), mbDONT_BLOCK );
configASSERT( xReturned == mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) );
( void ) xReturned; /* In case configASSERT() is not defined. */
xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer );
configASSERT( xNextLength == ( mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) );
( void ) xNextLength; /* In case configASSERT() is not defined. */
xReturned = xMessageBufferReceive( xMessageBuffer, ( void * ) pucFullBuffer, mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ), mbDONT_BLOCK );
configASSERT( xReturned == ( mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) );
( void ) xReturned; /* In case configASSERT() is not defined. */

View File

@ -693,6 +693,25 @@ size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
*/
#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer )
/**
* message_buffer.h
<pre>
size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
</pre>
* Returns the length (in bytes) of the next message in a message buffer.
* Useful if xMessageBufferReceive() returned 0 because the size of the buffer
* passed into xMessageBufferReceive() was too small to hold the next message.
*
* @param xMessageBuffer The handle of the message buffer being queried.
*
* @return The length (in bytes) of the next message in the message buffer, or 0
* if the message buffer is empty.
*
* \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes
* \ingroup MessageBufferManagement
*/
#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION;
/**
* message_buffer.h
*

View File

@ -138,6 +138,7 @@ UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup );
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait );
size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken );
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait );
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer );
size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken );
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );

View File

@ -142,6 +142,7 @@ only for ports that are using the MPU. */
#define xStreamBufferSend MPU_xStreamBufferSend
#define xStreamBufferSendFromISR MPU_xStreamBufferSendFromISR
#define xStreamBufferReceive MPU_xStreamBufferReceive
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
#define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR
#define vStreamBufferDelete MPU_vStreamBufferDelete
#define xStreamBufferIsFull MPU_xStreamBufferIsFull

View File

@ -839,6 +839,8 @@ StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
uint8_t * const pucStreamBufferStorageArea,
StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
#if( configUSE_TRACE_FACILITY == 1 )
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;

View File

@ -1136,6 +1136,18 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
}
/*-----------------------------------------------------------*/
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
{
size_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer );
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
/*-----------------------------------------------------------*/
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait )
{
size_t xReturn;

View File

@ -792,6 +792,48 @@ size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
}
/*-----------------------------------------------------------*/
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
{
StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
size_t xReturn, xBytesAvailable, xOriginalTail;
configASSERT( pxStreamBuffer );
/* Ensure the stream buffer is being used as a message buffer. */
if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
{
xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH )
{
/* The number of bytes available is greater than the number of bytes
required to hold the length of the next message, so another message
is available. Return its length without removing the length bytes
from the buffer. A copy of the tail is stored so the buffer can be
returned to its prior state as the message is not actually being
removed from the buffer. */
xOriginalTail = pxStreamBuffer->xTail;
( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable );
pxStreamBuffer->xTail = xOriginalTail;
}
else
{
/* The minimum amount of bytes in a message buffer is
( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is
less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid
value is 0. */
configASSERT( xBytesAvailable == 0 );
xReturn = 0;
}
}
else
{
xReturn = 0;
}
return xReturn;
}
/*-----------------------------------------------------------*/
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
void *pvRxData,
size_t xBufferLengthBytes,

View File

@ -1994,6 +1994,8 @@ BaseType_t xReturn;
FreeRTOSConfig.h file. */
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();
traceTASK_SWITCHED_IN();
/* Setting up the timer tick is hardware specific and thus in the
portable interface. */
if( xPortStartScheduler() != pdFALSE )