xTaskGenericNotify() now sets xYieldPending to pdTRUE even when the 'higher priority task woken' parameter is provided - making its behaviour consistent with event objects.

Ensure tasks that are blocked indefinitely on a direct to task notification return their state as eBlocked, previously was returned as eSuspended - making its behaviour consistent with event objects.
Fix typo in stream_buffer.c where "size_t xBytesAvailable ); PRIVILEGED_FUNCTION" had the semicolon in the wrong place.
Add testing of Stream Buffers to the AbortDelay.c tests.
Guard inclusion of C code when FreeRTOSConfig.h is included from an assembly file in the ARM7_LPC2129_IAR demo.
Fix minor typos in the Windows demo comment blocks.
This commit is contained in:
Richard Barry 2018-04-29 18:15:38 +00:00
parent 025088c280
commit a3148ba638
9 changed files with 124 additions and 30 deletions

View file

@ -29,7 +29,9 @@
#define FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H
/* Hardware specifics. */ /* Hardware specifics. */
#include <NXP/iolpc2129.h> #ifdef __ICCARM__
#include <NXP/iolpc2129.h>
#endif
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Application specific definitions. * Application specific definitions.

View file

@ -27,7 +27,9 @@
/* /*
* This file contains some test scenarios that ensure tasks respond correctly * This file contains some test scenarios that ensure tasks respond correctly
* to xTaskAbortDelay() calls. * to xTaskAbortDelay() calls. It also ensures tasks return the correct state
* of eBlocked when blocked indefinitely in both the case where a task is
* blocked on an object and when a task is blocked on a notification.
*/ */
/* Standard includes. */ /* Standard includes. */
@ -39,6 +41,7 @@
#include "queue.h" #include "queue.h"
#include "semphr.h" #include "semphr.h"
#include "event_groups.h" #include "event_groups.h"
#include "stream_buffer.h"
/* Demo includes. */ /* Demo includes. */
#include "AbortDelay.h" #include "AbortDelay.h"
@ -68,7 +71,8 @@ build. Remove the whole file if this is not the case. */
#define abtSEMAPHORE_TAKE_ABORTS 4 #define abtSEMAPHORE_TAKE_ABORTS 4
#define abtEVENT_GROUP_ABORTS 5 #define abtEVENT_GROUP_ABORTS 5
#define abtQUEUE_SEND_ABORTS 6 #define abtQUEUE_SEND_ABORTS 6
#define abtMAX_TESTS 7 #define abtSTREAM_BUFFER_RECEIVE 7
#define abtMAX_TESTS 8
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -95,6 +99,7 @@ static void prvTestAbortingTaskDelayUntil( void );
static void prvTestAbortingSemaphoreTake( void ); static void prvTestAbortingSemaphoreTake( void );
static void prvTestAbortingEventGroupWait( void ); static void prvTestAbortingEventGroupWait( void );
static void prvTestAbortingQueueSend( void ); static void prvTestAbortingQueueSend( void );
static void prvTestAbortingStreamBufferReceive( void );
/* /*
* Checks the amount of time a task spent in the Blocked state is within the * Checks the amount of time a task spent in the Blocked state is within the
@ -241,6 +246,10 @@ const uint32_t ulMax = 0xffffffffUL;
prvTestAbortingQueueSend(); prvTestAbortingQueueSend();
break; break;
case abtSTREAM_BUFFER_RECEIVE:
prvTestAbortingStreamBufferReceive();
break;
default: default:
/* Should not get here. */ /* Should not get here. */
break; break;
@ -417,6 +426,75 @@ EventBits_t xBitsToWaitFor = ( EventBits_t ) 0x01, xReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvTestAbortingStreamBufferReceive( void )
{
TickType_t xTimeAtStart;
StreamBufferHandle_t xStreamBuffer;
EventBits_t xReturn;
const size_t xTriggerLevelBytes = ( size_t ) 1;
uint8_t uxRxData;
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
{
/* Defines the memory that will actually hold the streams within the
stream buffer. */
static uint8_t ucStorageBuffer[ sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) + 1 ];
/* The variable used to hold the stream buffer structure. */
StaticStreamBuffer_t xStreamBufferStruct;
xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucStorageBuffer ),
xTriggerLevelBytes,
ucStorageBuffer,
&xStreamBufferStruct );
}
#else
{
xStreamBuffer = xStreamBufferCreate( sizeof( uint8_t ), xTriggerLevelBytes );
configASSERT( xStreamBuffer );
}
#endif
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This first delay should just time out. */
xReturn = xStreamBufferReceive( xStreamBuffer, &uxRxData, sizeof( uxRxData ), xMaxBlockTime );
if( xReturn != 0x00 )
{
xErrorOccurred = pdTRUE;
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This second delay should be aborted by the primary task half way
through xMaxBlockTime. */
xReturn = xStreamBufferReceive( xStreamBuffer, &uxRxData, sizeof( uxRxData ), xMaxBlockTime );
if( xReturn != 0x00 )
{
xErrorOccurred = pdTRUE;
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
/* Note the time before the delay so the length of the delay is known. */
xTimeAtStart = xTaskGetTickCount();
/* This third delay should just time out again. */
xReturn = xStreamBufferReceive( xStreamBuffer, &uxRxData, sizeof( uxRxData ), xMaxBlockTime );
if( xReturn != 0x00 )
{
xErrorOccurred = pdTRUE;
}
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
/* Not really necessary in this case, but for completeness. */
vStreamBufferDelete( xStreamBuffer );
}
/*-----------------------------------------------------------*/
static void prvTestAbortingQueueSend( void ) static void prvTestAbortingQueueSend( void )
{ {
TickType_t xTimeAtStart; TickType_t xTimeAtStart;
@ -523,8 +601,8 @@ SemaphoreHandle_t xSemaphore;
xTimeAtStart = xTaskGetTickCount(); xTimeAtStart = xTaskGetTickCount();
/* This second delay should be aborted by the primary task half way /* This second delay should be aborted by the primary task half way
through. */ through xMaxBlockTime. */
xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime ); xReturn = xSemaphoreTake( xSemaphore, portMAX_DELAY );
if( xReturn != pdFALSE ) if( xReturn != pdFALSE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
@ -567,8 +645,8 @@ BaseType_t xReturn;
xTimeAtStart = xTaskGetTickCount(); xTimeAtStart = xTaskGetTickCount();
/* This second delay should be aborted by the primary task half way /* This second delay should be aborted by the primary task half way
through. */ through xMaxBlockTime. */
xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime ); xReturn = xTaskNotifyWait( 0, 0, NULL, portMAX_DELAY );
if( xReturn != pdFALSE ) if( xReturn != pdFALSE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;

View file

@ -218,7 +218,6 @@ static TickType_t xIterationsWithoutCounterIncrement = ( TickType_t ) 0, xLastCy
{ {
/* The tests appear to be no longer running (stalled). */ /* The tests appear to be no longer running (stalled). */
xTestStatus = pdFAIL; xTestStatus = pdFAIL;
configASSERT( xTestStatus );
} }
} }
else else

View file

@ -68,7 +68,7 @@ The blinky demo is implemented and described in main_blinky.c.
If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is not 1 then the comprehensive test and If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is not 1 then the comprehensive test and
demo application will be built. The comprehensive test and demo application is demo application will be built. The comprehensive test and demo application is
implemented and described in main_full.c. */ implemented and described in main_full.c. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/* This demo uses heap_5.c, and these constants define the sizes of the regions /* This demo uses heap_5.c, and these constants define the sizes of the regions
that make up the total heap. heap_5 is only used for test and example purposes that make up the total heap. heap_5 is only used for test and example purposes

View file

@ -46,7 +46,7 @@
* in main.c. This file implements the comprehensive test and demo version. * in main.c. This file implements the comprehensive test and demo version.
* *
* NOTE 3: This file only contains the source code that is specific to the * NOTE 3: This file only contains the source code that is specific to the
* basic demo. Generic functions, such FreeRTOS hook functions, are defined in * full demo. Generic functions, such FreeRTOS hook functions, are defined in
* main.c. * main.c.
******************************************************************************* *******************************************************************************
* *

View file

@ -46,7 +46,7 @@
* in main.c. This file implements the comprehensive test and demo version. * in main.c. This file implements the comprehensive test and demo version.
* *
* NOTE 3: This file only contains the source code that is specific to the * NOTE 3: This file only contains the source code that is specific to the
* basic demo. Generic functions, such FreeRTOS hook functions, are defined in * full demo. Generic functions, such FreeRTOS hook functions, are defined in
* main.c. * main.c.
******************************************************************************* *******************************************************************************
* *

View file

@ -200,7 +200,7 @@ static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer,
uint8_t *pucData, uint8_t *pucData,
size_t xMaxCount, size_t xMaxCount,
size_t xBytesAvailable ); PRIVILEGED_FUNCTION size_t xBytesAvailable ) PRIVILEGED_FUNCTION;
/* /*
* Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to

View file

@ -1364,11 +1364,30 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
else if( pxStateList == &xSuspendedTaskList ) else if( pxStateList == &xSuspendedTaskList )
{ {
/* The task being queried is referenced from the suspended /* The task being queried is referenced from the suspended
list. Is it genuinely suspended or is it block list. Is it genuinely suspended or is it blocked
indefinitely? */ indefinitely? */
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ) if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL )
{ {
eReturn = eSuspended; #if( configUSE_TASK_NOTIFICATIONS == 1 )
{
/* The task does not appear on the vent list item of
and of the RTOS objects, but could still be in the
blocked state if it is waiting on its notification
rather than waiting on an object. */
if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION )
{
eReturn = eBlocked;
}
else
{
eReturn = eSuspended;
}
}
#else
{
eReturn = eSuspended;
}
#endif
} }
else else
{ {
@ -4772,13 +4791,11 @@ TickType_t uxReturn;
{ {
*pxHigherPriorityTaskWoken = pdTRUE; *pxHigherPriorityTaskWoken = pdTRUE;
} }
else
{ /* Mark that a yield is pending in case the user is not
/* Mark that a yield is pending in case the user is not using the "xHigherPriorityTaskWoken" parameter to an ISR
using the "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
safe FreeRTOS function. */ xYieldPending = pdTRUE;
xYieldPending = pdTRUE;
}
} }
else else
{ {
@ -4862,13 +4879,11 @@ TickType_t uxReturn;
{ {
*pxHigherPriorityTaskWoken = pdTRUE; *pxHigherPriorityTaskWoken = pdTRUE;
} }
else
{ /* Mark that a yield is pending in case the user is not
/* Mark that a yield is pending in case the user is not using the "xHigherPriorityTaskWoken" parameter in an ISR
using the "xHigherPriorityTaskWoken" parameter in an ISR safe FreeRTOS function. */
safe FreeRTOS function. */ xYieldPending = pdTRUE;
xYieldPending = pdTRUE;
}
} }
else else
{ {