mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Changes to the FreeRTOS code:
+ Introduced xTaskCreateStatic() to allow tasks to be created without any dynamic memory allocation. + When a task notification is used to unblock a task from an ISR, but the xHigherPriorityTaskWoken parameter is not used, then pend a context switch to occur during the next tick interrupt. Demo application changes: + Updated TaskNotify.c to test the case where a task is unblocked by an ISR, but does not use its xHigherPriorityTaskWoken parameter. + Updated the Win32 MSVC project to test statically allocated tasks being created and deleted. + Introduced StaticAllocation.c standard demo task.
This commit is contained in:
parent
7d6609f8db
commit
ea95020ffd
310
FreeRTOS/Demo/Common/Minimal/StaticAllocation.c
Normal file
310
FreeRTOS/Demo/Common/Minimal/StaticAllocation.c
Normal file
|
@ -0,0 +1,310 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Demonstrates how to create FreeRTOS objects using pre-allocated memory,
|
||||||
|
* rather than the normal dynamically allocated memory. Currently only tasks
|
||||||
|
* are being allocated statically.
|
||||||
|
*
|
||||||
|
* Two buffers are required by a task - one that is used by the task as its
|
||||||
|
* stack, and one that holds the task's control block (TCB).
|
||||||
|
* prvStaticallyAllocatedTaskCreator() creates and deletes tasks with all
|
||||||
|
* possible combinations of statically allocated and dynamically allocated
|
||||||
|
* stacks and TCBs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "StaticAllocation.h"
|
||||||
|
|
||||||
|
#define staticTASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A task that is created multiple times, using both statically and dynamically
|
||||||
|
* allocated stack and TCB.
|
||||||
|
*/
|
||||||
|
static void prvStaticallyAllocatedTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The task that creates and deletes the prvStaticallyAllocatedTask() task,
|
||||||
|
* using various priorities, and sometimes with statically and sometimes
|
||||||
|
* dynamically allocated stack and TCB.
|
||||||
|
*/
|
||||||
|
static void prvStaticallyAllocatedTaskCreator( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility function to create pseudo random numbers.
|
||||||
|
*/
|
||||||
|
static UBaseType_t prvRand( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The task that creates and deletes other tasks has to delay occasionally to
|
||||||
|
* ensure lower priority tasks are not starved of processing time. A pseudo
|
||||||
|
* random delay time is used just to add a little bit of randomisation into the
|
||||||
|
* execution pattern. prvGetNextDelayTime() generates the pseudo random delay.
|
||||||
|
*/
|
||||||
|
static TickType_t prvGetNextDelayTime( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* DummyTCB_t is a publicly accessible structure that has the same size and
|
||||||
|
alignment requirements as the real TCB structure. It is provided as a mechanism
|
||||||
|
for applications to know the size of the TCB (which is dependent on the
|
||||||
|
architecture and configuration file settings) without breaking the strict data
|
||||||
|
hiding policy by exposing the real TCB. This DummyTCB_t variable is passed into
|
||||||
|
the xTaskCreateStatic() function, and will hold the task's TCB. */
|
||||||
|
static DummyTCB_t xTCBBuffer;
|
||||||
|
|
||||||
|
/* This is the stack that will be used by the task. The alignment requirements
|
||||||
|
for the stack depend on the architecture, and the method of forcing an alignment
|
||||||
|
is dependent on the compiler, but any bad alignment is corrected inside the
|
||||||
|
FreeRTOS code. */
|
||||||
|
static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
|
||||||
|
|
||||||
|
/* Used by the pseudo random number generating function. */
|
||||||
|
static uint32_t ulNextRand = 0;
|
||||||
|
|
||||||
|
/* Used so a check task can ensure this test is still executing, and not
|
||||||
|
stalled. */
|
||||||
|
static volatile UBaseType_t uxCycleCounter = 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartStaticallyAllocatedTasks( void )
|
||||||
|
{
|
||||||
|
/* Create a single task, which then repeatedly creates and deletes the
|
||||||
|
task implemented by prvStaticallyAllocatedTask() at various different
|
||||||
|
priorities, and both with and without statically allocated TCB and stack. */
|
||||||
|
xTaskCreate( prvStaticallyAllocatedTaskCreator, "StatCreate", configMINIMAL_STACK_SIZE, NULL, staticTASK_PRIORITY, NULL );
|
||||||
|
|
||||||
|
/* Pseudo seed the random number generator. */
|
||||||
|
ulNextRand = ( uint32_t ) prvRand;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvStaticallyAllocatedTaskCreator( void *pvParameters )
|
||||||
|
{
|
||||||
|
TaskHandle_t xCreatedTask;
|
||||||
|
BaseType_t xReturned;
|
||||||
|
|
||||||
|
/* Avoid compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Create the task. xTaskCreateStatic() has two more parameters than
|
||||||
|
the usual xTaskCreate() function. The first new parameter is a pointer to
|
||||||
|
the pre-allocated stack. The second new parameter is a pointer to the
|
||||||
|
DummyTCB_t structure that will hold the task's TCB. If either pointer is
|
||||||
|
passed as NULL then the respective object will be allocated dynamically as
|
||||||
|
if xTaskCreate() had been called. */
|
||||||
|
xReturned = xTaskCreateStatic(
|
||||||
|
prvStaticallyAllocatedTask, /* Function that implements the task. */
|
||||||
|
"Static", /* Human readable name for the task. */
|
||||||
|
configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
|
||||||
|
NULL, /* Parameter to pass into the task. */
|
||||||
|
tskIDLE_PRIORITY, /* The priority of the task. */
|
||||||
|
&xCreatedTask, /* Handle of the task being created. */
|
||||||
|
&( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
|
||||||
|
&xTCBBuffer ); /* The variable that will hold that task's TCB. */
|
||||||
|
|
||||||
|
/* Check the task was created correctly, then delete the task. */
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
( void ) xReturned; /* In case configASSERT() is not defined. */
|
||||||
|
vTaskDelete( xCreatedTask );
|
||||||
|
|
||||||
|
/* Ensure lower priority tasks get CPU time. */
|
||||||
|
vTaskDelay( prvGetNextDelayTime() );
|
||||||
|
|
||||||
|
/* Create and delete the task a few times again - testing both static and
|
||||||
|
dynamic allocation for the stack and TCB. */
|
||||||
|
xReturned = xTaskCreateStatic(
|
||||||
|
prvStaticallyAllocatedTask, /* Function that implements the task. */
|
||||||
|
"Static", /* Human readable name for the task. */
|
||||||
|
configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
|
||||||
|
NULL, /* Parameter to pass into the task. */
|
||||||
|
staticTASK_PRIORITY + 1, /* The priority of the task. */
|
||||||
|
&xCreatedTask, /* Handle of the task being created. */
|
||||||
|
NULL, /* This time, dynamically allocate the stack. */
|
||||||
|
&xTCBBuffer ); /* The variable that will hold that task's TCB. */
|
||||||
|
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
( void ) xReturned; /* In case configASSERT() is not defined. */
|
||||||
|
vTaskDelete( xCreatedTask );
|
||||||
|
|
||||||
|
/* Just to show the check task that this task is still executing. */
|
||||||
|
uxCycleCounter++;
|
||||||
|
|
||||||
|
/* Ensure lower priority tasks get CPU time. */
|
||||||
|
vTaskDelay( prvGetNextDelayTime() );
|
||||||
|
|
||||||
|
xReturned = xTaskCreateStatic(
|
||||||
|
prvStaticallyAllocatedTask, /* Function that implements the task. */
|
||||||
|
"Static", /* Human readable name for the task. */
|
||||||
|
configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
|
||||||
|
NULL, /* Parameter to pass into the task. */
|
||||||
|
staticTASK_PRIORITY - 1, /* The priority of the task. */
|
||||||
|
&xCreatedTask, /* Handle of the task being created. */
|
||||||
|
&( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
|
||||||
|
NULL ); /* This time dynamically allocate the TCB. */
|
||||||
|
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
( void ) xReturned; /* In case configASSERT() is not defined. */
|
||||||
|
vTaskDelete( xCreatedTask );
|
||||||
|
|
||||||
|
/* Ensure lower priority tasks get CPU time. */
|
||||||
|
vTaskDelay( prvGetNextDelayTime() );
|
||||||
|
|
||||||
|
xReturned = xTaskCreateStatic(
|
||||||
|
prvStaticallyAllocatedTask, /* Function that implements the task. */
|
||||||
|
"Static", /* Human readable name for the task. */
|
||||||
|
configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
|
||||||
|
NULL, /* Parameter to pass into the task. */
|
||||||
|
staticTASK_PRIORITY, /* The priority of the task. */
|
||||||
|
&xCreatedTask, /* Handle of the task being created. */
|
||||||
|
NULL, /* This time dynamically allocate the stack and TCB. */
|
||||||
|
NULL ); /* This time dynamically allocate the stack and TCB. */
|
||||||
|
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
( void ) xReturned; /* In case configASSERT() is not defined. */
|
||||||
|
vTaskDelete( xCreatedTask );
|
||||||
|
|
||||||
|
/* Ensure lower priority tasks get CPU time. */
|
||||||
|
vTaskDelay( prvGetNextDelayTime() );
|
||||||
|
|
||||||
|
/* Just to show the check task that this task is still executing. */
|
||||||
|
uxCycleCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvStaticallyAllocatedTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* The created task doesn't do anything - just waits to get deleted. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static UBaseType_t prvRand( void )
|
||||||
|
{
|
||||||
|
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
|
||||||
|
|
||||||
|
/* Utility function to generate a pseudo random number. */
|
||||||
|
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
|
||||||
|
return( ( ulNextRand >> 16UL ) & 0x7fffUL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static TickType_t prvGetNextDelayTime( void )
|
||||||
|
{
|
||||||
|
TickType_t xNextDelay;
|
||||||
|
const TickType_t xMaxDelay = pdMS_TO_TICKS( ( TickType_t ) 150 );
|
||||||
|
const TickType_t xMinDelay = pdMS_TO_TICKS( ( TickType_t ) 75 );
|
||||||
|
const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 );
|
||||||
|
|
||||||
|
/* Generate the next delay time. This is kept within a narrow band so as
|
||||||
|
not to disturb the timing of other tests - but does add in some pseudo
|
||||||
|
randomisation into the tests. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
xNextDelay = prvRand() % xMaxDelay;
|
||||||
|
|
||||||
|
/* Just in case this loop is executed lots of times. */
|
||||||
|
vTaskDelay( xTinyDelay );
|
||||||
|
|
||||||
|
} while ( xNextDelay < xMinDelay );
|
||||||
|
|
||||||
|
return xNextDelay;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xAreStaticAllocationTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static UBaseType_t uxLastCycleCounter = 0;
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
if( uxCycleCounter == uxLastCycleCounter )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdPASS;
|
||||||
|
uxLastCycleCounter = uxCycleCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
|
@ -425,6 +425,7 @@ static void prvNotifiedTask( void *pvParameters )
|
||||||
{
|
{
|
||||||
const TickType_t xMaxPeriod = pdMS_TO_TICKS( 90 ), xMinPeriod = pdMS_TO_TICKS( 10 ), xDontBlock = 0;
|
const TickType_t xMaxPeriod = pdMS_TO_TICKS( 90 ), xMinPeriod = pdMS_TO_TICKS( 10 ), xDontBlock = 0;
|
||||||
TickType_t xPeriod;
|
TickType_t xPeriod;
|
||||||
|
const uint32_t ulCyclesToRaisePriority = 50UL;
|
||||||
|
|
||||||
/* Remove compiler warnings about unused parameters. */
|
/* Remove compiler warnings about unused parameters. */
|
||||||
( void ) pvParameters;
|
( void ) pvParameters;
|
||||||
|
@ -482,9 +483,28 @@ TickType_t xPeriod;
|
||||||
the function call. */
|
the function call. */
|
||||||
ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, xPeriod );
|
ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, xPeriod );
|
||||||
|
|
||||||
/* Wait for the next notification again, clearing all notifications if
|
/* Occasionally raise the priority of the task being notified to test
|
||||||
one is received, but this time blocking indefinitely. */
|
the path where the task is notified from an ISR and becomes the highest
|
||||||
ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
|
priority ready state task, but the pxHigherPriorityTaskWoken parameter
|
||||||
|
is NULL (which it is in the tick hook that sends notifications to this
|
||||||
|
task. */
|
||||||
|
if( ( ulNotifyCycleCount % ulCyclesToRaisePriority ) == 0 )
|
||||||
|
{
|
||||||
|
vTaskPrioritySet( xTaskToNotify, configMAX_PRIORITIES - 1 );
|
||||||
|
|
||||||
|
/* Wait for the next notification again, clearing all notifications if
|
||||||
|
one is received, but this time blocking indefinitely. */
|
||||||
|
ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
|
||||||
|
|
||||||
|
/* Reset the priority. */
|
||||||
|
vTaskPrioritySet( xTaskToNotify, notifyTASK_PRIORITY );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Wait for the next notification again, clearing all notifications if
|
||||||
|
one is received, but this time blocking indefinitely. */
|
||||||
|
ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
|
||||||
|
}
|
||||||
|
|
||||||
/* Incremented to show the task is still running. */
|
/* Incremented to show the task is still running. */
|
||||||
ulNotifyCycleCount++;
|
ulNotifyCycleCount++;
|
||||||
|
|
|
@ -114,9 +114,11 @@ task can tell if any of the suicidal tasks have failed to die.
|
||||||
*/
|
*/
|
||||||
static volatile UBaseType_t uxTasksRunningAtStart = 0;
|
static volatile UBaseType_t uxTasksRunningAtStart = 0;
|
||||||
|
|
||||||
/* Tasks are deleted by the idle task. Under heavy load the idle task might
|
/* When a task deletes itself, it stack and TCB are cleaned up by the Idle task.
|
||||||
not get much processing time, so it would be legitimate for several tasks to
|
Under heavy load the idle task might not get much processing time, so it would
|
||||||
remain undeleted for a short period. */
|
be legitimate for several tasks to remain undeleted for a short period. There
|
||||||
|
may also be a few other unexpected tasks if, for example, the tasks that test
|
||||||
|
static allocation are also being used. */
|
||||||
static const UBaseType_t uxMaxNumberOfExtraTasksRunning = 3;
|
static const UBaseType_t uxMaxNumberOfExtraTasksRunning = 3;
|
||||||
|
|
||||||
/* Used to store a handle to the task that should be killed by a suicidal task,
|
/* Used to store a handle to the task that should be killed by a suicidal task,
|
||||||
|
@ -151,7 +153,9 @@ UBaseType_t *puxPriority;
|
||||||
If this is done, then uxTasksRunningAtStart needs incrementing again as that
|
If this is done, then uxTasksRunningAtStart needs incrementing again as that
|
||||||
too is created when the scheduler is started. */
|
too is created when the scheduler is started. */
|
||||||
#if configUSE_TIMERS == 1
|
#if configUSE_TIMERS == 1
|
||||||
|
{
|
||||||
uxTasksRunningAtStart++;
|
uxTasksRunningAtStart++;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -125,7 +125,7 @@ be overridden by a definition in FreeRTOSConfig.h. */
|
||||||
/* Misc. */
|
/* Misc. */
|
||||||
#define recmuSHORT_DELAY ( pdMS_TO_TICKS( 20 ) )
|
#define recmuSHORT_DELAY ( pdMS_TO_TICKS( 20 ) )
|
||||||
#define recmuNO_DELAY ( ( TickType_t ) 0 )
|
#define recmuNO_DELAY ( ( TickType_t ) 0 )
|
||||||
#define recmuEIGHT_TICK_DELAY ( ( TickType_t ) 8 )
|
#define recmu15ms_DELAY ( pdMS_TO_TICKS( 15 ) )
|
||||||
|
|
||||||
/* The three tasks as described at the top of this file. */
|
/* The three tasks as described at the top of this file. */
|
||||||
static void prvRecursiveMutexControllingTask( void *pvParameters );
|
static void prvRecursiveMutexControllingTask( void *pvParameters );
|
||||||
|
@ -199,7 +199,7 @@ UBaseType_t ux;
|
||||||
long enough to ensure the polling task will execute again before the
|
long enough to ensure the polling task will execute again before the
|
||||||
block time expires. If the block time does expire then the error
|
block time expires. If the block time does expire then the error
|
||||||
flag will be set here. */
|
flag will be set here. */
|
||||||
if( xSemaphoreTakeRecursive( xMutex, recmuEIGHT_TICK_DELAY ) != pdPASS )
|
if( xSemaphoreTakeRecursive( xMutex, recmu15ms_DELAY ) != pdPASS )
|
||||||
{
|
{
|
||||||
xErrorOccurred = pdTRUE;
|
xErrorOccurred = pdTRUE;
|
||||||
}
|
}
|
||||||
|
|
79
FreeRTOS/Demo/Common/include/StaticAllocation.h
Normal file
79
FreeRTOS/Demo/Common/include/StaticAllocation.h
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STATIC_ALLOCATION_H
|
||||||
|
#define STATIC_ALLOCATION_H
|
||||||
|
|
||||||
|
void vStartStaticallyAllocatedTasks( void );
|
||||||
|
BaseType_t xAreStaticAllocationTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif /* STATIC_ALLOCATION_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,8 @@
|
||||||
* application requirements.
|
* application requirements.
|
||||||
*
|
*
|
||||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
|
||||||
|
* http://www.freertos.org/a00110.html
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
|
@ -102,6 +103,7 @@
|
||||||
#define configUSE_ALTERNATIVE_API 1
|
#define configUSE_ALTERNATIVE_API 1
|
||||||
#define configUSE_QUEUE_SETS 1
|
#define configUSE_QUEUE_SETS 1
|
||||||
#define configUSE_TASK_NOTIFICATIONS 1
|
#define configUSE_TASK_NOTIFICATIONS 1
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||||
|
|
||||||
/* Software timer related configuration options. */
|
/* Software timer related configuration options. */
|
||||||
#define configUSE_TIMERS 1
|
#define configUSE_TIMERS 1
|
||||||
|
|
|
@ -151,6 +151,7 @@
|
||||||
<ClCompile Include="..\Common\Minimal\QueueSetPolling.c" />
|
<ClCompile Include="..\Common\Minimal\QueueSetPolling.c" />
|
||||||
<ClCompile Include="..\Common\Minimal\recmutex.c" />
|
<ClCompile Include="..\Common\Minimal\recmutex.c" />
|
||||||
<ClCompile Include="..\Common\Minimal\semtest.c" />
|
<ClCompile Include="..\Common\Minimal\semtest.c" />
|
||||||
|
<ClCompile Include="..\Common\Minimal\StaticAllocation.c" />
|
||||||
<ClCompile Include="..\Common\Minimal\TaskNotify.c" />
|
<ClCompile Include="..\Common\Minimal\TaskNotify.c" />
|
||||||
<ClCompile Include="..\Common\Minimal\timerdemo.c" />
|
<ClCompile Include="..\Common\Minimal\timerdemo.c" />
|
||||||
<ClCompile Include="main.c">
|
<ClCompile Include="main.c">
|
||||||
|
|
|
@ -19,9 +19,6 @@
|
||||||
<UniqueIdentifier>{34567deb-d5ab-4a56-8640-0aaec609521a}</UniqueIdentifier>
|
<UniqueIdentifier>{34567deb-d5ab-4a56-8640-0aaec609521a}</UniqueIdentifier>
|
||||||
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
|
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Demo App Source\Common Demo Tasks">
|
|
||||||
<UniqueIdentifier>{2d4a700c-06e3-4dd2-afbe-ab1be71ebe2a}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="FreeRTOS Source\Source\Portable">
|
<Filter Include="FreeRTOS Source\Source\Portable">
|
||||||
<UniqueIdentifier>{88f409e6-d396-4ac5-94bd-7a99c914be46}</UniqueIdentifier>
|
<UniqueIdentifier>{88f409e6-d396-4ac5-94bd-7a99c914be46}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
@ -32,6 +29,15 @@
|
||||||
<Filter Include="Demo App Source\FreeRTOS+Trace Recorder">
|
<Filter Include="Demo App Source\FreeRTOS+Trace Recorder">
|
||||||
<UniqueIdentifier>{90b56567-bab6-4d92-b319-b514d378329d}</UniqueIdentifier>
|
<UniqueIdentifier>{90b56567-bab6-4d92-b319-b514d378329d}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Demo App Source\Full_Demo">
|
||||||
|
<UniqueIdentifier>{4ae1665e-a7bb-4c1a-81a3-531d883e6f2d}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Demo App Source\Full_Demo\Common Demo Tasks">
|
||||||
|
<UniqueIdentifier>{2d4a700c-06e3-4dd2-afbe-ab1be71ebe2a}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Demo App Source\Blinky_Demo">
|
||||||
|
<UniqueIdentifier>{fb86fa48-ac27-4f87-9215-ce9e1a1a85f9}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="main.c">
|
<ClCompile Include="main.c">
|
||||||
|
@ -50,46 +56,46 @@
|
||||||
<Filter>FreeRTOS Source\Source\Portable</Filter>
|
<Filter>FreeRTOS Source\Source\Portable</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\flop.c">
|
<ClCompile Include="..\Common\Minimal\flop.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\GenQTest.c">
|
<ClCompile Include="..\Common\Minimal\GenQTest.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\integer.c">
|
<ClCompile Include="..\Common\Minimal\integer.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\PollQ.c">
|
<ClCompile Include="..\Common\Minimal\PollQ.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\QPeek.c">
|
<ClCompile Include="..\Common\Minimal\QPeek.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\semtest.c">
|
<ClCompile Include="..\Common\Minimal\semtest.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\BlockQ.c">
|
<ClCompile Include="..\Common\Minimal\BlockQ.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\blocktim.c">
|
<ClCompile Include="..\Common\Minimal\blocktim.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\Source\timers.c">
|
<ClCompile Include="..\..\Source\timers.c">
|
||||||
<Filter>FreeRTOS Source\Source</Filter>
|
<Filter>FreeRTOS Source\Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\timerdemo.c">
|
<ClCompile Include="..\Common\Minimal\timerdemo.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\countsem.c">
|
<ClCompile Include="..\Common\Minimal\countsem.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\death.c">
|
<ClCompile Include="..\Common\Minimal\death.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\dynamic.c">
|
<ClCompile Include="..\Common\Minimal\dynamic.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\QueueSet.c">
|
<ClCompile Include="..\Common\Minimal\QueueSet.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Run-time-stats-utils.c">
|
<ClCompile Include="Run-time-stats-utils.c">
|
||||||
<Filter>Demo App Source</Filter>
|
<Filter>Demo App Source</Filter>
|
||||||
|
@ -113,16 +119,10 @@
|
||||||
<Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
|
<Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\QueueOverwrite.c">
|
<ClCompile Include="..\Common\Minimal\QueueOverwrite.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="main_full.c">
|
|
||||||
<Filter>Demo App Source</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="main_blinky.c">
|
|
||||||
<Filter>Demo App Source</Filter>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\EventGroupsDemo.c">
|
<ClCompile Include="..\Common\Minimal\EventGroupsDemo.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\Source\event_groups.c">
|
<ClCompile Include="..\..\Source\event_groups.c">
|
||||||
<Filter>FreeRTOS Source\Source</Filter>
|
<Filter>FreeRTOS Source\Source</Filter>
|
||||||
|
@ -131,16 +131,25 @@
|
||||||
<Filter>FreeRTOS Source\Source\Portable</Filter>
|
<Filter>FreeRTOS Source\Source\Portable</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\IntSemTest.c">
|
<ClCompile Include="..\Common\Minimal\IntSemTest.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\TaskNotify.c">
|
<ClCompile Include="..\Common\Minimal\TaskNotify.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\QueueSetPolling.c">
|
<ClCompile Include="..\Common\Minimal\QueueSetPolling.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\Common\Minimal\recmutex.c">
|
<ClCompile Include="..\Common\Minimal\recmutex.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="main_full.c">
|
||||||
|
<Filter>Demo App Source\Full_Demo</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="main_blinky.c">
|
||||||
|
<Filter>Demo App Source\Blinky_Demo</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\Common\Minimal\StaticAllocation.c">
|
||||||
|
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -154,6 +154,8 @@ void vApplicationMallocFailedHook( void );
|
||||||
void vApplicationIdleHook( void );
|
void vApplicationIdleHook( void );
|
||||||
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
|
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
|
||||||
void vApplicationTickHook( void );
|
void vApplicationTickHook( void );
|
||||||
|
void vApplicationGetIdleTaskMemory( DummyTCB_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize );
|
||||||
|
void vApplicationGetTimerTaskMemory( DummyTCB_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Writes trace data to a disk file when the trace recording is stopped.
|
* Writes trace data to a disk file when the trace recording is stopped.
|
||||||
|
@ -390,3 +392,37 @@ const HeapRegion_t xHeapRegions[] =
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationGetIdleTaskMemory( DummyTCB_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
|
||||||
|
{
|
||||||
|
/* The buffers used by the idle task must be static so they are persistent, and
|
||||||
|
so exist after this function returns. */
|
||||||
|
static DummyTCB_t xIdleTaskTCB;
|
||||||
|
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||||
|
|
||||||
|
/* configUSE_STATIC_ALLOCATION is set to 1, so the application has the
|
||||||
|
opportunity to supply the buffers that will be used by the Idle task as its
|
||||||
|
stack and to hold its TCB. If these are set to NULL then the buffers will
|
||||||
|
be allocated dynamically, just as if xTaskCreate() had been called. */
|
||||||
|
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
|
||||||
|
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
||||||
|
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
DummyTCB_t xTimerTaskTCB;
|
||||||
|
void vApplicationGetTimerTaskMemory( DummyTCB_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
|
||||||
|
{
|
||||||
|
/* The buffers used by the Timer/Daemon task must be static so they are
|
||||||
|
persistent, and so exist after this function returns. */
|
||||||
|
//static DummyTCB_t xTimerTaskTCB;
|
||||||
|
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
|
||||||
|
|
||||||
|
/* configUSE_STATIC_ALLOCATION is set to 1, so the application has the
|
||||||
|
opportunity to supply the buffers that will be used by the Timer/RTOS daemon
|
||||||
|
task as its stack and to hold its TCB. If these are set to NULL then the
|
||||||
|
buffers will be allocated dynamically, just as if xTaskCreate() had been
|
||||||
|
called. */
|
||||||
|
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
|
||||||
|
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
|
||||||
|
*pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@
|
||||||
* to ensure it gets processor time. Its main function is to check that all the
|
* to ensure it gets processor time. Its main function is to check that all the
|
||||||
* standard demo tasks are still operational. While no errors have been
|
* standard demo tasks are still operational. While no errors have been
|
||||||
* discovered the check task will print out "No Errors" along with some system
|
* discovered the check task will print out "No Errors" along with some system
|
||||||
* status information. If an error is discovered in the execution of a task
|
* status information. If an error is discovered in the execution of a task
|
||||||
* then the check task will print out an appropriate error message.
|
* then the check task will print out an appropriate error message.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -135,6 +135,7 @@
|
||||||
#include "IntSemTest.h"
|
#include "IntSemTest.h"
|
||||||
#include "TaskNotify.h"
|
#include "TaskNotify.h"
|
||||||
#include "QueueSetPolling.h"
|
#include "QueueSetPolling.h"
|
||||||
|
#include "StaticAllocation.h"
|
||||||
|
|
||||||
/* Priorities at which the tasks are created. */
|
/* Priorities at which the tasks are created. */
|
||||||
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
|
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
|
||||||
|
@ -214,6 +215,7 @@ int main_full( void )
|
||||||
vStartInterruptSemaphoreTasks();
|
vStartInterruptSemaphoreTasks();
|
||||||
vStartQueueSetPollingTask();
|
vStartQueueSetPollingTask();
|
||||||
xTaskCreate( prvDemoQueueSpaceFunctions, "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
xTaskCreate( prvDemoQueueSpaceFunctions, "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
|
vStartStaticallyAllocatedTasks();
|
||||||
|
|
||||||
#if( configUSE_PREEMPTION != 0 )
|
#if( configUSE_PREEMPTION != 0 )
|
||||||
{
|
{
|
||||||
|
@ -337,6 +339,10 @@ const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL );
|
||||||
{
|
{
|
||||||
pcStatusMessage = "Error: Queue set polling";
|
pcStatusMessage = "Error: Queue set polling";
|
||||||
}
|
}
|
||||||
|
else if( xAreStaticAllocationTasksStillRunning() != pdPASS )
|
||||||
|
{
|
||||||
|
pcStatusMessage = "Error: Static allocation";
|
||||||
|
}
|
||||||
|
|
||||||
/* This is the only task that uses stdout so its ok to call printf()
|
/* This is the only task that uses stdout so its ok to call printf()
|
||||||
directly. */
|
directly. */
|
||||||
|
|
|
@ -681,7 +681,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef pvPortMallocAligned
|
#ifndef pvPortMallocAligned
|
||||||
#define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxStackBuffer ) )
|
#define pvPortMallocAligned( x, puxPreallocatedBuffer ) ( ( ( puxPreallocatedBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxPreallocatedBuffer ) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef vPortFreeAligned
|
#ifndef vPortFreeAligned
|
||||||
|
@ -772,6 +772,10 @@ extern "C" {
|
||||||
#define portTICK_TYPE_IS_ATOMIC 0
|
#define portTICK_TYPE_IS_ATOMIC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef configSUPPORT_STATIC_ALLOCATION
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if( portTICK_TYPE_IS_ATOMIC == 0 )
|
#if( portTICK_TYPE_IS_ATOMIC == 0 )
|
||||||
/* Either variables of tick type cannot be read atomically, or
|
/* Either variables of tick type cannot be read atomically, or
|
||||||
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
|
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
|
||||||
|
|
|
@ -128,6 +128,12 @@ typedef enum
|
||||||
eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */
|
eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */
|
||||||
} eNotifyAction;
|
} eNotifyAction;
|
||||||
|
|
||||||
|
/* For data hiding purposes. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
eNothing = 0
|
||||||
|
} eDummy;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used internally only.
|
* Used internally only.
|
||||||
*/
|
*/
|
||||||
|
@ -183,6 +189,65 @@ typedef enum
|
||||||
eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */
|
eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */
|
||||||
} eSleepModeStatus;
|
} eSleepModeStatus;
|
||||||
|
|
||||||
|
/* Value that can be assigned to the eNotifyState member of the TCB. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
eNotWaitingNotification = 0,
|
||||||
|
eWaitingNotification,
|
||||||
|
eNotified
|
||||||
|
} eNotifyValue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FreeRTOS implements a strict data hiding policy, so the real task control
|
||||||
|
* block (TCB) structure is not accessible to the application code. However, if
|
||||||
|
* the application writer wants to statically allocate a TCB then the size of
|
||||||
|
* the TCB needs to be know. The dummy TCB structure below is used for this
|
||||||
|
* purpose. Its size will allows match the size of the real TCB, no matter what
|
||||||
|
* the FreeRTOSConfig.h settings.
|
||||||
|
*/
|
||||||
|
typedef struct xDUMMY_TCB
|
||||||
|
{
|
||||||
|
void *pxDummy1;
|
||||||
|
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||||
|
xMPU_SETTINGS xDummy2;
|
||||||
|
#endif
|
||||||
|
ListItem_t xDummy3[ 2 ];
|
||||||
|
UBaseType_t uxDummy5;
|
||||||
|
void *pxDummy6;
|
||||||
|
uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
|
||||||
|
#if ( portSTACK_GROWTH > 0 )
|
||||||
|
void *pxDummy8;
|
||||||
|
#endif
|
||||||
|
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
|
||||||
|
UBaseType_t uxDummy9;
|
||||||
|
#endif
|
||||||
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
UBaseType_t uxDummy10[ 2 ];
|
||||||
|
#endif
|
||||||
|
#if ( configUSE_MUTEXES == 1 )
|
||||||
|
UBaseType_t uxDummy12[ 2 ];
|
||||||
|
#endif
|
||||||
|
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
|
||||||
|
void *pxDummy14;
|
||||||
|
#endif
|
||||||
|
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
|
||||||
|
void pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
|
||||||
|
#endif
|
||||||
|
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||||
|
uint32_t ulDummy16;
|
||||||
|
#endif
|
||||||
|
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
||||||
|
struct _reent xDummy17;
|
||||||
|
#endif
|
||||||
|
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||||
|
uint32_t ulDummy18;
|
||||||
|
eDummy eDummy19;
|
||||||
|
#endif
|
||||||
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
UBaseType_t uxDummy20;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} DummyTCB_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the priority used by the idle task. This must not be modified.
|
* Defines the priority used by the idle task. This must not be modified.
|
||||||
|
@ -342,7 +407,112 @@ is used in assert() statements. */
|
||||||
* \defgroup xTaskCreate xTaskCreate
|
* \defgroup xTaskCreate xTaskCreate
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) )
|
#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ), ( NULL ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task. h
|
||||||
|
*<pre>
|
||||||
|
BaseType_t xTaskCreateStatic(
|
||||||
|
TaskFunction_t pvTaskCode,
|
||||||
|
const char * const pcName,
|
||||||
|
uint16_t usStackDepth,
|
||||||
|
void *pvParameters,
|
||||||
|
UBaseType_t uxPriority,
|
||||||
|
TaskHandle_t *pvCreatedTask,
|
||||||
|
StackType_t *pxStackBuffer,
|
||||||
|
DummyTCB_t *pxTCBBuffer
|
||||||
|
);</pre>
|
||||||
|
*
|
||||||
|
* Create a new task and add it to the list of tasks that are ready to run.
|
||||||
|
* If a task is created using xTaskCreate() then the stack and task control
|
||||||
|
* block (TCB) used by the task are allocated dynamically. If a task is created
|
||||||
|
* using xTaskCreateStatic() then the application writer can optionally provide
|
||||||
|
* the buffers that will hold the task stack and TCB respectively.
|
||||||
|
* xTaskCreateStatic() therefore allows tasks to be created without any dynamic
|
||||||
|
* memory allocation.
|
||||||
|
*
|
||||||
|
* @param pvTaskCode Pointer to the task entry function. Tasks
|
||||||
|
* must be implemented to never return (i.e. continuous loop).
|
||||||
|
*
|
||||||
|
* @param pcName A descriptive name for the task. This is mainly used to
|
||||||
|
* facilitate debugging. The maximum length of the string is defined by
|
||||||
|
* configMAX_TASK_NAME_LEN in FreeRTOSConfig.h.
|
||||||
|
*
|
||||||
|
* @param usStackDepth The size of the task stack specified as the number of
|
||||||
|
* variables the stack can hold - not the number of bytes. For example, if
|
||||||
|
* the stack is 32-bits wide and usStackDepth is defined as 100 then 400 bytes
|
||||||
|
* will be allocated for stack storage.
|
||||||
|
*
|
||||||
|
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||||
|
* being created.
|
||||||
|
*
|
||||||
|
* @param uxPriority The priority at which the task will run.
|
||||||
|
*
|
||||||
|
* @param pvCreatedTask Used to pass back a handle by which the created task
|
||||||
|
* can be referenced. Pass as NULL if the handle is not required.
|
||||||
|
*
|
||||||
|
* @param pxStackBuffer If pxStackBuffer is NULL then the stack used by the
|
||||||
|
* task will be allocated dynamically, just as if the task was created using
|
||||||
|
* xTaskCreate(). if pxStackBuffer is not NULL then it must point to a
|
||||||
|
* StackType_t array that has at least usStackDepth indexes - the array will
|
||||||
|
* then be used as the task's stack.
|
||||||
|
*
|
||||||
|
* @param pxTCBBuffer If pxTCBBuffer is NULL then the TCB (which is the
|
||||||
|
* structures used internally within FreeRTOS to hold information on the task)
|
||||||
|
* will be allocated dynamically, just as when xTaskCreate() is used. If
|
||||||
|
* pxTCBBuffer is not NULL then it must point to a variable of type DummyTCB_T,
|
||||||
|
* which will then be used as the TCB of the task being created.
|
||||||
|
*
|
||||||
|
* @return pdPASS if the task was successfully created and added to a ready
|
||||||
|
* list, otherwise an error code defined in the file projdefs.h
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
|
||||||
|
// Dimensions the buffer that the task being created will use as its stack.
|
||||||
|
// NOTE: This is the number of words the stack will hold, not the number of
|
||||||
|
// bytes. For example, if each stack item is 32-bits, and this is set to 100,
|
||||||
|
// then 400 bytes (100 * 32-bits) will be allocated.
|
||||||
|
#define STACK_SIZE 200
|
||||||
|
|
||||||
|
// Structure that will hold the TCB of the task being created.
|
||||||
|
DummyTCB_t xTCB;
|
||||||
|
|
||||||
|
// Buffer that the task being created will use as its stack.
|
||||||
|
StackType_t xStack[ STACK_SIZE ];
|
||||||
|
|
||||||
|
// Task to be created.
|
||||||
|
void vTaskCode( void * pvParameters )
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Task code goes here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function that creates a task.
|
||||||
|
void vOtherFunction( void )
|
||||||
|
{
|
||||||
|
static uint8_t ucParameterToPass;
|
||||||
|
TaskHandle_t xHandle = NULL;
|
||||||
|
|
||||||
|
// Create the task without using any dynamic memory allocation.
|
||||||
|
xTaskCreate( vTaskCode, // As per xTaskCreate() parameter.
|
||||||
|
"NAME", // As per xTaskCreate() parameter.
|
||||||
|
STACK_SIZE, // As per xTaskCreate() parameter.
|
||||||
|
&ucParameterToPass, // As per xTaskCreate() parameter.
|
||||||
|
tskIDLE_PRIORITY, // As per xTaskCreate() parameter.
|
||||||
|
&xHandle, // As per xTaskCreate() parameter.
|
||||||
|
xStack, // Pointer to the buffer that the task being created will use as its stack.
|
||||||
|
&xTCB ); // Pointer to a structure in which the TCB of the task being created will be stored.
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xTaskCreateStatic xTaskCreateStatic
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
#define xTaskCreateStatic( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, puxStackBuffer, pxDummyTCB ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( puxStackBuffer ), ( pxDummyTCB ), ( NULL ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* task. h
|
* task. h
|
||||||
|
@ -411,7 +581,7 @@ TaskHandle_t xHandle;
|
||||||
* \defgroup xTaskCreateRestricted xTaskCreateRestricted
|
* \defgroup xTaskCreateRestricted xTaskCreateRestricted
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) )
|
#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ( NULL ), ((x)->xRegions) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* task. h
|
* task. h
|
||||||
|
@ -1983,7 +2153,7 @@ BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGE
|
||||||
* Generic version of the task creation function which is in turn called by the
|
* Generic version of the task creation function which is in turn called by the
|
||||||
* xTaskCreate() and xTaskCreateRestricted() macros.
|
* xTaskCreate() and xTaskCreateRestricted() macros.
|
||||||
*/
|
*/
|
||||||
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, DummyTCB_t * const pxTCBBuffer, const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the uxTCBNumber assigned to the task referenced by the xTask parameter.
|
* Get the uxTCBNumber assigned to the task referenced by the xTask parameter.
|
||||||
|
|
|
@ -1935,8 +1935,8 @@ static void prvUnlockQueue( Queue_t * const pxQueue )
|
||||||
{
|
{
|
||||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||||
{
|
{
|
||||||
/* The task waiting has a higher priority so record that a
|
/* The task waiting has a higher priority so record that
|
||||||
context switch is required. */
|
a context switch is required. */
|
||||||
vTaskMissedYield();
|
vTaskMissedYield();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -105,6 +105,10 @@ functions but without including stdio.h here. */
|
||||||
#endif /* INCLUDE_vTaskSuspend */
|
#endif /* INCLUDE_vTaskSuspend */
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION != 1 ) )
|
||||||
|
#error configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h when the MPU is used.
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defines the size, in words, of the stack allocated to the idle task.
|
* Defines the size, in words, of the stack allocated to the idle task.
|
||||||
*/
|
*/
|
||||||
|
@ -118,13 +122,12 @@ functions but without including stdio.h here. */
|
||||||
#define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
|
#define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Value that can be assigned to the eNotifyState member of the TCB. */
|
/* Bits that can be set in tskTCB->uxStaticAllocationFlags to indicate that the
|
||||||
typedef enum
|
stack and TCB were statically allocated respectively. When these are statically
|
||||||
{
|
allocated they won't be freed if the task using the stack and TCB gets
|
||||||
eNotWaitingNotification = 0,
|
deleted. */
|
||||||
eWaitingNotification,
|
#define taskSTATICALLY_ALLOCATED_STACK ( ( UBaseType_t ) 0x01 )
|
||||||
eNotified
|
#define taskSTATICALLY_ALLOCATED_TCB ( ( UBaseType_t ) 0x02 )
|
||||||
} eNotifyValue;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Task control block. A task control block (TCB) is allocated for each task,
|
* Task control block. A task control block (TCB) is allocated for each task,
|
||||||
|
@ -137,7 +140,6 @@ typedef struct tskTaskControlBlock
|
||||||
|
|
||||||
#if ( portUSING_MPU_WRAPPERS == 1 )
|
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||||
xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
|
xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
|
||||||
BaseType_t xUsingStaticallyAllocatedStack; /* Set to pdTRUE if the stack is a statically allocated array, and pdFALSE if the stack is dynamically allocated. */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ListItem_t xGenericListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
|
ListItem_t xGenericListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
|
||||||
|
@ -151,17 +153,17 @@ typedef struct tskTaskControlBlock
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
|
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
|
||||||
UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
|
UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */
|
UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */
|
||||||
UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */
|
UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configUSE_MUTEXES == 1 )
|
#if ( configUSE_MUTEXES == 1 )
|
||||||
UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
|
UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
|
||||||
UBaseType_t uxMutexesHeld;
|
UBaseType_t uxMutexesHeld;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
|
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
|
||||||
|
@ -184,7 +186,7 @@ typedef struct tskTaskControlBlock
|
||||||
newlib and must provide system-wide implementations of the necessary
|
newlib and must provide system-wide implementations of the necessary
|
||||||
stubs. Be warned that (at the time of writing) the current newlib design
|
stubs. Be warned that (at the time of writing) the current newlib design
|
||||||
implements a system-wide malloc() that must be provided with locks. */
|
implements a system-wide malloc() that must be provided with locks. */
|
||||||
struct _reent xNewLib_reent;
|
struct _reent xNewLib_reent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||||
|
@ -192,7 +194,11 @@ typedef struct tskTaskControlBlock
|
||||||
volatile eNotifyValue eNotifyState;
|
volatile eNotifyValue eNotifyState;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} tskTCB;
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
UBaseType_t uxStaticAllocationFlags; /* Set to pdTRUE if the stack is a statically allocated array, and pdFALSE if the stack is dynamically allocated. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} tskTCB;
|
||||||
|
|
||||||
/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
|
/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
|
||||||
below to enable the use of older kernel aware debuggers. */
|
below to enable the use of older kernel aware debuggers. */
|
||||||
|
@ -232,12 +238,6 @@ PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been r
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
|
||||||
|
|
||||||
PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Other file private variables. --------------------------------*/
|
/* Other file private variables. --------------------------------*/
|
||||||
PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U;
|
PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U;
|
||||||
PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) 0U;
|
PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) 0U;
|
||||||
|
@ -248,6 +248,7 @@ PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE;
|
||||||
PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0;
|
PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0;
|
||||||
PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U;
|
PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U;
|
||||||
PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */
|
PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */
|
||||||
|
PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */
|
||||||
|
|
||||||
/* Context switches are held pending while the scheduler is suspended. Also,
|
/* Context switches are held pending while the scheduler is suspended. Also,
|
||||||
interrupts must not manipulate the xGenericListItem of a TCB, or any of the
|
interrupts must not manipulate the xGenericListItem of a TCB, or any of the
|
||||||
|
@ -409,21 +410,25 @@ being used for another purpose. The following bit definition is used to inform
|
||||||
the scheduler that the value should not be changed - in which case it is the
|
the scheduler that the value should not be changed - in which case it is the
|
||||||
responsibility of whichever module is using the value to ensure it gets set back
|
responsibility of whichever module is using the value to ensure it gets set back
|
||||||
to its original value when it is released. */
|
to its original value when it is released. */
|
||||||
#if configUSE_16_BIT_TICKS == 1
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
#define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U
|
#define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U
|
||||||
#else
|
#else
|
||||||
#define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL
|
#define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Callback function prototypes. --------------------------*/
|
/* Callback function prototypes. --------------------------*/
|
||||||
#if configCHECK_FOR_STACK_OVERFLOW > 0
|
#if( configCHECK_FOR_STACK_OVERFLOW > 0 )
|
||||||
extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName );
|
extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_TICK_HOOK > 0
|
#if( configUSE_TICK_HOOK > 0 )
|
||||||
extern void vApplicationTickHook( void );
|
extern void vApplicationTickHook( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
extern void vApplicationGetIdleTaskMemory( DummyTCB_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize );
|
||||||
|
#endif
|
||||||
|
|
||||||
/* File private functions. --------------------------------*/
|
/* File private functions. --------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -490,7 +495,7 @@ static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake ) PRIVI
|
||||||
* Allocates memory from the heap for a TCB and associated stack. Checks the
|
* Allocates memory from the heap for a TCB and associated stack. Checks the
|
||||||
* allocation was successful.
|
* allocation was successful.
|
||||||
*/
|
*/
|
||||||
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer ) PRIVILEGED_FUNCTION;
|
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer, TCB_t * const pucTCBBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fills an TaskStatus_t structure with information on each task that is
|
* Fills an TaskStatus_t structure with information on each task that is
|
||||||
|
@ -549,7 +554,7 @@ static void prvResetNextTaskUnblockTime( void );
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, DummyTCB_t * const pxTCBBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
TCB_t * pxNewTCB;
|
TCB_t * pxNewTCB;
|
||||||
|
@ -560,7 +565,7 @@ StackType_t *pxTopOfStack;
|
||||||
|
|
||||||
/* Allocate the memory required by the TCB and stack for the new task,
|
/* Allocate the memory required by the TCB and stack for the new task,
|
||||||
checking that the allocation was successful. */
|
checking that the allocation was successful. */
|
||||||
pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );
|
pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer, ( TCB_t* ) pxTCBBuffer ); /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
|
||||||
|
|
||||||
if( pxNewTCB != NULL )
|
if( pxNewTCB != NULL )
|
||||||
{
|
{
|
||||||
|
@ -576,20 +581,6 @@ StackType_t *pxTopOfStack;
|
||||||
xRunPrivileged = pdFALSE;
|
xRunPrivileged = pdFALSE;
|
||||||
}
|
}
|
||||||
uxPriority &= ~portPRIVILEGE_BIT;
|
uxPriority &= ~portPRIVILEGE_BIT;
|
||||||
|
|
||||||
if( puxStackBuffer != NULL )
|
|
||||||
{
|
|
||||||
/* The application provided its own stack. Note this so no
|
|
||||||
attempt is made to delete the stack should that task be
|
|
||||||
deleted. */
|
|
||||||
pxNewTCB->xUsingStaticallyAllocatedStack = pdTRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The stack was allocated dynamically. Note this so it can be
|
|
||||||
deleted again if the task is deleted. */
|
|
||||||
pxNewTCB->xUsingStaticallyAllocatedStack = pdFALSE;
|
|
||||||
}
|
|
||||||
#endif /* portUSING_MPU_WRAPPERS == 1 */
|
#endif /* portUSING_MPU_WRAPPERS == 1 */
|
||||||
|
|
||||||
/* Calculate the top of stack address. This depends on whether the
|
/* Calculate the top of stack address. This depends on whether the
|
||||||
|
@ -1045,7 +1036,7 @@ StackType_t *pxTopOfStack;
|
||||||
else if( ( pxStateList == &xTasksWaitingTermination ) || ( pxStateList == NULL ) )
|
else if( ( pxStateList == &xTasksWaitingTermination ) || ( pxStateList == NULL ) )
|
||||||
{
|
{
|
||||||
/* The task being queried is referenced from the deleted
|
/* The task being queried is referenced from the deleted
|
||||||
tasks list, or it is not referenced from any lists at
|
tasks list, or it is not referenced from any lists at
|
||||||
all. */
|
all. */
|
||||||
eReturn = eDeleted;
|
eReturn = eDeleted;
|
||||||
}
|
}
|
||||||
|
@ -1555,20 +1546,18 @@ StackType_t *pxTopOfStack;
|
||||||
void vTaskStartScheduler( void )
|
void vTaskStartScheduler( void )
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
DummyTCB_t *pxIdleTaskTCBBuffer = NULL;
|
||||||
|
StackType_t *pxIdleTaskStackBuffer = NULL;
|
||||||
|
uint16_t usIdleTaskStackSize = tskIDLE_STACK_SIZE;
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &usIdleTaskStackSize );
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
/* Add the idle task at the lowest priority. */
|
/* Add the idle task at the lowest priority. */
|
||||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
xReturn = xTaskGenericCreate( prvIdleTask, "IDLE", usIdleTaskStackSize, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle, pxIdleTaskStackBuffer, pxIdleTaskTCBBuffer, NULL ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
|
||||||
{
|
|
||||||
/* Create the idle task, storing its handle in xIdleTaskHandle so it can
|
|
||||||
be returned by the xTaskGetIdleTaskHandle() function. */
|
|
||||||
xReturn = xTaskCreate( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
/* Create the idle task without storing its handle. */
|
|
||||||
xReturn = xTaskCreate( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
|
|
||||||
}
|
|
||||||
#endif /* INCLUDE_xTaskGetIdleTaskHandle */
|
|
||||||
|
|
||||||
#if ( configUSE_TIMERS == 1 )
|
#if ( configUSE_TIMERS == 1 )
|
||||||
{
|
{
|
||||||
|
@ -1628,6 +1617,10 @@ BaseType_t xReturn;
|
||||||
or the timer task. */
|
or the timer task. */
|
||||||
configASSERT( xReturn );
|
configASSERT( xReturn );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0,
|
||||||
|
meaning xIdleTaskHandle is not used anywhere else. */
|
||||||
|
( void ) xIdleTaskHandle;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -3145,10 +3138,17 @@ static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer )
|
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer, TCB_t * const pxTCBBuffer )
|
||||||
{
|
{
|
||||||
TCB_t *pxNewTCB;
|
TCB_t *pxNewTCB;
|
||||||
|
|
||||||
|
#if( configASSERT_DEFINED == 1 )
|
||||||
|
{
|
||||||
|
volatile size_t xSize = sizeof( DummyTCB_t );
|
||||||
|
configASSERT( xSize == sizeof( TCB_t ) );
|
||||||
|
}
|
||||||
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/* If the stack grows down then allocate the stack then the TCB so the stack
|
/* If the stack grows down then allocate the stack then the TCB so the stack
|
||||||
does not grow into the TCB. Likewise if the stack grows up then allocate
|
does not grow into the TCB. Likewise if the stack grows up then allocate
|
||||||
the TCB then the stack. */
|
the TCB then the stack. */
|
||||||
|
@ -3156,7 +3156,7 @@ TCB_t *pxNewTCB;
|
||||||
{
|
{
|
||||||
/* Allocate space for the TCB. Where the memory comes from depends on
|
/* Allocate space for the TCB. Where the memory comes from depends on
|
||||||
the implementation of the port malloc function. */
|
the implementation of the port malloc function. */
|
||||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
|
pxNewTCB = ( TCB_t * ) pvPortMallocAligned( sizeof( TCB_t ), pxTCBBuffer );
|
||||||
|
|
||||||
if( pxNewTCB != NULL )
|
if( pxNewTCB != NULL )
|
||||||
{
|
{
|
||||||
|
@ -3167,8 +3167,12 @@ TCB_t *pxNewTCB;
|
||||||
|
|
||||||
if( pxNewTCB->pxStack == NULL )
|
if( pxNewTCB->pxStack == NULL )
|
||||||
{
|
{
|
||||||
/* Could not allocate the stack. Delete the allocated TCB. */
|
/* Could not allocate the stack. Delete the allocated TCB - if
|
||||||
vPortFree( pxNewTCB );
|
it was allocated dynamically. */
|
||||||
|
if( pxTCBBuffer == NULL )
|
||||||
|
{
|
||||||
|
vPortFree( pxNewTCB );
|
||||||
|
}
|
||||||
pxNewTCB = NULL;
|
pxNewTCB = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3182,9 +3186,8 @@ TCB_t *pxNewTCB;
|
||||||
|
|
||||||
if( pxStack != NULL )
|
if( pxStack != NULL )
|
||||||
{
|
{
|
||||||
/* Allocate space for the TCB. Where the memory comes from depends
|
/* Allocate space for the TCB. */
|
||||||
on the implementation of the port malloc function. */
|
pxNewTCB = ( TCB_t * ) pvPortMallocAligned( sizeof( TCB_t ), pxTCBBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some paths. */
|
||||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
|
|
||||||
|
|
||||||
if( pxNewTCB != NULL )
|
if( pxNewTCB != NULL )
|
||||||
{
|
{
|
||||||
|
@ -3199,6 +3202,10 @@ TCB_t *pxNewTCB;
|
||||||
{
|
{
|
||||||
vPortFree( pxStack );
|
vPortFree( pxStack );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3217,6 +3224,34 @@ TCB_t *pxNewTCB;
|
||||||
( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( StackType_t ) );
|
( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( StackType_t ) );
|
||||||
}
|
}
|
||||||
#endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */
|
#endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
pxNewTCB->uxStaticAllocationFlags = 0;
|
||||||
|
|
||||||
|
if( puxStackBuffer != NULL )
|
||||||
|
{
|
||||||
|
/* The application provided its own stack - note the fact so no
|
||||||
|
attempt is made to delete the stack if the task is deleted. */
|
||||||
|
pxNewTCB->uxStaticAllocationFlags |= taskSTATICALLY_ALLOCATED_STACK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pxTCBBuffer != NULL )
|
||||||
|
{
|
||||||
|
/* The application provided its own TCB. Note the fact so no
|
||||||
|
attempt is made to delete the TCB if the task is deleted. */
|
||||||
|
pxNewTCB->uxStaticAllocationFlags |= taskSTATICALLY_ALLOCATED_TCB;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
}
|
}
|
||||||
|
|
||||||
return pxNewTCB;
|
return pxNewTCB;
|
||||||
|
@ -3373,22 +3408,34 @@ TCB_t *pxNewTCB;
|
||||||
}
|
}
|
||||||
#endif /* configUSE_NEWLIB_REENTRANT */
|
#endif /* configUSE_NEWLIB_REENTRANT */
|
||||||
|
|
||||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
{
|
{
|
||||||
/* Only free the stack if it was allocated dynamically in the first
|
/* Only free the stack and TCB if they were allocated dynamically in
|
||||||
place. */
|
the first place. */
|
||||||
if( pxTCB->xUsingStaticallyAllocatedStack == pdFALSE )
|
if( ( pxTCB->uxStaticAllocationFlags & taskSTATICALLY_ALLOCATED_STACK ) == ( UBaseType_t ) 0 )
|
||||||
{
|
{
|
||||||
vPortFreeAligned( pxTCB->pxStack );
|
vPortFreeAligned( pxTCB->pxStack );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( pxTCB->uxStaticAllocationFlags & taskSTATICALLY_ALLOCATED_TCB ) == ( UBaseType_t ) 0 )
|
||||||
|
{
|
||||||
|
vPortFreeAligned( pxTCB );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
vPortFreeAligned( pxTCB->pxStack );
|
vPortFreeAligned( pxTCB->pxStack );
|
||||||
|
vPortFree( pxTCB );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vPortFree( pxTCB );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* INCLUDE_vTaskDelete */
|
#endif /* INCLUDE_vTaskDelete */
|
||||||
|
@ -4392,6 +4439,13 @@ TickType_t uxReturn;
|
||||||
{
|
{
|
||||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Mark that a yield is pending in case the user is not
|
||||||
|
using the "xHigherPriorityTaskWoken" parameter to an ISR
|
||||||
|
safe FreeRTOS function. */
|
||||||
|
xYieldPending = pdTRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4475,6 +4529,13 @@ TickType_t uxReturn;
|
||||||
{
|
{
|
||||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Mark that a yield is pending in case the user is not
|
||||||
|
using the "xHigherPriorityTaskWoken" parameter in an ISR
|
||||||
|
safe FreeRTOS function. */
|
||||||
|
xYieldPending = pdTRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4496,11 +4557,9 @@ TickType_t uxReturn;
|
||||||
TCB_t *pxTCB;
|
TCB_t *pxTCB;
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
pxTCB = ( TCB_t * ) xTask;
|
|
||||||
|
|
||||||
/* If null is passed in here then it is the calling task that is having
|
/* If null is passed in here then it is the calling task that is having
|
||||||
its notification state cleared. */
|
its notification state cleared. */
|
||||||
pxTCB = prvGetTCBFromHandle( pxTCB );
|
pxTCB = prvGetTCBFromHandle( xTask );
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
@ -4520,6 +4579,8 @@ TickType_t uxReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_TASK_NOTIFICATIONS */
|
#endif /* configUSE_TASK_NOTIFICATIONS */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef FREERTOS_MODULE_TEST
|
#ifdef FREERTOS_MODULE_TEST
|
||||||
#include "tasks_test_access_functions.h"
|
#include "tasks_test_access_functions.h"
|
||||||
|
|
|
@ -178,6 +178,16 @@ PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
|
/* If static allocation is supported then the application must provide the
|
||||||
|
following callback function - which enables the application to optionally
|
||||||
|
provide the memory that will be used by the timer task as the task's stack
|
||||||
|
and TCB. */
|
||||||
|
extern void vApplicationGetTimerTaskMemory( DummyTCB_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialise the infrastructure used by the timer service task if it has not
|
* Initialise the infrastructure used by the timer service task if it has not
|
||||||
* been initialised already.
|
* been initialised already.
|
||||||
|
@ -240,6 +250,10 @@ static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseTy
|
||||||
BaseType_t xTimerCreateTimerTask( void )
|
BaseType_t xTimerCreateTimerTask( void )
|
||||||
{
|
{
|
||||||
BaseType_t xReturn = pdFAIL;
|
BaseType_t xReturn = pdFAIL;
|
||||||
|
DummyTCB_t *pxTimerTaskTCBBuffer = NULL;
|
||||||
|
StackType_t *pxTimerTaskStackBuffer = NULL;
|
||||||
|
uint16_t usTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||||
|
|
||||||
|
|
||||||
/* This function is called when the scheduler is started if
|
/* This function is called when the scheduler is started if
|
||||||
configUSE_TIMERS is set to 1. Check that the infrastructure used by the
|
configUSE_TIMERS is set to 1. Check that the infrastructure used by the
|
||||||
|
@ -249,16 +263,24 @@ BaseType_t xReturn = pdFAIL;
|
||||||
|
|
||||||
if( xTimerQueue != NULL )
|
if( xTimerQueue != NULL )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &usTimerTaskStackSize );
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
|
||||||
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
|
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
|
||||||
{
|
{
|
||||||
/* Create the timer task, storing its handle in xTimerTaskHandle so
|
/* Create the timer task, storing its handle in xTimerTaskHandle so
|
||||||
it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */
|
it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */
|
||||||
xReturn = xTaskCreate( prvTimerTask, "Tmr Svc", ( uint16_t ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );
|
xReturn = xTaskGenericCreate( prvTimerTask, "Tmr Svc", usTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle, pxTimerTaskStackBuffer, pxTimerTaskTCBBuffer, NULL );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
/* Create the timer task without storing its handle. */
|
/* Create the timer task without storing its handle. */
|
||||||
xReturn = xTaskCreate( prvTimerTask, "Tmr Svc", ( uint16_t ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL);
|
xReturn = xTaskGenericCreate( prvTimerTask, "Tmr Svc", usTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL, pxTimerTaskStackBuffer, pxTimerTaskTCBBuffer, NULL );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue