+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-/*\r
- * This file defines one of the more complex set of demo/test tasks. They are\r
- * designed to stress test the queue implementation though pseudo simultaneous\r
- * multiple reads and multiple writes from both tasks of varying priority and\r
- * interrupts. The interrupts are prioritised such to ensure that nesting\r
- * occurs (for those ports that support it).\r
- *\r
- * The test ensures that, while being accessed from three tasks and two\r
- * interrupts, all the data sent to the queues is also received from\r
- * the same queue, and that no duplicate items are either sent or received.\r
- * The tests also ensure that a low priority task is never able to successfully\r
- * read from or write to a queue when a task of higher priority is attempting\r
- * the same operation.\r
- */\r
-\r
-/* Standard includes. */\r
-#include <string.h>\r
-\r
-/* SafeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-#include "queue.h"\r
-#include "task.h"\r
-\r
-/* Demo app includes. */\r
-#include "IntQueue.h"\r
-#include "IntQueueTimer.h"\r
-\r
-/* Priorities used by test tasks. */\r
-#ifndef intqHIGHER_PRIORITY\r
- #define intqHIGHER_PRIORITY ( configMAX_PRIORITIES - 2 )\r
-#endif\r
-#define intqLOWER_PRIORITY ( tskIDLE_PRIORITY )\r
-\r
-/* The number of values to send/receive before checking that all values were\r
-processed as expected. */\r
-#define intqNUM_VALUES_TO_LOG ( 200 )\r
-#define intqSHORT_DELAY ( 75 )\r
-\r
-/* The value by which the value being sent to or received from a queue should\r
-increment past intqNUM_VALUES_TO_LOG before we check that all values have been\r
-sent/received correctly. This is done to ensure that all tasks and interrupts\r
-accessing the queue have completed their accesses with the\r
-intqNUM_VALUES_TO_LOG range. */\r
-#define intqVALUE_OVERRUN ( 50 )\r
-\r
-/* The delay used by the polling task. A short delay is used for code\r
-coverage. */\r
-#define intqONE_TICK_DELAY ( 1 )\r
-\r
-/* Each task and interrupt is given a unique identifier. This value is used to\r
-identify which task sent or received each value. The identifier is also used\r
-to distinguish between two tasks that are running the same task function. */\r
-#define intqHIGH_PRIORITY_TASK1 ( ( unsigned portBASE_TYPE ) 1 )\r
-#define intqHIGH_PRIORITY_TASK2 ( ( unsigned portBASE_TYPE ) 2 )\r
-#define intqLOW_PRIORITY_TASK ( ( unsigned portBASE_TYPE ) 3 )\r
-#define intqFIRST_INTERRUPT ( ( unsigned portBASE_TYPE ) 4 )\r
-#define intqSECOND_INTERRUPT ( ( unsigned portBASE_TYPE ) 5 )\r
-#define intqQUEUE_LENGTH ( ( unsigned portBASE_TYPE ) 10 )\r
-\r
-/* At least intqMIN_ACCEPTABLE_TASK_COUNT values should be sent to/received\r
-from each queue by each task, otherwise an error is detected. */\r
-#define intqMIN_ACCEPTABLE_TASK_COUNT ( 5 )\r
-\r
-/* Send the next value to the queue that is normally empty. This is called\r
-from within the interrupts. */\r
-#define timerNORMALLY_EMPTY_TX() \\r
- if( xQueueIsQueueFullFromISR( xNormallyEmptyQueue ) != pdTRUE ) \\r
- { \\r
- unsigned portBASE_TYPE uxSavedInterruptStatus; \\r
- uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \\r
- { \\r
- uxValueForNormallyEmptyQueue++; \\r
- xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ); \\r
- } \\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \\r
- } \\r
-\r
-/* Send the next value to the queue that is normally full. This is called\r
-from within the interrupts. */\r
-#define timerNORMALLY_FULL_TX() \\r
- if( xQueueIsQueueFullFromISR( xNormallyFullQueue ) != pdTRUE ) \\r
- { \\r
- unsigned portBASE_TYPE uxSavedInterruptStatus; \\r
- uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \\r
- { \\r
- uxValueForNormallyFullQueue++; \\r
- xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ); \\r
- } \\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \\r
- } \\r
-\r
-/* Receive a value from the normally empty queue. This is called from within\r
-an interrupt. */\r
-#define timerNORMALLY_EMPTY_RX() \\r
- if( xQueueReceiveFromISR( xNormallyEmptyQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) != pdPASS ) \\r
- { \\r
- prvQueueAccessLogError( __LINE__ ); \\r
- } \\r
- else \\r
- { \\r
- prvRecordValue_NormallyEmpty( uxRxedValue, intqSECOND_INTERRUPT ); \\r
- }\r
-\r
-/* Receive a value from the normally full queue. This is called from within\r
-an interrupt. */\r
-#define timerNORMALLY_FULL_RX() \\r
- if( xQueueReceiveFromISR( xNormallyFullQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) == pdPASS ) \\r
- { \\r
- prvRecordValue_NormallyFull( uxRxedValue, intqSECOND_INTERRUPT ); \\r
- } \\r
-\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* The two queues used by the test. */\r
-static xQueueHandle xNormallyEmptyQueue, xNormallyFullQueue;\r
-\r
-/* Variables used to detect a stall in one of the tasks. */\r
-static unsigned portBASE_TYPE uxHighPriorityLoops1 = 0, uxHighPriorityLoops2 = 0, uxLowPriorityLoops1 = 0, uxLowPriorityLoops2 = 0;\r
-\r
-/* Any unexpected behaviour sets xErrorStatus to fail and log the line that\r
-caused the error in xErrorLine. */\r
-static portBASE_TYPE xErrorStatus = pdPASS;\r
-static volatile unsigned portBASE_TYPE xErrorLine = ( unsigned portBASE_TYPE ) 0;\r
-\r
-/* Used for sequencing between tasks. */\r
-static portBASE_TYPE xWasSuspended = pdFALSE;\r
-\r
-/* The values that are sent to the queues. An incremented value is sent each\r
-time to each queue. */\r
-volatile unsigned portBASE_TYPE uxValueForNormallyEmptyQueue = 0, uxValueForNormallyFullQueue = 0;\r
-\r
-/* A handle to some of the tasks is required so they can be suspended/resumed. */\r
-xTaskHandle xHighPriorityNormallyEmptyTask1, xHighPriorityNormallyEmptyTask2, xHighPriorityNormallyFullTask1, xHighPriorityNormallyFullTask2;\r
-\r
-/* When a value is received in a queue the value is ticked off in the array\r
-the array position of the value is set to a the identifier of the task or\r
-interrupt that accessed the queue. This way missing or duplicate values can be\r
-detected. */\r
-static unsigned portCHAR ucNormallyEmptyReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 };\r
-static unsigned portCHAR ucNormallyFullReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 };\r
-\r
-/* The test tasks themselves. */\r
-static void prvLowerPriorityNormallyEmptyTask( void *pvParameters );\r
-static void prvLowerPriorityNormallyFullTask( void *pvParameters );\r
-static void prvHigherPriorityNormallyEmptyTask( void *pvParameters );\r
-static void prv1stHigherPriorityNormallyFullTask( void *pvParameters );\r
-static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters );\r
-\r
-/* Used to mark the positions within the ucNormallyEmptyReceivedValues and\r
-ucNormallyFullReceivedValues arrays, while checking for duplicates. */\r
-static void prvRecordValue_NormallyEmpty( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource );\r
-static void prvRecordValue_NormallyFull( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource );\r
-\r
-/* Logs the line on which an error occurred. */\r
-static void prvQueueAccessLogError( unsigned portBASE_TYPE uxLine );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vStartInterruptQueueTasks( void )\r
-{\r
- /* Start the test tasks. */\r
- xTaskCreate( prvHigherPriorityNormallyEmptyTask, ( signed portCHAR * ) "H1QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask1 );\r
- xTaskCreate( prvHigherPriorityNormallyEmptyTask, ( signed portCHAR * ) "H2QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask2 );\r
- xTaskCreate( prvLowerPriorityNormallyEmptyTask, ( signed portCHAR * ) "LQRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL );\r
- xTaskCreate( prv1stHigherPriorityNormallyFullTask, ( signed portCHAR * ) "H1QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask1 );\r
- xTaskCreate( prv2ndHigherPriorityNormallyFullTask, ( signed portCHAR * ) "H2QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask2 );\r
- xTaskCreate( prvLowerPriorityNormallyFullTask, ( signed portCHAR * ) "LQRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL );\r
-\r
- /* Create the queues that are accessed by multiple tasks and multiple\r
- interrupts. */\r
- xNormallyFullQueue = xQueueCreate( intqQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) );\r
- xNormallyEmptyQueue = xQueueCreate( intqQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) );\r
-\r
- /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
- in use. The queue registry is provided as a means for kernel aware\r
- debuggers to locate queues and has no purpose if a kernel aware debugger\r
- is not being used. The call to vQueueAddToRegistry() will be removed\r
- by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is\r
- defined to be less than 1. */\r
- vQueueAddToRegistry( xNormallyFullQueue, ( signed portCHAR * ) "NormallyFull" );\r
- vQueueAddToRegistry( xNormallyEmptyQueue, ( signed portCHAR * ) "NormallyEmpty" );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvRecordValue_NormallyFull( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource )\r
-{\r
- if( uxValue < intqNUM_VALUES_TO_LOG )\r
- {\r
- /* We don't expect to receive the same value twice, so if the value\r
- has already been marked as received an error has occurred. */\r
- if( ucNormallyFullReceivedValues[ uxValue ] != 0x00 )\r
- {\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- /* Log that this value has been received. */\r
- ucNormallyFullReceivedValues[ uxValue ] = uxSource;\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvRecordValue_NormallyEmpty( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource )\r
-{\r
- if( uxValue < intqNUM_VALUES_TO_LOG )\r
- {\r
- /* We don't expect to receive the same value twice, so if the value\r
- has already been marked as received an error has occurred. */\r
- if( ucNormallyEmptyReceivedValues[ uxValue ] != 0x00 )\r
- {\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- /* Log that this value has been received. */\r
- ucNormallyEmptyReceivedValues[ uxValue ] = uxSource;\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvQueueAccessLogError( unsigned portBASE_TYPE uxLine )\r
-{\r
- /* Latch the line number that caused the error. */\r
- xErrorLine = uxLine;\r
- xErrorStatus = pdFAIL;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvHigherPriorityNormallyEmptyTask( void *pvParameters )\r
-{\r
-unsigned portBASE_TYPE uxRxed, ux, uxTask1, uxTask2, uxInterrupts, uxErrorCount1 = 0, uxErrorCount2 = 0;\r
-\r
- /* The timer should not be started until after the scheduler has started.\r
- More than one task is running this code so we check the parameter value\r
- to determine which task should start the timer. */\r
- if( ( unsigned portBASE_TYPE ) pvParameters == intqHIGH_PRIORITY_TASK1 )\r
- {\r
- vInitialiseTimerForIntQueueTest();\r
- }\r
-\r
- for( ;; )\r
- {\r
- /* Block waiting to receive a value from the normally empty queue.\r
- Interrupts will write to the queue so we should receive a value. */\r
- if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqSHORT_DELAY ) != pdPASS )\r
- {\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
- else\r
- {\r
- /* Note which value was received so we can check all expected\r
- values are received and no values are duplicated. */\r
- prvRecordValue_NormallyEmpty( uxRxed, ( unsigned portBASE_TYPE ) pvParameters );\r
- }\r
-\r
- /* Ensure the other task running this code gets a chance to execute. */\r
- taskYIELD();\r
-\r
- if( ( unsigned portBASE_TYPE ) pvParameters == intqHIGH_PRIORITY_TASK1 )\r
- {\r
- /* Have we received all the expected values? */\r
- if( uxValueForNormallyEmptyQueue > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) )\r
- {\r
- vTaskSuspend( xHighPriorityNormallyEmptyTask2 );\r
-\r
- uxTask1 = 0;\r
- uxTask2 = 0;\r
- uxInterrupts = 0;\r
-\r
- /* Loop through the array, checking that both tasks have\r
- placed values into the array, and that no values are missing.\r
- Start at 1 as we expect position 0 to be unused. */\r
- for( ux = 1; ux < intqNUM_VALUES_TO_LOG; ux++ )\r
- {\r
- if( ucNormallyEmptyReceivedValues[ ux ] == 0 )\r
- {\r
- /* A value is missing. */\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
- else\r
- {\r
- if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIORITY_TASK1 )\r
- {\r
- /* Value was placed into the array by task 1. */\r
- uxTask1++;\r
- }\r
- else if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIORITY_TASK2 )\r
- {\r
- /* Value was placed into the array by task 2. */\r
- uxTask2++;\r
- }\r
- else if( ucNormallyEmptyReceivedValues[ ux ] == intqSECOND_INTERRUPT )\r
- {\r
- uxInterrupts++;\r
- }\r
- }\r
- }\r
-\r
- if( uxTask1 < intqMIN_ACCEPTABLE_TASK_COUNT )\r
- {\r
- /* Only task 2 seemed to log any values. */\r
- uxErrorCount1++;\r
- if( uxErrorCount1 > 2 )\r
- {\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
- }\r
- else\r
- {\r
- uxErrorCount1 = 0;\r
- }\r
-\r
- if( uxTask2 < intqMIN_ACCEPTABLE_TASK_COUNT )\r
- {\r
- /* Only task 1 seemed to log any values. */\r
- uxErrorCount2++;\r
- if( uxErrorCount2 > 2 )\r
- {\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
- }\r
- else\r
- {\r
- uxErrorCount2 = 0;\r
- }\r
-\r
- if( uxInterrupts == 0 )\r
- {\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- /* Clear the array again, ready to start a new cycle. */\r
- memset( ucNormallyEmptyReceivedValues, 0x00, sizeof( ucNormallyEmptyReceivedValues ) );\r
-\r
- uxHighPriorityLoops1++;\r
- uxValueForNormallyEmptyQueue = 0;\r
-\r
- /* Suspend ourselves, allowing the lower priority task to\r
- actually receive something from the queue. Until now it\r
- will have been prevented from doing so by the higher\r
- priority tasks. The lower priority task will resume us\r
- if it receives something. We will then resume the other\r
- higher priority task. */\r
- vTaskSuspend( NULL );\r
- vTaskResume( xHighPriorityNormallyEmptyTask2 );\r
- }\r
- }\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvLowerPriorityNormallyEmptyTask( void *pvParameters )\r
-{\r
-unsigned portBASE_TYPE uxValue, uxRxed;\r
-\r
- /* The parameters are not being used so avoid compiler warnings. */\r
- ( void ) pvParameters;\r
-\r
- for( ;; )\r
- {\r
- if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqONE_TICK_DELAY ) != errQUEUE_EMPTY )\r
- {\r
- /* We should only obtain a value when the high priority task is\r
- suspended. */\r
- if( xTaskIsTaskSuspended( xHighPriorityNormallyEmptyTask1 ) == pdFALSE )\r
- {\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- prvRecordValue_NormallyEmpty( uxRxed, intqLOW_PRIORITY_TASK );\r
-\r
- /* Wake the higher priority task again. */\r
- vTaskResume( xHighPriorityNormallyEmptyTask1 );\r
- uxLowPriorityLoops1++;\r
- }\r
- else\r
- {\r
- /* Raise our priority while we send so we can preempt the higher\r
- priority task, and ensure we get the Tx value into the queue. */\r
- vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 );\r
-\r
- portENTER_CRITICAL();\r
- {\r
- uxValueForNormallyEmptyQueue++;\r
- uxValue = uxValueForNormallyEmptyQueue;\r
- }\r
- portEXIT_CRITICAL();\r
-\r
- if( xQueueSend( xNormallyEmptyQueue, &uxValue, portMAX_DELAY ) != pdPASS )\r
- {\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- vTaskPrioritySet( NULL, intqLOWER_PRIORITY );\r
- }\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prv1stHigherPriorityNormallyFullTask( void *pvParameters )\r
-{\r
-unsigned portBASE_TYPE uxValueToTx, ux, uxInterrupts;\r
-\r
- /* The parameters are not being used so avoid compiler warnings. */\r
- ( void ) pvParameters;\r
-\r
- /* Make sure the queue starts full or near full. >> 1 as there are two\r
- high priority tasks. */\r
- for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ )\r
- {\r
- portENTER_CRITICAL();\r
- {\r
- uxValueForNormallyFullQueue++;\r
- uxValueToTx = uxValueForNormallyFullQueue;\r
- }\r
- portEXIT_CRITICAL();\r
-\r
- xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY );\r
- }\r
-\r
- for( ;; )\r
- {\r
- portENTER_CRITICAL();\r
- {\r
- uxValueForNormallyFullQueue++;\r
- uxValueToTx = uxValueForNormallyFullQueue;\r
- }\r
- portEXIT_CRITICAL();\r
-\r
- if( xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) != pdPASS )\r
- {\r
- /* intqHIGH_PRIORITY_TASK2 is never suspended so we would not\r
- expect it to ever time out. */\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- /* Allow the other task running this code to run. */\r
- taskYIELD();\r
-\r
- /* Have all the expected values been sent to the queue? */\r
- if( uxValueToTx > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) )\r
- {\r
- /* Make sure the other high priority task completes its send of\r
- any values below intqNUM_VALUE_TO_LOG. */\r
- vTaskDelay( intqSHORT_DELAY );\r
-\r
- vTaskSuspend( xHighPriorityNormallyFullTask2 );\r
-\r
- if( xWasSuspended == pdTRUE )\r
- {\r
- /* We would have expected the other high priority task to have\r
- set this back to false by now. */\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- /* Set the suspended flag so an error is not logged if the other\r
- task recognises a time out when it is unsuspended. */\r
- xWasSuspended = pdTRUE;\r
-\r
- /* Check interrupts are also sending. */\r
- uxInterrupts = 0U;\r
-\r
- /* Start at 1 as we expect position 0 to be unused. */\r
- for( ux = 1; ux < intqNUM_VALUES_TO_LOG; ux++ )\r
- {\r
- if( ucNormallyFullReceivedValues[ ux ] == 0 )\r
- {\r
- /* A value was missing. */\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
- else if( ucNormallyFullReceivedValues[ ux ] == intqSECOND_INTERRUPT )\r
- {\r
- uxInterrupts++;\r
- }\r
- }\r
-\r
- if( uxInterrupts == 0 )\r
- {\r
- /* No writes from interrupts were found. Are interrupts\r
- actually running? */\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- /* Reset the array ready for the next cycle. */\r
- memset( ucNormallyFullReceivedValues, 0x00, sizeof( ucNormallyFullReceivedValues ) );\r
-\r
- uxHighPriorityLoops2++;\r
- uxValueForNormallyFullQueue = 0;\r
-\r
- /* Suspend ourselves, allowing the lower priority task to\r
- actually receive something from the queue. Until now it\r
- will have been prevented from doing so by the higher\r
- priority tasks. The lower priority task will resume us\r
- if it receives something. We will then resume the other\r
- higher priority task. */\r
- vTaskSuspend( NULL );\r
- vTaskResume( xHighPriorityNormallyFullTask2 );\r
- }\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters )\r
-{\r
-unsigned portBASE_TYPE uxValueToTx, ux;\r
-\r
- /* The parameters are not being used so avoid compiler warnings. */\r
- ( void ) pvParameters;\r
-\r
- /* Make sure the queue starts full or near full. >> 1 as there are two\r
- high priority tasks. */\r
- for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ )\r
- {\r
- portENTER_CRITICAL();\r
- {\r
- uxValueForNormallyFullQueue++;\r
- uxValueToTx = uxValueForNormallyFullQueue;\r
- }\r
- portEXIT_CRITICAL();\r
-\r
- xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY );\r
- }\r
-\r
- for( ;; )\r
- {\r
- portENTER_CRITICAL();\r
- {\r
- uxValueForNormallyFullQueue++;\r
- uxValueToTx = uxValueForNormallyFullQueue;\r
- }\r
- portEXIT_CRITICAL();\r
-\r
- if( xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) != pdPASS )\r
- {\r
- if( xWasSuspended != pdTRUE )\r
- {\r
- /* It is ok to time out if the task has been suspended. */\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
- }\r
-\r
- xWasSuspended = pdFALSE;\r
-\r
- taskYIELD();\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvLowerPriorityNormallyFullTask( void *pvParameters )\r
-{\r
-unsigned portBASE_TYPE uxValue, uxTxed = 9999;\r
-\r
- /* The parameters are not being used so avoid compiler warnings. */\r
- ( void ) pvParameters;\r
-\r
- for( ;; )\r
- {\r
- if( xQueueSend( xNormallyFullQueue, &uxTxed, intqONE_TICK_DELAY ) != errQUEUE_FULL )\r
- {\r
- /* We would only expect to succeed when the higher priority task\r
- is suspended. */\r
- if( xTaskIsTaskSuspended( xHighPriorityNormallyFullTask1 ) == pdFALSE )\r
- {\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- vTaskResume( xHighPriorityNormallyFullTask1 );\r
- uxLowPriorityLoops2++;\r
- }\r
- else\r
- {\r
- /* Raise our priority while we receive so we can preempt the higher\r
- priority task, and ensure we get the value from the queue. */\r
- vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 );\r
-\r
- if( xQueueReceive( xNormallyFullQueue, &uxValue, portMAX_DELAY ) != pdPASS )\r
- {\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
- else\r
- {\r
- prvRecordValue_NormallyFull( uxValue, intqLOW_PRIORITY_TASK );\r
- }\r
-\r
- vTaskPrioritySet( NULL, intqLOWER_PRIORITY );\r
- }\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xFirstTimerHandler( void )\r
-{\r
-portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, uxRxedValue;\r
-static unsigned portBASE_TYPE uxNextOperation = 0;\r
-\r
- /* Called from a timer interrupt. Perform various read and write\r
- accesses on the queues. */\r
-\r
- uxNextOperation++;\r
-\r
- if( uxNextOperation & ( unsigned portBASE_TYPE ) 0x01 )\r
- {\r
- timerNORMALLY_EMPTY_TX();\r
- timerNORMALLY_EMPTY_TX();\r
- timerNORMALLY_EMPTY_TX();\r
- }\r
- else\r
- {\r
- timerNORMALLY_FULL_RX();\r
- timerNORMALLY_FULL_RX();\r
- timerNORMALLY_FULL_RX();\r
- }\r
-\r
- return xHigherPriorityTaskWoken;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xSecondTimerHandler( void )\r
-{\r
-unsigned portBASE_TYPE uxRxedValue;\r
-portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
-static unsigned portBASE_TYPE uxNextOperation = 0;\r
-\r
- /* Called from a timer interrupt. Perform various read and write\r
- accesses on the queues. */\r
-\r
- uxNextOperation++;\r
-\r
- if( uxNextOperation & ( unsigned portBASE_TYPE ) 0x01 )\r
- {\r
- timerNORMALLY_EMPTY_TX();\r
- timerNORMALLY_EMPTY_TX();\r
-\r
- timerNORMALLY_EMPTY_RX();\r
- timerNORMALLY_EMPTY_RX();\r
- }\r
- else\r
- {\r
- timerNORMALLY_FULL_RX();\r
- timerNORMALLY_FULL_TX();\r
- timerNORMALLY_FULL_TX();\r
- timerNORMALLY_FULL_TX();\r
- timerNORMALLY_FULL_TX();\r
- }\r
-\r
- return xHigherPriorityTaskWoken;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-\r
-portBASE_TYPE xAreIntQueueTasksStillRunning( void )\r
-{\r
-static unsigned portBASE_TYPE uxLastHighPriorityLoops1 = 0, uxLastHighPriorityLoops2 = 0, uxLastLowPriorityLoops1 = 0, uxLastLowPriorityLoops2 = 0;\r
-\r
- /* xErrorStatus can be set outside of this function. This function just\r
- checks that all the tasks are still cycling. */\r
-\r
- if( uxHighPriorityLoops1 == uxLastHighPriorityLoops1 )\r
- {\r
- /* The high priority 1 task has stalled. */\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- uxLastHighPriorityLoops1 = uxHighPriorityLoops1;\r
-\r
- if( uxHighPriorityLoops2 == uxLastHighPriorityLoops2 )\r
- {\r
- /* The high priority 2 task has stalled. */\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- uxLastHighPriorityLoops2 = uxHighPriorityLoops2;\r
-\r
- if( uxLowPriorityLoops1 == uxLastLowPriorityLoops1 )\r
- {\r
- /* The low priority 1 task has stalled. */\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- uxLastLowPriorityLoops1 = uxLowPriorityLoops1;\r
-\r
- if( uxLowPriorityLoops2 == uxLastLowPriorityLoops2 )\r
- {\r
- /* The low priority 2 task has stalled. */\r
- prvQueueAccessLogError( __LINE__ );\r
- }\r
-\r
- uxLastLowPriorityLoops2 = uxLowPriorityLoops2;\r
-\r
- return xErrorStatus;\r
-}\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-/*\r
- * This file contains some test scenarios that ensure tasks do not exit queue\r
- * send or receive functions prematurely. A description of the tests is\r
- * included within the code.\r
- */\r
-\r
-/* Kernel includes. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "queue.h"\r
-\r
-/* Demo includes. */\r
-#include "blocktim.h"\r
-\r
-/* Task priorities. Allow these to be overridden. */\r
-#ifndef bktPRIMARY_PRIORITY\r
- #define bktPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 )\r
-#endif\r
-\r
-#ifndef bktSECONDARY_PRIORITY\r
- #define bktSECONDARY_PRIORITY ( configMAX_PRIORITIES - 4 )\r
-#endif\r
-\r
-/* Task behaviour. */\r
-#define bktQUEUE_LENGTH ( 5 )\r
-#define bktSHORT_WAIT ( ( ( portTickType ) 20 ) / portTICK_RATE_MS )\r
-#define bktPRIMARY_BLOCK_TIME ( 10 )\r
-#define bktALLOWABLE_MARGIN ( 15 )\r
-#define bktTIME_TO_BLOCK ( 175 )\r
-#define bktDONT_BLOCK ( ( portTickType ) 0 )\r
-#define bktRUN_INDICATOR ( ( unsigned portBASE_TYPE ) 0x55 )\r
-\r
-/* The queue on which the tasks block. */\r
-static xQueueHandle xTestQueue;\r
-\r
-/* Handle to the secondary task is required by the primary task for calls\r
-to vTaskSuspend/Resume(). */\r
-static xTaskHandle xSecondary;\r
-\r
-/* Used to ensure that tasks are still executing without error. */\r
-static volatile portBASE_TYPE xPrimaryCycles = 0, xSecondaryCycles = 0;\r
-static volatile portBASE_TYPE xErrorOccurred = pdFALSE;\r
-\r
-/* Provides a simple mechanism for the primary task to know when the\r
-secondary task has executed. */\r
-static volatile unsigned portBASE_TYPE xRunIndicator;\r
-\r
-/* The two test tasks. Their behaviour is commented within the files. */\r
-static void vPrimaryBlockTimeTestTask( void *pvParameters );\r
-static void vSecondaryBlockTimeTestTask( void *pvParameters );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vCreateBlockTimeTasks( void )\r
-{\r
- /* Create the queue on which the two tasks block. */\r
- xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( portBASE_TYPE ) );\r
-\r
- /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
- in use. The queue registry is provided as a means for kernel aware\r
- debuggers to locate queues and has no purpose if a kernel aware debugger\r
- is not being used. The call to vQueueAddToRegistry() will be removed\r
- by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is\r
- defined to be less than 1. */\r
- vQueueAddToRegistry( xTestQueue, ( signed char * ) "Block_Time_Queue" );\r
-\r
- /* Create the two test tasks. */\r
- xTaskCreate( vPrimaryBlockTimeTestTask, ( signed char * )"BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );\r
- xTaskCreate( vSecondaryBlockTimeTestTask, ( signed char * )"BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vPrimaryBlockTimeTestTask( void *pvParameters )\r
-{\r
-portBASE_TYPE xItem, xData;\r
-portTickType xTimeWhenBlocking;\r
-portTickType xTimeToBlock, xBlockedTime;\r
-\r
- ( void ) pvParameters;\r
-\r
- for( ;; )\r
- {\r
- /*********************************************************************\r
- Test 1\r
-\r
- Simple block time wakeup test on queue receives. */\r
- for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
- {\r
- /* The queue is empty. Attempt to read from the queue using a block\r
- time. When we wake, ensure the delta in time is as expected. */\r
- xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;\r
-\r
- xTimeWhenBlocking = xTaskGetTickCount();\r
-\r
- /* We should unblock after xTimeToBlock having not received\r
- anything on the queue. */\r
- if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* How long were we blocked for? */\r
- xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
-\r
- if( xBlockedTime < xTimeToBlock )\r
- {\r
- /* Should not have blocked for less than we requested. */\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )\r
- {\r
- /* Should not have blocked for longer than we requested,\r
- although we would not necessarily run as soon as we were\r
- unblocked so a margin is allowed. */\r
- xErrorOccurred = pdTRUE;\r
- }\r
- }\r
-\r
- /*********************************************************************\r
- Test 2\r
-\r
- Simple block time wakeup test on queue sends.\r
-\r
- First fill the queue. It should be empty so all sends should pass. */\r
- for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
- {\r
- if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- #if configUSE_PREEMPTION == 0\r
- taskYIELD();\r
- #endif\r
- }\r
-\r
- for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
- {\r
- /* The queue is full. Attempt to write to the queue using a block\r
- time. When we wake, ensure the delta in time is as expected. */\r
- xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;\r
-\r
- xTimeWhenBlocking = xTaskGetTickCount();\r
-\r
- /* We should unblock after xTimeToBlock having not received\r
- anything on the queue. */\r
- if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* How long were we blocked for? */\r
- xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
-\r
- if( xBlockedTime < xTimeToBlock )\r
- {\r
- /* Should not have blocked for less than we requested. */\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )\r
- {\r
- /* Should not have blocked for longer than we requested,\r
- although we would not necessarily run as soon as we were\r
- unblocked so a margin is allowed. */\r
- xErrorOccurred = pdTRUE;\r
- }\r
- }\r
-\r
- /*********************************************************************\r
- Test 3\r
-\r
- Wake the other task, it will block attempting to post to the queue.\r
- When we read from the queue the other task will wake, but before it\r
- can run we will post to the queue again. When the other task runs it\r
- will find the queue still full, even though it was woken. It should\r
- recognise that its block time has not expired and return to block for\r
- the remains of its block time.\r
-\r
- Wake the other task so it blocks attempting to post to the already\r
- full queue. */\r
- xRunIndicator = 0;\r
- vTaskResume( xSecondary );\r
-\r
- /* We need to wait a little to ensure the other task executes. */\r
- while( xRunIndicator != bktRUN_INDICATOR )\r
- {\r
- /* The other task has not yet executed. */\r
- vTaskDelay( bktSHORT_WAIT );\r
- }\r
- /* Make sure the other task is blocked on the queue. */\r
- vTaskDelay( bktSHORT_WAIT );\r
- xRunIndicator = 0;\r
-\r
- for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
- {\r
- /* Now when we make space on the queue the other task should wake\r
- but not execute as this task has higher priority. */\r
- if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* Now fill the queue again before the other task gets a chance to\r
- execute. If the other task had executed we would find the queue\r
- full ourselves, and the other task have set xRunIndicator. */\r
- if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- if( xRunIndicator == bktRUN_INDICATOR )\r
- {\r
- /* The other task should not have executed. */\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* Raise the priority of the other task so it executes and blocks\r
- on the queue again. */\r
- vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );\r
-\r
- /* The other task should now have re-blocked without exiting the\r
- queue function. */\r
- if( xRunIndicator == bktRUN_INDICATOR )\r
- {\r
- /* The other task should not have executed outside of the\r
- queue function. */\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* Set the priority back down. */\r
- vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );\r
- }\r
-\r
- /* Let the other task timeout. When it unblockes it will check that it\r
- unblocked at the correct time, then suspend itself. */\r
- while( xRunIndicator != bktRUN_INDICATOR )\r
- {\r
- vTaskDelay( bktSHORT_WAIT );\r
- }\r
- vTaskDelay( bktSHORT_WAIT );\r
- xRunIndicator = 0;\r
-\r
-\r
- /*********************************************************************\r
- Test 4\r
-\r
- As per test 3 - but with the send and receive the other way around.\r
- The other task blocks attempting to read from the queue.\r
-\r
- Empty the queue. We should find that it is full. */\r
- for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
- {\r
- if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
- }\r
-\r
- /* Wake the other task so it blocks attempting to read from the\r
- already empty queue. */\r
- vTaskResume( xSecondary );\r
-\r
- /* We need to wait a little to ensure the other task executes. */\r
- while( xRunIndicator != bktRUN_INDICATOR )\r
- {\r
- vTaskDelay( bktSHORT_WAIT );\r
- }\r
- vTaskDelay( bktSHORT_WAIT );\r
- xRunIndicator = 0;\r
-\r
- for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
- {\r
- /* Now when we place an item on the queue the other task should\r
- wake but not execute as this task has higher priority. */\r
- if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* Now empty the queue again before the other task gets a chance to\r
- execute. If the other task had executed we would find the queue\r
- empty ourselves, and the other task would be suspended. */\r
- if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- if( xRunIndicator == bktRUN_INDICATOR )\r
- {\r
- /* The other task should not have executed. */\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* Raise the priority of the other task so it executes and blocks\r
- on the queue again. */\r
- vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );\r
-\r
- /* The other task should now have re-blocked without exiting the\r
- queue function. */\r
- if( xRunIndicator == bktRUN_INDICATOR )\r
- {\r
- /* The other task should not have executed outside of the\r
- queue function. */\r
- xErrorOccurred = pdTRUE;\r
- }\r
- vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );\r
- }\r
-\r
- /* Let the other task timeout. When it unblockes it will check that it\r
- unblocked at the correct time, then suspend itself. */\r
- while( xRunIndicator != bktRUN_INDICATOR )\r
- {\r
- vTaskDelay( bktSHORT_WAIT );\r
- }\r
- vTaskDelay( bktSHORT_WAIT );\r
-\r
- xPrimaryCycles++;\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vSecondaryBlockTimeTestTask( void *pvParameters )\r
-{\r
-portTickType xTimeWhenBlocking, xBlockedTime;\r
-portBASE_TYPE xData;\r
-\r
- ( void ) pvParameters;\r
-\r
- for( ;; )\r
- {\r
- /*********************************************************************\r
- Test 1 and 2\r
-\r
- This task does does not participate in these tests. */\r
- vTaskSuspend( NULL );\r
-\r
- /*********************************************************************\r
- Test 3\r
-\r
- The first thing we do is attempt to read from the queue. It should be\r
- full so we block. Note the time before we block so we can check the\r
- wake time is as per that expected. */\r
- xTimeWhenBlocking = xTaskGetTickCount();\r
-\r
- /* We should unblock after bktTIME_TO_BLOCK having not sent\r
- anything to the queue. */\r
- xData = 0;\r
- xRunIndicator = bktRUN_INDICATOR;\r
- if( xQueueSend( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* How long were we inside the send function? */\r
- xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
-\r
- /* We should not have blocked for less time than bktTIME_TO_BLOCK. */\r
- if( xBlockedTime < bktTIME_TO_BLOCK )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* We should of not blocked for much longer than bktALLOWABLE_MARGIN\r
- either. A margin is permitted as we would not necessarily run as\r
- soon as we unblocked. */\r
- if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* Suspend ready for test 3. */\r
- xRunIndicator = bktRUN_INDICATOR;\r
- vTaskSuspend( NULL );\r
-\r
- /*********************************************************************\r
- Test 4\r
-\r
- As per test three, but with the send and receive reversed. */\r
- xTimeWhenBlocking = xTaskGetTickCount();\r
-\r
- /* We should unblock after bktTIME_TO_BLOCK having not received\r
- anything on the queue. */\r
- xRunIndicator = bktRUN_INDICATOR;\r
- if( xQueueReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
-\r
- /* We should not have blocked for less time than bktTIME_TO_BLOCK. */\r
- if( xBlockedTime < bktTIME_TO_BLOCK )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* We should of not blocked for much longer than bktALLOWABLE_MARGIN\r
- either. A margin is permitted as we would not necessarily run as soon\r
- as we unblocked. */\r
- if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- xRunIndicator = bktRUN_INDICATOR;\r
-\r
- xSecondaryCycles++;\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xAreBlockTimeTestTasksStillRunning( void )\r
-{\r
-static portBASE_TYPE xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0;\r
-portBASE_TYPE xReturn = pdPASS;\r
-\r
- /* Have both tasks performed at least one cycle since this function was\r
- last called? */\r
- if( xPrimaryCycles == xLastPrimaryCycleCount )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- if( xSecondaryCycles == xLastSecondaryCycleCount )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- if( xErrorOccurred == pdTRUE )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- xLastSecondaryCycleCount = xSecondaryCycles;\r
- xLastPrimaryCycleCount = xPrimaryCycles;\r
-\r
- return xReturn;\r
-}\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-\r
-/* \r
- * Simple demonstration of the usage of counting semaphore.\r
- */\r
-\r
-/* Scheduler include files. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "semphr.h"\r
-\r
-/* Demo program include files. */\r
-#include "countsem.h"\r
-\r
-/* The maximum count value that the semaphore used for the demo can hold. */\r
-#define countMAX_COUNT_VALUE ( 200 )\r
-\r
-/* Constants used to indicate whether or not the semaphore should have been\r
-created with its maximum count value, or its minimum count value. These \r
-numbers are used to ensure that the pointers passed in as the task parameters\r
-are valid. */\r
-#define countSTART_AT_MAX_COUNT ( 0xaa )\r
-#define countSTART_AT_ZERO ( 0x55 )\r
-\r
-/* Two tasks are created for the test. One uses a semaphore created with its\r
-count value set to the maximum, and one with the count value set to zero. */\r
-#define countNUM_TEST_TASKS ( 2 )\r
-#define countDONT_BLOCK ( 0 )\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* Flag that will be latched to pdTRUE should any unexpected behaviour be\r
-detected in any of the tasks. */\r
-static volatile portBASE_TYPE xErrorDetected = pdFALSE;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * The demo task. This simply counts the semaphore up to its maximum value,\r
- * the counts it back down again. The result of each semaphore 'give' and\r
- * 'take' is inspected, with an error being flagged if it is found not to be\r
- * the expected result.\r
- */\r
-static void prvCountingSemaphoreTask( void *pvParameters );\r
-\r
-/*\r
- * Utility function to increment the semaphore count value up from zero to\r
- * countMAX_COUNT_VALUE.\r
- */\r
-static void prvIncrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter );\r
-\r
-/*\r
- * Utility function to decrement the semaphore count value up from \r
- * countMAX_COUNT_VALUE to zero.\r
- */\r
-static void prvDecrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* The structure that is passed into the task as the task parameter. */\r
-typedef struct COUNT_SEM_STRUCT\r
-{\r
- /* The semaphore to be used for the demo. */\r
- xSemaphoreHandle xSemaphore;\r
-\r
- /* Set to countSTART_AT_MAX_COUNT if the semaphore should be created with\r
- its count value set to its max count value, or countSTART_AT_ZERO if it\r
- should have been created with its count value set to 0. */\r
- unsigned portBASE_TYPE uxExpectedStartCount; \r
-\r
- /* Incremented on each cycle of the demo task. Used to detect a stalled\r
- task. */\r
- unsigned portBASE_TYPE uxLoopCounter; \r
-} xCountSemStruct;\r
-\r
-/* Two structures are defined, one is passed to each test task. */\r
-static volatile xCountSemStruct xParameters[ countNUM_TEST_TASKS ];\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vStartCountingSemaphoreTasks( void )\r
-{\r
- /* Create the semaphores that we are going to use for the test/demo. The\r
- first should be created such that it starts at its maximum count value,\r
- the second should be created such that it starts with a count value of zero. */\r
- xParameters[ 0 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, countMAX_COUNT_VALUE );\r
- xParameters[ 0 ].uxExpectedStartCount = countSTART_AT_MAX_COUNT;\r
- xParameters[ 0 ].uxLoopCounter = 0;\r
-\r
- xParameters[ 1 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, 0 );\r
- xParameters[ 1 ].uxExpectedStartCount = 0;\r
- xParameters[ 1 ].uxLoopCounter = 0;\r
-\r
- /* vQueueAddToRegistry() adds the semaphore to the registry, if one is\r
- in use. The registry is provided as a means for kernel aware \r
- debuggers to locate semaphores and has no purpose if a kernel aware debugger\r
- is not being used. The call to vQueueAddToRegistry() will be removed\r
- by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is \r
- defined to be less than 1. */\r
- vQueueAddToRegistry( ( xQueueHandle ) xParameters[ 0 ].xSemaphore, ( signed portCHAR * ) "Counting_Sem_1" );\r
- vQueueAddToRegistry( ( xQueueHandle ) xParameters[ 1 ].xSemaphore, ( signed portCHAR * ) "Counting_Sem_2" );\r
-\r
-\r
- /* Were the semaphores created? */\r
- if( ( xParameters[ 0 ].xSemaphore != NULL ) || ( xParameters[ 1 ].xSemaphore != NULL ) )\r
- {\r
- /* Create the demo tasks, passing in the semaphore to use as the parameter. */\r
- xTaskCreate( prvCountingSemaphoreTask, ( signed portCHAR * ) "CNT1", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 0 ] ), tskIDLE_PRIORITY, NULL );\r
- xTaskCreate( prvCountingSemaphoreTask, ( signed portCHAR * ) "CNT2", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL ); \r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvDecrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter )\r
-{\r
-unsigned portBASE_TYPE ux;\r
-\r
- /* If the semaphore count is at its maximum then we should not be able to\r
- 'give' the semaphore. */\r
- if( xSemaphoreGive( xSemaphore ) == pdPASS )\r
- {\r
- xErrorDetected = pdTRUE;\r
- }\r
-\r
- /* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */\r
- for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )\r
- {\r
- if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS )\r
- {\r
- /* We expected to be able to take the semaphore. */\r
- xErrorDetected = pdTRUE;\r
- }\r
-\r
- ( *puxLoopCounter )++;\r
- }\r
-\r
- #if configUSE_PREEMPTION == 0\r
- taskYIELD();\r
- #endif\r
-\r
- /* If the semaphore count is zero then we should not be able to 'take' \r
- the semaphore. */\r
- if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )\r
- {\r
- xErrorDetected = pdTRUE;\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvIncrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter )\r
-{\r
-unsigned portBASE_TYPE ux;\r
-\r
- /* If the semaphore count is zero then we should not be able to 'take' \r
- the semaphore. */\r
- if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )\r
- {\r
- xErrorDetected = pdTRUE;\r
- }\r
-\r
- /* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */\r
- for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )\r
- {\r
- if( xSemaphoreGive( xSemaphore ) != pdPASS )\r
- {\r
- /* We expected to be able to take the semaphore. */\r
- xErrorDetected = pdTRUE;\r
- }\r
-\r
- ( *puxLoopCounter )++;\r
- }\r
-\r
- #if configUSE_PREEMPTION == 0\r
- taskYIELD();\r
- #endif\r
-\r
- /* If the semaphore count is at its maximum then we should not be able to\r
- 'give' the semaphore. */\r
- if( xSemaphoreGive( xSemaphore ) == pdPASS )\r
- {\r
- xErrorDetected = pdTRUE;\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCountingSemaphoreTask( void *pvParameters )\r
-{\r
-xCountSemStruct *pxParameter;\r
-\r
- #ifdef USE_STDIO\r
- void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
- \r
- const portCHAR * const pcTaskStartMsg = "Counting semaphore demo started.\r\n";\r
-\r
- /* Queue a message for printing to say the task has started. */\r
- vPrintDisplayMessage( &pcTaskStartMsg );\r
- #endif\r
-\r
- /* The semaphore to be used was passed as the parameter. */\r
- pxParameter = ( xCountSemStruct * ) pvParameters;\r
-\r
- /* Did we expect to find the semaphore already at its max count value, or\r
- at zero? */\r
- if( pxParameter->uxExpectedStartCount == countSTART_AT_MAX_COUNT )\r
- {\r
- prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );\r
- }\r
-\r
- /* Now we expect the semaphore count to be 0, so this time there is an\r
- error if we can take the semaphore. */\r
- if( xSemaphoreTake( pxParameter->xSemaphore, 0 ) == pdPASS )\r
- {\r
- xErrorDetected = pdTRUE;\r
- }\r
-\r
- for( ;; )\r
- {\r
- prvIncrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );\r
- prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xAreCountingSemaphoreTasksStillRunning( void )\r
-{\r
-static unsigned portBASE_TYPE uxLastCount0 = 0, uxLastCount1 = 0;\r
-portBASE_TYPE xReturn = pdPASS;\r
-\r
- /* Return fail if any 'give' or 'take' did not result in the expected\r
- behaviour. */\r
- if( xErrorDetected != pdFALSE )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- /* Return fail if either task is not still incrementing its loop counter. */\r
- if( uxLastCount0 == xParameters[ 0 ].uxLoopCounter )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
- else\r
- {\r
- uxLastCount0 = xParameters[ 0 ].uxLoopCounter;\r
- }\r
-\r
- if( uxLastCount1 == xParameters[ 1 ].uxLoopCounter )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
- else\r
- {\r
- uxLastCount1 = xParameters[ 1 ].uxLoopCounter;\r
- }\r
-\r
- return xReturn;\r
-}\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef QUEUE_ACCESS_TEST\r
-#define QUEUE_ACCESS_TEST\r
-\r
-void vStartInterruptQueueTasks( void );\r
-portBASE_TYPE xAreIntQueueTasksStillRunning( void );\r
-portBASE_TYPE xFirstTimerHandler( void );\r
-portBASE_TYPE xSecondTimerHandler( void );\r
-\r
-#endif /* QUEUE_ACCESS_TEST */\r
-\r
-\r
-\r
-\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef BLOCK_TIME_TEST_H\r
-#define BLOCK_TIME_TEST_H\r
-\r
-void vCreateBlockTimeTasks( void );\r
-portBASE_TYPE xAreBlockTimeTestTasksStillRunning( void );\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef COUNT_SEMAPHORE_TEST_H\r
-#define COUNT_SEMAPHORE_TEST_H\r
-\r
-void vStartCountingSemaphoreTasks( void );\r
-portBASE_TYPE xAreCountingSemaphoreTasksStillRunning( void );\r
-\r
-#endif\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef RECURSIVE_MUTEX_TEST_H\r
-#define RECURSIVE_MUTEX_TEST_H\r
-\r
-void vStartRecursiveMutexTasks( void );\r
-portBASE_TYPE xAreRecursiveMutexTasksStillRunning( void );\r
-\r
-#endif\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-/*\r
- The tasks defined on this page demonstrate the use of recursive mutexes.\r
-\r
- For recursive mutex functionality the created mutex should be created using\r
- xSemaphoreCreateRecursiveMutex(), then be manipulated\r
- using the xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() API\r
- functions.\r
-\r
- This demo creates three tasks all of which access the same recursive mutex:\r
-\r
- prvRecursiveMutexControllingTask() has the highest priority so executes \r
- first and grabs the mutex. It then performs some recursive accesses - \r
- between each of which it sleeps for a short period to let the lower \r
- priority tasks execute. When it has completed its demo functionality\r
- it gives the mutex back before suspending itself.\r
-\r
- prvRecursiveMutexBlockingTask() attempts to access the mutex by performing\r
- a blocking 'take'. The blocking task has a lower priority than the \r
- controlling task so by the time it executes the mutex has already been\r
- taken by the controlling task, causing the blocking task to block. It \r
- does not unblock until the controlling task has given the mutex back, \r
- and it does not actually run until the controlling task has suspended \r
- itself (due to the relative priorities). When it eventually does obtain\r
- the mutex all it does is give the mutex back prior to also suspending \r
- itself. At this point both the controlling task and the blocking task are \r
- suspended.\r
-\r
- prvRecursiveMutexPollingTask() runs at the idle priority. It spins round\r
- a tight loop attempting to obtain the mutex with a non-blocking call. As\r
- the lowest priority task it will not successfully obtain the mutex until\r
- both the controlling and blocking tasks are suspended. Once it eventually \r
- does obtain the mutex it first unsuspends both the controlling task and\r
- blocking task prior to giving the mutex back - resulting in the polling\r
- task temporarily inheriting the controlling tasks priority.\r
-*/\r
-\r
-/* Scheduler include files. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "semphr.h"\r
-\r
-/* Demo app include files. */\r
-#include "recmutex.h"\r
-\r
-/* Priorities assigned to the three tasks. */\r
-#define recmuCONTROLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
-#define recmuBLOCKING_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
-#define recmuPOLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 )\r
-\r
-/* The recursive call depth. */\r
-#define recmuMAX_COUNT ( 10 )\r
-\r
-/* Misc. */\r
-#define recmuSHORT_DELAY ( 20 / portTICK_RATE_MS )\r
-#define recmuNO_DELAY ( ( portTickType ) 0 )\r
-#define recmuTWO_TICK_DELAY ( ( portTickType ) 2 )\r
-\r
-/* The three tasks as described at the top of this file. */\r
-static void prvRecursiveMutexControllingTask( void *pvParameters );\r
-static void prvRecursiveMutexBlockingTask( void *pvParameters );\r
-static void prvRecursiveMutexPollingTask( void *pvParameters );\r
-\r
-/* The mutex used by the demo. */\r
-static xSemaphoreHandle xMutex;\r
-\r
-/* Variables used to detect and latch errors. */\r
-static volatile portBASE_TYPE xErrorOccurred = pdFALSE, xControllingIsSuspended = pdFALSE, xBlockingIsSuspended = pdFALSE;\r
-static volatile unsigned portBASE_TYPE uxControllingCycles = 0, uxBlockingCycles = 0, uxPollingCycles = 0;\r
-\r
-/* Handles of the two higher priority tasks, required so they can be resumed \r
-(unsuspended). */\r
-static xTaskHandle xControllingTaskHandle, xBlockingTaskHandle;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vStartRecursiveMutexTasks( void )\r
-{\r
- /* Just creates the mutex and the three tasks. */\r
-\r
- xMutex = xSemaphoreCreateRecursiveMutex();\r
-\r
- /* vQueueAddToRegistry() adds the mutex to the registry, if one is\r
- in use. The registry is provided as a means for kernel aware \r
- debuggers to locate mutex and has no purpose if a kernel aware debugger\r
- is not being used. The call to vQueueAddToRegistry() will be removed\r
- by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is \r
- defined to be less than 1. */\r
- vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Recursive_Mutex" );\r
-\r
-\r
- if( xMutex != NULL )\r
- {\r
- xTaskCreate( prvRecursiveMutexControllingTask, ( signed portCHAR * ) "Rec1", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle );\r
- xTaskCreate( prvRecursiveMutexBlockingTask, ( signed portCHAR * ) "Rec2", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle );\r
- xTaskCreate( prvRecursiveMutexPollingTask, ( signed portCHAR * ) "Rec3", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL );\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvRecursiveMutexControllingTask( void *pvParameters )\r
-{\r
-unsigned portBASE_TYPE ux;\r
-\r
- /* Just to remove compiler warning. */\r
- ( void ) pvParameters;\r
-\r
- for( ;; )\r
- {\r
- /* Should not be able to 'give' the mutex, as we have not yet 'taken'\r
- it. The first time through, the mutex will not have been used yet,\r
- subsequent times through, at this point the mutex will be held by the\r
- polling task. */\r
- if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- for( ux = 0; ux < recmuMAX_COUNT; ux++ )\r
- {\r
- /* We should now be able to take the mutex as many times as\r
- we like.\r
- \r
- The first time through the mutex will be immediately available, on\r
- subsequent times through the mutex will be held by the polling task\r
- at this point and this Take will cause the polling task to inherit\r
- the priority of this task. In this case the block time must be\r
- long enough to ensure the polling task will execute again before the\r
- block time expires. If the block time does expire then the error\r
- flag will be set here. */\r
- if( xSemaphoreTakeRecursive( xMutex, recmuTWO_TICK_DELAY ) != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* Ensure the other task attempting to access the mutex (and the\r
- other demo tasks) are able to execute to ensure they either block\r
- (where a block time is specified) or return an error (where no \r
- block time is specified) as the mutex is held by this task. */\r
- vTaskDelay( recmuSHORT_DELAY );\r
- }\r
-\r
- /* For each time we took the mutex, give it back. */\r
- for( ux = 0; ux < recmuMAX_COUNT; ux++ )\r
- {\r
- /* Ensure the other task attempting to access the mutex (and the\r
- other demo tasks) are able to execute. */\r
- vTaskDelay( recmuSHORT_DELAY );\r
-\r
- /* We should now be able to give the mutex as many times as we\r
- took it. When the mutex is available again the Blocking task\r
- should be unblocked but not run because it has a lower priority\r
- than this task. The polling task should also not run at this point\r
- as it too has a lower priority than this task. */\r
- if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
- }\r
-\r
- /* Having given it back the same number of times as it was taken, we\r
- should no longer be the mutex owner, so the next give sh ould fail. */\r
- if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* Keep count of the number of cycles this task has performed so a \r
- stall can be detected. */\r
- uxControllingCycles++;\r
-\r
- /* Suspend ourselves to the blocking task can execute. */\r
- xControllingIsSuspended = pdTRUE;\r
- vTaskSuspend( NULL );\r
- xControllingIsSuspended = pdFALSE;\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvRecursiveMutexBlockingTask( void *pvParameters )\r
-{\r
- /* Just to remove compiler warning. */\r
- ( void ) pvParameters;\r
-\r
- for( ;; )\r
- {\r
- /* This task will run while the controlling task is blocked, and the\r
- controlling task will block only once it has the mutex - therefore\r
- this call should block until the controlling task has given up the \r
- mutex, and not actually execute past this call until the controlling \r
- task is suspended. */\r
- if( xSemaphoreTakeRecursive( xMutex, portMAX_DELAY ) == pdPASS )\r
- {\r
- if( xControllingIsSuspended != pdTRUE )\r
- {\r
- /* Did not expect to execute until the controlling task was\r
- suspended. */\r
- xErrorOccurred = pdTRUE;\r
- }\r
- else\r
- {\r
- /* Give the mutex back before suspending ourselves to allow\r
- the polling task to obtain the mutex. */\r
- if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- xBlockingIsSuspended = pdTRUE;\r
- vTaskSuspend( NULL );\r
- xBlockingIsSuspended = pdFALSE;\r
- }\r
- }\r
- else\r
- {\r
- /* We should not leave the xSemaphoreTakeRecursive() function\r
- until the mutex was obtained. */\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* The controlling and blocking tasks should be in lock step. */\r
- if( uxControllingCycles != ( uxBlockingCycles + 1 ) )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- /* Keep count of the number of cycles this task has performed so a \r
- stall can be detected. */\r
- uxBlockingCycles++;\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvRecursiveMutexPollingTask( void *pvParameters )\r
-{\r
- /* Just to remove compiler warning. */\r
- ( void ) pvParameters;\r
-\r
- for( ;; )\r
- {\r
- /* Keep attempting to obtain the mutex. We should only obtain it when\r
- the blocking task has suspended itself, which in turn should only\r
- happen when the controlling task is also suspended. */\r
- if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS )\r
- {\r
- /* Is the blocking task suspended? */\r
- if( ( xBlockingIsSuspended != pdTRUE ) || ( xControllingIsSuspended != pdTRUE ) )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
- else\r
- {\r
- /* Keep count of the number of cycles this task has performed \r
- so a stall can be detected. */\r
- uxPollingCycles++;\r
-\r
- /* We can resume the other tasks here even though they have a\r
- higher priority than the polling task. When they execute they\r
- will attempt to obtain the mutex but fail because the polling\r
- task is still the mutex holder. The polling task (this task)\r
- will then inherit the higher priority. The Blocking task will\r
- block indefinitely when it attempts to obtain the mutex, the\r
- Controlling task will only block for a fixed period and an\r
- error will be latched if the polling task has not returned the\r
- mutex by the time this fixed period has expired. */\r
- vTaskResume( xBlockingTaskHandle );\r
- vTaskResume( xControllingTaskHandle );\r
- \r
- /* The other two tasks should now have executed and no longer\r
- be suspended. */\r
- if( ( xBlockingIsSuspended == pdTRUE ) || ( xControllingIsSuspended == pdTRUE ) )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- } \r
- \r
- /* Release the mutex, disinheriting the higher priority again. */\r
- if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
- }\r
- }\r
-\r
- #if configUSE_PREEMPTION == 0\r
- {\r
- taskYIELD();\r
- }\r
- #endif\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-/* This is called to check that all the created tasks are still running. */\r
-portBASE_TYPE xAreRecursiveMutexTasksStillRunning( void )\r
-{\r
-portBASE_TYPE xReturn;\r
-static unsigned portBASE_TYPE uxLastControllingCycles = 0, uxLastBlockingCycles = 0, uxLastPollingCycles = 0;\r
-\r
- /* Is the controlling task still cycling? */\r
- if( uxLastControllingCycles == uxControllingCycles )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
- else\r
- {\r
- uxLastControllingCycles = uxControllingCycles;\r
- }\r
-\r
- /* Is the blocking task still cycling? */\r
- if( uxLastBlockingCycles == uxBlockingCycles )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
- else\r
- {\r
- uxLastBlockingCycles = uxBlockingCycles;\r
- }\r
-\r
- /* Is the polling task still cycling? */\r
- if( uxLastPollingCycles == uxPollingCycles )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
- else\r
- {\r
- uxLastPollingCycles = uxPollingCycles;\r
- }\r
-\r
- if( xErrorOccurred == pdTRUE )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
- else\r
- {\r
- xReturn = pdTRUE;\r
- }\r
-\r
- return xReturn;\r
-}\r
-\r
-\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef INC_FREERTOS_H\r
-#define INC_FREERTOS_H\r
-\r
-\r
-/*\r
- * Include the generic headers required for the FreeRTOS port being used.\r
- */\r
-#include <stddef.h>\r
-\r
-/* Basic FreeRTOS definitions. */\r
-#include "projdefs.h"\r
-\r
-/* Application specific configuration options. */\r
-#include "FreeRTOSConfig.h"\r
-\r
-/* Definitions specific to the port being used. */\r
-#include "portable.h"\r
-\r
-\r
-/* Defines the prototype to which the application task hook function must\r
-conform. */\r
-typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );\r
-\r
-\r
-\r
-\r
-\r
-/*\r
- * Check all the required application specific macros have been defined.\r
- * These macros are application specific and (as downloaded) are defined\r
- * within FreeRTOSConfig.h.\r
- */\r
-\r
-#ifndef configUSE_PREEMPTION\r
- #error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef configUSE_IDLE_HOOK\r
- #error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef configUSE_TICK_HOOK\r
- #error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef configUSE_CO_ROUTINES\r
- #error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_vTaskPrioritySet\r
- #error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_uxTaskPriorityGet\r
- #error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_vTaskDelete \r
- #error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_vTaskSuspend \r
- #error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_vTaskDelayUntil\r
- #error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_vTaskDelay\r
- #error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef configUSE_16_BIT_TICKS\r
- #error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_xTaskGetIdleTaskHandle\r
- #define INCLUDE_xTaskGetIdleTaskHandle 0\r
-#endif\r
-\r
-#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle\r
- #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0\r
-#endif\r
-\r
-#ifndef INCLUDE_pcTaskGetTaskName\r
- #define INCLUDE_pcTaskGetTaskName 0\r
-#endif\r
-\r
-#ifndef configUSE_APPLICATION_TASK_TAG\r
- #define configUSE_APPLICATION_TASK_TAG 0\r
-#endif\r
-\r
-#ifndef INCLUDE_uxTaskGetStackHighWaterMark\r
- #define INCLUDE_uxTaskGetStackHighWaterMark 0\r
-#endif\r
-\r
-#ifndef configUSE_RECURSIVE_MUTEXES\r
- #define configUSE_RECURSIVE_MUTEXES 0\r
-#endif\r
-\r
-#ifndef configUSE_MUTEXES\r
- #define configUSE_MUTEXES 0\r
-#endif\r
-\r
-#ifndef configUSE_TIMERS\r
- #define configUSE_TIMERS 0\r
-#endif\r
-\r
-#ifndef configUSE_COUNTING_SEMAPHORES\r
- #define configUSE_COUNTING_SEMAPHORES 0\r
-#endif\r
-\r
-#ifndef configUSE_ALTERNATIVE_API\r
- #define configUSE_ALTERNATIVE_API 0\r
-#endif\r
-\r
-#ifndef portCRITICAL_NESTING_IN_TCB\r
- #define portCRITICAL_NESTING_IN_TCB 0\r
-#endif\r
-\r
-#ifndef configMAX_TASK_NAME_LEN\r
- #define configMAX_TASK_NAME_LEN 16\r
-#endif\r
-\r
-#ifndef configIDLE_SHOULD_YIELD\r
- #define configIDLE_SHOULD_YIELD 1\r
-#endif\r
-\r
-#if configMAX_TASK_NAME_LEN < 1\r
- #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h\r
-#endif\r
-\r
-#ifndef INCLUDE_xTaskResumeFromISR\r
- #define INCLUDE_xTaskResumeFromISR 1\r
-#endif\r
-\r
-#ifndef configASSERT\r
- #define configASSERT( x )\r
-#endif\r
-\r
-#ifndef portALIGNMENT_ASSERT_pxCurrentTCB\r
- #define portALIGNMENT_ASSERT_pxCurrentTCB configASSERT\r
-#endif\r
-\r
-/* The timers module relies on xTaskGetSchedulerState(). */\r
-#if configUSE_TIMERS == 1\r
-\r
- #ifndef configTIMER_TASK_PRIORITY\r
- #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined.\r
- #endif /* configTIMER_TASK_PRIORITY */\r
-\r
- #ifndef configTIMER_QUEUE_LENGTH\r
- #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined.\r
- #endif /* configTIMER_QUEUE_LENGTH */\r
-\r
- #ifndef configTIMER_TASK_STACK_DEPTH\r
- #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined.\r
- #endif /* configTIMER_TASK_STACK_DEPTH */\r
-\r
-#endif /* configUSE_TIMERS */\r
-\r
-#ifndef INCLUDE_xTaskGetSchedulerState\r
- #define INCLUDE_xTaskGetSchedulerState 0\r
-#endif\r
-\r
-#ifndef INCLUDE_xTaskGetCurrentTaskHandle\r
- #define INCLUDE_xTaskGetCurrentTaskHandle 0\r
-#endif\r
-\r
-\r
-#ifndef portSET_INTERRUPT_MASK_FROM_ISR\r
- #define portSET_INTERRUPT_MASK_FROM_ISR() 0\r
-#endif\r
-\r
-#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR\r
- #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue\r
-#endif\r
-\r
-#ifndef portCLEAN_UP_TCB\r
- #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB\r
-#endif\r
-\r
-#ifndef configQUEUE_REGISTRY_SIZE\r
- #define configQUEUE_REGISTRY_SIZE 0U\r
-#endif\r
-\r
-#if ( configQUEUE_REGISTRY_SIZE < 1 )\r
- #define vQueueAddToRegistry( xQueue, pcName )\r
- #define vQueueUnregisterQueue( xQueue )\r
-#endif\r
-\r
-#ifndef portPOINTER_SIZE_TYPE\r
- #define portPOINTER_SIZE_TYPE unsigned long\r
-#endif\r
-\r
-/* Remove any unused trace macros. */\r
-#ifndef traceSTART\r
- /* Used to perform any necessary initialisation - for example, open a file\r
- into which trace is to be written. */\r
- #define traceSTART()\r
-#endif\r
-\r
-#ifndef traceEND\r
- /* Use to close a trace, for example close a file into which trace has been\r
- written. */\r
- #define traceEND()\r
-#endif\r
-\r
-#ifndef traceTASK_SWITCHED_IN\r
- /* Called after a task has been selected to run. pxCurrentTCB holds a pointer\r
- to the task control block of the selected task. */\r
- #define traceTASK_SWITCHED_IN()\r
-#endif\r
-\r
-#ifndef traceTASK_SWITCHED_OUT\r
- /* Called before a task has been selected to run. pxCurrentTCB holds a pointer\r
- to the task control block of the task being switched out. */\r
- #define traceTASK_SWITCHED_OUT()\r
-#endif\r
-\r
-#ifndef traceTASK_PRIORITY_INHERIT\r
- /* Called when a task attempts to take a mutex that is already held by a\r
- lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task\r
- that holds the mutex. uxInheritedPriority is the priority the mutex holder\r
- will inherit (the priority of the task that is attempting to obtain the\r
- muted. */\r
- #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority )\r
-#endif\r
-\r
-#ifndef traceTASK_PRIORITY_DISINHERIT\r
- /* Called when a task releases a mutex, the holding of which had resulted in\r
- the task inheriting the priority of a higher priority task. \r
- pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the\r
- mutex. uxOriginalPriority is the task's configured (base) priority. */\r
- #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority )\r
-#endif\r
-\r
-#ifndef traceBLOCKING_ON_QUEUE_RECEIVE\r
- /* Task is about to block because it cannot read from a\r
- queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore\r
- upon which the read was attempted. pxCurrentTCB points to the TCB of the\r
- task that attempted the read. */\r
- #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )\r
-#endif\r
-\r
-#ifndef traceBLOCKING_ON_QUEUE_SEND\r
- /* Task is about to block because it cannot write to a\r
- queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore\r
- upon which the write was attempted. pxCurrentTCB points to the TCB of the\r
- task that attempted the write. */\r
- #define traceBLOCKING_ON_QUEUE_SEND( pxQueue )\r
-#endif\r
-\r
-#ifndef configCHECK_FOR_STACK_OVERFLOW\r
- #define configCHECK_FOR_STACK_OVERFLOW 0\r
-#endif\r
-\r
-/* The following event macros are embedded in the kernel API calls. */\r
-\r
-#ifndef traceQUEUE_CREATE \r
- #define traceQUEUE_CREATE( pxNewQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_CREATE_FAILED\r
- #define traceQUEUE_CREATE_FAILED( ucQueueType )\r
-#endif\r
-\r
-#ifndef traceCREATE_MUTEX\r
- #define traceCREATE_MUTEX( pxNewQueue )\r
-#endif\r
-\r
-#ifndef traceCREATE_MUTEX_FAILED\r
- #define traceCREATE_MUTEX_FAILED()\r
-#endif\r
-\r
-#ifndef traceGIVE_MUTEX_RECURSIVE\r
- #define traceGIVE_MUTEX_RECURSIVE( pxMutex )\r
-#endif\r
-\r
-#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED\r
- #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )\r
-#endif\r
-\r
-#ifndef traceTAKE_MUTEX_RECURSIVE\r
- #define traceTAKE_MUTEX_RECURSIVE( pxMutex )\r
-#endif\r
-\r
-#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED\r
- #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex )\r
-#endif\r
-\r
-#ifndef traceCREATE_COUNTING_SEMAPHORE\r
- #define traceCREATE_COUNTING_SEMAPHORE()\r
-#endif\r
-\r
-#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED\r
- #define traceCREATE_COUNTING_SEMAPHORE_FAILED()\r
-#endif\r
-\r
-#ifndef traceQUEUE_SEND\r
- #define traceQUEUE_SEND( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_SEND_FAILED\r
- #define traceQUEUE_SEND_FAILED( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_RECEIVE\r
- #define traceQUEUE_RECEIVE( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_PEEK\r
- #define traceQUEUE_PEEK( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_RECEIVE_FAILED\r
- #define traceQUEUE_RECEIVE_FAILED( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_SEND_FROM_ISR\r
- #define traceQUEUE_SEND_FROM_ISR( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_SEND_FROM_ISR_FAILED\r
- #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_RECEIVE_FROM_ISR\r
- #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED\r
- #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_DELETE\r
- #define traceQUEUE_DELETE( pxQueue )\r
-#endif\r
-\r
-#ifndef traceTASK_CREATE\r
- #define traceTASK_CREATE( pxNewTCB )\r
-#endif\r
-\r
-#ifndef traceTASK_CREATE_FAILED\r
- #define traceTASK_CREATE_FAILED()\r
-#endif\r
-\r
-#ifndef traceTASK_DELETE\r
- #define traceTASK_DELETE( pxTaskToDelete )\r
-#endif\r
-\r
-#ifndef traceTASK_DELAY_UNTIL\r
- #define traceTASK_DELAY_UNTIL()\r
-#endif\r
-\r
-#ifndef traceTASK_DELAY\r
- #define traceTASK_DELAY()\r
-#endif\r
-\r
-#ifndef traceTASK_PRIORITY_SET\r
- #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )\r
-#endif\r
-\r
-#ifndef traceTASK_SUSPEND\r
- #define traceTASK_SUSPEND( pxTaskToSuspend )\r
-#endif\r
-\r
-#ifndef traceTASK_RESUME\r
- #define traceTASK_RESUME( pxTaskToResume )\r
-#endif\r
-\r
-#ifndef traceTASK_RESUME_FROM_ISR\r
- #define traceTASK_RESUME_FROM_ISR( pxTaskToResume )\r
-#endif\r
-\r
-#ifndef traceTASK_INCREMENT_TICK\r
- #define traceTASK_INCREMENT_TICK( xTickCount )\r
-#endif\r
-\r
-#ifndef traceTIMER_CREATE\r
- #define traceTIMER_CREATE( pxNewTimer )\r
-#endif\r
-\r
-#ifndef traceTIMER_CREATE_FAILED\r
- #define traceTIMER_CREATE_FAILED()\r
-#endif\r
-\r
-#ifndef traceTIMER_COMMAND_SEND\r
- #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn )\r
-#endif\r
-\r
-#ifndef traceTIMER_EXPIRED\r
- #define traceTIMER_EXPIRED( pxTimer )\r
-#endif\r
-\r
-#ifndef traceTIMER_COMMAND_RECEIVED\r
- #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )\r
-#endif\r
-\r
-#ifndef configGENERATE_RUN_TIME_STATS\r
- #define configGENERATE_RUN_TIME_STATS 0\r
-#endif\r
-\r
-#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
-\r
- #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS\r
- #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base.\r
- #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */\r
-\r
- #ifndef portGET_RUN_TIME_COUNTER_VALUE\r
- #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE\r
- #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information.\r
- #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */\r
- #endif /* portGET_RUN_TIME_COUNTER_VALUE */\r
-\r
-#endif /* configGENERATE_RUN_TIME_STATS */\r
-\r
-#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS\r
- #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()\r
-#endif\r
-\r
-#ifndef configUSE_MALLOC_FAILED_HOOK\r
- #define configUSE_MALLOC_FAILED_HOOK 0\r
-#endif\r
-\r
-#ifndef portPRIVILEGE_BIT\r
- #define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 )\r
-#endif\r
-\r
-#ifndef portYIELD_WITHIN_API\r
- #define portYIELD_WITHIN_API portYIELD\r
-#endif\r
-\r
-#ifndef pvPortMallocAligned\r
- #define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxStackBuffer ) )\r
-#endif\r
-\r
-#ifndef vPortFreeAligned\r
- #define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )\r
-#endif\r
-\r
-#endif /* INC_FREERTOS_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef STACK_MACROS_H\r
-#define STACK_MACROS_H\r
-\r
-/*\r
- * Call the stack overflow hook function if the stack of the task being swapped\r
- * out is currently overflowed, or looks like it might have overflowed in the\r
- * past.\r
- *\r
- * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check\r
- * the current stack state only - comparing the current top of stack value to\r
- * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1\r
- * will also cause the last few stack bytes to be checked to ensure the value\r
- * to which the bytes were set when the task was created have not been\r
- * overwritten. Note this second test does not guarantee that an overflowed\r
- * stack will always be recognised.\r
- */\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( configCHECK_FOR_STACK_OVERFLOW == 0 )\r
-\r
- /* FreeRTOSConfig.h is not set to check for stack overflows. */\r
- #define taskFIRST_CHECK_FOR_STACK_OVERFLOW()\r
- #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()\r
-\r
-#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( configCHECK_FOR_STACK_OVERFLOW == 1 )\r
-\r
- /* FreeRTOSConfig.h is only set to use the first method of\r
- overflow checking. */\r
- #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) )\r
-\r
- /* Only the current stack state is to be checked. */\r
- #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \\r
- { \\r
- /* Is the currently saved stack pointer within the stack limit? */ \\r
- if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \\r
- { \\r
- vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
- } \\r
- }\r
-\r
-#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) )\r
-\r
- /* Only the current stack state is to be checked. */\r
- #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \\r
- { \\r
- \\r
- /* Is the currently saved stack pointer within the stack limit? */ \\r
- if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \\r
- { \\r
- vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
- } \\r
- }\r
-\r
-#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )\r
-\r
- #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \\r
- { \\r
- static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \\r
- \\r
- \\r
- /* Has the extremity of the task stack ever been written over? */ \\r
- if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \\r
- { \\r
- vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
- } \\r
- }\r
-\r
-#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )\r
-\r
- #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \\r
- { \\r
- char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \\r
- static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \\r
- \\r
- \\r
- pcEndOfStack -= sizeof( ucExpectedStackBytes ); \\r
- \\r
- /* Has the extremity of the task stack ever been written over? */ \\r
- if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \\r
- { \\r
- vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
- } \\r
- }\r
-\r
-#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */\r
-/*-----------------------------------------------------------*/\r
-\r
-#endif /* STACK_MACROS_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef CO_ROUTINE_H\r
-#define CO_ROUTINE_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "include FreeRTOS.h must appear in source files before include croutine.h"\r
-#endif\r
-\r
-#include "list.h"\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/* Used to hide the implementation of the co-routine control block. The\r
-control block structure however has to be included in the header due to\r
-the macro implementation of the co-routine functionality. */\r
-typedef void * xCoRoutineHandle;\r
-\r
-/* Defines the prototype to which co-routine functions must conform. */\r
-typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );\r
-\r
-typedef struct corCoRoutineControlBlock\r
-{\r
- crCOROUTINE_CODE pxCoRoutineFunction;\r
- xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */\r
- xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */\r
- unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */\r
- unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */\r
- unsigned short uxState; /*< Used internally by the co-routine implementation. */\r
-} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */\r
-\r
-/**\r
- * croutine. h\r
- *<pre>\r
- portBASE_TYPE xCoRoutineCreate(\r
- crCOROUTINE_CODE pxCoRoutineCode,\r
- unsigned portBASE_TYPE uxPriority,\r
- unsigned portBASE_TYPE uxIndex\r
- );</pre>\r
- *\r
- * Create a new co-routine and add it to the list of co-routines that are\r
- * ready to run.\r
- *\r
- * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine\r
- * functions require special syntax - see the co-routine section of the WEB\r
- * documentation for more information.\r
- *\r
- * @param uxPriority The priority with respect to other co-routines at which\r
- * the co-routine will run.\r
- *\r
- * @param uxIndex Used to distinguish between different co-routines that\r
- * execute the same function. See the example below and the co-routine section\r
- * of the WEB documentation for further information.\r
- *\r
- * @return pdPASS if the co-routine was successfully created and added to a ready\r
- * list, otherwise an error code defined with ProjDefs.h.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- // This may not be necessary for const variables.\r
- static const char cLedToFlash[ 2 ] = { 5, 6 };\r
- static const portTickType uxFlashRates[ 2 ] = { 200, 400 };\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // This co-routine just delays for a fixed period, then toggles\r
- // an LED. Two co-routines are created using this function, so\r
- // the uxIndex parameter is used to tell the co-routine which\r
- // LED to flash and how long to delay. This assumes xQueue has\r
- // already been created.\r
- vParTestToggleLED( cLedToFlash[ uxIndex ] );\r
- crDELAY( xHandle, uxFlashRates[ uxIndex ] );\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }\r
-\r
- // Function that creates two co-routines.\r
- void vOtherFunction( void )\r
- {\r
- unsigned char ucParameterToPass;\r
- xTaskHandle xHandle;\r
- \r
- // Create two co-routines at priority 0. The first is given index 0\r
- // so (from the code above) toggles LED 5 every 200 ticks. The second\r
- // is given index 1 so toggles LED 6 every 400 ticks.\r
- for( uxIndex = 0; uxIndex < 2; uxIndex++ )\r
- {\r
- xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );\r
- }\r
- }\r
- </pre>\r
- * \defgroup xCoRoutineCreate xCoRoutineCreate\r
- * \ingroup Tasks\r
- */\r
-signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );\r
-\r
-\r
-/**\r
- * croutine. h\r
- *<pre>\r
- void vCoRoutineSchedule( void );</pre>\r
- *\r
- * Run a co-routine.\r
- *\r
- * vCoRoutineSchedule() executes the highest priority co-routine that is able\r
- * to run. The co-routine will execute until it either blocks, yields or is\r
- * preempted by a task. Co-routines execute cooperatively so one\r
- * co-routine cannot be preempted by another, but can be preempted by a task.\r
- *\r
- * If an application comprises of both tasks and co-routines then\r
- * vCoRoutineSchedule should be called from the idle task (in an idle task\r
- * hook).\r
- *\r
- * Example usage:\r
- <pre>\r
- // This idle task hook will schedule a co-routine each time it is called.\r
- // The rest of the idle task will execute between co-routine calls.\r
- void vApplicationIdleHook( void )\r
- {\r
- vCoRoutineSchedule();\r
- }\r
-\r
- // Alternatively, if you do not require any other part of the idle task to\r
- // execute, the idle task hook can call vCoRoutineScheduler() within an\r
- // infinite loop.\r
- void vApplicationIdleHook( void )\r
- {\r
- for( ;; )\r
- {\r
- vCoRoutineSchedule();\r
- }\r
- }\r
- </pre>\r
- * \defgroup vCoRoutineSchedule vCoRoutineSchedule\r
- * \ingroup Tasks\r
- */\r
-void vCoRoutineSchedule( void );\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crSTART( xCoRoutineHandle xHandle );</pre>\r
- *\r
- * This macro MUST always be called at the start of a co-routine function.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static long ulAVariable;\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Co-routine functionality goes here.\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }</pre>\r
- * \defgroup crSTART crSTART\r
- * \ingroup Tasks\r
- */\r
-#define crSTART( pxCRCB ) switch( ( ( corCRCB * )( pxCRCB ) )->uxState ) { case 0:\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crEND();</pre>\r
- *\r
- * This macro MUST always be called at the end of a co-routine function.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static long ulAVariable;\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Co-routine functionality goes here.\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }</pre>\r
- * \defgroup crSTART crSTART\r
- * \ingroup Tasks\r
- */\r
-#define crEND() }\r
-\r
-/*\r
- * These macros are intended for internal use by the co-routine implementation\r
- * only. The macros should not be used directly by application writers.\r
- */\r
-#define crSET_STATE0( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):\r
-#define crSET_STATE1( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):\r
-\r
-/**\r
- * croutine. h\r
- *<pre>\r
- crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>\r
- *\r
- * Delay a co-routine for a fixed period of time.\r
- *\r
- * crDELAY can only be called from the co-routine function itself - not\r
- * from within a function called by the co-routine function. This is because\r
- * co-routines do not maintain their own stack.\r
- *\r
- * @param xHandle The handle of the co-routine to delay. This is the xHandle\r
- * parameter of the co-routine function.\r
- *\r
- * @param xTickToDelay The number of ticks that the co-routine should delay\r
- * for. The actual amount of time this equates to is defined by\r
- * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS\r
- * can be used to convert ticks to milliseconds.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- // This may not be necessary for const variables.\r
- // We are to delay for 200ms.\r
- static const xTickType xDelayTime = 200 / portTICK_RATE_MS;\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Delay for 200ms.\r
- crDELAY( xHandle, xDelayTime );\r
-\r
- // Do something here.\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }</pre>\r
- * \defgroup crDELAY crDELAY\r
- * \ingroup Tasks\r
- */\r
-#define crDELAY( xHandle, xTicksToDelay ) \\r
- if( ( xTicksToDelay ) > 0 ) \\r
- { \\r
- vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \\r
- } \\r
- crSET_STATE0( ( xHandle ) );\r
-\r
-/**\r
- * <pre>\r
- crQUEUE_SEND(\r
- xCoRoutineHandle xHandle,\r
- xQueueHandle pxQueue,\r
- void *pvItemToQueue,\r
- portTickType xTicksToWait,\r
- portBASE_TYPE *pxResult\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine\r
- * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.\r
- *\r
- * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas\r
- * xQueueSend() and xQueueReceive() can only be used from tasks.\r
- *\r
- * crQUEUE_SEND can only be called from the co-routine function itself - not\r
- * from within a function called by the co-routine function. This is because\r
- * co-routines do not maintain their own stack.\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xHandle The handle of the calling co-routine. This is the xHandle\r
- * parameter of the co-routine function.\r
- *\r
- * @param pxQueue The handle of the queue on which the data will be posted.\r
- * The handle is obtained as the return value when the queue is created using\r
- * the xQueueCreate() API function.\r
- *\r
- * @param pvItemToQueue A pointer to the data being posted onto the queue.\r
- * The number of bytes of each queued item is specified when the queue is\r
- * created. This number of bytes is copied from pvItemToQueue into the queue\r
- * itself.\r
- *\r
- * @param xTickToDelay The number of ticks that the co-routine should block\r
- * to wait for space to become available on the queue, should space not be\r
- * available immediately. The actual amount of time this equates to is defined\r
- * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant\r
- * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example\r
- * below).\r
- *\r
- * @param pxResult The variable pointed to by pxResult will be set to pdPASS if\r
- * data was successfully posted onto the queue, otherwise it will be set to an\r
- * error defined within ProjDefs.h.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine function that blocks for a fixed period then posts a number onto\r
- // a queue.\r
- static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static portBASE_TYPE xNumberToPost = 0;\r
- static portBASE_TYPE xResult;\r
-\r
- // Co-routines must begin with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // This assumes the queue has already been created.\r
- crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );\r
-\r
- if( xResult != pdPASS )\r
- {\r
- // The message was not posted!\r
- }\r
-\r
- // Increment the number to be posted onto the queue.\r
- xNumberToPost++;\r
-\r
- // Delay for 100 ticks.\r
- crDELAY( xHandle, 100 );\r
- }\r
-\r
- // Co-routines must end with a call to crEND().\r
- crEND();\r
- }</pre>\r
- * \defgroup crQUEUE_SEND crQUEUE_SEND\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \\r
-{ \\r
- *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \\r
- if( *( pxResult ) == errQUEUE_BLOCKED ) \\r
- { \\r
- crSET_STATE0( ( xHandle ) ); \\r
- *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \\r
- } \\r
- if( *pxResult == errQUEUE_YIELD ) \\r
- { \\r
- crSET_STATE1( ( xHandle ) ); \\r
- *pxResult = pdPASS; \\r
- } \\r
-}\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crQUEUE_RECEIVE(\r
- xCoRoutineHandle xHandle,\r
- xQueueHandle pxQueue,\r
- void *pvBuffer,\r
- portTickType xTicksToWait,\r
- portBASE_TYPE *pxResult\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine\r
- * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.\r
- *\r
- * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas\r
- * xQueueSend() and xQueueReceive() can only be used from tasks.\r
- *\r
- * crQUEUE_RECEIVE can only be called from the co-routine function itself - not\r
- * from within a function called by the co-routine function. This is because\r
- * co-routines do not maintain their own stack.\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xHandle The handle of the calling co-routine. This is the xHandle\r
- * parameter of the co-routine function.\r
- *\r
- * @param pxQueue The handle of the queue from which the data will be received.\r
- * The handle is obtained as the return value when the queue is created using\r
- * the xQueueCreate() API function.\r
- *\r
- * @param pvBuffer The buffer into which the received item is to be copied.\r
- * The number of bytes of each queued item is specified when the queue is\r
- * created. This number of bytes is copied into pvBuffer.\r
- *\r
- * @param xTickToDelay The number of ticks that the co-routine should block\r
- * to wait for data to become available from the queue, should data not be\r
- * available immediately. The actual amount of time this equates to is defined\r
- * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant\r
- * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the\r
- * crQUEUE_SEND example).\r
- *\r
- * @param pxResult The variable pointed to by pxResult will be set to pdPASS if\r
- * data was successfully retrieved from the queue, otherwise it will be set to\r
- * an error code as defined within ProjDefs.h.\r
- *\r
- * Example usage:\r
- <pre>\r
- // A co-routine receives the number of an LED to flash from a queue. It\r
- // blocks on the queue until the number is received.\r
- static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static portBASE_TYPE xResult;\r
- static unsigned portBASE_TYPE uxLEDToFlash;\r
-\r
- // All co-routines must start with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Wait for data to become available on the queue.\r
- crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );\r
-\r
- if( xResult == pdPASS )\r
- {\r
- // We received the LED to flash - flash it!\r
- vParTestToggleLED( uxLEDToFlash );\r
- }\r
- }\r
-\r
- crEND();\r
- }</pre>\r
- * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \\r
-{ \\r
- *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \\r
- if( *( pxResult ) == errQUEUE_BLOCKED ) \\r
- { \\r
- crSET_STATE0( ( xHandle ) ); \\r
- *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \\r
- } \\r
- if( *( pxResult ) == errQUEUE_YIELD ) \\r
- { \\r
- crSET_STATE1( ( xHandle ) ); \\r
- *( pxResult ) = pdPASS; \\r
- } \\r
-}\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crQUEUE_SEND_FROM_ISR(\r
- xQueueHandle pxQueue,\r
- void *pvItemToQueue,\r
- portBASE_TYPE xCoRoutinePreviouslyWoken\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the\r
- * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()\r
- * functions used by tasks.\r
- *\r
- * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to\r
- * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and\r
- * xQueueReceiveFromISR() can only be used to pass data between a task and and\r
- * ISR.\r
- *\r
- * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue\r
- * that is being used from within a co-routine.\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto\r
- * the same queue multiple times from a single interrupt. The first call\r
- * should always pass in pdFALSE. Subsequent calls should pass in\r
- * the value returned from the previous call.\r
- *\r
- * @return pdTRUE if a co-routine was woken by posting onto the queue. This is\r
- * used by the ISR to determine if a context switch may be required following\r
- * the ISR.\r
- *\r
- * Example usage:\r
- <pre>\r
- // A co-routine that blocks on a queue waiting for characters to be received.\r
- static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- char cRxedChar;\r
- portBASE_TYPE xResult;\r
-\r
- // All co-routines must start with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Wait for data to become available on the queue. This assumes the\r
- // queue xCommsRxQueue has already been created!\r
- crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );\r
-\r
- // Was a character received?\r
- if( xResult == pdPASS )\r
- {\r
- // Process the character here.\r
- }\r
- }\r
-\r
- // All co-routines must end with a call to crEND().\r
- crEND();\r
- }\r
-\r
- // An ISR that uses a queue to send characters received on a serial port to\r
- // a co-routine.\r
- void vUART_ISR( void )\r
- {\r
- char cRxedChar;\r
- portBASE_TYPE xCRWokenByPost = pdFALSE;\r
-\r
- // We loop around reading characters until there are none left in the UART.\r
- while( UART_RX_REG_NOT_EMPTY() )\r
- {\r
- // Obtain the character from the UART.\r
- cRxedChar = UART_RX_REG;\r
-\r
- // Post the character onto a queue. xCRWokenByPost will be pdFALSE\r
- // the first time around the loop. If the post causes a co-routine\r
- // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.\r
- // In this manner we can ensure that if more than one co-routine is\r
- // blocked on the queue only one is woken by this ISR no matter how\r
- // many characters are posted to the queue.\r
- xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );\r
- }\r
- }</pre>\r
- * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )\r
-\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crQUEUE_SEND_FROM_ISR(\r
- xQueueHandle pxQueue,\r
- void *pvBuffer,\r
- portBASE_TYPE * pxCoRoutineWoken\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the\r
- * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()\r
- * functions used by tasks.\r
- *\r
- * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to\r
- * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and\r
- * xQueueReceiveFromISR() can only be used to pass data between a task and and\r
- * ISR.\r
- *\r
- * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data\r
- * from a queue that is being used from within a co-routine (a co-routine\r
- * posted to the queue).\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvBuffer A pointer to a buffer into which the received item will be\r
- * placed. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from the queue into\r
- * pvBuffer.\r
- *\r
- * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become\r
- * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a\r
- * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise\r
- * *pxCoRoutineWoken will remain unchanged.\r
- *\r
- * @return pdTRUE an item was successfully received from the queue, otherwise\r
- * pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
- // A co-routine that posts a character to a queue then blocks for a fixed\r
- // period. The character is incremented each time.\r
- static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // cChar holds its value while this co-routine is blocked and must therefore\r
- // be declared static.\r
- static char cCharToTx = 'a';\r
- portBASE_TYPE xResult;\r
-\r
- // All co-routines must start with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Send the next character to the queue.\r
- crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );\r
-\r
- if( xResult == pdPASS )\r
- {\r
- // The character was successfully posted to the queue.\r
- }\r
- else\r
- {\r
- // Could not post the character to the queue.\r
- }\r
-\r
- // Enable the UART Tx interrupt to cause an interrupt in this\r
- // hypothetical UART. The interrupt will obtain the character\r
- // from the queue and send it.\r
- ENABLE_RX_INTERRUPT();\r
-\r
- // Increment to the next character then block for a fixed period.\r
- // cCharToTx will maintain its value across the delay as it is\r
- // declared static.\r
- cCharToTx++;\r
- if( cCharToTx > 'x' )\r
- {\r
- cCharToTx = 'a';\r
- }\r
- crDELAY( 100 );\r
- }\r
-\r
- // All co-routines must end with a call to crEND().\r
- crEND();\r
- }\r
-\r
- // An ISR that uses a queue to receive characters to send on a UART.\r
- void vUART_ISR( void )\r
- {\r
- char cCharToTx;\r
- portBASE_TYPE xCRWokenByPost = pdFALSE;\r
-\r
- while( UART_TX_REG_EMPTY() )\r
- {\r
- // Are there any characters in the queue waiting to be sent?\r
- // xCRWokenByPost will automatically be set to pdTRUE if a co-routine\r
- // is woken by the post - ensuring that only a single co-routine is\r
- // woken no matter how many times we go around this loop.\r
- if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )\r
- {\r
- SEND_CHARACTER( cCharToTx );\r
- }\r
- }\r
- }</pre>\r
- * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )\r
-\r
-/*\r
- * This function is intended for internal use by the co-routine macros only.\r
- * The macro nature of the co-routine implementation requires that the\r
- * prototype appears here. The function should not be used by application\r
- * writers.\r
- *\r
- * Removes the current co-routine from its ready list and places it in the\r
- * appropriate delayed list.\r
- */\r
-void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );\r
-\r
-/*\r
- * This function is intended for internal use by the queue implementation only.\r
- * The function should not be used by application writers.\r
- *\r
- * Removes the highest priority co-routine from the event list and places it in\r
- * the pending ready list.\r
- */\r
-signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* CO_ROUTINE_H */\r
+++ /dev/null
-#ifndef TIMER_TEST_H\r
-#define TIMER_TEST_H\r
-\r
-#define tmrtestNUM_TIMERS 2\r
-\r
-\r
-extern portTickType xTickCount;\r
-extern xTaskHandle pxCurrentTCB;\r
-extern portTickType xNumOfOverflows;\r
-\r
-static void vTimerTest_Initialise( void );\r
-static portBASE_TYPE xTimerTest1_xTimeStartAndResetWakeTimeCalculation( void );\r
-portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier );\r
-\r
-static void prvCheckServiceTaskBehaviour( portBASE_TYPE x, portBASE_TYPE xExpireTimeHasOverflowed, portBASE_TYPE xTickCountOverflowed );\r
-\r
-static void prvTestFailed( void );\r
-\r
-xTIMER *xAutoReloadTimers[ tmrtestNUM_TIMERS ];\r
-unsigned portBASE_TYPE uxAutoReloadTimerCounters[ tmrtestNUM_TIMERS ];\r
-portBASE_TYPE xTestStatus = pdPASS;\r
-xTaskHandle xTestTask1 = NULL, xTestTask2 = NULL;\r
-\r
-struct xTestData\r
-{\r
- portTickType xStartTickCount;\r
- portTickType xTimerPeriod;\r
- portTickType xTickIncrementBetweenCommandAndProcessing;\r
- portTickType xExpectedCalculatedExpiryTime;\r
- xList * pxExpectedList;\r
- unsigned portBASE_TYPE uxExpectedCallbackCount;\r
-};\r
-\r
-const struct xTestData xTestCase[] =\r
-{\r
- /* xStartTickCount, xTimerPeriod, Tck Inc, Expected Expire Time, Expected list, Expected callback count */\r
-\r
- /* Test cases when the command to start a timer and the processing of the\r
- start command execute without the tick count incrementing in between. */\r
- { portMAX_DELAY - 8, 2, 0, ( portMAX_DELAY - 8 ) + 2, &xActiveTimerList1, 0 }, /* Expire before an overflow. */\r
- { portMAX_DELAY - 8, 8, 0, ( portMAX_DELAY - 8 ) + 8, &xActiveTimerList1, 0 }, /* Expire immediately before and overflow. */\r
- { portMAX_DELAY - 8, 9, 0, 0, &xActiveTimerList2, 0 }, /* Expire on an overflow. */\r
- { portMAX_DELAY - 8, portMAX_DELAY, 0, ( ( portMAX_DELAY - 8 ) - 1 ), &xActiveTimerList2, 0 }, /* Delay for the longest possible time. */\r
- { portMAX_DELAY, portMAX_DELAY, 0, ( portMAX_DELAY - 1 ), &xActiveTimerList2, 0 }, /* Delay for the longest possible time starting from the maximum tick count. */\r
- { 0, portMAX_DELAY, 0, ( portMAX_DELAY ), &xActiveTimerList1, 0 }, /* Delay for the maximum ticks, starting with from the minimum tick count. */\r
-\r
- /* Test cases when the command to start a timer and the processing of the\r
- start command execute at different tick count values. */\r
- { portMAX_DELAY - 8, 2, 1, ( portMAX_DELAY - 8 ) + 2, &xActiveTimerList1, 0 }, /* The expire time does not overflow, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 8, 8, 2, ( portMAX_DELAY - 8 ) + 8, &xActiveTimerList1, 0 }, /* The expire time does not overflow but is on the portMAX_DELAY limit, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 8, 9, 3, 0, &xActiveTimerList2, 0 }, /* The expire time overflows to 0, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 2, 9, 1, ( portMAX_DELAY - 2 ) + 9, &xActiveTimerList2, 0 }, /* The expire time overflows, but the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 2, 9, 3, ( portMAX_DELAY - 2 ) + 9, &xActiveTimerList2, 0 }, /* The timer overflows between the command and processing the command. The expire time also overflows. */\r
-\r
- /* Add tests where the timer should have expired by the time the command is processed. */\r
- { 10, 9, 10, ( 10 + ( 2 * 9 ) ), &xActiveTimerList1, 1 }, /* Nothing overflows, but the time between the timer being set and the command being processed is greater than the timers expiry time. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded. */\r
- { portMAX_DELAY - 2, 9, 10, ( portMAX_DELAY - 2 ) + ( 2 * 9 ), &xActiveTimerList2, 1 }, /* The timer overflows between the command and processing the command. The expire time also overflows and the number of ticks that occur between the command and the processing exceeds the timer expiry period. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 2, 9, 9, ( portMAX_DELAY - 2 ) + ( 2 * 9 ), &xActiveTimerList2, 1 }, /* The timer overflows between the command and processing the command. The expire time also overflows and the number of ticks between command and processing equals the timer expiry period. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
-\r
- { portMAX_DELAY - 20, 9, 21, ( portMAX_DELAY - 20 ) + ( 3 * 9 ), &xActiveTimerList2, 2 }, /* The tick count has overflowed but the timer expire time has not overflowed. The tick count overflows to 0. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 20, 9, 22, ( portMAX_DELAY - 20 ) + ( 3 * 9 ), &xActiveTimerList2, 2 }, /* The tick count has overflowed but the timer expire time has not overflowed. The tick count overflows to greater than 0. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 5, 2, 20, ( portMAX_DELAY - 5 ) + ( 11 * 2 ), &xActiveTimerList2, 10 }, /* The tick and expire time overflow, but the first expire time overflow results in a time that is less than the tick count. */\r
-};\r
-\r
-typedef struct tskTaskControlBlockx\r
-{\r
- volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */\r
-\r
- #if ( portUSING_MPU_WRAPPERS == 1 )\r
- xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */\r
- #endif \r
- \r
- xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */\r
- xListItem xEventListItem; /*< List item used to place the TCB in event lists. */\r
- unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */\r
- portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */\r
- signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */\r
-\r
- #if ( portSTACK_GROWTH > 0 )\r
- portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */\r
- #endif\r
-\r
- #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
- unsigned portBASE_TYPE uxCriticalNesting;\r
- #endif\r
-\r
- #if ( configUSE_TRACE_FACILITY == 1 )\r
- unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */\r
- #endif\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */\r
- #endif\r
-\r
- #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
- pdTASK_HOOK_CODE pxTaskTag;\r
- #endif\r
-\r
- #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
- unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */\r
- #endif\r
-\r
-} tskTCBx;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vAutoReloadTimerCallback( xTIMER *pxTimer )\r
-{\r
-portBASE_TYPE xTimerID = ( portBASE_TYPE ) pxTimer->pvTimerID;\r
-\r
- if( xTimerID < tmrtestNUM_TIMERS )\r
- {\r
- ( uxAutoReloadTimerCounters[ xTimerID ] )++;\r
- }\r
- else\r
- {\r
- prvTestFailed();\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vTimerTest_Initialise( void )\r
-{\r
-portBASE_TYPE xTimerNumber;\r
-extern void prvInitialiseTaskLists( void );\r
-extern portBASE_TYPE xSchedulerRunning;\r
-\r
- prvInitialiseTaskLists();\r
- xTimerQueue = NULL;\r
- xSchedulerRunning = pdTRUE;\r
-\r
- for( xTimerNumber = 0; xTimerNumber < tmrtestNUM_TIMERS; xTimerNumber++ )\r
- {\r
- /* Delete any existing timers. */\r
- if( xAutoReloadTimers[ xTimerNumber ] != NULL )\r
- {\r
- vPortFree( xAutoReloadTimers[ xTimerNumber ] );\r
- }\r
-\r
- /* Create new autoreload timers. */\r
- xAutoReloadTimers[ xTimerNumber ] = xTimerCreate( "Timer", 0xffff, pdTRUE, ( void * ) xTimerNumber, vAutoReloadTimerCallback );\r
- uxAutoReloadTimerCounters[ xTimerNumber ] = 0;\r
- if( xAutoReloadTimers == NULL )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- /* Initialise lists so they are empty. */\r
- vListInitialise( &xActiveTimerList1 );\r
- vListInitialise( &xActiveTimerList2 );\r
-\r
- /* Call prvSampleTimeNow with a tick count of zero so it sets its \r
- internal static "last time" variable to zero. */\r
- xTickCount = 0;\r
- xNumOfOverflows = 0;\r
- prvSampleTimeNow( &xTimerNumber );\r
-\r
- /* Initialise the list pointers in case prvSampleTimeNow() changed them. */\r
- pxCurrentTimerList = &xActiveTimerList1;\r
- pxOverflowTimerList = &xActiveTimerList2;\r
-\r
-// if( xTestTask1 == NULL )\r
- {\r
- xTaskCreate( (pdTASK_CODE)prvTestFailed, "Task1", configMINIMAL_STACK_SIZE, NULL, 0, &xTestTask1 );\r
- }\r
-\r
-// if( xTestTask2 == NULL )\r
- {\r
- xTaskCreate( (pdTASK_CODE)prvTestFailed, "Task1", configMINIMAL_STACK_SIZE, NULL, 0, &xTestTask2 );\r
- }\r
-\r
- pxCurrentTCB = xTestTask1;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvTestFailed( void )\r
-{\r
-static unsigned long ulFailures = 0;\r
-\r
- ulFailures++;\r
- xTestStatus = pdFAIL;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckServiceTaskBehaviour( portBASE_TYPE x, portBASE_TYPE xExpireTimeHasOverflowed, portBASE_TYPE xTickCountOverflowed )\r
-{\r
-portBASE_TYPE xListWasEmpty;\r
-portTickType xNextExpireTime;\r
-extern xList * volatile pxOverflowDelayedTaskList, *pxDelayedTaskList;\r
-extern xList pxReadyTasksLists[];\r
-\r
- xListWasEmpty = portMAX_DELAY;\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- /* If the timer expire time has overflowed it should be present in the overflow \r
- list of active timers, unless the tick count has also overflowed and the expire\r
- time has not passed. If the expire time has not overflowed it should be \r
- present in the current list of active timers. Either way, its expire time should \r
- equal the expected expire time. */\r
- if( ( xExpireTimeHasOverflowed == pdTRUE ) && ( xTickCountOverflowed == pdFALSE ) )\r
- { \r
- /* The timer will be in the overflow list, so prvGetNextExpireTime()\r
- should not have found it, but instead returned an expire time that\r
- will ensure the timer service task will unblock when the lists need\r
- switching. */\r
- if( ( xNextExpireTime != 0 ) || ( xListWasEmpty == pdFALSE ) )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
- else\r
- {\r
- if( ( xNextExpireTime != xTestCase[ x ].xExpectedCalculatedExpiryTime ) || ( xListWasEmpty != pdFALSE ) )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
-\r
- /* Has the timer expired the expected number of times? */\r
- if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- /* The task should now be blocked. It should only appear in the overflow\r
- delayed task list if xNextExpireTime is equal to 0. */\r
- if( xNextExpireTime == 0 )\r
- {\r
- if( listIS_CONTAINED_WITHIN( pxOverflowDelayedTaskList, &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != 0 )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
- else\r
- {\r
- if( listIS_CONTAINED_WITHIN( pxDelayedTaskList, &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- /* The timer should have be re-loaded, and still be referenced from one\r
- or other of the active lists. */\r
- if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- if( listIS_CONTAINED_WITHIN( NULL, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdTRUE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- /* Move the task back to the ready list from the delayed list. */\r
- vListRemove( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) );\r
- vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static portBASE_TYPE xTimerTest1_xTimeStartAndResetWakeTimeCalculation( void )\r
-{\r
-portBASE_TYPE x, xListWasEmpty;\r
-portTickType xNextExpireTime;\r
-\r
- if( sizeof( portTickType ) != 2 )\r
- {\r
- /* This test should be performed using 16bit ticks. */\r
- prvTestFailed();\r
- }\r
-\r
- for( x = 0; x < ( sizeof( xTestCase ) / sizeof( struct xTestData ) ); x++ )\r
- {\r
- /* Set everything back to its start condition. */\r
- vTimerTest_Initialise();\r
-\r
- /* Load the tick count with the test case data. */\r
- xTickCount = xTestCase[ x ].xStartTickCount;\r
-\r
- /* Query the timers list to see if it contains any timers, and if so,\r
- obtain the time at which the next timer will expire. The list should be\r
- empty, so 0 should be returned (to cause the task to unblock when a\r
- tick overflow occurs. Likewise xListWasEmpty should be set to pdTRUE. */\r
- xListWasEmpty = portMAX_DELAY;\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- if( ( xListWasEmpty != pdTRUE ) || ( xNextExpireTime != ( portTickType ) 0 ) )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
-\r
-\r
- /* Call prvProcessReceivedCommands() just so the code under test knows\r
- what the tick count is in the pre-condition state. */\r
- prvProcessReceivedCommands();\r
-\r
- xAutoReloadTimers[ 0 ]->xTimerPeriodInTicks = xTestCase[ x ].xTimerPeriod;\r
- xTimerStart( xAutoReloadTimers[ 0 ], 0 );\r
-\r
- /* Move the tick count on to the time at which the command should be \r
- processed. */\r
- xTickCount += xTestCase[ x ].xTickIncrementBetweenCommandAndProcessing;\r
-\r
- /* Process the sent command with the updated tick count. */\r
- prvProcessReceivedCommands();\r
-\r
-xTickCount += 2;\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- if( listIS_CONTAINED_WITHIN( xTestCase[ x ].pxExpectedList, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
- if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( xTickCount < xTestCase[ x ].xStartTickCount ) /* The tick count has overflowed */\r
- {\r
- if( xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed. */\r
- {\r
- if( xTestCase[ x ].xExpectedCalculatedExpiryTime <= xTickCount ) /* The timer expire time has passed */\r
- {\r
- /* The expire time should never have passed when here is\r
- reached because the timer whould have been processed enough\r
- times to make the expire time catch up. */\r
- prvTestFailed();\r
- }\r
- else /* The timer expire time has not passed. */\r
- {\r
- prvCheckServiceTaskBehaviour( x, pdTRUE, pdTRUE );\r
- }\r
- }\r
- else /* The timer expire time has not overflowed. */\r
- {\r
- /* If the timer expire time has not overflowed but the tick count has \r
- overflowed, then the timer expire time must have been passed. The \r
- expire time should never have passed when here is reached because \r
- the timer whould have been processed enough times to make the expire \r
- time catch up. */\r
- prvTestFailed();\r
- }\r
- }\r
- else /* The tick count has not overflowed. */\r
- {\r
- if( xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed */\r
- {\r
- /* If the expire time has overflowed, but the tick count has not\r
- overflowed, then the timer expire time cannot have been passed. */\r
- prvCheckServiceTaskBehaviour( x, pdTRUE, pdFALSE );\r
- }\r
- else /* The timer expire time has not overflowed. */\r
- {\r
- if( xTickCount >= xTestCase[ x ].xExpectedCalculatedExpiryTime ) /* The timer expire time has passed */\r
- {\r
- /* The expire time should never have passed when here is\r
- reached because the timer whould have been processed enough\r
- times to make the expire time catch up. */\r
- prvTestFailed();\r
- }\r
- else /* The timer expire time has not passed. */\r
- {\r
- prvCheckServiceTaskBehaviour( x, pdFALSE, pdFALSE );\r
- }\r
- }\r
- }\r
- }\r
-\r
- return xTestStatus;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier )\r
-{\r
-unsigned portBASE_TYPE uxExpectedIncrements, x, uxMix = 0, uxPeriod;\r
-const unsigned portBASE_TYPE uxMaxIterations = 0xffff;\r
-extern xList pxReadyTasksLists[];\r
-portTickType xNextExpireTime;\r
-portBASE_TYPE xListWasEmpty;\r
-extern xTaskHandle pxCurrentTCB;\r
-\r
- if( sizeof( portTickType ) != 2 )\r
- {\r
- /* This test should be performed using 16bit ticks. */\r
- prvTestFailed();\r
- }\r
-\r
- /* Initialise the test. This will create tmrtestNUM_TIMERS timers. */\r
- vTimerTest_Initialise();\r
-\r
- /* Give each timer a period, then start it running. */\r
- for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
- {\r
- uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
- xTimerChangePeriod( xAutoReloadTimers[ x ], ( portTickType ) uxPeriod, 0 );\r
- xTimerStart( xAutoReloadTimers[ x ], 0 );\r
- prvProcessReceivedCommands();\r
- }\r
-\r
- xTickCount = 1;\r
- x = 1;\r
-\r
- /* Simulate the task running. */\r
- while( x <= uxMaxIterations )\r
- {\r
- /* Query the timers list to see if it contains any timers, and if so,\r
- obtain the time at which the next timer will expire. */\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- /* It is legitimate for tick increments to occur here. */\r
- if( ( uxMix < 2 ) && ( x < ( uxMaxIterations + 3 ) ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
-\r
- /* If a timer has expired, process it. Otherwise, block this task\r
- until either a timer does expire, or a command is received. */\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
- \r
- /* If the task blocked, increment the tick until it unblocks. */\r
- while( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- if( ( uxMix == 1 ) && ( x < ( uxMaxIterations + 3 ) ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- if( ( uxMix == 2 ) && ( x < ( uxMaxIterations + 2 ) ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- else\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- }\r
-\r
- uxMix++;\r
- if( uxMix > 8 )\r
- {\r
- uxMix = 0;\r
- }\r
-\r
- /* Make sure time does not go past that expected. */\r
- if( x > uxMaxIterations )\r
- {\r
- xTickCount -= ( portTickType ) ( x - uxMaxIterations );\r
- }\r
-\r
- /* Empty the command queue. */\r
- prvProcessReceivedCommands(); \r
- }\r
-\r
- /* Catch up with the tick count, if it was incremented more than once in one\r
- go. */\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
- \r
- /* This time, if the task blocked, there is nothing left to do. If it didn't\r
- block then empty the command queue for good measure. */\r
- if( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != pdFALSE )\r
- {\r
- /* Empty the command queue. */\r
- prvProcessReceivedCommands(); \r
- }\r
-\r
- /* Check each timer has incremented the expected number of times. */\r
- for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
- {\r
- uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
- uxExpectedIncrements = ( uxMaxIterations / ( unsigned portBASE_TYPE ) uxPeriod );\r
- \r
- if( uxAutoReloadTimerCounters[ x ] != uxExpectedIncrements )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- return xTestStatus;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vRunTimerModuleTests( void )\r
-{\r
- xTimerTest1_xTimeStartAndResetWakeTimeCalculation();\r
- xTimerTest2_xTestFreeRunningBehaviour( 1 );\r
- xTimerTest2_xTestFreeRunningBehaviour( 10 );\r
- xTimerTest2_xTestFreeRunningBehaviour( 25 );\r
- xTimerTest2_xTestFreeRunningBehaviour( 50 );\r
- xTimerTest2_xTestFreeRunningBehaviour( 121 );\r
-\r
- for( ;; );\r
-}\r
-\r
-#endif TIMER_TEST_H\r
-\r
+++ /dev/null
-#ifndef TIMER_TEST_H\r
-#define TIMER_TEST_H\r
-\r
-#define tmrtestNUM_TIMERS 15\r
-\r
-\r
-extern portTickType xTickCount;\r
-extern xTaskHandle pxCurrentTCB;\r
-extern portTickType xNumOfOverflows;\r
-\r
-static void vTimerTest_Initialise( void );\r
-static portBASE_TYPE xTimerTest1_xTimeStartAndResetWakeTimeCalculation( void );\r
-portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier );\r
-\r
-static void prvCheckServiceTaskBehaviour( portBASE_TYPE x, portBASE_TYPE xExpireTimeHasOverflowed, portBASE_TYPE xTickCountOverflowed );\r
-\r
-static void prvTestFailed( void );\r
-\r
-xTIMER *xAutoReloadTimers[ tmrtestNUM_TIMERS ];\r
-unsigned portBASE_TYPE uxAutoReloadTimerCounters[ tmrtestNUM_TIMERS ];\r
-portBASE_TYPE xTestStatus = pdPASS;\r
-xTaskHandle xTestTask1 = NULL, xTestTask2 = NULL;\r
-\r
-struct xTestData\r
-{\r
- portTickType xStartTickCount;\r
- portTickType xTimerPeriod;\r
- portTickType xTickIncrementBetweenCommandAndProcessing;\r
- portTickType xExpectedCalculatedExpiryTime;\r
- xList * pxExpectedList;\r
- unsigned portBASE_TYPE uxExpectedCallbackCount;\r
-};\r
-\r
-const struct xTestData xTestCase[] =\r
-{\r
- /* xStartTickCount, xTimerPeriod, Tck Inc, Expected Expire Time, Expected list, Expected callback count, Second tick inc */\r
-\r
- /* Test cases when the command to start a timer and the processing of the\r
- start command execute without the tick count incrementing in between. */\r
- { portMAX_DELAY - 8, 2, 0, ( portMAX_DELAY - 8 ) + 2, &xActiveTimerList1, 0 }, /* Expire before an overflow. */\r
- { portMAX_DELAY - 8, 8, 0, ( portMAX_DELAY - 8 ) + 8, &xActiveTimerList1, 0 }, /* Expire immediately before and overflow. */\r
- { portMAX_DELAY - 8, 9, 0, 0, &xActiveTimerList2, 0 }, /* Expire on an overflow. */\r
- { portMAX_DELAY - 8, portMAX_DELAY, 0, ( ( portMAX_DELAY - 8 ) - 1 ), &xActiveTimerList2, 0 }, /* Delay for the longest possible time. */\r
- { portMAX_DELAY, portMAX_DELAY, 0, ( portMAX_DELAY - 1 ), &xActiveTimerList2, 0 }, /* Delay for the longest possible time starting from the maximum tick count. */\r
- { 0, portMAX_DELAY, 0, ( portMAX_DELAY ), &xActiveTimerList1, 0 }, /* Delay for the maximum ticks, starting with from the minimum tick count. */\r
-\r
- /* Test cases when the command to start a timer and the processing of the\r
- start command execute at different tick count values. */\r
- { portMAX_DELAY - 8, 2, 1, ( portMAX_DELAY - 8 ) + 2, &xActiveTimerList1, 0 }, /* The expire time does not overflow, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 8, 8, 2, ( portMAX_DELAY - 8 ) + 8, &xActiveTimerList1, 0 }, /* The expire time does not overflow but is on the portMAX_DELAY limit, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 8, 9, 3, 0, &xActiveTimerList2, 0 }, /* The expire time overflows to 0, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 2, 9, 1, ( portMAX_DELAY - 2 ) + 9, &xActiveTimerList2, 0 }, /* The expire time overflows, but the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 2, 9, 3, ( portMAX_DELAY - 2 ) + 9, &xActiveTimerList2, 0 }, /* The timer overflows between the command and processing the command. The expire time also overflows. */\r
-\r
- /* Add tests where the timer should have expired by the time the command is processed. */\r
- { 10, 9, 10, ( 10 + ( 2 * 9 ) ), &xActiveTimerList1, 1 }, /* Nothing overflows, but the time between the timer being set and the command being processed is greater than the timers expiry time. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded. */\r
- { portMAX_DELAY - 2, 9, 10, ( portMAX_DELAY - 2 ) + ( 2 * 9 ), &xActiveTimerList2, 1 }, /* The timer overflows between the command and processing the command. The expire time also overflows and the number of ticks that occur between the command and the processing exceeds the timer expiry period. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 2, 9, 9, ( portMAX_DELAY - 2 ) + ( 2 * 9 ), &xActiveTimerList2, 1 }, /* The timer overflows between the command and processing the command. The expire time also overflows and the number of ticks between command and processing equals the timer expiry period. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
-\r
- { portMAX_DELAY - 20, 9, 21, ( portMAX_DELAY - 20 ) + ( 3 * 9 ), &xActiveTimerList2, 2 }, /* The tick count has overflowed but the timer expire time has not overflowed. The tick count overflows to 0. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 20, 9, 22, ( portMAX_DELAY - 20 ) + ( 3 * 9 ), &xActiveTimerList2, 2 }, /* The tick count has overflowed but the timer expire time has not overflowed. The tick count overflows to greater than 0. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 5, 2, 20, ( portMAX_DELAY - 5 ) + ( 11 * 2 ), &xActiveTimerList2, 10 }, /* The tick and expire time overflow, but the first expire time overflow results in a time that is less than the tick count. */\r
-};\r
-\r
-typedef struct tskTaskControlBlockx\r
-{\r
- volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */\r
-\r
- #if ( portUSING_MPU_WRAPPERS == 1 )\r
- xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */\r
- #endif \r
- \r
- xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */\r
- xListItem xEventListItem; /*< List item used to place the TCB in event lists. */\r
- unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */\r
- portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */\r
- signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */\r
-\r
- #if ( portSTACK_GROWTH > 0 )\r
- portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */\r
- #endif\r
-\r
- #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
- unsigned portBASE_TYPE uxCriticalNesting;\r
- #endif\r
-\r
- #if ( configUSE_TRACE_FACILITY == 1 )\r
- unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */\r
- #endif\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */\r
- #endif\r
-\r
- #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
- pdTASK_HOOK_CODE pxTaskTag;\r
- #endif\r
-\r
- #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
- unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */\r
- #endif\r
-\r
-} tskTCBx;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vAutoReloadTimerCallback( xTIMER *pxTimer )\r
-{\r
-portBASE_TYPE xTimerID = ( portBASE_TYPE ) pxTimer->pvTimerID;\r
-\r
- if( xTimerID < tmrtestNUM_TIMERS )\r
- {\r
- ( uxAutoReloadTimerCounters[ xTimerID ] )++;\r
- }\r
- else\r
- {\r
- prvTestFailed();\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vTimerTest_Initialise( void )\r
-{\r
-portBASE_TYPE xTimerNumber;\r
-extern void prvInitialiseTaskLists( void );\r
-extern portBASE_TYPE xSchedulerRunning;\r
-\r
- prvInitialiseTaskLists();\r
- xTimerQueue = NULL;\r
- xSchedulerRunning = pdTRUE;\r
-\r
- for( xTimerNumber = 0; xTimerNumber < tmrtestNUM_TIMERS; xTimerNumber++ )\r
- {\r
- /* Delete any existing timers. */\r
- if( xAutoReloadTimers[ xTimerNumber ] != NULL )\r
- {\r
- vPortFree( xAutoReloadTimers[ xTimerNumber ] );\r
- }\r
-\r
- /* Create new autoreload timers. */\r
- xAutoReloadTimers[ xTimerNumber ] = xTimerCreate( "Timer", 0xffff, pdTRUE, ( void * ) xTimerNumber, vAutoReloadTimerCallback );\r
- uxAutoReloadTimerCounters[ xTimerNumber ] = 0;\r
- if( xAutoReloadTimers == NULL )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- /* Initialise lists so they are empty. */\r
- vListInitialise( &xActiveTimerList1 );\r
- vListInitialise( &xActiveTimerList2 );\r
-\r
- /* Call prvSampleTimeNow with a tick count of zero so it sets its \r
- internal static "last time" variable to zero. */\r
- xTickCount = 0;\r
- xNumOfOverflows = 0;\r
- prvSampleTimeNow( &xTimerNumber );\r
-\r
- /* Initialise the list pointers in case prvSampleTimeNow() changed them. */\r
- pxCurrentTimerList = &xActiveTimerList1;\r
- pxOverflowTimerList = &xActiveTimerList2;\r
-\r
-// if( xTestTask1 == NULL )\r
- {\r
- xTaskCreate( (pdTASK_CODE)prvTestFailed, "Task1", configMINIMAL_STACK_SIZE, NULL, 0, &xTestTask1 );\r
- }\r
-\r
-// if( xTestTask2 == NULL )\r
- {\r
- xTaskCreate( (pdTASK_CODE)prvTestFailed, "Task1", configMINIMAL_STACK_SIZE, NULL, 0, &xTestTask2 );\r
- }\r
-\r
- pxCurrentTCB = xTestTask1;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvTestFailed( void )\r
-{\r
-static unsigned long ulFailures = 0;\r
-\r
- ulFailures++;\r
- xTestStatus = pdFAIL;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckServiceTaskBehaviour( portBASE_TYPE x, portBASE_TYPE xExpireTimeHasOverflowed, portBASE_TYPE xTickCountOverflowed )\r
-{\r
-portBASE_TYPE xListWasEmpty;\r
-portTickType xNextExpireTime;\r
-extern xList * volatile pxOverflowDelayedTaskList, *pxDelayedTaskList;\r
-extern xList pxReadyTasksLists[];\r
-\r
- xListWasEmpty = portMAX_DELAY;\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- /* If the timer expire time has overflowed it should be present in the overflow \r
- list of active timers, unless the tick count has also overflowed and the expire\r
- time has not passed. If the expire time has not overflowed it should be \r
- present in the current list of active timers. Either way, its expire time should \r
- equal the expected expire time. */\r
- if( ( xExpireTimeHasOverflowed == pdTRUE ) && ( xTickCountOverflowed == pdFALSE ) )\r
- { \r
- /* The timer will be in the overflow list, so prvGetNextExpireTime()\r
- should not have found it, but instead returned an expire time that\r
- will ensure the timer service task will unblock when the lists need\r
- switching. */\r
- if( ( xNextExpireTime != 0 ) || ( xListWasEmpty == pdFALSE ) )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
- else\r
- {\r
- if( ( xNextExpireTime != xTestCase[ x ].xExpectedCalculatedExpiryTime ) || ( xListWasEmpty != pdFALSE ) )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
-\r
- /* Has the timer expired the expected number of times? */\r
- if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- /* The task should now be blocked. It should only appear in the overflow\r
- delayed task list if xNextExpireTime is equal to 0. */\r
- if( xNextExpireTime == 0 )\r
- {\r
- if( listIS_CONTAINED_WITHIN( pxOverflowDelayedTaskList, &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != 0 )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
- else\r
- {\r
- if( listIS_CONTAINED_WITHIN( pxDelayedTaskList, &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- /* The timer should have be re-loaded, and still be referenced from one\r
- or other of the active lists. */\r
- if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- if( listIS_CONTAINED_WITHIN( NULL, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdTRUE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- /* Move the task back to the ready list from the delayed list. */\r
- vListRemove( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) );\r
- vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static portBASE_TYPE xTimerTest1_xTimeStartAndResetWakeTimeCalculation( void )\r
-{\r
-portBASE_TYPE x, xListWasEmpty;\r
-portTickType xNextExpireTime;\r
-\r
- if( sizeof( portTickType ) != 2 )\r
- {\r
- /* This test should be performed using 16bit ticks. */\r
- prvTestFailed();\r
- }\r
-\r
- for( x = 0; x < ( sizeof( xTestCase ) / sizeof( struct xTestData ) ); x++ )\r
- {\r
- /* Set everything back to its start condition. */\r
- vTimerTest_Initialise();\r
-\r
- /* Load the tick count with the test case data. */\r
- xTickCount = xTestCase[ x ].xStartTickCount;\r
-\r
- /* Query the timers list to see if it contains any timers, and if so,\r
- obtain the time at which the next timer will expire. The list should be\r
- empty, so 0 should be returned (to cause the task to unblock when a\r
- tick overflow occurs. Likewise xListWasEmpty should be set to pdTRUE. */\r
- xListWasEmpty = portMAX_DELAY;\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- if( ( xListWasEmpty != pdTRUE ) || ( xNextExpireTime != ( portTickType ) 0 ) )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
-\r
-\r
- /* Call prvProcessReceivedCommands() just so the code under test knows\r
- what the tick count is in the pre-condition state. */\r
- prvProcessReceivedCommands();\r
-\r
- xAutoReloadTimers[ 0 ]->xTimerPeriodInTicks = xTestCase[ x ].xTimerPeriod;\r
- xTimerStart( xAutoReloadTimers[ 0 ], 0 );\r
-\r
- /* Move the tick count on to the time at which the command should be \r
- processed. */\r
- xTickCount += xTestCase[ x ].xTickIncrementBetweenCommandAndProcessing;\r
-\r
- /* Process the sent command with the updated tick count. */\r
- prvProcessReceivedCommands();\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- if( listIS_CONTAINED_WITHIN( xTestCase[ x ].pxExpectedList, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
- if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( xTickCount < xTestCase[ x ].xStartTickCount ) /* The tick count has overflowed */\r
- {\r
- if( xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed. */\r
- {\r
- if( xTestCase[ x ].xExpectedCalculatedExpiryTime <= xTickCount ) /* The timer expire time has passed */\r
- {\r
- /* The expire time should never have passed when here is\r
- reached because the timer whould have been processed enough\r
- times to make the expire time catch up. */\r
- prvTestFailed();\r
- }\r
- else /* The timer expire time has not passed. */\r
- {\r
- prvCheckServiceTaskBehaviour( x, pdTRUE, pdTRUE );\r
- }\r
- }\r
- else /* The timer expire time has not overflowed. */\r
- {\r
- /* If the timer expire time has not overflowed but the tick count has \r
- overflowed, then the timer expire time must have been passed. The \r
- expire time should never have passed when here is reached because \r
- the timer whould have been processed enough times to make the expire \r
- time catch up. */\r
- prvTestFailed();\r
- }\r
- }\r
- else /* The tick count has not overflowed. */\r
- {\r
- if( xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed */\r
- {\r
- /* If the expire time has overflowed, but the tick count has not\r
- overflowed, then the timer expire time cannot have been passed. */\r
- prvCheckServiceTaskBehaviour( x, pdTRUE, pdFALSE );\r
- }\r
- else /* The timer expire time has not overflowed. */\r
- {\r
- if( xTickCount >= xTestCase[ x ].xExpectedCalculatedExpiryTime ) /* The timer expire time has passed */\r
- {\r
- /* The expire time should never have passed when here is\r
- reached because the timer whould have been processed enough\r
- times to make the expire time catch up. */\r
- prvTestFailed();\r
- }\r
- else /* The timer expire time has not passed. */\r
- {\r
- prvCheckServiceTaskBehaviour( x, pdFALSE, pdFALSE );\r
- }\r
- }\r
- }\r
- }\r
-\r
- return xTestStatus;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier )\r
-{\r
-unsigned portBASE_TYPE uxExpectedIncrements, x, uxMix = 0, uxPeriod;\r
-const unsigned portBASE_TYPE uxMaxIterations = 0x1fffff;\r
-extern xList pxReadyTasksLists[];\r
-portTickType xNextExpireTime;\r
-portBASE_TYPE xListWasEmpty;\r
-extern xTaskHandle pxCurrentTCB;\r
-\r
- if( sizeof( portTickType ) != 2 )\r
- {\r
- /* This test should be performed using 16bit ticks. */\r
- prvTestFailed();\r
- }\r
-\r
- /* Initialise the test. This will create tmrtestNUM_TIMERS timers. */\r
- vTimerTest_Initialise();\r
-\r
- /* Give each timer a period, then start it running. */\r
- for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
- {\r
- uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
- xTimerChangePeriod( xAutoReloadTimers[ x ], ( portTickType ) uxPeriod, 0 );\r
- xTimerStart( xAutoReloadTimers[ x ], 0 );\r
- prvProcessReceivedCommands();\r
- }\r
-\r
- xTickCount = 1;\r
- x = 1;\r
-\r
- /* Simulate the task running. */\r
- while( x <= uxMaxIterations )\r
- {\r
- /* Query the timers list to see if it contains any timers, and if so,\r
- obtain the time at which the next timer will expire. */\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- /* It is legitimate for tick increments to occur here. */\r
- if( ( uxMix < 2 ) && ( x < uxMaxIterations - 5 ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
-\r
- /* If a timer has expired, process it. Otherwise, block this task\r
- until either a timer does expire, or a command is received. */\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
- \r
- /* If the task blocked, increment the tick until it unblocks. */\r
- while( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- if( ( uxMix == 1 ) && ( x < ( uxMaxIterations + 3 ) ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- if( ( uxMix == 2 ) && ( x < ( uxMaxIterations + 2 ) ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- else\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- }\r
-\r
- uxMix++;\r
- if( uxMix > 8 )\r
- {\r
- uxMix = 0;\r
- }\r
-\r
- /* Make sure time does not go past that expected. */\r
- if( x > uxMaxIterations )\r
- {\r
- xTickCount -= ( portTickType ) ( x - uxMaxIterations );\r
- }\r
-\r
- /* Empty the command queue. */\r
- prvProcessReceivedCommands(); \r
- }\r
-\r
- /* Catch up with the tick count, if it was incremented more than once in one\r
- go. */\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
- \r
- /* This time, if the task blocked, there is nothing left to do. If it didn't\r
- block then empty the command queue for good measure. */\r
- if( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != pdFALSE )\r
- {\r
- /* Empty the command queue. */\r
- prvProcessReceivedCommands(); \r
- }\r
-\r
- /* Check each timer has incremented the expected number of times. */\r
- for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
- {\r
- uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
- uxExpectedIncrements = ( uxMaxIterations / ( unsigned portBASE_TYPE ) uxPeriod );\r
- \r
- if( ( uxExpectedIncrements - uxAutoReloadTimerCounters[ x ] ) > 1 )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- return xTestStatus;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vRunTimerModuleTests( void )\r
-{\r
-unsigned long x;\r
-\r
- xTimerTest1_xTimeStartAndResetWakeTimeCalculation();\r
-\r
- for( x = 1; x < 1000; x++ )\r
- {\r
- xTimerTest2_xTestFreeRunningBehaviour( x );\r
- }\r
-\r
- for( ;; );\r
-}\r
-\r
-#endif TIMER_TEST_H\r
-\r
+++ /dev/null
-#ifndef TIMER_TEST_H\r
-#define TIMER_TEST_H\r
-\r
-#define tmrtestNUM_TIMERS 15\r
-\r
-\r
-extern portTickType xTickCount;\r
-extern xTaskHandle pxCurrentTCB;\r
-extern portTickType xNumOfOverflows;\r
-\r
-static void vTimerTest_Initialise( void );\r
-static portBASE_TYPE xTimerTest1_xTimeStartAndResetWakeTimeCalculation( void );\r
-portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier );\r
-\r
-static void prvCheckServiceTaskBehaviour( portBASE_TYPE x, portBASE_TYPE xExpireTimeHasOverflowed, portBASE_TYPE xTickCountOverflowed );\r
-\r
-static void prvTestFailed( void );\r
-\r
-xTIMER *xAutoReloadTimers[ tmrtestNUM_TIMERS ];\r
-unsigned portBASE_TYPE uxAutoReloadTimerCounters[ tmrtestNUM_TIMERS ];\r
-portBASE_TYPE xTestStatus = pdPASS;\r
-xTaskHandle xTestTask1 = NULL, xTestTask2 = NULL;\r
-\r
-struct xTestData\r
-{\r
- portTickType xStartTickCount;\r
- portTickType xTimerPeriod;\r
- portTickType xTickIncrementBetweenCommandAndProcessing;\r
- portTickType xExpectedCalculatedExpiryTime;\r
- xList * pxExpectedList;\r
- unsigned portBASE_TYPE uxExpectedCallbackCount;\r
-};\r
-\r
-const struct xTestData xTestCase[] =\r
-{\r
- /* xStartTickCount, xTimerPeriod, Tck Inc, Expected Expire Time, Expected list, Expected callback count, Second tick inc */\r
-\r
- /* Test cases when the command to start a timer and the processing of the\r
- start command execute without the tick count incrementing in between. */\r
- { portMAX_DELAY - 8, 2, 0, ( portMAX_DELAY - 8 ) + 2, &xActiveTimerList1, 0 }, /* Expire before an overflow. */\r
- { portMAX_DELAY - 8, 8, 0, ( portMAX_DELAY - 8 ) + 8, &xActiveTimerList1, 0 }, /* Expire immediately before and overflow. */\r
- { portMAX_DELAY - 8, 9, 0, 0, &xActiveTimerList2, 0 }, /* Expire on an overflow. */\r
- { portMAX_DELAY - 8, portMAX_DELAY, 0, ( ( portMAX_DELAY - 8 ) - 1 ), &xActiveTimerList2, 0 }, /* Delay for the longest possible time. */\r
- { portMAX_DELAY, portMAX_DELAY, 0, ( portMAX_DELAY - 1 ), &xActiveTimerList2, 0 }, /* Delay for the longest possible time starting from the maximum tick count. */\r
- { 0, portMAX_DELAY, 0, ( portMAX_DELAY ), &xActiveTimerList1, 0 }, /* Delay for the maximum ticks, starting with from the minimum tick count. */\r
-\r
- /* Test cases when the command to start a timer and the processing of the\r
- start command execute at different tick count values. */\r
- { portMAX_DELAY - 8, 2, 1, ( portMAX_DELAY - 8 ) + 2, &xActiveTimerList1, 0 }, /* The expire time does not overflow, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 8, 8, 2, ( portMAX_DELAY - 8 ) + 8, &xActiveTimerList1, 0 }, /* The expire time does not overflow but is on the portMAX_DELAY limit, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 8, 9, 3, 0, &xActiveTimerList2, 0 }, /* The expire time overflows to 0, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 2, 9, 1, ( portMAX_DELAY - 2 ) + 9, &xActiveTimerList2, 0 }, /* The expire time overflows, but the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 2, 9, 3, ( portMAX_DELAY - 2 ) + 9, &xActiveTimerList2, 0 }, /* The timer overflows between the command and processing the command. The expire time also overflows. */\r
-\r
- /* Add tests where the timer should have expired by the time the command is processed. */\r
- { 10, 9, 10, ( 10 + ( 2 * 9 ) ), &xActiveTimerList1, 1 }, /* Nothing overflows, but the time between the timer being set and the command being processed is greater than the timers expiry time. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded. */\r
- { portMAX_DELAY - 2, 9, 10, ( portMAX_DELAY - 2 ) + ( 2 * 9 ), &xActiveTimerList2, 1 }, /* The timer overflows between the command and processing the command. The expire time also overflows and the number of ticks that occur between the command and the processing exceeds the timer expiry period. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 2, 9, 9, ( portMAX_DELAY - 2 ) + ( 2 * 9 ), &xActiveTimerList2, 1 }, /* The timer overflows between the command and processing the command. The expire time also overflows and the number of ticks between command and processing equals the timer expiry period. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
-\r
- { portMAX_DELAY - 20, 9, 21, ( portMAX_DELAY - 20 ) + ( 3 * 9 ), &xActiveTimerList2, 2 }, /* The tick count has overflowed but the timer expire time has not overflowed. The tick count overflows to 0. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 20, 9, 22, ( portMAX_DELAY - 20 ) + ( 3 * 9 ), &xActiveTimerList2, 2 }, /* The tick count has overflowed but the timer expire time has not overflowed. The tick count overflows to greater than 0. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 5, 2, 20, ( portMAX_DELAY - 5 ) + ( 11 * 2 ), &xActiveTimerList2, 10 }, /* The tick and expire time overflow, but the first expire time overflow results in a time that is less than the tick count. */\r
-};\r
-\r
-typedef struct tskTaskControlBlockx\r
-{\r
- volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */\r
-\r
- #if ( portUSING_MPU_WRAPPERS == 1 )\r
- xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */\r
- #endif \r
- \r
- xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */\r
- xListItem xEventListItem; /*< List item used to place the TCB in event lists. */\r
- unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */\r
- portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */\r
- signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */\r
-\r
- #if ( portSTACK_GROWTH > 0 )\r
- portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */\r
- #endif\r
-\r
- #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
- unsigned portBASE_TYPE uxCriticalNesting;\r
- #endif\r
-\r
- #if ( configUSE_TRACE_FACILITY == 1 )\r
- unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */\r
- #endif\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */\r
- #endif\r
-\r
- #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
- pdTASK_HOOK_CODE pxTaskTag;\r
- #endif\r
-\r
- #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
- unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */\r
- #endif\r
-\r
-} tskTCBx;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vAutoReloadTimerCallback( xTIMER *pxTimer )\r
-{\r
-portBASE_TYPE xTimerID = ( portBASE_TYPE ) pxTimer->pvTimerID;\r
-\r
- if( xTimerID < tmrtestNUM_TIMERS )\r
- {\r
- ( uxAutoReloadTimerCounters[ xTimerID ] )++;\r
- }\r
- else\r
- {\r
- prvTestFailed();\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vTimerTest_Initialise( void )\r
-{\r
-portBASE_TYPE xTimerNumber;\r
-extern void prvInitialiseTaskLists( void );\r
-extern portBASE_TYPE xSchedulerRunning;\r
-\r
- prvInitialiseTaskLists();\r
- xTimerQueue = NULL;\r
- xSchedulerRunning = pdTRUE;\r
-\r
- for( xTimerNumber = 0; xTimerNumber < tmrtestNUM_TIMERS; xTimerNumber++ )\r
- {\r
- /* Delete any existing timers. */\r
- if( xAutoReloadTimers[ xTimerNumber ] != NULL )\r
- {\r
- vPortFree( xAutoReloadTimers[ xTimerNumber ] );\r
- }\r
-\r
- /* Create new autoreload timers. */\r
- xAutoReloadTimers[ xTimerNumber ] = xTimerCreate( "Timer", 0xffff, pdTRUE, ( void * ) xTimerNumber, vAutoReloadTimerCallback );\r
- uxAutoReloadTimerCounters[ xTimerNumber ] = 0;\r
- if( xAutoReloadTimers == NULL )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- /* Initialise lists so they are empty. */\r
- vListInitialise( &xActiveTimerList1 );\r
- vListInitialise( &xActiveTimerList2 );\r
-\r
- /* Call prvSampleTimeNow with a tick count of zero so it sets its \r
- internal static "last time" variable to zero. */\r
- xTickCount = 0;\r
- xNumOfOverflows = 0;\r
- prvSampleTimeNow( &xTimerNumber );\r
-\r
- /* Initialise the list pointers in case prvSampleTimeNow() changed them. */\r
- pxCurrentTimerList = &xActiveTimerList1;\r
- pxOverflowTimerList = &xActiveTimerList2;\r
-\r
-// if( xTestTask1 == NULL )\r
- {\r
- xTaskCreate( (pdTASK_CODE)prvTestFailed, "Task1", configMINIMAL_STACK_SIZE, NULL, 0, &xTestTask1 );\r
- }\r
-\r
-// if( xTestTask2 == NULL )\r
- {\r
- xTaskCreate( (pdTASK_CODE)prvTestFailed, "Task1", configMINIMAL_STACK_SIZE, NULL, 0, &xTestTask2 );\r
- }\r
-\r
- pxCurrentTCB = xTestTask1;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvTestFailed( void )\r
-{\r
-static unsigned long ulFailures = 0;\r
-\r
- ulFailures++;\r
- xTestStatus = pdFAIL;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckServiceTaskBehaviour( portBASE_TYPE x, portBASE_TYPE xExpireTimeHasOverflowed, portBASE_TYPE xTickCountOverflowed )\r
-{\r
-portBASE_TYPE xListWasEmpty;\r
-portTickType xNextExpireTime;\r
-extern xList * volatile pxOverflowDelayedTaskList, *pxDelayedTaskList;\r
-extern xList pxReadyTasksLists[];\r
-\r
- xListWasEmpty = portMAX_DELAY;\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- /* If the timer expire time has overflowed it should be present in the overflow \r
- list of active timers, unless the tick count has also overflowed and the expire\r
- time has not passed. If the expire time has not overflowed it should be \r
- present in the current list of active timers. Either way, its expire time should \r
- equal the expected expire time. */\r
- if( ( xExpireTimeHasOverflowed == pdTRUE ) && ( xTickCountOverflowed == pdFALSE ) )\r
- { \r
- /* The timer will be in the overflow list, so prvGetNextExpireTime()\r
- should not have found it, but instead returned an expire time that\r
- will ensure the timer service task will unblock when the lists need\r
- switching. */\r
- if( ( xNextExpireTime != 0 ) || ( xListWasEmpty == pdFALSE ) )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
- else\r
- {\r
- if( ( xNextExpireTime != xTestCase[ x ].xExpectedCalculatedExpiryTime ) || ( xListWasEmpty != pdFALSE ) )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
-\r
- /* Has the timer expired the expected number of times? */\r
- if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- /* The task should now be blocked. It should only appear in the overflow\r
- delayed task list if xNextExpireTime is equal to 0. */\r
- if( xNextExpireTime == 0 )\r
- {\r
- if( listIS_CONTAINED_WITHIN( pxOverflowDelayedTaskList, &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != 0 )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
- else\r
- {\r
- if( listIS_CONTAINED_WITHIN( pxDelayedTaskList, &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- /* The timer should have be re-loaded, and still be referenced from one\r
- or other of the active lists. */\r
- if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- if( listIS_CONTAINED_WITHIN( NULL, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdTRUE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- /* Move the task back to the ready list from the delayed list. */\r
- vListRemove( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) );\r
- vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static portBASE_TYPE xTimerTest1_xTimeStartAndResetWakeTimeCalculation( void )\r
-{\r
-portBASE_TYPE x, xListWasEmpty;\r
-portTickType xNextExpireTime;\r
-\r
- if( sizeof( portTickType ) != 2 )\r
- {\r
- /* This test should be performed using 16bit ticks. */\r
- prvTestFailed();\r
- }\r
-\r
- for( x = 0; x < ( sizeof( xTestCase ) / sizeof( struct xTestData ) ); x++ )\r
- {\r
- /* Set everything back to its start condition. */\r
- vTimerTest_Initialise();\r
-\r
- /* Load the tick count with the test case data. */\r
- xTickCount = xTestCase[ x ].xStartTickCount;\r
-\r
- /* Query the timers list to see if it contains any timers, and if so,\r
- obtain the time at which the next timer will expire. The list should be\r
- empty, so 0 should be returned (to cause the task to unblock when a\r
- tick overflow occurs. Likewise xListWasEmpty should be set to pdTRUE. */\r
- xListWasEmpty = portMAX_DELAY;\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- if( ( xListWasEmpty != pdTRUE ) || ( xNextExpireTime != ( portTickType ) 0 ) )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
-\r
-\r
- /* Call prvProcessReceivedCommands() just so the code under test knows\r
- what the tick count is in the pre-condition state. */\r
- prvProcessReceivedCommands();\r
-\r
- xAutoReloadTimers[ 0 ]->xTimerPeriodInTicks = xTestCase[ x ].xTimerPeriod;\r
- xTimerStart( xAutoReloadTimers[ 0 ], 0 );\r
-\r
- /* Move the tick count on to the time at which the command should be \r
- processed. */\r
- xTickCount += xTestCase[ x ].xTickIncrementBetweenCommandAndProcessing;\r
-\r
- /* Process the sent command with the updated tick count. */\r
- prvProcessReceivedCommands();\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- if( listIS_CONTAINED_WITHIN( xTestCase[ x ].pxExpectedList, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
- if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( xTickCount < xTestCase[ x ].xStartTickCount ) /* The tick count has overflowed */\r
- {\r
- if( xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed. */\r
- {\r
- if( xTestCase[ x ].xExpectedCalculatedExpiryTime <= xTickCount ) /* The timer expire time has passed */\r
- {\r
- /* The expire time should never have passed when here is\r
- reached because the timer whould have been processed enough\r
- times to make the expire time catch up. */\r
- prvTestFailed();\r
- }\r
- else /* The timer expire time has not passed. */\r
- {\r
- prvCheckServiceTaskBehaviour( x, pdTRUE, pdTRUE );\r
- }\r
- }\r
- else /* The timer expire time has not overflowed. */\r
- {\r
- /* If the timer expire time has not overflowed but the tick count has \r
- overflowed, then the timer expire time must have been passed. The \r
- expire time should never have passed when here is reached because \r
- the timer whould have been processed enough times to make the expire \r
- time catch up. */\r
- prvTestFailed();\r
- }\r
- }\r
- else /* The tick count has not overflowed. */\r
- {\r
- if( xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed */\r
- {\r
- /* If the expire time has overflowed, but the tick count has not\r
- overflowed, then the timer expire time cannot have been passed. */\r
- prvCheckServiceTaskBehaviour( x, pdTRUE, pdFALSE );\r
- }\r
- else /* The timer expire time has not overflowed. */\r
- {\r
- if( xTickCount >= xTestCase[ x ].xExpectedCalculatedExpiryTime ) /* The timer expire time has passed */\r
- {\r
- /* The expire time should never have passed when here is\r
- reached because the timer whould have been processed enough\r
- times to make the expire time catch up. */\r
- prvTestFailed();\r
- }\r
- else /* The timer expire time has not passed. */\r
- {\r
- prvCheckServiceTaskBehaviour( x, pdFALSE, pdFALSE );\r
- }\r
- }\r
- }\r
- }\r
-\r
- return xTestStatus;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier )\r
-{\r
-unsigned portBASE_TYPE uxExpectedIncrements, x, uxMix = 0, uxPeriod;\r
-const unsigned portBASE_TYPE uxMaxIterations = 0x1fffff;\r
-extern xList pxReadyTasksLists[];\r
-portTickType xNextExpireTime;\r
-portBASE_TYPE xListWasEmpty;\r
-extern xTaskHandle pxCurrentTCB;\r
-\r
- if( sizeof( portTickType ) != 2 )\r
- {\r
- /* This test should be performed using 16bit ticks. */\r
- prvTestFailed();\r
- }\r
-\r
- /* Initialise the test. This will create tmrtestNUM_TIMERS timers. */\r
- vTimerTest_Initialise();\r
-\r
- /* Give each timer a period, then start it running. */\r
- for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
- {\r
- uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
- xTimerChangePeriod( xAutoReloadTimers[ x ], ( portTickType ) uxPeriod, 0 );\r
- xTimerStart( xAutoReloadTimers[ x ], 0 );\r
- prvProcessReceivedCommands();\r
- }\r
-\r
- xTickCount = 1;\r
- x = 1;\r
-\r
- /* Simulate the task running. */\r
- while( x <= uxMaxIterations )\r
- {\r
- /* Query the timers list to see if it contains any timers, and if so,\r
- obtain the time at which the next timer will expire. */\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- /* It is legitimate for tick increments to occur here. */\r
- if( ( uxMix < 2 ) && ( x < uxMaxIterations - 5 ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
-\r
- /* If a timer has expired, process it. Otherwise, block this task\r
- until either a timer does expire, or a command is received. */\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
- \r
- /* If the task blocked, increment the tick until it unblocks. */\r
- while( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- if( ( uxMix == 1 ) && ( x < ( uxMaxIterations + 3 ) ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- if( ( uxMix == 2 ) && ( x < ( uxMaxIterations + 2 ) ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- else\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- }\r
-\r
- uxMix++;\r
- if( uxMix > 8 )\r
- {\r
- uxMix = 0;\r
- }\r
-\r
- /* Make sure time does not go past that expected. */\r
- if( x > uxMaxIterations )\r
- {\r
- xTickCount -= ( portTickType ) ( x - uxMaxIterations );\r
- }\r
-\r
- /* Empty the command queue. */\r
- prvProcessReceivedCommands(); \r
- }\r
-\r
- /* Catch up with the tick count, if it was incremented more than once in one\r
- go. */\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
- \r
- /* This time, if the task blocked, there is nothing left to do. If it didn't\r
- block then empty the command queue for good measure. */\r
- if( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != pdFALSE )\r
- {\r
- /* Empty the command queue. */\r
- prvProcessReceivedCommands(); \r
- }\r
-\r
- /* Check each timer has incremented the expected number of times. */\r
- for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
- {\r
- uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
- uxExpectedIncrements = ( uxMaxIterations / ( unsigned portBASE_TYPE ) uxPeriod );\r
- \r
- if( ( uxExpectedIncrements - uxAutoReloadTimerCounters[ x ] ) > 1 )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- return xTestStatus;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vRunTimerModuleTests( void )\r
-{\r
-unsigned long x;\r
-\r
- xTimerTest1_xTimeStartAndResetWakeTimeCalculation();\r
-\r
- for( x = 1; x < 1000; x++ )\r
- {\r
- xTimerTest2_xTestFreeRunningBehaviour( x );\r
- }\r
-\r
- for( ;; );\r
-}\r
-\r
-#endif TIMER_TEST_H\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-/*\r
- * This is the list implementation used by the scheduler. While it is tailored\r
- * heavily for the schedulers needs, it is also available for use by\r
- * application code.\r
- *\r
- * xLists can only store pointers to xListItems. Each xListItem contains a\r
- * numeric value (xItemValue). Most of the time the lists are sorted in\r
- * descending item value order.\r
- *\r
- * Lists are created already containing one list item. The value of this\r
- * item is the maximum possible that can be stored, it is therefore always at\r
- * the end of the list and acts as a marker. The list member pxHead always\r
- * points to this marker - even though it is at the tail of the list. This\r
- * is because the tail contains a wrap back pointer to the true head of\r
- * the list.\r
- *\r
- * In addition to it's value, each list item contains a pointer to the next\r
- * item in the list (pxNext), a pointer to the list it is in (pxContainer)\r
- * and a pointer to back to the object that contains it. These later two\r
- * pointers are included for efficiency of list manipulation. There is\r
- * effectively a two way link between the object containing the list item and\r
- * the list item itself.\r
- *\r
- *\r
- * \page ListIntroduction List Implementation\r
- * \ingroup FreeRTOSIntro\r
- */\r
-\r
-\r
-#ifndef LIST_H\r
-#define LIST_H\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-/*\r
- * Definition of the only type of object that a list can contain.\r
- */\r
-struct xLIST_ITEM\r
-{\r
- portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */\r
- volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */\r
- volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */\r
- void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */\r
- void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */\r
-};\r
-typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */\r
-\r
-struct xMINI_LIST_ITEM\r
-{\r
- portTickType xItemValue;\r
- volatile struct xLIST_ITEM *pxNext;\r
- volatile struct xLIST_ITEM *pxPrevious;\r
-};\r
-typedef struct xMINI_LIST_ITEM xMiniListItem;\r
-\r
-/*\r
- * Definition of the type of queue used by the scheduler.\r
- */\r
-typedef struct xLIST\r
-{\r
- volatile unsigned portBASE_TYPE uxNumberOfItems;\r
- volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */\r
- volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */\r
-} xList;\r
-\r
-/*\r
- * Access macro to set the owner of a list item. The owner of a list item\r
- * is the object (usually a TCB) that contains the list item.\r
- *\r
- * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER\r
- * \ingroup LinkedList\r
- */\r
-#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) ( pxOwner )\r
-\r
-/*\r
- * Access macro to set the value of the list item. In most cases the value is\r
- * used to sort the list in descending order.\r
- *\r
- * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE\r
- * \ingroup LinkedList\r
- */\r
-#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = ( xValue )\r
-\r
-/*\r
- * Access macro the retrieve the value of the list item. The value can\r
- * represent anything - for example a the priority of a task, or the time at\r
- * which a task should be unblocked.\r
- *\r
- * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )\r
-\r
-/*\r
- * Access macro the retrieve the value of the list item at the head of a given\r
- * list.\r
- *\r
- * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->xItemValue )\r
-\r
-/*\r
- * Access macro to determine if a list contains any items. The macro will\r
- * only have the value true if the list is empty.\r
- *\r
- * \page listLIST_IS_EMPTY listLIST_IS_EMPTY\r
- * \ingroup LinkedList\r
- */\r
-#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )\r
-\r
-/*\r
- * Access macro to return the number of items in the list.\r
- */\r
-#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )\r
-\r
-/*\r
- * Access function to obtain the owner of the next entry in a list.\r
- *\r
- * The list member pxIndex is used to walk through a list. Calling\r
- * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list\r
- * and returns that entries pxOwner parameter. Using multiple calls to this\r
- * function it is therefore possible to move through every item contained in\r
- * a list.\r
- *\r
- * The pxOwner parameter of a list item is a pointer to the object that owns\r
- * the list item. In the scheduler this is normally a task control block.\r
- * The pxOwner parameter effectively creates a two way link between the list\r
- * item and its owner.\r
- *\r
- * @param pxList The list from which the next item owner is to be returned.\r
- *\r
- * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \\r
-{ \\r
-xList * const pxConstList = ( pxList ); \\r
- /* Increment the index to the next item and return the item, ensuring */ \\r
- /* we don't return the marker used at the end of the list. */ \\r
- ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \\r
- if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \\r
- { \\r
- ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \\r
- } \\r
- ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \\r
-}\r
-\r
-\r
-/*\r
- * Access function to obtain the owner of the first entry in a list. Lists\r
- * are normally sorted in ascending item value order.\r
- *\r
- * This function returns the pxOwner member of the first item in the list.\r
- * The pxOwner parameter of a list item is a pointer to the object that owns\r
- * the list item. In the scheduler this is normally a task control block.\r
- * The pxOwner parameter effectively creates a two way link between the list\r
- * item and its owner.\r
- *\r
- * @param pxList The list from which the owner of the head item is to be\r
- * returned.\r
- *\r
- * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )\r
-\r
-/*\r
- * Check to see if a list item is within a list. The list item maintains a\r
- * "container" pointer that points to the list it is in. All this macro does\r
- * is check to see if the container and the list match.\r
- *\r
- * @param pxList The list we want to know if the list item is within.\r
- * @param pxListItem The list item we want to know if is in the list.\r
- * @return pdTRUE is the list item is in the list, otherwise pdFALSE.\r
- * pointer against\r
- */\r
-#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) )\r
-\r
-/*\r
- * Must be called before a list is used! This initialises all the members\r
- * of the list structure and inserts the xListEnd item into the list as a\r
- * marker to the back of the list.\r
- *\r
- * @param pxList Pointer to the list being initialised.\r
- *\r
- * \page vListInitialise vListInitialise\r
- * \ingroup LinkedList\r
- */\r
-void vListInitialise( xList *pxList );\r
-\r
-/*\r
- * Must be called before a list item is used. This sets the list container to\r
- * null so the item does not think that it is already contained in a list.\r
- *\r
- * @param pxItem Pointer to the list item being initialised.\r
- *\r
- * \page vListInitialiseItem vListInitialiseItem\r
- * \ingroup LinkedList\r
- */\r
-void vListInitialiseItem( xListItem *pxItem );\r
-\r
-/*\r
- * Insert a list item into a list. The item will be inserted into the list in\r
- * a position determined by its item value (descending item value order).\r
- *\r
- * @param pxList The list into which the item is to be inserted.\r
- *\r
- * @param pxNewListItem The item to that is to be placed in the list.\r
- *\r
- * \page vListInsert vListInsert\r
- * \ingroup LinkedList\r
- */\r
-void vListInsert( xList *pxList, xListItem *pxNewListItem );\r
-\r
-/*\r
- * Insert a list item into a list. The item will be inserted in a position\r
- * such that it will be the last item within the list returned by multiple\r
- * calls to listGET_OWNER_OF_NEXT_ENTRY.\r
- *\r
- * The list member pvIndex is used to walk through a list. Calling\r
- * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.\r
- * Placing an item in a list using vListInsertEnd effectively places the item\r
- * in the list position pointed to by pvIndex. This means that every other\r
- * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before\r
- * the pvIndex parameter again points to the item being inserted.\r
- *\r
- * @param pxList The list into which the item is to be inserted.\r
- *\r
- * @param pxNewListItem The list item to be inserted into the list.\r
- *\r
- * \page vListInsertEnd vListInsertEnd\r
- * \ingroup LinkedList\r
- */\r
-void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );\r
-\r
-/*\r
- * Remove an item from a list. The list item has a pointer to the list that\r
- * it is in, so only the list item need be passed into the function.\r
- *\r
- * @param vListRemove The item to be removed. The item will remove itself from\r
- * the list pointed to by it's pxContainer parameter.\r
- *\r
- * \page vListRemove vListRemove\r
- * \ingroup LinkedList\r
- */\r
-void vListRemove( xListItem *pxItemToRemove );\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef MPU_WRAPPERS_H\r
-#define MPU_WRAPPERS_H\r
-\r
-/* This file redefines API functions to be called through a wrapper macro, but\r
-only for ports that are using the MPU. */\r
-#ifdef portUSING_MPU_WRAPPERS\r
-\r
- /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is\r
- included from queue.c or task.c to prevent it from having an effect within\r
- those files. */\r
- #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
-\r
- #define xTaskGenericCreate MPU_xTaskGenericCreate\r
- #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions\r
- #define vTaskDelete MPU_vTaskDelete\r
- #define vTaskDelayUntil MPU_vTaskDelayUntil\r
- #define vTaskDelay MPU_vTaskDelay\r
- #define uxTaskPriorityGet MPU_uxTaskPriorityGet\r
- #define vTaskPrioritySet MPU_vTaskPrioritySet\r
- #define vTaskSuspend MPU_vTaskSuspend\r
- #define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended\r
- #define vTaskResume MPU_vTaskResume\r
- #define vTaskSuspendAll MPU_vTaskSuspendAll\r
- #define xTaskResumeAll MPU_xTaskResumeAll\r
- #define xTaskGetTickCount MPU_xTaskGetTickCount\r
- #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks\r
- #define vTaskList MPU_vTaskList\r
- #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats\r
- #define vTaskStartTrace MPU_vTaskStartTrace\r
- #define ulTaskEndTrace MPU_ulTaskEndTrace\r
- #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag\r
- #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag\r
- #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook\r
- #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark\r
- #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle\r
- #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState\r
-\r
- #define xQueueCreate MPU_xQueueCreate\r
- #define xQueueCreateMutex MPU_xQueueCreateMutex\r
- #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive\r
- #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive\r
- #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore\r
- #define xQueueGenericSend MPU_xQueueGenericSend\r
- #define xQueueAltGenericSend MPU_xQueueAltGenericSend\r
- #define xQueueAltGenericReceive MPU_xQueueAltGenericReceive\r
- #define xQueueGenericReceive MPU_xQueueGenericReceive\r
- #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting\r
- #define vQueueDelete MPU_vQueueDelete\r
-\r
- #define pvPortMalloc MPU_pvPortMalloc\r
- #define vPortFree MPU_vPortFree\r
- #define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize\r
- #define vPortInitialiseBlocks MPU_vPortInitialiseBlocks\r
-\r
- #if configQUEUE_REGISTRY_SIZE > 0\r
- #define vQueueAddToRegistry MPU_vQueueAddToRegistry\r
- #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue\r
- #endif\r
-\r
- /* Remove the privileged function macro. */\r
- #define PRIVILEGED_FUNCTION\r
-\r
- #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */\r
-\r
- /* Ensure API functions go in the privileged execution section. */\r
- #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))\r
- #define PRIVILEGED_DATA __attribute__((section("privileged_data")))\r
- //#define PRIVILEGED_DATA\r
-\r
- #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */\r
-\r
-#else /* portUSING_MPU_WRAPPERS */\r
-\r
- #define PRIVILEGED_FUNCTION\r
- #define PRIVILEGED_DATA\r
- #define portUSING_MPU_WRAPPERS 0\r
-\r
-#endif /* portUSING_MPU_WRAPPERS */\r
-\r
-\r
-#endif /* MPU_WRAPPERS_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-/*-----------------------------------------------------------\r
- * Portable layer API. Each function must be defined for each port.\r
- *----------------------------------------------------------*/\r
-\r
-#ifndef PORTABLE_H\r
-#define PORTABLE_H\r
-\r
-/* Include the macro file relevant to the port being used. */\r
-\r
-#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT\r
- #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"\r
- typedef void ( __interrupt __far *pxISR )();\r
-#endif\r
-\r
-#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT\r
- #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"\r
- typedef void ( __interrupt __far *pxISR )();\r
-#endif\r
-\r
-#ifdef GCC_MEGA_AVR\r
- #include "../portable/GCC/ATMega323/portmacro.h"\r
-#endif\r
-\r
-#ifdef IAR_MEGA_AVR\r
- #include "../portable/IAR/ATMega323/portmacro.h"\r
-#endif\r
-\r
-#ifdef MPLAB_PIC24_PORT\r
- #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"\r
-#endif\r
-\r
-#ifdef MPLAB_DSPIC_PORT\r
- #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"\r
-#endif\r
-\r
-#ifdef MPLAB_PIC18F_PORT\r
- #include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h"\r
-#endif\r
-\r
-#ifdef MPLAB_PIC32MX_PORT\r
- #include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h"\r
-#endif\r
-\r
-#ifdef _FEDPICC\r
- #include "libFreeRTOS/Include/portmacro.h"\r
-#endif\r
-\r
-#ifdef SDCC_CYGNAL\r
- #include "../../Source/portable/SDCC/Cygnal/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_ARM7\r
- #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_ARM7_ECLIPSE\r
- #include "portmacro.h"\r
-#endif\r
-\r
-#ifdef ROWLEY_LPC23xx\r
- #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"\r
-#endif\r
-\r
-#ifdef IAR_MSP430\r
- #include "..\..\Source\portable\IAR\MSP430\portmacro.h" \r
-#endif\r
- \r
-#ifdef GCC_MSP430\r
- #include "../../Source/portable/GCC/MSP430F449/portmacro.h"\r
-#endif\r
-\r
-#ifdef ROWLEY_MSP430\r
- #include "../../Source/portable/Rowley/MSP430F449/portmacro.h"\r
-#endif\r
-\r
-#ifdef ARM7_LPC21xx_KEIL_RVDS\r
- #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"\r
-#endif\r
-\r
-#ifdef SAM7_GCC\r
- #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"\r
-#endif\r
-\r
-#ifdef SAM7_IAR\r
- #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"\r
-#endif\r
-\r
-#ifdef SAM9XE_IAR\r
- #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"\r
-#endif\r
-\r
-#ifdef LPC2000_IAR\r
- #include "..\..\Source\portable\IAR\LPC2000\portmacro.h"\r
-#endif\r
-\r
-#ifdef STR71X_IAR\r
- #include "..\..\Source\portable\IAR\STR71x\portmacro.h"\r
-#endif\r
-\r
-#ifdef STR75X_IAR\r
- #include "..\..\Source\portable\IAR\STR75x\portmacro.h"\r
-#endif\r
- \r
-#ifdef STR75X_GCC\r
- #include "..\..\Source\portable\GCC\STR75x\portmacro.h"\r
-#endif\r
-\r
-#ifdef STR91X_IAR\r
- #include "..\..\Source\portable\IAR\STR91x\portmacro.h"\r
-#endif\r
- \r
-#ifdef GCC_H8S\r
- #include "../../Source/portable/GCC/H8S2329/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_AT91FR40008\r
- #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"\r
-#endif\r
-\r
-#ifdef RVDS_ARMCM3_LM3S102\r
- #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_ARMCM3_LM3S102\r
- #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_ARMCM3\r
- #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"\r
-#endif\r
-\r
-#ifdef IAR_ARM_CM3\r
- #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"\r
-#endif\r
-\r
-#ifdef IAR_ARMCM3_LM\r
- #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"\r
-#endif\r
- \r
-#ifdef HCS12_CODE_WARRIOR\r
- #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"\r
-#endif \r
-\r
-#ifdef MICROBLAZE_GCC\r
- #include "../../Source/portable/GCC/MicroBlaze/portmacro.h"\r
-#endif\r
-\r
-#ifdef TERN_EE\r
- #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_HCS12\r
- #include "../../Source/portable/GCC/HCS12/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_MCF5235\r
- #include "../../Source/portable/GCC/MCF5235/portmacro.h"\r
-#endif\r
-\r
-#ifdef COLDFIRE_V2_GCC\r
- #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"\r
-#endif\r
-\r
-#ifdef COLDFIRE_V2_CODEWARRIOR\r
- #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_PPC405\r
- #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_PPC440\r
- #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"\r
-#endif\r
-\r
-#ifdef _16FX_SOFTUNE\r
- #include "..\..\Source\portable\Softune\MB96340\portmacro.h"\r
-#endif\r
-\r
-#ifdef BCC_INDUSTRIAL_PC_PORT\r
- /* A short file name has to be used in place of the normal\r
- FreeRTOSConfig.h when using the Borland compiler. */\r
- #include "frconfig.h"\r
- #include "..\portable\BCC\16BitDOS\PC\prtmacro.h"\r
- typedef void ( __interrupt __far *pxISR )();\r
-#endif\r
-\r
-#ifdef BCC_FLASH_LITE_186_PORT\r
- /* A short file name has to be used in place of the normal\r
- FreeRTOSConfig.h when using the Borland compiler. */\r
- #include "frconfig.h"\r
- #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"\r
- typedef void ( __interrupt __far *pxISR )();\r
-#endif\r
-\r
-#ifdef __GNUC__\r
- #ifdef __AVR32_AVR32A__\r
- #include "portmacro.h"\r
- #endif\r
-#endif\r
-\r
-#ifdef __ICCAVR32__\r
- #ifdef __CORE__\r
- #if __CORE__ == __AVR32A__\r
- #include "portmacro.h"\r
- #endif\r
- #endif\r
-#endif\r
-\r
-#ifdef __91467D\r
- #include "portmacro.h"\r
-#endif\r
-\r
-#ifdef __96340\r
- #include "portmacro.h"\r
-#endif\r
-\r
-\r
-#ifdef __IAR_V850ES_Fx3__\r
- #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_V850ES_Jx3__\r
- #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_V850ES_Jx3_L__\r
- #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_V850ES_Jx2__\r
- #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_V850ES_Hx2__\r
- #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_78K0R_Kx3__\r
- #include "../../Source/portable/IAR/78K0R/portmacro.h"\r
-#endif\r
- \r
-#ifdef __IAR_78K0R_Kx3L__\r
- #include "../../Source/portable/IAR/78K0R/portmacro.h"\r
-#endif\r
- \r
-/* Catch all to ensure portmacro.h is included in the build. Newer demos\r
-have the path as part of the project options, rather than as relative from\r
-the project location. If portENTER_CRITICAL() has not been defined then\r
-portmacro.h has not yet been included - as every portmacro.h provides a\r
-portENTER_CRITICAL() definition. Check the demo application for your demo\r
-to find the path to the correct portmacro.h file. */\r
-#ifndef portENTER_CRITICAL\r
- #include "portmacro.h" \r
-#endif\r
- \r
-#if portBYTE_ALIGNMENT == 8\r
- #define portBYTE_ALIGNMENT_MASK ( 0x0007 )\r
-#endif\r
-\r
-#if portBYTE_ALIGNMENT == 4\r
- #define portBYTE_ALIGNMENT_MASK ( 0x0003 )\r
-#endif\r
-\r
-#if portBYTE_ALIGNMENT == 2\r
- #define portBYTE_ALIGNMENT_MASK ( 0x0001 )\r
-#endif\r
-\r
-#if portBYTE_ALIGNMENT == 1\r
- #define portBYTE_ALIGNMENT_MASK ( 0x0000 )\r
-#endif\r
-\r
-#ifndef portBYTE_ALIGNMENT_MASK\r
- #error "Invalid portBYTE_ALIGNMENT definition"\r
-#endif\r
-\r
-#ifndef portNUM_CONFIGURABLE_REGIONS\r
- #define portNUM_CONFIGURABLE_REGIONS 1\r
-#endif\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-#include "mpu_wrappers.h"\r
-\r
-/*\r
- * Setup the stack of a new task so it is ready to be placed under the\r
- * scheduler control. The registers have to be placed on the stack in\r
- * the order that the port expects to find them.\r
- *\r
- */\r
-#if( portUSING_MPU_WRAPPERS == 1 )\r
- portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION;\r
-#else\r
- portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters );\r
-#endif\r
-\r
-/*\r
- * Map to the memory management routines required for the port.\r
- */\r
-void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;\r
-void vPortFree( void *pv ) PRIVILEGED_FUNCTION;\r
-void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;\r
-size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Setup the hardware ready for the scheduler to take control. This generally\r
- * sets up a tick interrupt and sets timers for the correct tick frequency.\r
- */\r
-portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so\r
- * the hardware is left in its original condition after the scheduler stops\r
- * executing.\r
- */\r
-void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * The structures and methods of manipulating the MPU are contained within the\r
- * port layer.\r
- *\r
- * Fills the xMPUSettings structure with the memory region information\r
- * contained in xRegions.\r
- */\r
-#if( portUSING_MPU_WRAPPERS == 1 ) \r
- struct xMEMORY_REGION;\r
- void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth ) PRIVILEGED_FUNCTION;\r
-#endif\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* PORTABLE_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef PROJDEFS_H\r
-#define PROJDEFS_H\r
-\r
-/* Defines the prototype to which task functions must conform. */\r
-typedef void (*pdTASK_CODE)( void * );\r
-\r
-#define pdTRUE ( 1 )\r
-#define pdFALSE ( 0 )\r
-\r
-#define pdPASS ( 1 )\r
-#define pdFAIL ( 0 )\r
-#define errQUEUE_EMPTY ( 0 )\r
-#define errQUEUE_FULL ( 0 )\r
-\r
-/* Error definitions. */\r
-#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )\r
-#define errNO_TASK_TO_RUN ( -2 )\r
-#define errQUEUE_BLOCKED ( -4 )\r
-#define errQUEUE_YIELD ( -5 )\r
-\r
-#endif /* PROJDEFS_H */\r
-\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-\r
-#ifndef QUEUE_H\r
-#define QUEUE_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "#include FreeRTOS.h" must appear in source files before "#include queue.h"\r
-#endif\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-#include "mpu_wrappers.h"\r
-\r
-/**\r
- * Type by which queues are referenced. For example, a call to xQueueCreate\r
- * returns (via a pointer parameter) an xQueueHandle variable that can then\r
- * be used as a parameter to xQueueSend(), xQueueReceive(), etc.\r
- */\r
-typedef void * xQueueHandle;\r
-\r
-\r
-/* For internal use only. */\r
-#define queueSEND_TO_BACK ( 0 )\r
-#define queueSEND_TO_FRONT ( 1 )\r
-\r
-/* For internal use only. These definitions *must* match those in queue.c. */\r
-#define queueQUEUE_TYPE_BASE ( 0U )\r
-#define queueQUEUE_TYPE_MUTEX ( 1U )\r
-#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )\r
-#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )\r
-#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- xQueueHandle xQueueCreate(\r
- unsigned portBASE_TYPE uxQueueLength,\r
- unsigned portBASE_TYPE uxItemSize\r
- );\r
- * </pre>\r
- *\r
- * Creates a new queue instance. This allocates the storage required by the\r
- * new queue and returns a handle for the queue.\r
- *\r
- * @param uxQueueLength The maximum number of items that the queue can contain.\r
- *\r
- * @param uxItemSize The number of bytes each item in the queue will require.\r
- * Items are queued by copy, not by reference, so this is the number of bytes\r
- * that will be copied for each posted item. Each item on the queue must be\r
- * the same size.\r
- *\r
- * @return If the queue is successfully create then a handle to the newly\r
- * created queue is returned. If the queue cannot be created then 0 is\r
- * returned.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- };\r
-\r
- void vATask( void *pvParameters )\r
- {\r
- xQueueHandle xQueue1, xQueue2;\r
-\r
- // Create a queue capable of containing 10 unsigned long values.\r
- xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
- if( xQueue1 == 0 )\r
- {\r
- // Queue was not created and must not be used.\r
- }\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue2 == 0 )\r
- {\r
- // Queue was not created and must not be used.\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueCreate xQueueCreate\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueSendToToFront(\r
- xQueueHandle xQueue,\r
- const void * pvItemToQueue,\r
- portTickType xTicksToWait\r
- );\r
- * </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSend().\r
- *\r
- * Post an item to the front of a queue. The item is queued by copy, not by\r
- * reference. This function must not be called from an interrupt service\r
- * routine. See xQueueSendFromISR () for an alternative which may be used\r
- * in an ISR.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0 and the\r
- * queue is full. The time is defined in tick periods so the constant\r
- * portTICK_RATE_MS should be used to convert to real time if this is required.\r
- *\r
- * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- unsigned long ulVar = 10UL;\r
-\r
- void vATask( void *pvParameters )\r
- {\r
- xQueueHandle xQueue1, xQueue2;\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 unsigned long values.\r
- xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an unsigned long. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueSend xQueueSend\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueSendToBack(\r
- xQueueHandle xQueue,\r
- const void * pvItemToQueue,\r
- portTickType xTicksToWait\r
- );\r
- * </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSend().\r
- *\r
- * Post an item to the back of a queue. The item is queued by copy, not by\r
- * reference. This function must not be called from an interrupt service\r
- * routine. See xQueueSendFromISR () for an alternative which may be used\r
- * in an ISR.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0 and the queue\r
- * is full. The time is defined in tick periods so the constant\r
- * portTICK_RATE_MS should be used to convert to real time if this is required.\r
- *\r
- * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- unsigned long ulVar = 10UL;\r
-\r
- void vATask( void *pvParameters )\r
- {\r
- xQueueHandle xQueue1, xQueue2;\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 unsigned long values.\r
- xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an unsigned long. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueSend xQueueSend\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueSend(\r
- xQueueHandle xQueue,\r
- const void * pvItemToQueue,\r
- portTickType xTicksToWait\r
- );\r
- * </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSend(). It is included for\r
- * backward compatibility with versions of FreeRTOS.org that did not\r
- * include the xQueueSendToFront() and xQueueSendToBack() macros. It is\r
- * equivalent to xQueueSendToBack().\r
- *\r
- * Post an item on a queue. The item is queued by copy, not by reference.\r
- * This function must not be called from an interrupt service routine.\r
- * See xQueueSendFromISR () for an alternative which may be used in an ISR.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0 and the\r
- * queue is full. The time is defined in tick periods so the constant\r
- * portTICK_RATE_MS should be used to convert to real time if this is required.\r
- *\r
- * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- unsigned long ulVar = 10UL;\r
-\r
- void vATask( void *pvParameters )\r
- {\r
- xQueueHandle xQueue1, xQueue2;\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 unsigned long values.\r
- xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an unsigned long. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueSend xQueueSend\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )\r
-\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueGenericSend(\r
- xQueueHandle xQueue,\r
- const void * pvItemToQueue,\r
- portTickType xTicksToWait\r
- portBASE_TYPE xCopyPosition\r
- );\r
- * </pre>\r
- *\r
- * It is preferred that the macros xQueueSend(), xQueueSendToFront() and\r
- * xQueueSendToBack() are used in place of calling this function directly.\r
- *\r
- * Post an item on a queue. The item is queued by copy, not by reference.\r
- * This function must not be called from an interrupt service routine.\r
- * See xQueueSendFromISR () for an alternative which may be used in an ISR.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0 and the\r
- * queue is full. The time is defined in tick periods so the constant\r
- * portTICK_RATE_MS should be used to convert to real time if this is required.\r
- *\r
- * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the\r
- * item at the back of the queue, or queueSEND_TO_FRONT to place the item\r
- * at the front of the queue (for high priority messages).\r
- *\r
- * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- unsigned long ulVar = 10UL;\r
-\r
- void vATask( void *pvParameters )\r
- {\r
- xQueueHandle xQueue1, xQueue2;\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 unsigned long values.\r
- xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an unsigned long. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueSend xQueueSend\r
- * \ingroup QueueManagement\r
- */\r
-signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueuePeek(\r
- xQueueHandle xQueue,\r
- void *pvBuffer,\r
- portTickType xTicksToWait\r
- );</pre>\r
- *\r
- * This is a macro that calls the xQueueGenericReceive() function.\r
- *\r
- * Receive an item from a queue without removing the item from the queue.\r
- * The item is received by copy so a buffer of adequate size must be\r
- * provided. The number of bytes copied into the buffer was defined when\r
- * the queue was created.\r
- *\r
- * Successfully received items remain on the queue so will be returned again\r
- * by the next call, or a call to xQueueReceive().\r
- *\r
- * This macro must not be used in an interrupt service routine.\r
- *\r
- * @param pxQueue The handle to the queue from which the item is to be\r
- * received.\r
- *\r
- * @param pvBuffer Pointer to the buffer into which the received item will\r
- * be copied.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for an item to receive should the queue be empty at the time\r
- * of the call. The time is defined in tick periods so the constant\r
- * portTICK_RATE_MS should be used to convert to real time if this is required.\r
- * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue\r
- * is empty.\r
- *\r
- * @return pdTRUE if an item was successfully received from the queue,\r
- * otherwise pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- xQueueHandle xQueue;\r
-\r
- // Task to create a queue and post a value.\r
- void vATask( void *pvParameters )\r
- {\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
-\r
- // ...\r
-\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
-\r
- // ... Rest of task code.\r
- }\r
-\r
- // Task to peek the data from the queue.\r
- void vADifferentTask( void *pvParameters )\r
- {\r
- struct AMessage *pxRxedMessage;\r
-\r
- if( xQueue != 0 )\r
- {\r
- // Peek a message on the created queue. Block for 10 ticks if a\r
- // message is not immediately available.\r
- if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
- {\r
- // pcRxedMessage now points to the struct AMessage variable posted\r
- // by vATask, but the item still remains on the queue.\r
- }\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueReceive xQueueReceive\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueReceive(\r
- xQueueHandle xQueue,\r
- void *pvBuffer,\r
- portTickType xTicksToWait\r
- );</pre>\r
- *\r
- * This is a macro that calls the xQueueGenericReceive() function.\r
- *\r
- * Receive an item from a queue. The item is received by copy so a buffer of\r
- * adequate size must be provided. The number of bytes copied into the buffer\r
- * was defined when the queue was created.\r
- *\r
- * Successfully received items are removed from the queue.\r
- *\r
- * This function must not be used in an interrupt service routine. See\r
- * xQueueReceiveFromISR for an alternative that can.\r
- *\r
- * @param pxQueue The handle to the queue from which the item is to be\r
- * received.\r
- *\r
- * @param pvBuffer Pointer to the buffer into which the received item will\r
- * be copied.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for an item to receive should the queue be empty at the time\r
- * of the call. xQueueReceive() will return immediately if xTicksToWait\r
- * is zero and the queue is empty. The time is defined in tick periods so the\r
- * constant portTICK_RATE_MS should be used to convert to real time if this is\r
- * required.\r
- *\r
- * @return pdTRUE if an item was successfully received from the queue,\r
- * otherwise pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- xQueueHandle xQueue;\r
-\r
- // Task to create a queue and post a value.\r
- void vATask( void *pvParameters )\r
- {\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
-\r
- // ...\r
-\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
-\r
- // ... Rest of task code.\r
- }\r
-\r
- // Task to receive from the queue.\r
- void vADifferentTask( void *pvParameters )\r
- {\r
- struct AMessage *pxRxedMessage;\r
-\r
- if( xQueue != 0 )\r
- {\r
- // Receive a message on the created queue. Block for 10 ticks if a\r
- // message is not immediately available.\r
- if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
- {\r
- // pcRxedMessage now points to the struct AMessage variable posted\r
- // by vATask.\r
- }\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueReceive xQueueReceive\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )\r
-\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueGenericReceive(\r
- xQueueHandle xQueue,\r
- void *pvBuffer,\r
- portTickType xTicksToWait\r
- portBASE_TYPE xJustPeek\r
- );</pre>\r
- *\r
- * It is preferred that the macro xQueueReceive() be used rather than calling\r
- * this function directly.\r
- *\r
- * Receive an item from a queue. The item is received by copy so a buffer of\r
- * adequate size must be provided. The number of bytes copied into the buffer\r
- * was defined when the queue was created.\r
- *\r
- * This function must not be used in an interrupt service routine. See\r
- * xQueueReceiveFromISR for an alternative that can.\r
- *\r
- * @param pxQueue The handle to the queue from which the item is to be\r
- * received.\r
- *\r
- * @param pvBuffer Pointer to the buffer into which the received item will\r
- * be copied.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for an item to receive should the queue be empty at the time\r
- * of the call. The time is defined in tick periods so the constant\r
- * portTICK_RATE_MS should be used to convert to real time if this is required.\r
- * xQueueGenericReceive() will return immediately if the queue is empty and\r
- * xTicksToWait is 0.\r
- *\r
- * @param xJustPeek When set to true, the item received from the queue is not\r
- * actually removed from the queue - meaning a subsequent call to\r
- * xQueueReceive() will return the same item. When set to false, the item\r
- * being received from the queue is also removed from the queue.\r
- *\r
- * @return pdTRUE if an item was successfully received from the queue,\r
- * otherwise pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- xQueueHandle xQueue;\r
-\r
- // Task to create a queue and post a value.\r
- void vATask( void *pvParameters )\r
- {\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
-\r
- // ...\r
-\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
-\r
- // ... Rest of task code.\r
- }\r
-\r
- // Task to receive from the queue.\r
- void vADifferentTask( void *pvParameters )\r
- {\r
- struct AMessage *pxRxedMessage;\r
-\r
- if( xQueue != 0 )\r
- {\r
- // Receive a message on the created queue. Block for 10 ticks if a\r
- // message is not immediately available.\r
- if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
- {\r
- // pcRxedMessage now points to the struct AMessage variable posted\r
- // by vATask.\r
- }\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueReceive xQueueReceive\r
- * \ingroup QueueManagement\r
- */\r
-signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek );\r
-\r
-/**\r
- * queue. h\r
- * <pre>unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );</pre>\r
- *\r
- * Return the number of messages stored in a queue.\r
- *\r
- * @param xQueue A handle to the queue being queried.\r
- *\r
- * @return The number of messages available in the queue.\r
- *\r
- * \page uxQueueMessagesWaiting uxQueueMessagesWaiting\r
- * \ingroup QueueManagement\r
- */\r
-unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );\r
-\r
-/**\r
- * queue. h\r
- * <pre>void vQueueDelete( xQueueHandle xQueue );</pre>\r
- *\r
- * Delete a queue - freeing all the memory allocated for storing of items\r
- * placed on the queue.\r
- *\r
- * @param xQueue A handle to the queue to be deleted.\r
- *\r
- * \page vQueueDelete vQueueDelete\r
- * \ingroup QueueManagement\r
- */\r
-void vQueueDelete( xQueueHandle pxQueue );\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueSendToFrontFromISR(\r
- xQueueHandle pxQueue,\r
- const void *pvItemToQueue,\r
- portBASE_TYPE *pxHigherPriorityTaskWoken\r
- );\r
- </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSendFromISR().\r
- *\r
- * Post an item to the front of a queue. It is safe to use this macro from\r
- * within an interrupt service routine.\r
- *\r
- * Items are queued by copy not reference so it is preferable to only\r
- * queue small items, especially when called from an ISR. In most cases\r
- * it would be preferable to store a pointer to the item being queued.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
- * errQUEUE_FULL.\r
- *\r
- * Example usage for buffered IO (where the ISR can obtain more than one value\r
- * per call):\r
- <pre>\r
- void vBufferISR( void )\r
- {\r
- char cIn;\r
- portBASE_TYPE xHigherPrioritTaskWoken;\r
-\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWoken = pdFALSE;\r
-\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
-\r
- // Post the byte.\r
- xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
-\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
-\r
- // Now the buffer is empty we can switch context if necessary.\r
- if( xHigherPriorityTaskWoken )\r
- {\r
- taskYIELD ();\r
- }\r
- }\r
- </pre>\r
- *\r
- * \defgroup xQueueSendFromISR xQueueSendFromISR\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT )\r
-\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueSendToBackFromISR(\r
- xQueueHandle pxQueue,\r
- const void *pvItemToQueue,\r
- portBASE_TYPE *pxHigherPriorityTaskWoken\r
- );\r
- </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSendFromISR().\r
- *\r
- * Post an item to the back of a queue. It is safe to use this macro from\r
- * within an interrupt service routine.\r
- *\r
- * Items are queued by copy not reference so it is preferable to only\r
- * queue small items, especially when called from an ISR. In most cases\r
- * it would be preferable to store a pointer to the item being queued.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
- * errQUEUE_FULL.\r
- *\r
- * Example usage for buffered IO (where the ISR can obtain more than one value\r
- * per call):\r
- <pre>\r
- void vBufferISR( void )\r
- {\r
- char cIn;\r
- portBASE_TYPE xHigherPriorityTaskWoken;\r
-\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWoken = pdFALSE;\r
-\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
-\r
- // Post the byte.\r
- xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
-\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
-\r
- // Now the buffer is empty we can switch context if necessary.\r
- if( xHigherPriorityTaskWoken )\r
- {\r
- taskYIELD ();\r
- }\r
- }\r
- </pre>\r
- *\r
- * \defgroup xQueueSendFromISR xQueueSendFromISR\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueSendFromISR(\r
- xQueueHandle pxQueue,\r
- const void *pvItemToQueue,\r
- portBASE_TYPE *pxHigherPriorityTaskWoken\r
- );\r
- </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSendFromISR(). It is included\r
- * for backward compatibility with versions of FreeRTOS.org that did not\r
- * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR()\r
- * macros.\r
- *\r
- * Post an item to the back of a queue. It is safe to use this function from\r
- * within an interrupt service routine.\r
- *\r
- * Items are queued by copy not reference so it is preferable to only\r
- * queue small items, especially when called from an ISR. In most cases\r
- * it would be preferable to store a pointer to the item being queued.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xQueueSendFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
- * errQUEUE_FULL.\r
- *\r
- * Example usage for buffered IO (where the ISR can obtain more than one value\r
- * per call):\r
- <pre>\r
- void vBufferISR( void )\r
- {\r
- char cIn;\r
- portBASE_TYPE xHigherPriorityTaskWoken;\r
-\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWoken = pdFALSE;\r
-\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
-\r
- // Post the byte.\r
- xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
-\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
-\r
- // Now the buffer is empty we can switch context if necessary.\r
- if( xHigherPriorityTaskWoken )\r
- {\r
- // Actual macro used here is port specific.\r
- taskYIELD_FROM_ISR ();\r
- }\r
- }\r
- </pre>\r
- *\r
- * \defgroup xQueueSendFromISR xQueueSendFromISR\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueGenericSendFromISR(\r
- xQueueHandle pxQueue,\r
- const void *pvItemToQueue,\r
- portBASE_TYPE *pxHigherPriorityTaskWoken,\r
- portBASE_TYPE xCopyPosition\r
- );\r
- </pre>\r
- *\r
- * It is preferred that the macros xQueueSendFromISR(),\r
- * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place\r
- * of calling this function directly.\r
- *\r
- * Post an item on a queue. It is safe to use this function from within an\r
- * interrupt service routine.\r
- *\r
- * Items are queued by copy not reference so it is preferable to only\r
- * queue small items, especially when called from an ISR. In most cases\r
- * it would be preferable to store a pointer to the item being queued.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the\r
- * item at the back of the queue, or queueSEND_TO_FRONT to place the item\r
- * at the front of the queue (for high priority messages).\r
- *\r
- * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
- * errQUEUE_FULL.\r
- *\r
- * Example usage for buffered IO (where the ISR can obtain more than one value\r
- * per call):\r
- <pre>\r
- void vBufferISR( void )\r
- {\r
- char cIn;\r
- portBASE_TYPE xHigherPriorityTaskWokenByPost;\r
-\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWokenByPost = pdFALSE;\r
-\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
-\r
- // Post each byte.\r
- xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );\r
-\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
-\r
- // Now the buffer is empty we can switch context if necessary. Note that the\r
- // name of the yield function required is port specific.\r
- if( xHigherPriorityTaskWokenByPost )\r
- {\r
- taskYIELD_YIELD_FROM_ISR();\r
- }\r
- }\r
- </pre>\r
- *\r
- * \defgroup xQueueSendFromISR xQueueSendFromISR\r
- * \ingroup QueueManagement\r
- */\r
-signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition );\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- portBASE_TYPE xQueueReceiveFromISR(\r
- xQueueHandle pxQueue,\r
- void *pvBuffer,\r
- portBASE_TYPE *pxTaskWoken\r
- );\r
- * </pre>\r
- *\r
- * Receive an item from a queue. It is safe to use this function from within an\r
- * interrupt service routine.\r
- *\r
- * @param pxQueue The handle to the queue from which the item is to be\r
- * received.\r
- *\r
- * @param pvBuffer Pointer to the buffer into which the received item will\r
- * be copied.\r
- *\r
- * @param pxTaskWoken A task may be blocked waiting for space to become\r
- * available on the queue. If xQueueReceiveFromISR causes such a task to\r
- * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will\r
- * remain unchanged.\r
- *\r
- * @return pdTRUE if an item was successfully received from the queue,\r
- * otherwise pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
-\r
- xQueueHandle xQueue;\r
-\r
- // Function to create a queue and post some values.\r
- void vAFunction( void *pvParameters )\r
- {\r
- char cValueToPost;\r
- const portTickType xBlockTime = ( portTickType )0xff;\r
-\r
- // Create a queue capable of containing 10 characters.\r
- xQueue = xQueueCreate( 10, sizeof( char ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
-\r
- // ...\r
-\r
- // Post some characters that will be used within an ISR. If the queue\r
- // is full then this task will block for xBlockTime ticks.\r
- cValueToPost = 'a';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
- cValueToPost = 'b';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
-\r
- // ... keep posting characters ... this task may block when the queue\r
- // becomes full.\r
-\r
- cValueToPost = 'c';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
- }\r
-\r
- // ISR that outputs all the characters received on the queue.\r
- void vISR_Routine( void )\r
- {\r
- portBASE_TYPE xTaskWokenByReceive = pdFALSE;\r
- char cRxedChar;\r
-\r
- while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )\r
- {\r
- // A character was received. Output the character now.\r
- vOutputCharacter( cRxedChar );\r
-\r
- // If removing the character from the queue woke the task that was\r
- // posting onto the queue cTaskWokenByReceive will have been set to\r
- // pdTRUE. No matter how many times this loop iterates only one\r
- // task will be woken.\r
- }\r
-\r
- if( cTaskWokenByPost != ( char ) pdFALSE;\r
- {\r
- taskYIELD ();\r
- }\r
- }\r
- </pre>\r
- * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR\r
- * \ingroup QueueManagement\r
- */\r
-signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
-\r
-/*\r
- * Utilities to query queue that are safe to use from an ISR. These utilities\r
- * should be used only from witin an ISR, or within a critical section.\r
- */\r
-signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue );\r
-signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue );\r
-unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue );\r
-\r
-\r
-/*\r
- * xQueueAltGenericSend() is an alternative version of xQueueGenericSend().\r
- * Likewise xQueueAltGenericReceive() is an alternative version of\r
- * xQueueGenericReceive().\r
- *\r
- * The source code that implements the alternative (Alt) API is much\r
- * simpler because it executes everything from within a critical section.\r
- * This is the approach taken by many other RTOSes, but FreeRTOS.org has the\r
- * preferred fully featured API too. The fully featured API has more\r
- * complex code that takes longer to execute, but makes much less use of\r
- * critical sections. Therefore the alternative API sacrifices interrupt\r
- * responsiveness to gain execution speed, whereas the fully featured API\r
- * sacrifices execution speed to ensure better interrupt responsiveness.\r
- */\r
-signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
-signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
-#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )\r
-#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )\r
-#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )\r
-#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )\r
-\r
-/*\r
- * The functions defined above are for passing data to and from tasks. The\r
- * functions below are the equivalents for passing data to and from\r
- * co-routines.\r
- *\r
- * These functions are called from the co-routine macro implementation and\r
- * should not be called directly from application code. Instead use the macro\r
- * wrappers defined within croutine.h.\r
- */\r
-signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );\r
-signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
-signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait );\r
-signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );\r
-\r
-/*\r
- * For internal use only. Use xSemaphoreCreateMutex() or\r
- * xSemaphoreCreateCounting() instead of calling these functions directly.\r
- */\r
-xQueueHandle xQueueCreateMutex( unsigned char ucQueueType );\r
-xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );\r
-\r
-/*\r
- * For internal use only. Use xSemaphoreTakeMutexRecursive() or\r
- * xSemaphoreGiveMutexRecursive() instead of calling these functions directly.\r
- */\r
-portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime );\r
-portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex );\r
-\r
-/*\r
- * Reset a queue back to its original empty state. pdPASS is returned if the\r
- * queue is successfully reset. pdFAIL is returned if the queue could not be\r
- * reset because there are tasks blocked on the queue waiting to either\r
- * receive from the queue or send to the queue.\r
- */\r
-#define xQueueReset( pxQueue ) xQueueGenericReset( pxQueue, pdFALSE )\r
-\r
-/*\r
- * The registry is provided as a means for kernel aware debuggers to\r
- * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add\r
- * a queue, semaphore or mutex handle to the registry if you want the handle\r
- * to be available to a kernel aware debugger. If you are not using a kernel\r
- * aware debugger then this function can be ignored.\r
- *\r
- * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the\r
- * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0\r
- * within FreeRTOSConfig.h for the registry to be available. Its value\r
- * does not effect the number of queues, semaphores and mutexes that can be\r
- * created - just the number that the registry can hold.\r
- *\r
- * @param xQueue The handle of the queue being added to the registry. This\r
- * is the handle returned by a call to xQueueCreate(). Semaphore and mutex\r
- * handles can also be passed in here.\r
- *\r
- * @param pcName The name to be associated with the handle. This is the\r
- * name that the kernel aware debugger will display.\r
- */\r
-#if configQUEUE_REGISTRY_SIZE > 0U\r
- void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName );\r
-#endif\r
-\r
-/*\r
- * Generic version of the queue creation function, which is in turn called by \r
- * any queue, semaphore or mutex creation function or macro.\r
- */\r
-xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType );\r
-\r
-/* Not public API functions. */\r
-void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait );\r
-portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue );\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* QUEUE_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#ifndef SEMAPHORE_H\r
-#define SEMAPHORE_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "#include FreeRTOS.h" must appear in source files before "#include semphr.h"\r
-#endif\r
-\r
-#include "queue.h"\r
-\r
-typedef xQueueHandle xSemaphoreHandle;\r
-\r
-#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1U )\r
-#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0U )\r
-#define semGIVE_BLOCK_TIME ( ( portTickType ) 0U )\r
-\r
-\r
-/**\r
- * semphr. h\r
- * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>\r
- *\r
- * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.\r
- * The queue length is 1 as this is a binary semaphore. The data size is 0\r
- * as we don't want to actually store any data - we just want to know if the\r
- * queue is empty or full.\r
- *\r
- * This type of semaphore can be used for pure synchronisation between tasks or\r
- * between an interrupt and a task. The semaphore need not be given back once\r
- * obtained, so one task/interrupt can continuously 'give' the semaphore while\r
- * another continuously 'takes' the semaphore. For this reason this type of\r
- * semaphore does not use a priority inheritance mechanism. For an alternative\r
- * that does use priority inheritance see xSemaphoreCreateMutex().\r
- *\r
- * @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.\r
- *\r
- * Example usage:\r
- <pre>\r
- xSemaphoreHandle xSemaphore;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().\r
- // This is a macro so pass the variable in directly.\r
- vSemaphoreCreateBinary( xSemaphore );\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // The semaphore was created successfully.\r
- // The semaphore can now be used. \r
- }\r
- }\r
- </pre>\r
- * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary\r
- * \ingroup Semaphores\r
- */\r
-#define vSemaphoreCreateBinary( xSemaphore ) \\r
- { \\r
- ( xSemaphore ) = xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \\r
- if( ( xSemaphore ) != NULL ) \\r
- { \\r
- xSemaphoreGive( ( xSemaphore ) ); \\r
- } \\r
- }\r
-\r
-/**\r
- * semphr. h\r
- * <pre>xSemaphoreTake( \r
- * xSemaphoreHandle xSemaphore, \r
- * portTickType xBlockTime \r
- * )</pre>\r
- *\r
- * <i>Macro</i> to obtain a semaphore. The semaphore must have previously been\r
- * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or\r
- * xSemaphoreCreateCounting().\r
- *\r
- * @param xSemaphore A handle to the semaphore being taken - obtained when\r
- * the semaphore was created.\r
- *\r
- * @param xBlockTime The time in ticks to wait for the semaphore to become\r
- * available. The macro portTICK_RATE_MS can be used to convert this to a\r
- * real time. A block time of zero can be used to poll the semaphore. A block\r
- * time of portMAX_DELAY can be used to block indefinitely (provided\r
- * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).\r
- *\r
- * @return pdTRUE if the semaphore was obtained. pdFALSE\r
- * if xBlockTime expired without the semaphore becoming available.\r
- *\r
- * Example usage:\r
- <pre>\r
- xSemaphoreHandle xSemaphore = NULL;\r
-\r
- // A task that creates a semaphore.\r
- void vATask( void * pvParameters )\r
- {\r
- // Create the semaphore to guard a shared resource.\r
- vSemaphoreCreateBinary( xSemaphore );\r
- }\r
-\r
- // A task that uses the semaphore.\r
- void vAnotherTask( void * pvParameters )\r
- {\r
- // ... Do other things.\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // See if we can obtain the semaphore. If the semaphore is not available\r
- // wait 10 ticks to see if it becomes free. \r
- if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )\r
- {\r
- // We were able to obtain the semaphore and can now access the\r
- // shared resource.\r
-\r
- // ...\r
-\r
- // We have finished accessing the shared resource. Release the \r
- // semaphore.\r
- xSemaphoreGive( xSemaphore );\r
- }\r
- else\r
- {\r
- // We could not obtain the semaphore and can therefore not access\r
- // the shared resource safely.\r
- }\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreTake xSemaphoreTake\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )\r
-\r
-/**\r
- * semphr. h\r
- * xSemaphoreTakeRecursive( \r
- * xSemaphoreHandle xMutex, \r
- * portTickType xBlockTime \r
- * )\r
- *\r
- * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore. \r
- * The mutex must have previously been created using a call to \r
- * xSemaphoreCreateRecursiveMutex();\r
- * \r
- * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this\r
- * macro to be available.\r
- * \r
- * This macro must not be used on mutexes created using xSemaphoreCreateMutex().\r
- *\r
- * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex \r
- * doesn't become available again until the owner has called \r
- * xSemaphoreGiveRecursive() for each successful 'take' request. For example, \r
- * if a task successfully 'takes' the same mutex 5 times then the mutex will \r
- * not be available to any other task until it has also 'given' the mutex back\r
- * exactly five times.\r
- *\r
- * @param xMutex A handle to the mutex being obtained. This is the\r
- * handle returned by xSemaphoreCreateRecursiveMutex();\r
- *\r
- * @param xBlockTime The time in ticks to wait for the semaphore to become\r
- * available. The macro portTICK_RATE_MS can be used to convert this to a\r
- * real time. A block time of zero can be used to poll the semaphore. If\r
- * the task already owns the semaphore then xSemaphoreTakeRecursive() will\r
- * return immediately no matter what the value of xBlockTime. \r
- *\r
- * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime\r
- * expired without the semaphore becoming available.\r
- *\r
- * Example usage:\r
- <pre>\r
- xSemaphoreHandle xMutex = NULL;\r
-\r
- // A task that creates a mutex.\r
- void vATask( void * pvParameters )\r
- {\r
- // Create the mutex to guard a shared resource.\r
- xMutex = xSemaphoreCreateRecursiveMutex();\r
- }\r
-\r
- // A task that uses the mutex.\r
- void vAnotherTask( void * pvParameters )\r
- {\r
- // ... Do other things.\r
-\r
- if( xMutex != NULL )\r
- {\r
- // See if we can obtain the mutex. If the mutex is not available\r
- // wait 10 ticks to see if it becomes free. \r
- if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )\r
- {\r
- // We were able to obtain the mutex and can now access the\r
- // shared resource.\r
-\r
- // ...\r
- // For some reason due to the nature of the code further calls to \r
- // xSemaphoreTakeRecursive() are made on the same mutex. In real\r
- // code these would not be just sequential calls as this would make\r
- // no sense. Instead the calls are likely to be buried inside\r
- // a more complex call structure.\r
- xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
- xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
-\r
- // The mutex has now been 'taken' three times, so will not be \r
- // available to another task until it has also been given back\r
- // three times. Again it is unlikely that real code would have\r
- // these calls sequentially, but instead buried in a more complex\r
- // call structure. This is just for illustrative purposes.\r
- xSemaphoreGiveRecursive( xMutex );\r
- xSemaphoreGiveRecursive( xMutex );\r
- xSemaphoreGiveRecursive( xMutex );\r
-\r
- // Now the mutex can be taken by other tasks.\r
- }\r
- else\r
- {\r
- // We could not obtain the mutex and can therefore not access\r
- // the shared resource safely.\r
- }\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )\r
-\r
-\r
-/* \r
- * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().\r
- *\r
- * The source code that implements the alternative (Alt) API is much \r
- * simpler because it executes everything from within a critical section. \r
- * This is the approach taken by many other RTOSes, but FreeRTOS.org has the \r
- * preferred fully featured API too. The fully featured API has more \r
- * complex code that takes longer to execute, but makes much less use of \r
- * critical sections. Therefore the alternative API sacrifices interrupt \r
- * responsiveness to gain execution speed, whereas the fully featured API\r
- * sacrifices execution speed to ensure better interrupt responsiveness.\r
- */\r
-#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>\r
- *\r
- * <i>Macro</i> to release a semaphore. The semaphore must have previously been\r
- * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or\r
- * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().\r
- *\r
- * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for\r
- * an alternative which can be used from an ISR.\r
- *\r
- * This macro must also not be used on semaphores created using \r
- * xSemaphoreCreateRecursiveMutex().\r
- *\r
- * @param xSemaphore A handle to the semaphore being released. This is the\r
- * handle returned when the semaphore was created.\r
- *\r
- * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.\r
- * Semaphores are implemented using queues. An error can occur if there is\r
- * no space on the queue to post a message - indicating that the \r
- * semaphore was not first obtained correctly.\r
- *\r
- * Example usage:\r
- <pre>\r
- xSemaphoreHandle xSemaphore = NULL;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- // Create the semaphore to guard a shared resource.\r
- vSemaphoreCreateBinary( xSemaphore );\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- if( xSemaphoreGive( xSemaphore ) != pdTRUE )\r
- {\r
- // We would expect this call to fail because we cannot give\r
- // a semaphore without first "taking" it!\r
- }\r
-\r
- // Obtain the semaphore - don't block if the semaphore is not\r
- // immediately available.\r
- if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )\r
- {\r
- // We now have the semaphore and can access the shared resource.\r
-\r
- // ...\r
-\r
- // We have finished accessing the shared resource so can free the\r
- // semaphore.\r
- if( xSemaphoreGive( xSemaphore ) != pdTRUE )\r
- {\r
- // We would not expect this call to fail because we must have\r
- // obtained the semaphore to get here.\r
- }\r
- }\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreGive xSemaphoreGive\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>\r
- *\r
- * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.\r
- * The mutex must have previously been created using a call to \r
- * xSemaphoreCreateRecursiveMutex();\r
- * \r
- * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this\r
- * macro to be available.\r
- *\r
- * This macro must not be used on mutexes created using xSemaphoreCreateMutex().\r
- * \r
- * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex \r
- * doesn't become available again until the owner has called \r
- * xSemaphoreGiveRecursive() for each successful 'take' request. For example, \r
- * if a task successfully 'takes' the same mutex 5 times then the mutex will \r
- * not be available to any other task until it has also 'given' the mutex back\r
- * exactly five times.\r
- *\r
- * @param xMutex A handle to the mutex being released, or 'given'. This is the\r
- * handle returned by xSemaphoreCreateMutex();\r
- *\r
- * @return pdTRUE if the semaphore was given.\r
- *\r
- * Example usage:\r
- <pre>\r
- xSemaphoreHandle xMutex = NULL;\r
-\r
- // A task that creates a mutex.\r
- void vATask( void * pvParameters )\r
- {\r
- // Create the mutex to guard a shared resource.\r
- xMutex = xSemaphoreCreateRecursiveMutex();\r
- }\r
-\r
- // A task that uses the mutex.\r
- void vAnotherTask( void * pvParameters )\r
- {\r
- // ... Do other things.\r
-\r
- if( xMutex != NULL )\r
- {\r
- // See if we can obtain the mutex. If the mutex is not available\r
- // wait 10 ticks to see if it becomes free. \r
- if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )\r
- {\r
- // We were able to obtain the mutex and can now access the\r
- // shared resource.\r
-\r
- // ...\r
- // For some reason due to the nature of the code further calls to \r
- // xSemaphoreTakeRecursive() are made on the same mutex. In real\r
- // code these would not be just sequential calls as this would make\r
- // no sense. Instead the calls are likely to be buried inside\r
- // a more complex call structure.\r
- xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
- xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
-\r
- // The mutex has now been 'taken' three times, so will not be \r
- // available to another task until it has also been given back\r
- // three times. Again it is unlikely that real code would have\r
- // these calls sequentially, it would be more likely that the calls\r
- // to xSemaphoreGiveRecursive() would be called as a call stack\r
- // unwound. This is just for demonstrative purposes.\r
- xSemaphoreGiveRecursive( xMutex );\r
- xSemaphoreGiveRecursive( xMutex );\r
- xSemaphoreGiveRecursive( xMutex );\r
-\r
- // Now the mutex can be taken by other tasks.\r
- }\r
- else\r
- {\r
- // We could not obtain the mutex and can therefore not access\r
- // the shared resource safely.\r
- }\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )\r
-\r
-/* \r
- * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().\r
- *\r
- * The source code that implements the alternative (Alt) API is much \r
- * simpler because it executes everything from within a critical section. \r
- * This is the approach taken by many other RTOSes, but FreeRTOS.org has the \r
- * preferred fully featured API too. The fully featured API has more \r
- * complex code that takes longer to execute, but makes much less use of \r
- * critical sections. Therefore the alternative API sacrifices interrupt \r
- * responsiveness to gain execution speed, whereas the fully featured API\r
- * sacrifices execution speed to ensure better interrupt responsiveness.\r
- */\r
-#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>\r
- xSemaphoreGiveFromISR( \r
- xSemaphoreHandle xSemaphore, \r
- signed portBASE_TYPE *pxHigherPriorityTaskWoken\r
- )</pre>\r
- *\r
- * <i>Macro</i> to release a semaphore. The semaphore must have previously been\r
- * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().\r
- *\r
- * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())\r
- * must not be used with this macro.\r
- *\r
- * This macro can be used from an ISR.\r
- *\r
- * @param xSemaphore A handle to the semaphore being released. This is the\r
- * handle returned when the semaphore was created.\r
- *\r
- * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.\r
- *\r
- * Example usage:\r
- <pre>\r
- \#define LONG_TIME 0xffff\r
- \#define TICKS_TO_WAIT 10\r
- xSemaphoreHandle xSemaphore = NULL;\r
-\r
- // Repetitive task.\r
- void vATask( void * pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // We want this task to run every 10 ticks of a timer. The semaphore \r
- // was created before this task was started.\r
-\r
- // Block waiting for the semaphore to become available.\r
- if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )\r
- {\r
- // It is time to execute.\r
-\r
- // ...\r
-\r
- // We have finished our task. Return to the top of the loop where\r
- // we will block on the semaphore until it is time to execute \r
- // again. Note when using the semaphore for synchronisation with an\r
- // ISR in this manner there is no need to 'give' the semaphore back.\r
- }\r
- }\r
- }\r
-\r
- // Timer ISR\r
- void vTimerISR( void * pvParameters )\r
- {\r
- static unsigned char ucLocalTickCount = 0;\r
- static signed portBASE_TYPE xHigherPriorityTaskWoken;\r
-\r
- // A timer tick has occurred.\r
-\r
- // ... Do other time functions.\r
-\r
- // Is it time for vATask () to run?\r
- xHigherPriorityTaskWoken = pdFALSE;\r
- ucLocalTickCount++;\r
- if( ucLocalTickCount >= TICKS_TO_WAIT )\r
- {\r
- // Unblock the task by releasing the semaphore.\r
- xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );\r
-\r
- // Reset the count so we release the semaphore again in 10 ticks time.\r
- ucLocalTickCount = 0;\r
- }\r
-\r
- if( xHigherPriorityTaskWoken != pdFALSE )\r
- {\r
- // We can force a context switch here. Context switching from an\r
- // ISR uses port specific syntax. Check the demo task for your port\r
- // to find the syntax required.\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>\r
- *\r
- * <i>Macro</i> that implements a mutex semaphore by using the existing queue \r
- * mechanism.\r
- *\r
- * Mutexes created using this macro can be accessed using the xSemaphoreTake()\r
- * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and \r
- * xSemaphoreGiveRecursive() macros should not be used.\r
- * \r
- * This type of semaphore uses a priority inheritance mechanism so a task \r
- * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the \r
- * semaphore it is no longer required. \r
- *\r
- * Mutex type semaphores cannot be used from within interrupt service routines. \r
- *\r
- * See vSemaphoreCreateBinary() for an alternative implementation that can be \r
- * used for pure synchronisation (where one task or interrupt always 'gives' the \r
- * semaphore and another always 'takes' the semaphore) and from within interrupt \r
- * service routines.\r
- *\r
- * @return xSemaphore Handle to the created mutex semaphore. Should be of type \r
- * xSemaphoreHandle.\r
- *\r
- * Example usage:\r
- <pre>\r
- xSemaphoreHandle xSemaphore;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
- // This is a macro so pass the variable in directly.\r
- xSemaphore = xSemaphoreCreateMutex();\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // The semaphore was created successfully.\r
- // The semaphore can now be used. \r
- }\r
- }\r
- </pre>\r
- * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )\r
-\r
-\r
-/**\r
- * semphr. h\r
- * <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>\r
- *\r
- * <i>Macro</i> that implements a recursive mutex by using the existing queue \r
- * mechanism.\r
- *\r
- * Mutexes created using this macro can be accessed using the \r
- * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The \r
- * xSemaphoreTake() and xSemaphoreGive() macros should not be used.\r
- *\r
- * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex \r
- * doesn't become available again until the owner has called \r
- * xSemaphoreGiveRecursive() for each successful 'take' request. For example, \r
- * if a task successfully 'takes' the same mutex 5 times then the mutex will \r
- * not be available to any other task until it has also 'given' the mutex back\r
- * exactly five times.\r
- * \r
- * This type of semaphore uses a priority inheritance mechanism so a task \r
- * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the \r
- * semaphore it is no longer required. \r
- *\r
- * Mutex type semaphores cannot be used from within interrupt service routines. \r
- *\r
- * See vSemaphoreCreateBinary() for an alternative implementation that can be \r
- * used for pure synchronisation (where one task or interrupt always 'gives' the \r
- * semaphore and another always 'takes' the semaphore) and from within interrupt \r
- * service routines.\r
- *\r
- * @return xSemaphore Handle to the created mutex semaphore. Should be of type \r
- * xSemaphoreHandle.\r
- *\r
- * Example usage:\r
- <pre>\r
- xSemaphoreHandle xSemaphore;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
- // This is a macro so pass the variable in directly.\r
- xSemaphore = xSemaphoreCreateRecursiveMutex();\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // The semaphore was created successfully.\r
- // The semaphore can now be used. \r
- }\r
- }\r
- </pre>\r
- * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>\r
- *\r
- * <i>Macro</i> that creates a counting semaphore by using the existing \r
- * queue mechanism. \r
- *\r
- * Counting semaphores are typically used for two things:\r
- *\r
- * 1) Counting events. \r
- *\r
- * In this usage scenario an event handler will 'give' a semaphore each time\r
- * an event occurs (incrementing the semaphore count value), and a handler \r
- * task will 'take' a semaphore each time it processes an event \r
- * (decrementing the semaphore count value). The count value is therefore \r
- * the difference between the number of events that have occurred and the \r
- * number that have been processed. In this case it is desirable for the \r
- * initial count value to be zero.\r
- *\r
- * 2) Resource management.\r
- *\r
- * In this usage scenario the count value indicates the number of resources\r
- * available. To obtain control of a resource a task must first obtain a \r
- * semaphore - decrementing the semaphore count value. When the count value\r
- * reaches zero there are no free resources. When a task finishes with the\r
- * resource it 'gives' the semaphore back - incrementing the semaphore count\r
- * value. In this case it is desirable for the initial count value to be\r
- * equal to the maximum count value, indicating that all resources are free.\r
- *\r
- * @param uxMaxCount The maximum count value that can be reached. When the \r
- * semaphore reaches this value it can no longer be 'given'.\r
- *\r
- * @param uxInitialCount The count value assigned to the semaphore when it is\r
- * created.\r
- *\r
- * @return Handle to the created semaphore. Null if the semaphore could not be\r
- * created.\r
- * \r
- * Example usage:\r
- <pre>\r
- xSemaphoreHandle xSemaphore;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- xSemaphoreHandle xSemaphore = NULL;\r
-\r
- // Semaphore cannot be used before a call to xSemaphoreCreateCounting().\r
- // The max value to which the semaphore can count should be 10, and the\r
- // initial value assigned to the count should be 0.\r
- xSemaphore = xSemaphoreCreateCounting( 10, 0 );\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // The semaphore was created successfully.\r
- // The semaphore can now be used. \r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>void vSemaphoreDelete( xSemaphoreHandle xSemaphore );</pre>\r
- *\r
- * Delete a semaphore. This function must be used with care. For example,\r
- * do not delete a mutex type semaphore if the mutex is held by a task.\r
- *\r
- * @param xSemaphore A handle to the semaphore to be deleted.\r
- *\r
- * \page vSemaphoreDelete vSemaphoreDelete\r
- * \ingroup Semaphores\r
- */\r
-#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) xSemaphore )\r
-\r
-#endif /* SEMAPHORE_H */\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-\r
-#ifndef TASK_H\r
-#define TASK_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "include FreeRTOS.h must appear in source files before include task.h"\r
-#endif\r
-\r
-#include "portable.h"\r
-#include "list.h"\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/*-----------------------------------------------------------\r
- * MACROS AND DEFINITIONS\r
- *----------------------------------------------------------*/\r
-\r
-#define tskKERNEL_VERSION_NUMBER "V7.1.0"\r
-\r
-/**\r
- * task. h\r
- *\r
- * Type by which tasks are referenced. For example, a call to xTaskCreate\r
- * returns (via a pointer parameter) an xTaskHandle variable that can then\r
- * be used as a parameter to vTaskDelete to delete the task.\r
- *\r
- * \page xTaskHandle xTaskHandle\r
- * \ingroup Tasks\r
- */\r
-typedef void * xTaskHandle;\r
-\r
-/*\r
- * Used internally only.\r
- */\r
-typedef struct xTIME_OUT\r
-{\r
- portBASE_TYPE xOverflowCount;\r
- portTickType xTimeOnEntering;\r
-} xTimeOutType;\r
-\r
-/*\r
- * Defines the memory ranges allocated to the task when an MPU is used.\r
- */\r
-typedef struct xMEMORY_REGION\r
-{\r
- void *pvBaseAddress;\r
- unsigned long ulLengthInBytes;\r
- unsigned long ulParameters;\r
-} xMemoryRegion;\r
-\r
-/*\r
- * Parameters required to create an MPU protected task.\r
- */\r
-typedef struct xTASK_PARAMTERS\r
-{\r
- pdTASK_CODE pvTaskCode;\r
- const signed char * const pcName;\r
- unsigned short usStackDepth;\r
- void *pvParameters;\r
- unsigned portBASE_TYPE uxPriority;\r
- portSTACK_TYPE *puxStackBuffer;\r
- xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ];\r
-} xTaskParameters;\r
-\r
-/*\r
- * Defines the priority used by the idle task. This must not be modified.\r
- *\r
- * \ingroup TaskUtils\r
- */\r
-#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0U )\r
-\r
-/**\r
- * task. h\r
- *\r
- * Macro for forcing a context switch.\r
- *\r
- * \page taskYIELD taskYIELD\r
- * \ingroup SchedulerControl\r
- */\r
-#define taskYIELD() portYIELD()\r
-\r
-/**\r
- * task. h\r
- *\r
- * Macro to mark the start of a critical code region. Preemptive context\r
- * switches cannot occur when in a critical region.\r
- *\r
- * NOTE: This may alter the stack (depending on the portable implementation)\r
- * so must be used with care!\r
- *\r
- * \page taskENTER_CRITICAL taskENTER_CRITICAL\r
- * \ingroup SchedulerControl\r
- */\r
-#define taskENTER_CRITICAL() portENTER_CRITICAL()\r
-\r
-/**\r
- * task. h\r
- *\r
- * Macro to mark the end of a critical code region. Preemptive context\r
- * switches cannot occur when in a critical region.\r
- *\r
- * NOTE: This may alter the stack (depending on the portable implementation)\r
- * so must be used with care!\r
- *\r
- * \page taskEXIT_CRITICAL taskEXIT_CRITICAL\r
- * \ingroup SchedulerControl\r
- */\r
-#define taskEXIT_CRITICAL() portEXIT_CRITICAL()\r
-\r
-/**\r
- * task. h\r
- *\r
- * Macro to disable all maskable interrupts.\r
- *\r
- * \page taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS\r
- * \ingroup SchedulerControl\r
- */\r
-#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS()\r
-\r
-/**\r
- * task. h\r
- *\r
- * Macro to enable microcontroller interrupts.\r
- *\r
- * \page taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS\r
- * \ingroup SchedulerControl\r
- */\r
-#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()\r
-\r
-/* Definitions returned by xTaskGetSchedulerState(). */\r
-#define taskSCHEDULER_NOT_STARTED 0\r
-#define taskSCHEDULER_RUNNING 1\r
-#define taskSCHEDULER_SUSPENDED 2\r
-\r
-/*-----------------------------------------------------------\r
- * TASK CREATION API\r
- *----------------------------------------------------------*/\r
-\r
-/**\r
- * task. h\r
- *<pre>\r
- portBASE_TYPE xTaskCreate(\r
- pdTASK_CODE pvTaskCode,\r
- const char * const pcName,\r
- unsigned short usStackDepth,\r
- void *pvParameters,\r
- unsigned portBASE_TYPE uxPriority,\r
- xTaskHandle *pvCreatedTask\r
- );</pre>\r
- *\r
- * Create a new task and add it to the list of tasks that are ready to run.\r
- *\r
- * xTaskCreate() can only be used to create a task that has unrestricted\r
- * access to the entire microcontroller memory map. Systems that include MPU\r
- * support can alternatively create an MPU constrained task using\r
- * xTaskCreateRestricted().\r
- *\r
- * @param pvTaskCode Pointer to the task entry function. Tasks\r
- * must be implemented to never return (i.e. continuous loop).\r
- *\r
- * @param pcName A descriptive name for the task. This is mainly used to\r
- * facilitate debugging. Max length defined by tskMAX_TASK_NAME_LEN - default\r
- * is 16.\r
- *\r
- * @param usStackDepth The size of the task stack specified as the number of\r
- * variables the stack can hold - not the number of bytes. For example, if\r
- * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes\r
- * will be allocated for stack storage.\r
- *\r
- * @param pvParameters Pointer that will be used as the parameter for the task\r
- * being created.\r
- *\r
- * @param uxPriority The priority at which the task should run. Systems that\r
- * include MPU support can optionally create tasks in a privileged (system)\r
- * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For\r
- * example, to create a privileged task at priority 2 the uxPriority parameter\r
- * should be set to ( 2 | portPRIVILEGE_BIT ).\r
- *\r
- * @param pvCreatedTask Used to pass back a handle by which the created task\r
- * can be referenced.\r
- *\r
- * @return pdPASS if the task was successfully created and added to a ready\r
- * list, otherwise an error code defined in the file errors. h\r
- *\r
- * Example usage:\r
- <pre>\r
- // Task to be created.\r
- void vTaskCode( void * pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // Task code goes here.\r
- }\r
- }\r
-\r
- // Function that creates a task.\r
- void vOtherFunction( void )\r
- {\r
- static unsigned char ucParameterToPass;\r
- xTaskHandle xHandle;\r
-\r
- // Create the task, storing the handle. Note that the passed parameter ucParameterToPass\r
- // must exist for the lifetime of the task, so in this case is declared static. If it was just an\r
- // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time\r
- // the new task attempts to access it.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // Use the handle to delete the task.\r
- vTaskDelete( xHandle );\r
- }\r
- </pre>\r
- * \defgroup xTaskCreate xTaskCreate\r
- * \ingroup Tasks\r
- */\r
-#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) )\r
-\r
-/**\r
- * task. h\r
- *<pre>\r
- portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle *pxCreatedTask );</pre>\r
- *\r
- * xTaskCreateRestricted() should only be used in systems that include an MPU\r
- * implementation.\r
- *\r
- * Create a new task and add it to the list of tasks that are ready to run.\r
- * The function parameters define the memory regions and associated access\r
- * permissions allocated to the task.\r
- *\r
- * @param pxTaskDefinition Pointer to a structure that contains a member\r
- * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API\r
- * documentation) plus an optional stack buffer and the memory region\r
- * definitions.\r
- *\r
- * @param pxCreatedTask Used to pass back a handle by which the created task\r
- * can be referenced.\r
- *\r
- * @return pdPASS if the task was successfully created and added to a ready\r
- * list, otherwise an error code defined in the file errors. h\r
- *\r
- * Example usage:\r
- <pre>\r
-// Create an xTaskParameters structure that defines the task to be created.\r
-static const xTaskParameters xCheckTaskParameters =\r
-{\r
- vATask, // pvTaskCode - the function that implements the task.\r
- "ATask", // pcName - just a text name for the task to assist debugging.\r
- 100, // usStackDepth - the stack size DEFINED IN WORDS.\r
- NULL, // pvParameters - passed into the task function as the function parameters.\r
- ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.\r
- cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.\r
-\r
- // xRegions - Allocate up to three separate memory regions for access by\r
- // the task, with appropriate access permissions. Different processors have\r
- // different memory alignment requirements - refer to the FreeRTOS documentation\r
- // for full information.\r
- { \r
- // Base address Length Parameters\r
- { cReadWriteArray, 32, portMPU_REGION_READ_WRITE },\r
- { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },\r
- { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }\r
- }\r
-};\r
-\r
-int main( void )\r
-{\r
-xTaskHandle xHandle;\r
-\r
- // Create a task from the const structure defined above. The task handle\r
- // is requested (the second parameter is not NULL) but in this case just for\r
- // demonstration purposes as its not actually used.\r
- xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );\r
-\r
- // Start the scheduler.\r
- vTaskStartScheduler();\r
-\r
- // Will only get here if there was insufficient memory to create the idle\r
- // task.\r
- for( ;; );\r
-}\r
- </pre>\r
- * \defgroup xTaskCreateRestricted xTaskCreateRestricted\r
- * \ingroup Tasks\r
- */\r
-#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) )\r
-\r
-/**\r
- * task. h\r
- *<pre>\r
- void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );</pre>\r
- *\r
- * Memory regions are assigned to a restricted task when the task is created by\r
- * a call to xTaskCreateRestricted(). These regions can be redefined using\r
- * vTaskAllocateMPURegions().\r
- *\r
- * @param xTask The handle of the task being updated.\r
- *\r
- * @param xRegions A pointer to an xMemoryRegion structure that contains the\r
- * new memory region definitions.\r
- *\r
- * Example usage:\r
- <pre>\r
-// Define an array of xMemoryRegion structures that configures an MPU region\r
-// allowing read/write access for 1024 bytes starting at the beginning of the\r
-// ucOneKByte array. The other two of the maximum 3 definable regions are\r
-// unused so set to zero.\r
-static const xMemoryRegion xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =\r
-{ \r
- // Base address Length Parameters\r
- { ucOneKByte, 1024, portMPU_REGION_READ_WRITE },\r
- { 0, 0, 0 },\r
- { 0, 0, 0 }\r
-};\r
-\r
-void vATask( void *pvParameters )\r
-{\r
- // This task was created such that it has access to certain regions of\r
- // memory as defined by the MPU configuration. At some point it is\r
- // desired that these MPU regions are replaced with that defined in the\r
- // xAltRegions const struct above. Use a call to vTaskAllocateMPURegions()\r
- // for this purpose. NULL is used as the task handle to indicate that this\r
- // function should modify the MPU regions of the calling task.\r
- vTaskAllocateMPURegions( NULL, xAltRegions );\r
- \r
- // Now the task can continue its function, but from this point on can only\r
- // access its stack and the ucOneKByte array (unless any other statically\r
- // defined or shared regions have been declared elsewhere).\r
-}\r
- </pre>\r
- * \defgroup xTaskCreateRestricted xTaskCreateRestricted\r
- * \ingroup Tasks\r
- */\r
-void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskDelete( xTaskHandle pxTask );</pre>\r
- *\r
- * INCLUDE_vTaskDelete must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Remove a task from the RTOS real time kernels management. The task being\r
- * deleted will be removed from all ready, blocked, suspended and event lists.\r
- *\r
- * NOTE: The idle task is responsible for freeing the kernel allocated\r
- * memory from tasks that have been deleted. It is therefore important that\r
- * the idle task is not starved of microcontroller processing time if your\r
- * application makes any calls to vTaskDelete (). Memory allocated by the\r
- * task code is not automatically freed, and should be freed before the task\r
- * is deleted.\r
- *\r
- * See the demo application file death.c for sample code that utilises\r
- * vTaskDelete ().\r
- *\r
- * @param pxTask The handle of the task to be deleted. Passing NULL will\r
- * cause the calling task to be deleted.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vOtherFunction( void )\r
- {\r
- xTaskHandle xHandle;\r
-\r
- // Create the task, storing the handle.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // Use the handle to delete the task.\r
- vTaskDelete( xHandle );\r
- }\r
- </pre>\r
- * \defgroup vTaskDelete vTaskDelete\r
- * \ingroup Tasks\r
- */\r
-void vTaskDelete( xTaskHandle pxTaskToDelete ) PRIVILEGED_FUNCTION;\r
-\r
-/*-----------------------------------------------------------\r
- * TASK CONTROL API\r
- *----------------------------------------------------------*/\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskDelay( portTickType xTicksToDelay );</pre>\r
- *\r
- * Delay a task for a given number of ticks. The actual time that the\r
- * task remains blocked depends on the tick rate. The constant\r
- * portTICK_RATE_MS can be used to calculate real time from the tick\r
- * rate - with the resolution of one tick period.\r
- *\r
- * INCLUDE_vTaskDelay must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- *\r
- * vTaskDelay() specifies a time at which the task wishes to unblock relative to\r
- * the time at which vTaskDelay() is called. For example, specifying a block\r
- * period of 100 ticks will cause the task to unblock 100 ticks after\r
- * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method\r
- * of controlling the frequency of a cyclical task as the path taken through the\r
- * code, as well as other task and interrupt activity, will effect the frequency\r
- * at which vTaskDelay() gets called and therefore the time at which the task\r
- * next executes. See vTaskDelayUntil() for an alternative API function designed\r
- * to facilitate fixed frequency execution. It does this by specifying an\r
- * absolute time (rather than a relative time) at which the calling task should\r
- * unblock.\r
- *\r
- * @param xTicksToDelay The amount of time, in tick periods, that\r
- * the calling task should block.\r
- *\r
- * Example usage:\r
-\r
- void vTaskFunction( void * pvParameters )\r
- {\r
- void vTaskFunction( void * pvParameters )\r
- {\r
- // Block for 500ms.\r
- const portTickType xDelay = 500 / portTICK_RATE_MS;\r
-\r
- for( ;; )\r
- {\r
- // Simply toggle the LED every 500ms, blocking between each toggle.\r
- vToggleLED();\r
- vTaskDelay( xDelay );\r
- }\r
- }\r
-\r
- * \defgroup vTaskDelay vTaskDelay\r
- * \ingroup TaskCtrl\r
- */\r
-void vTaskDelay( portTickType xTicksToDelay ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );</pre>\r
- *\r
- * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Delay a task until a specified time. This function can be used by cyclical\r
- * tasks to ensure a constant execution frequency.\r
- *\r
- * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will\r
- * cause a task to block for the specified number of ticks from the time vTaskDelay () is\r
- * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed\r
- * execution frequency as the time between a task starting to execute and that task\r
- * calling vTaskDelay () may not be fixed [the task may take a different path though the\r
- * code between calls, or may get interrupted or preempted a different number of times\r
- * each time it executes].\r
- *\r
- * Whereas vTaskDelay () specifies a wake time relative to the time at which the function\r
- * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to\r
- * unblock.\r
- *\r
- * The constant portTICK_RATE_MS can be used to calculate real time from the tick\r
- * rate - with the resolution of one tick period.\r
- *\r
- * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the\r
- * task was last unblocked. The variable must be initialised with the current time\r
- * prior to its first use (see the example below). Following this the variable is\r
- * automatically updated within vTaskDelayUntil ().\r
- *\r
- * @param xTimeIncrement The cycle time period. The task will be unblocked at\r
- * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the\r
- * same xTimeIncrement parameter value will cause the task to execute with\r
- * a fixed interface period.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Perform an action every 10 ticks.\r
- void vTaskFunction( void * pvParameters )\r
- {\r
- portTickType xLastWakeTime;\r
- const portTickType xFrequency = 10;\r
-\r
- // Initialise the xLastWakeTime variable with the current time.\r
- xLastWakeTime = xTaskGetTickCount ();\r
- for( ;; )\r
- {\r
- // Wait for the next cycle.\r
- vTaskDelayUntil( &xLastWakeTime, xFrequency );\r
-\r
- // Perform action here.\r
- }\r
- }\r
- </pre>\r
- * \defgroup vTaskDelayUntil vTaskDelayUntil\r
- * \ingroup TaskCtrl\r
- */\r
-void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );</pre>\r
- *\r
- * INCLUDE_xTaskPriorityGet must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Obtain the priority of any task.\r
- *\r
- * @param pxTask Handle of the task to be queried. Passing a NULL\r
- * handle results in the priority of the calling task being returned.\r
- *\r
- * @return The priority of pxTask.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vAFunction( void )\r
- {\r
- xTaskHandle xHandle;\r
-\r
- // Create a task, storing the handle.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // ...\r
-\r
- // Use the handle to obtain the priority of the created task.\r
- // It was created with tskIDLE_PRIORITY, but may have changed\r
- // it itself.\r
- if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )\r
- {\r
- // The task has changed it's priority.\r
- }\r
-\r
- // ...\r
-\r
- // Is our priority higher than the created task?\r
- if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )\r
- {\r
- // Our priority (obtained using NULL handle) is higher.\r
- }\r
- }\r
- </pre>\r
- * \defgroup uxTaskPriorityGet uxTaskPriorityGet\r
- * \ingroup TaskCtrl\r
- */\r
-unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );</pre>\r
- *\r
- * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Set the priority of any task.\r
- *\r
- * A context switch will occur before the function returns if the priority\r
- * being set is higher than the currently executing task.\r
- *\r
- * @param pxTask Handle to the task for which the priority is being set.\r
- * Passing a NULL handle results in the priority of the calling task being set.\r
- *\r
- * @param uxNewPriority The priority to which the task will be set.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vAFunction( void )\r
- {\r
- xTaskHandle xHandle;\r
-\r
- // Create a task, storing the handle.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // ...\r
-\r
- // Use the handle to raise the priority of the created task.\r
- vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );\r
-\r
- // ...\r
-\r
- // Use a NULL handle to raise our priority to the same value.\r
- vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );\r
- }\r
- </pre>\r
- * \defgroup vTaskPrioritySet vTaskPrioritySet\r
- * \ingroup TaskCtrl\r
- */\r
-void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskSuspend( xTaskHandle pxTaskToSuspend );</pre>\r
- *\r
- * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Suspend any task. When suspended a task will never get any microcontroller\r
- * processing time, no matter what its priority.\r
- *\r
- * Calls to vTaskSuspend are not accumulative -\r
- * i.e. calling vTaskSuspend () twice on the same task still only requires one\r
- * call to vTaskResume () to ready the suspended task.\r
- *\r
- * @param pxTaskToSuspend Handle to the task being suspended. Passing a NULL\r
- * handle will cause the calling task to be suspended.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vAFunction( void )\r
- {\r
- xTaskHandle xHandle;\r
-\r
- // Create a task, storing the handle.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // ...\r
-\r
- // Use the handle to suspend the created task.\r
- vTaskSuspend( xHandle );\r
-\r
- // ...\r
-\r
- // The created task will not run during this period, unless\r
- // another task calls vTaskResume( xHandle ).\r
-\r
- //...\r
-\r
-\r
- // Suspend ourselves.\r
- vTaskSuspend( NULL );\r
-\r
- // We cannot get here unless another task calls vTaskResume\r
- // with our handle as the parameter.\r
- }\r
- </pre>\r
- * \defgroup vTaskSuspend vTaskSuspend\r
- * \ingroup TaskCtrl\r
- */\r
-void vTaskSuspend( xTaskHandle pxTaskToSuspend ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskResume( xTaskHandle pxTaskToResume );</pre>\r
- *\r
- * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Resumes a suspended task.\r
- *\r
- * A task that has been suspended by one of more calls to vTaskSuspend ()\r
- * will be made available for running again by a single call to\r
- * vTaskResume ().\r
- *\r
- * @param pxTaskToResume Handle to the task being readied.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vAFunction( void )\r
- {\r
- xTaskHandle xHandle;\r
-\r
- // Create a task, storing the handle.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // ...\r
-\r
- // Use the handle to suspend the created task.\r
- vTaskSuspend( xHandle );\r
-\r
- // ...\r
-\r
- // The created task will not run during this period, unless\r
- // another task calls vTaskResume( xHandle ).\r
-\r
- //...\r
-\r
-\r
- // Resume the suspended task ourselves.\r
- vTaskResume( xHandle );\r
-\r
- // The created task will once again get microcontroller processing\r
- // time in accordance with it priority within the system.\r
- }\r
- </pre>\r
- * \defgroup vTaskResume vTaskResume\r
- * \ingroup TaskCtrl\r
- */\r
-void vTaskResume( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void xTaskResumeFromISR( xTaskHandle pxTaskToResume );</pre>\r
- *\r
- * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be\r
- * available. See the configuration section for more information.\r
- *\r
- * An implementation of vTaskResume() that can be called from within an ISR.\r
- *\r
- * A task that has been suspended by one of more calls to vTaskSuspend ()\r
- * will be made available for running again by a single call to\r
- * xTaskResumeFromISR ().\r
- *\r
- * @param pxTaskToResume Handle to the task being readied.\r
- *\r
- * \defgroup vTaskResumeFromISR vTaskResumeFromISR\r
- * \ingroup TaskCtrl\r
- */\r
-portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION;\r
-\r
-/*-----------------------------------------------------------\r
- * SCHEDULER CONTROL\r
- *----------------------------------------------------------*/\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskStartScheduler( void );</pre>\r
- *\r
- * Starts the real time kernel tick processing. After calling the kernel\r
- * has control over which tasks are executed and when. This function\r
- * does not return until an executing task calls vTaskEndScheduler ().\r
- *\r
- * At least one task should be created via a call to xTaskCreate ()\r
- * before calling vTaskStartScheduler (). The idle task is created\r
- * automatically when the first application task is created.\r
- *\r
- * See the demo application file main.c for an example of creating\r
- * tasks and starting the kernel.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vAFunction( void )\r
- {\r
- // Create at least one task before starting the kernel.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
-\r
- // Start the real time kernel with preemption.\r
- vTaskStartScheduler ();\r
-\r
- // Will not get here unless a task calls vTaskEndScheduler ()\r
- }\r
- </pre>\r
- *\r
- * \defgroup vTaskStartScheduler vTaskStartScheduler\r
- * \ingroup SchedulerControl\r
- */\r
-void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskEndScheduler( void );</pre>\r
- *\r
- * Stops the real time kernel tick. All created tasks will be automatically\r
- * deleted and multitasking (either preemptive or cooperative) will\r
- * stop. Execution then resumes from the point where vTaskStartScheduler ()\r
- * was called, as if vTaskStartScheduler () had just returned.\r
- *\r
- * See the demo application file main. c in the demo/PC directory for an\r
- * example that uses vTaskEndScheduler ().\r
- *\r
- * vTaskEndScheduler () requires an exit function to be defined within the\r
- * portable layer (see vPortEndScheduler () in port. c for the PC port). This\r
- * performs hardware specific operations such as stopping the kernel tick.\r
- *\r
- * vTaskEndScheduler () will cause all of the resources allocated by the\r
- * kernel to be freed - but will not free resources allocated by application\r
- * tasks.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vTaskCode( void * pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // Task code goes here.\r
-\r
- // At some point we want to end the real time kernel processing\r
- // so call ...\r
- vTaskEndScheduler ();\r
- }\r
- }\r
-\r
- void vAFunction( void )\r
- {\r
- // Create at least one task before starting the kernel.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
-\r
- // Start the real time kernel with preemption.\r
- vTaskStartScheduler ();\r
-\r
- // Will only get here when the vTaskCode () task has called\r
- // vTaskEndScheduler (). When we get here we are back to single task\r
- // execution.\r
- }\r
- </pre>\r
- *\r
- * \defgroup vTaskEndScheduler vTaskEndScheduler\r
- * \ingroup SchedulerControl\r
- */\r
-void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskSuspendAll( void );</pre>\r
- *\r
- * Suspends all real time kernel activity while keeping interrupts (including the\r
- * kernel tick) enabled.\r
- *\r
- * After calling vTaskSuspendAll () the calling task will continue to execute\r
- * without risk of being swapped out until a call to xTaskResumeAll () has been\r
- * made.\r
- *\r
- * API functions that have the potential to cause a context switch (for example,\r
- * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler\r
- * is suspended.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vTask1( void * pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // Task code goes here.\r
-\r
- // ...\r
-\r
- // At some point the task wants to perform a long operation during\r
- // which it does not want to get swapped out. It cannot use\r
- // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the\r
- // operation may cause interrupts to be missed - including the\r
- // ticks.\r
-\r
- // Prevent the real time kernel swapping out the task.\r
- vTaskSuspendAll ();\r
-\r
- // Perform the operation here. There is no need to use critical\r
- // sections as we have all the microcontroller processing time.\r
- // During this time interrupts will still operate and the kernel\r
- // tick count will be maintained.\r
-\r
- // ...\r
-\r
- // The operation is complete. Restart the kernel.\r
- xTaskResumeAll ();\r
- }\r
- }\r
- </pre>\r
- * \defgroup vTaskSuspendAll vTaskSuspendAll\r
- * \ingroup SchedulerControl\r
- */\r
-void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>char xTaskResumeAll( void );</pre>\r
- *\r
- * Resumes real time kernel activity following a call to vTaskSuspendAll ().\r
- * After a call to vTaskSuspendAll () the kernel will take control of which\r
- * task is executing at any time.\r
- *\r
- * @return If resuming the scheduler caused a context switch then pdTRUE is\r
- * returned, otherwise pdFALSE is returned.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vTask1( void * pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // Task code goes here.\r
-\r
- // ...\r
-\r
- // At some point the task wants to perform a long operation during\r
- // which it does not want to get swapped out. It cannot use\r
- // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the\r
- // operation may cause interrupts to be missed - including the\r
- // ticks.\r
-\r
- // Prevent the real time kernel swapping out the task.\r
- vTaskSuspendAll ();\r
-\r
- // Perform the operation here. There is no need to use critical\r
- // sections as we have all the microcontroller processing time.\r
- // During this time interrupts will still operate and the real\r
- // time kernel tick count will be maintained.\r
-\r
- // ...\r
-\r
- // The operation is complete. Restart the kernel. We want to force\r
- // a context switch - but there is no point if resuming the scheduler\r
- // caused a context switch already.\r
- if( !xTaskResumeAll () )\r
- {\r
- taskYIELD ();\r
- }\r
- }\r
- }\r
- </pre>\r
- * \defgroup xTaskResumeAll xTaskResumeAll\r
- * \ingroup SchedulerControl\r
- */\r
-signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );</pre>\r
- *\r
- * Utility task that simply returns pdTRUE if the task referenced by xTask is\r
- * currently in the Suspended state, or pdFALSE if the task referenced by xTask\r
- * is in any other state.\r
- *\r
- */\r
-signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) PRIVILEGED_FUNCTION;\r
-\r
-/*-----------------------------------------------------------\r
- * TASK UTILITIES\r
- *----------------------------------------------------------*/\r
-\r
-/**\r
- * task. h\r
- * <PRE>portTickType xTaskGetTickCount( void );</PRE>\r
- *\r
- * @return The count of ticks since vTaskStartScheduler was called.\r
- *\r
- * \page xTaskGetTickCount xTaskGetTickCount\r
- * \ingroup TaskUtils\r
- */\r
-portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>portTickType xTaskGetTickCountFromISR( void );</PRE>\r
- *\r
- * @return The count of ticks since vTaskStartScheduler was called.\r
- *\r
- * This is a version of xTaskGetTickCount() that is safe to be called from an\r
- * ISR - provided that portTickType is the natural word size of the\r
- * microcontroller being used or interrupt nesting is either not supported or\r
- * not being used.\r
- *\r
- * \page xTaskGetTickCount xTaskGetTickCount\r
- * \ingroup TaskUtils\r
- */\r
-portTickType xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>unsigned short uxTaskGetNumberOfTasks( void );</PRE>\r
- *\r
- * @return The number of tasks that the real time kernel is currently managing.\r
- * This includes all ready, blocked and suspended tasks. A task that\r
- * has been deleted but not yet freed by the idle task will also be\r
- * included in the count.\r
- *\r
- * \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks\r
- * \ingroup TaskUtils\r
- */\r
-unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery );</PRE>\r
- *\r
- * @return The text (human readable) name of the task referenced by the handle\r
- * xTaskToQueury. A task can query its own name by either passing in its own\r
- * handle, or by setting xTaskToQuery to NULL. INCLUDE_pcTaskGetTaskName must be\r
- * set to 1 in FreeRTOSConfig.h for pcTaskGetTaskName() to be available.\r
- *\r
- * \page pcTaskGetTaskName pcTaskGetTaskName\r
- * \ingroup TaskUtils\r
- */\r
-signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery );\r
-\r
-/**\r
- * task. h\r
- * <PRE>void vTaskList( char *pcWriteBuffer );</PRE>\r
- *\r
- * configUSE_TRACE_FACILITY must be defined as 1 for this function to be\r
- * available. See the configuration section for more information.\r
- *\r
- * NOTE: This function will disable interrupts for its duration. It is\r
- * not intended for normal application runtime use but as a debug aid.\r
- *\r
- * Lists all the current tasks, along with their current state and stack\r
- * usage high water mark.\r
- *\r
- * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or\r
- * suspended ('S').\r
- *\r
- * @param pcWriteBuffer A buffer into which the above mentioned details\r
- * will be written, in ascii form. This buffer is assumed to be large\r
- * enough to contain the generated report. Approximately 40 bytes per\r
- * task should be sufficient.\r
- *\r
- * \page vTaskList vTaskList\r
- * \ingroup TaskUtils\r
- */\r
-void vTaskList( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>void vTaskGetRunTimeStats( char *pcWriteBuffer );</PRE>\r
- *\r
- * configGENERATE_RUN_TIME_STATS must be defined as 1 for this function\r
- * to be available. The application must also then provide definitions\r
- * for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and\r
- * portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter\r
- * and return the timers current count value respectively. The counter\r
- * should be at least 10 times the frequency of the tick count.\r
- *\r
- * NOTE: This function will disable interrupts for its duration. It is\r
- * not intended for normal application runtime use but as a debug aid.\r
- *\r
- * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total\r
- * accumulated execution time being stored for each task. The resolution\r
- * of the accumulated time value depends on the frequency of the timer\r
- * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.\r
- * Calling vTaskGetRunTimeStats() writes the total execution time of each\r
- * task into a buffer, both as an absolute count value and as a percentage\r
- * of the total system execution time.\r
- *\r
- * @param pcWriteBuffer A buffer into which the execution times will be\r
- * written, in ascii form. This buffer is assumed to be large enough to\r
- * contain the generated report. Approximately 40 bytes per task should\r
- * be sufficient.\r
- *\r
- * \page vTaskGetRunTimeStats vTaskGetRunTimeStats\r
- * \ingroup TaskUtils\r
- */\r
-void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>void vTaskStartTrace( char * pcBuffer, unsigned portBASE_TYPE uxBufferSize );</PRE>\r
- *\r
- * Starts a real time kernel activity trace. The trace logs the identity of\r
- * which task is running when.\r
- *\r
- * The trace file is stored in binary format. A separate DOS utility called\r
- * convtrce.exe is used to convert this into a tab delimited text file which\r
- * can be viewed and plotted in a spread sheet.\r
- *\r
- * @param pcBuffer The buffer into which the trace will be written.\r
- *\r
- * @param ulBufferSize The size of pcBuffer in bytes. The trace will continue\r
- * until either the buffer in full, or ulTaskEndTrace () is called.\r
- *\r
- * \page vTaskStartTrace vTaskStartTrace\r
- * \ingroup TaskUtils\r
- */\r
-void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>unsigned long ulTaskEndTrace( void );</PRE>\r
- *\r
- * Stops a kernel activity trace. See vTaskStartTrace ().\r
- *\r
- * @return The number of bytes that have been written into the trace buffer.\r
- *\r
- * \page usTaskEndTrace usTaskEndTrace\r
- * \ingroup TaskUtils\r
- */\r
-unsigned long ulTaskEndTrace( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task.h\r
- * <PRE>unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );</PRE>\r
- *\r
- * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for\r
- * this function to be available.\r
- *\r
- * Returns the high water mark of the stack associated with xTask. That is,\r
- * the minimum free stack space there has been (in words, so on a 32 bit machine\r
- * a value of 1 means 4 bytes) since the task started. The smaller the returned\r
- * number the closer the task has come to overflowing its stack.\r
- *\r
- * @param xTask Handle of the task associated with the stack to be checked.\r
- * Set xTask to NULL to check the stack of the calling task.\r
- *\r
- * @return The smallest amount of free stack space there has been (in bytes)\r
- * since the task referenced by xTask was created.\r
- */\r
-unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) PRIVILEGED_FUNCTION;\r
-\r
-/* When using trace macros it is sometimes necessary to include tasks.h before\r
-FreeRTOS.h. When this is done pdTASK_HOOK_CODE will not yet have been defined,\r
-so the following two prototypes will cause a compilation error. This can be\r
-fixed by simply guarding against the inclusion of these two prototypes unless\r
-they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration\r
-constant. */\r
-#ifdef configUSE_APPLICATION_TASK_TAG\r
- #if configUSE_APPLICATION_TASK_TAG == 1\r
- /**\r
- * task.h\r
- * <pre>void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );</pre>\r
- *\r
- * Sets pxHookFunction to be the task hook function used by the task xTask.\r
- * Passing xTask as NULL has the effect of setting the calling tasks hook\r
- * function.\r
- */\r
- void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) PRIVILEGED_FUNCTION;\r
-\r
- /**\r
- * task.h\r
- * <pre>void xTaskGetApplicationTaskTag( xTaskHandle xTask );</pre>\r
- *\r
- * Returns the pxHookFunction value assigned to the task xTask.\r
- */\r
- pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) PRIVILEGED_FUNCTION;\r
- #endif /* configUSE_APPLICATION_TASK_TAG ==1 */\r
-#endif /* ifdef configUSE_APPLICATION_TASK_TAG */\r
-\r
-/**\r
- * task.h\r
- * <pre>portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );</pre>\r
- *\r
- * Calls the hook function associated with xTask. Passing xTask as NULL has\r
- * the effect of calling the Running tasks (the calling task) hook function.\r
- *\r
- * pvParameter is passed to the hook function for the task to interpret as it\r
- * wants.\r
- */\r
-portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * xTaskGetIdleTaskHandle() is only available if \r
- * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h.\r
- *\r
- * Simply returns the handle of the idle task. It is not valid to call\r
- * xTaskGetIdleTaskHandle() before the scheduler has been started.\r
- */\r
-xTaskHandle xTaskGetIdleTaskHandle( void );\r
-\r
-/*-----------------------------------------------------------\r
- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES\r
- *----------------------------------------------------------*/\r
-\r
-/*\r
- * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY\r
- * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS\r
- * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
- *\r
- * Called from the real time kernel tick (either preemptive or cooperative),\r
- * this increments the tick count and checks if any tasks that are blocked\r
- * for a finite period required removing from a blocked list and placing on\r
- * a ready list.\r
- */\r
-void vTaskIncrementTick( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN\r
- * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
- *\r
- * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.\r
- *\r
- * Removes the calling task from the ready list and places it both\r
- * on the list of tasks waiting for a particular event, and the\r
- * list of delayed tasks. The task will be removed from both lists\r
- * and replaced on the ready list should either the event occur (and\r
- * there be no higher priority tasks waiting on the same event) or\r
- * the delay period expires.\r
- *\r
- * @param pxEventList The list containing tasks that are blocked waiting\r
- * for the event to occur.\r
- *\r
- * @param xTicksToWait The maximum amount of time that the task should wait\r
- * for the event to occur. This is specified in kernel ticks,the constant\r
- * portTICK_RATE_MS can be used to convert kernel ticks into a real time\r
- * period.\r
- */\r
-void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN\r
- * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
- *\r
- * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.\r
- *\r
- * This function performs nearly the same function as vTaskPlaceOnEventList().\r
- * The difference being that this function does not permit tasks to block\r
- * indefinitely, whereas vTaskPlaceOnEventList() does.\r
- *\r
- * @return pdTRUE if the task being removed has a higher priority than the task\r
- * making the call, otherwise pdFALSE.\r
- */\r
-void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN\r
- * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
- *\r
- * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.\r
- *\r
- * Removes a task from both the specified event list and the list of blocked\r
- * tasks, and places it on a ready queue.\r
- *\r
- * xTaskRemoveFromEventList () will be called if either an event occurs to\r
- * unblock a task, or the block timeout period expires.\r
- *\r
- * @return pdTRUE if the task being removed has a higher priority than the task\r
- * making the call, otherwise pdFALSE.\r
- */\r
-signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY\r
- * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS\r
- * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
- *\r
- * Sets the pointer to the current TCB to the TCB of the highest priority task\r
- * that is ready to run.\r
- */\r
-void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Return the handle of the calling task.\r
- */\r
-xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Capture the current time status for future reference.\r
- */\r
-void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Compare the time status now with that previously captured to see if the\r
- * timeout has expired.\r
- */\r
-portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Shortcut used by the queue implementation to prevent unnecessary call to\r
- * taskYIELD();\r
- */\r
-void vTaskMissedYield( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Returns the scheduler state as taskSCHEDULER_RUNNING,\r
- * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED.\r
- */\r
-portBASE_TYPE xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Raises the priority of the mutex holder to that of the calling task should\r
- * the mutex holder have a priority less than the calling task.\r
- */\r
-void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Set the priority of a task back to its proper priority in the case that it\r
- * inherited a higher priority while it was holding a semaphore.\r
- */\r
-void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Generic version of the task creation function which is in turn called by the\r
- * xTaskCreate() and xTaskCreateRestricted() macros.\r
- */\r
-signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Get the uxTCBNumber assigned to the task referenced by the xTask parameter.\r
- */\r
-unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask );\r
-\r
-/* \r
- * Set the uxTCBNumber of the task referenced by the xTask parameter to\r
- * ucHandle.\r
- */\r
-void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle );\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-#endif /* TASK_H */\r
-\r
-\r
-\r
+++ /dev/null
-#ifndef TIMER_TEST_H\r
-#define TIMER_TEST_H\r
-\r
-#define tmrtestNUM_TIMERS 15\r
-\r
-\r
-extern portTickType xTickCount;\r
-extern xTaskHandle pxCurrentTCB;\r
-extern portTickType xNumOfOverflows;\r
-\r
-static void vTimerTest_Initialise( void );\r
-static portBASE_TYPE xTimerTest1_xTimeStartAndResetWakeTimeCalculation( void );\r
-portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier );\r
-\r
-static void prvCheckServiceTaskBehaviour( portBASE_TYPE x, portBASE_TYPE xExpireTimeHasOverflowed, portBASE_TYPE xTickCountOverflowed );\r
-\r
-static void prvTestFailed( void );\r
-\r
-xTIMER *xAutoReloadTimers[ tmrtestNUM_TIMERS ];\r
-unsigned portBASE_TYPE uxAutoReloadTimerCounters[ tmrtestNUM_TIMERS ];\r
-portBASE_TYPE xTestStatus = pdPASS;\r
-xTaskHandle xTestTask1 = NULL, xTestTask2 = NULL;\r
-\r
-struct xTestData\r
-{\r
- portTickType xStartTickCount;\r
- portTickType xTimerPeriod;\r
- portTickType xTickIncrementBetweenCommandAndProcessing;\r
- portTickType xExpectedCalculatedExpiryTime;\r
- xList * pxExpectedList;\r
- unsigned portBASE_TYPE uxExpectedCallbackCount;\r
-};\r
-\r
-const struct xTestData xTestCase[] =\r
-{\r
- /* xStartTickCount, xTimerPeriod, Tck Inc, Expected Expire Time, Expected list, Expected callback count, Second tick inc */\r
-\r
- /* Test cases when the command to start a timer and the processing of the\r
- start command execute without the tick count incrementing in between. */\r
- { portMAX_DELAY - 8, 2, 0, ( portMAX_DELAY - 8 ) + 2, &xActiveTimerList1, 0 }, /* Expire before an overflow. */\r
- { portMAX_DELAY - 8, 8, 0, ( portMAX_DELAY - 8 ) + 8, &xActiveTimerList1, 0 }, /* Expire immediately before and overflow. */\r
- { portMAX_DELAY - 8, 9, 0, 0, &xActiveTimerList2, 0 }, /* Expire on an overflow. */\r
- { portMAX_DELAY - 8, portMAX_DELAY, 0, ( ( portMAX_DELAY - 8 ) - 1 ), &xActiveTimerList2, 0 }, /* Delay for the longest possible time. */\r
- { portMAX_DELAY, portMAX_DELAY, 0, ( portMAX_DELAY - 1 ), &xActiveTimerList2, 0 }, /* Delay for the longest possible time starting from the maximum tick count. */\r
- { 0, portMAX_DELAY, 0, ( portMAX_DELAY ), &xActiveTimerList1, 0 }, /* Delay for the maximum ticks, starting with from the minimum tick count. */\r
-\r
- /* Test cases when the command to start a timer and the processing of the\r
- start command execute at different tick count values. */\r
- { portMAX_DELAY - 8, 2, 1, ( portMAX_DELAY - 8 ) + 2, &xActiveTimerList1, 0 }, /* The expire time does not overflow, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 8, 8, 2, ( portMAX_DELAY - 8 ) + 8, &xActiveTimerList1, 0 }, /* The expire time does not overflow but is on the portMAX_DELAY limit, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 8, 9, 3, 0, &xActiveTimerList2, 0 }, /* The expire time overflows to 0, and the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 2, 9, 1, ( portMAX_DELAY - 2 ) + 9, &xActiveTimerList2, 0 }, /* The expire time overflows, but the tick count does not overflow between the command and processing the command. */\r
- { portMAX_DELAY - 2, 9, 3, ( portMAX_DELAY - 2 ) + 9, &xActiveTimerList2, 0 }, /* The timer overflows between the command and processing the command. The expire time also overflows. */\r
-\r
- /* Add tests where the timer should have expired by the time the command is processed. */\r
- { 10, 9, 10, ( 10 + ( 2 * 9 ) ), &xActiveTimerList1, 1 }, /* Nothing overflows, but the time between the timer being set and the command being processed is greater than the timers expiry time. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded. */\r
- { portMAX_DELAY - 2, 9, 10, ( portMAX_DELAY - 2 ) + ( 2 * 9 ), &xActiveTimerList2, 1 }, /* The timer overflows between the command and processing the command. The expire time also overflows and the number of ticks that occur between the command and the processing exceeds the timer expiry period. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 2, 9, 9, ( portMAX_DELAY - 2 ) + ( 2 * 9 ), &xActiveTimerList2, 1 }, /* The timer overflows between the command and processing the command. The expire time also overflows and the number of ticks between command and processing equals the timer expiry period. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
-\r
- { portMAX_DELAY - 20, 9, 21, ( portMAX_DELAY - 20 ) + ( 3 * 9 ), &xActiveTimerList2, 2 }, /* The tick count has overflowed but the timer expire time has not overflowed. The tick count overflows to 0. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 20, 9, 22, ( portMAX_DELAY - 20 ) + ( 3 * 9 ), &xActiveTimerList2, 2 }, /* The tick count has overflowed but the timer expire time has not overflowed. The tick count overflows to greater than 0. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
- { portMAX_DELAY - 5, 2, 20, ( portMAX_DELAY - 5 ) + ( 11 * 2 ), &xActiveTimerList2, 10 }, /* The tick and expire time overflow, but the first expire time overflow results in a time that is less than the tick count. */\r
-};\r
-\r
-typedef struct tskTaskControlBlockx\r
-{\r
- volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */\r
-\r
- #if ( portUSING_MPU_WRAPPERS == 1 )\r
- xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */\r
- #endif \r
- \r
- xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */\r
- xListItem xEventListItem; /*< List item used to place the TCB in event lists. */\r
- unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */\r
- portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */\r
- signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */\r
-\r
- #if ( portSTACK_GROWTH > 0 )\r
- portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */\r
- #endif\r
-\r
- #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
- unsigned portBASE_TYPE uxCriticalNesting;\r
- #endif\r
-\r
- #if ( configUSE_TRACE_FACILITY == 1 )\r
- unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */\r
- #endif\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */\r
- #endif\r
-\r
- #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
- pdTASK_HOOK_CODE pxTaskTag;\r
- #endif\r
-\r
- #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
- unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */\r
- #endif\r
-\r
-} tskTCBx;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vAutoReloadTimerCallback( xTIMER *pxTimer )\r
-{\r
-portBASE_TYPE xTimerID = ( portBASE_TYPE ) pxTimer->pvTimerID;\r
-\r
- if( xTimerID < tmrtestNUM_TIMERS )\r
- {\r
- ( uxAutoReloadTimerCounters[ xTimerID ] )++;\r
- }\r
- else\r
- {\r
- prvTestFailed();\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vTimerTest_Initialise( void )\r
-{\r
-portBASE_TYPE xTimerNumber;\r
-extern void prvInitialiseTaskLists( void );\r
-extern portBASE_TYPE xSchedulerRunning;\r
-\r
- prvInitialiseTaskLists();\r
- xTimerQueue = NULL;\r
- xSchedulerRunning = pdTRUE;\r
-\r
- for( xTimerNumber = 0; xTimerNumber < tmrtestNUM_TIMERS; xTimerNumber++ )\r
- {\r
- /* Delete any existing timers. */\r
- if( xAutoReloadTimers[ xTimerNumber ] != NULL )\r
- {\r
- vPortFree( xAutoReloadTimers[ xTimerNumber ] );\r
- }\r
-\r
- /* Create new autoreload timers. */\r
- xAutoReloadTimers[ xTimerNumber ] = xTimerCreate( "Timer", 0xffff, pdTRUE, ( void * ) xTimerNumber, vAutoReloadTimerCallback );\r
- uxAutoReloadTimerCounters[ xTimerNumber ] = 0;\r
- if( xAutoReloadTimers == NULL )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- /* Initialise lists so they are empty. */\r
- vListInitialise( &xActiveTimerList1 );\r
- vListInitialise( &xActiveTimerList2 );\r
-\r
- /* Call prvSampleTimeNow with a tick count of zero so it sets its \r
- internal static "last time" variable to zero. */\r
- xTickCount = 0;\r
- xNumOfOverflows = 0;\r
- prvSampleTimeNow( &xTimerNumber );\r
-\r
- /* Initialise the list pointers in case prvSampleTimeNow() changed them. */\r
- pxCurrentTimerList = &xActiveTimerList1;\r
- pxOverflowTimerList = &xActiveTimerList2;\r
-\r
-// if( xTestTask1 == NULL )\r
- {\r
- xTaskCreate( (pdTASK_CODE)prvTestFailed, "Task1", configMINIMAL_STACK_SIZE, NULL, 0, &xTestTask1 );\r
- }\r
-\r
-// if( xTestTask2 == NULL )\r
- {\r
- xTaskCreate( (pdTASK_CODE)prvTestFailed, "Task1", configMINIMAL_STACK_SIZE, NULL, 0, &xTestTask2 );\r
- }\r
-\r
- pxCurrentTCB = xTestTask1;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvTestFailed( void )\r
-{\r
-static unsigned long ulFailures = 0;\r
-\r
- ulFailures++;\r
- xTestStatus = pdFAIL;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckServiceTaskBehaviour( portBASE_TYPE x, portBASE_TYPE xExpireTimeHasOverflowed, portBASE_TYPE xTickCountOverflowed )\r
-{\r
-portBASE_TYPE xListWasEmpty;\r
-portTickType xNextExpireTime;\r
-extern xList * volatile pxOverflowDelayedTaskList, *pxDelayedTaskList;\r
-extern xList pxReadyTasksLists[];\r
-\r
- xListWasEmpty = portMAX_DELAY;\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- /* If the timer expire time has overflowed it should be present in the overflow \r
- list of active timers, unless the tick count has also overflowed and the expire\r
- time has not passed. If the expire time has not overflowed it should be \r
- present in the current list of active timers. Either way, its expire time should \r
- equal the expected expire time. */\r
- if( ( xExpireTimeHasOverflowed == pdTRUE ) && ( xTickCountOverflowed == pdFALSE ) )\r
- { \r
- /* The timer will be in the overflow list, so prvGetNextExpireTime()\r
- should not have found it, but instead returned an expire time that\r
- will ensure the timer service task will unblock when the lists need\r
- switching. */\r
- if( ( xNextExpireTime != 0 ) || ( xListWasEmpty == pdFALSE ) )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
- else\r
- {\r
- if( ( xNextExpireTime != xTestCase[ x ].xExpectedCalculatedExpiryTime ) || ( xListWasEmpty != pdFALSE ) )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
-\r
- /* Has the timer expired the expected number of times? */\r
- if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- /* The task should now be blocked. It should only appear in the overflow\r
- delayed task list if xNextExpireTime is equal to 0. */\r
- if( xNextExpireTime == 0 )\r
- {\r
- if( listIS_CONTAINED_WITHIN( pxOverflowDelayedTaskList, &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != 0 )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
- else\r
- {\r
- if( listIS_CONTAINED_WITHIN( pxDelayedTaskList, &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- /* The timer should have be re-loaded, and still be referenced from one\r
- or other of the active lists. */\r
- if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- if( listIS_CONTAINED_WITHIN( NULL, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdTRUE )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- /* Move the task back to the ready list from the delayed list. */\r
- vListRemove( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) );\r
- vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static portBASE_TYPE xTimerTest1_xTimeStartAndResetWakeTimeCalculation( void )\r
-{\r
-portBASE_TYPE x, xListWasEmpty;\r
-portTickType xNextExpireTime;\r
-\r
- if( sizeof( portTickType ) != 2 )\r
- {\r
- /* This test should be performed using 16bit ticks. */\r
- prvTestFailed();\r
- }\r
-\r
- for( x = 0; x < ( sizeof( xTestCase ) / sizeof( struct xTestData ) ); x++ )\r
- {\r
- /* Set everything back to its start condition. */\r
- vTimerTest_Initialise();\r
-\r
- /* Load the tick count with the test case data. */\r
- xTickCount = xTestCase[ x ].xStartTickCount;\r
-\r
- /* Query the timers list to see if it contains any timers, and if so,\r
- obtain the time at which the next timer will expire. The list should be\r
- empty, so 0 should be returned (to cause the task to unblock when a\r
- tick overflow occurs. Likewise xListWasEmpty should be set to pdTRUE. */\r
- xListWasEmpty = portMAX_DELAY;\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- if( ( xListWasEmpty != pdTRUE ) || ( xNextExpireTime != ( portTickType ) 0 ) )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
-\r
-\r
- /* Call prvProcessReceivedCommands() just so the code under test knows\r
- what the tick count is in the pre-condition state. */\r
- prvProcessReceivedCommands();\r
-\r
- xAutoReloadTimers[ 0 ]->xTimerPeriodInTicks = xTestCase[ x ].xTimerPeriod;\r
- xTimerStart( xAutoReloadTimers[ 0 ], 0 );\r
-\r
- /* Move the tick count on to the time at which the command should be \r
- processed. */\r
- xTickCount += xTestCase[ x ].xTickIncrementBetweenCommandAndProcessing;\r
-\r
- /* Process the sent command with the updated tick count. */\r
- prvProcessReceivedCommands();\r
-\r
- if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
- {\r
- prvTestFailed();\r
- }\r
- if( listIS_CONTAINED_WITHIN( xTestCase[ x ].pxExpectedList, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdFALSE )\r
- {\r
- prvTestFailed();\r
- }\r
- if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
- {\r
- prvTestFailed();\r
- }\r
-\r
- if( xTickCount < xTestCase[ x ].xStartTickCount ) /* The tick count has overflowed */\r
- {\r
- if( xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed. */\r
- {\r
- if( xTestCase[ x ].xExpectedCalculatedExpiryTime <= xTickCount ) /* The timer expire time has passed */\r
- {\r
- /* The expire time should never have passed when here is\r
- reached because the timer whould have been processed enough\r
- times to make the expire time catch up. */\r
- prvTestFailed();\r
- }\r
- else /* The timer expire time has not passed. */\r
- {\r
- prvCheckServiceTaskBehaviour( x, pdTRUE, pdTRUE );\r
- }\r
- }\r
- else /* The timer expire time has not overflowed. */\r
- {\r
- /* If the timer expire time has not overflowed but the tick count has \r
- overflowed, then the timer expire time must have been passed. The \r
- expire time should never have passed when here is reached because \r
- the timer whould have been processed enough times to make the expire \r
- time catch up. */\r
- prvTestFailed();\r
- }\r
- }\r
- else /* The tick count has not overflowed. */\r
- {\r
- if( xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed */\r
- {\r
- /* If the expire time has overflowed, but the tick count has not\r
- overflowed, then the timer expire time cannot have been passed. */\r
- prvCheckServiceTaskBehaviour( x, pdTRUE, pdFALSE );\r
- }\r
- else /* The timer expire time has not overflowed. */\r
- {\r
- if( xTickCount >= xTestCase[ x ].xExpectedCalculatedExpiryTime ) /* The timer expire time has passed */\r
- {\r
- /* The expire time should never have passed when here is\r
- reached because the timer whould have been processed enough\r
- times to make the expire time catch up. */\r
- prvTestFailed();\r
- }\r
- else /* The timer expire time has not passed. */\r
- {\r
- prvCheckServiceTaskBehaviour( x, pdFALSE, pdFALSE );\r
- }\r
- }\r
- }\r
- }\r
-\r
- return xTestStatus;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier )\r
-{\r
-unsigned portBASE_TYPE uxExpectedIncrements, x, uxMix = 0, uxPeriod;\r
-const unsigned portBASE_TYPE uxMaxIterations = 0x1fffff;\r
-extern xList pxReadyTasksLists[];\r
-portTickType xNextExpireTime;\r
-portBASE_TYPE xListWasEmpty;\r
-extern xTaskHandle pxCurrentTCB;\r
-\r
- if( sizeof( portTickType ) != 2 )\r
- {\r
- /* This test should be performed using 16bit ticks. */\r
- prvTestFailed();\r
- }\r
-\r
- /* Initialise the test. This will create tmrtestNUM_TIMERS timers. */\r
- vTimerTest_Initialise();\r
-\r
- /* Give each timer a period, then start it running. */\r
- for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
- {\r
- uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
- xTimerChangePeriod( xAutoReloadTimers[ x ], ( portTickType ) uxPeriod, 0 );\r
- xTimerStart( xAutoReloadTimers[ x ], 0 );\r
- prvProcessReceivedCommands();\r
- }\r
-\r
- xTickCount = 1;\r
- x = 1;\r
-\r
- /* Simulate the task running. */\r
- while( x <= uxMaxIterations )\r
- {\r
- /* Query the timers list to see if it contains any timers, and if so,\r
- obtain the time at which the next timer will expire. */\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- /* It is legitimate for tick increments to occur here. */\r
- if( ( uxMix < 2 ) && ( x < uxMaxIterations - 5 ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
-\r
- /* If a timer has expired, process it. Otherwise, block this task\r
- until either a timer does expire, or a command is received. */\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
- \r
- /* If the task blocked, increment the tick until it unblocks. */\r
- while( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
- {\r
- if( ( uxMix == 1 ) && ( x < ( uxMaxIterations + 3 ) ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- if( ( uxMix == 2 ) && ( x < ( uxMaxIterations + 2 ) ) )\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- else\r
- {\r
- vTaskIncrementTick();\r
- x++;\r
- }\r
- }\r
-\r
- uxMix++;\r
- if( uxMix > 8 )\r
- {\r
- uxMix = 0;\r
- }\r
-\r
- /* Make sure time does not go past that expected. */\r
- if( x > uxMaxIterations )\r
- {\r
- xTickCount -= ( portTickType ) ( x - uxMaxIterations );\r
- }\r
-\r
- /* Empty the command queue. */\r
- prvProcessReceivedCommands(); \r
- }\r
-\r
- /* Catch up with the tick count, if it was incremented more than once in one\r
- go. */\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
- \r
- /* This time, if the task blocked, there is nothing left to do. If it didn't\r
- block then empty the command queue for good measure. */\r
- if( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != pdFALSE )\r
- {\r
- /* Empty the command queue. */\r
- prvProcessReceivedCommands(); \r
- }\r
-\r
- /* Check each timer has incremented the expected number of times. */\r
- for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
- {\r
- uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
- uxExpectedIncrements = ( uxMaxIterations / ( unsigned portBASE_TYPE ) uxPeriod );\r
- \r
- if( ( uxExpectedIncrements - uxAutoReloadTimerCounters[ x ] ) > 1 )\r
- {\r
- prvTestFailed();\r
- }\r
- }\r
-\r
- return xTestStatus;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vRunTimerModuleTests( void )\r
-{\r
-unsigned long x;\r
-\r
- xTimerTest1_xTimeStartAndResetWakeTimeCalculation();\r
-\r
- for( x = 1; x < 1000; x++ )\r
- {\r
- xTimerTest2_xTestFreeRunningBehaviour( x );\r
- }\r
-\r
- for( ;; );\r
-}\r
-\r
-#endif TIMER_TEST_H\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-\r
-#ifndef TIMERS_H\r
-#define TIMERS_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "include FreeRTOS.h must appear in source files before include timers.h"\r
-#endif\r
-\r
-#include "portable.h"\r
-#include "list.h"\r
-#include "task.h"\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/* IDs for commands that can be sent/received on the timer queue. These are to\r
-be used solely through the macros that make up the public software timer API,\r
-as defined below. */\r
-#define tmrCOMMAND_START 0\r
-#define tmrCOMMAND_STOP 1\r
-#define tmrCOMMAND_CHANGE_PERIOD 2\r
-#define tmrCOMMAND_DELETE 3\r
-\r
-/*-----------------------------------------------------------\r
- * MACROS AND DEFINITIONS\r
- *----------------------------------------------------------*/\r
-\r
- /**\r
- * Type by which software timers are referenced. For example, a call to\r
- * xTimerCreate() returns an xTimerHandle variable that can then be used to\r
- * reference the subject timer in calls to other software timer API functions\r
- * (for example, xTimerStart(), xTimerReset(), etc.).\r
- */\r
-typedef void * xTimerHandle;\r
-\r
-/* Define the prototype to which timer callback functions must conform. */\r
-typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer );\r
-\r
-/**\r
- * xTimerHandle xTimerCreate( const signed char *pcTimerName,\r
- * portTickType xTimerPeriodInTicks,\r
- * unsigned portBASE_TYPE uxAutoReload,\r
- * void * pvTimerID,\r
- * tmrTIMER_CALLBACK pxCallbackFunction );\r
- *\r
- * Creates a new software timer instance. This allocates the storage required\r
- * by the new timer, initialises the new timers internal state, and returns a\r
- * handle by which the new timer can be referenced.\r
- *\r
- * Timers are created in the dormant state. The xTimerStart(), xTimerReset(),\r
- * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and\r
- * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the\r
- * active state.\r
- *\r
- * @param pcTimerName A text name that is assigned to the timer. This is done\r
- * purely to assist debugging. The kernel itself only ever references a timer by\r
- * its handle, and never by its name.\r
- *\r
- * @param xTimerPeriodInTicks The timer period. The time is defined in tick periods so\r
- * the constant portTICK_RATE_MS can be used to convert a time that has been\r
- * specified in milliseconds. For example, if the timer must expire after 100\r
- * ticks, then xTimerPeriodInTicks should be set to 100. Alternatively, if the timer\r
- * must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_RATE_MS )\r
- * provided configTICK_RATE_HZ is less than or equal to 1000.\r
- *\r
- * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will\r
- * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. If\r
- * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and\r
- * enter the dormant state after it expires.\r
- *\r
- * @param pvTimerID An identifier that is assigned to the timer being created.\r
- * Typically this would be used in the timer callback function to identify which\r
- * timer expired when the same callback function is assigned to more than one\r
- * timer.\r
- *\r
- * @param pxCallbackFunction The function to call when the timer expires.\r
- * Callback functions must have the prototype defined by tmrTIMER_CALLBACK,\r
- * which is "void vCallbackFunction( xTimerHandle xTimer );".\r
- *\r
- * @return If the timer is successfully create then a handle to the newly\r
- * created timer is returned. If the timer cannot be created (because either\r
- * there is insufficient FreeRTOS heap remaining to allocate the timer\r
- * structures, or the timer period was set to 0) then 0 is returned.\r
- *\r
- * Example usage:\r
- *\r
- * #define NUM_TIMERS 5\r
- *\r
- * // An array to hold handles to the created timers.\r
- * xTimerHandle xTimers[ NUM_TIMERS ];\r
- *\r
- * // An array to hold a count of the number of times each timer expires.\r
- * long lExpireCounters[ NUM_TIMERS ] = { 0 };\r
- *\r
- * // Define a callback function that will be used by multiple timer instances.\r
- * // The callback function does nothing but count the number of times the\r
- * // associated timer expires, and stop the timer once the timer has expired\r
- * // 10 times.\r
- * void vTimerCallback( xTimerHandle pxTimer )\r
- * {\r
- * long lArrayIndex;\r
- * const long xMaxExpiryCountBeforeStopping = 10;\r
- *\r
- * // Optionally do something if the pxTimer parameter is NULL.\r
- * configASSERT( pxTimer );\r
- * \r
- * // Which timer expired?\r
- * lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer );\r
- *\r
- * // Increment the number of times that pxTimer has expired.\r
- * lExpireCounters[ lArrayIndex ] += 1;\r
- *\r
- * // If the timer has expired 10 times then stop it from running.\r
- * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping )\r
- * {\r
- * // Do not use a block time if calling a timer API function from a\r
- * // timer callback function, as doing so could cause a deadlock!\r
- * xTimerStop( pxTimer, 0 );\r
- * }\r
- * }\r
- *\r
- * void main( void )\r
- * {\r
- * long x;\r
- *\r
- * // Create then start some timers. Starting the timers before the scheduler\r
- * // has been started means the timers will start running immediately that\r
- * // the scheduler starts.\r
- * for( x = 0; x < NUM_TIMERS; x++ )\r
- * {\r
- * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.\r
- * ( 100 * x ), // The timer period in ticks.\r
- * pdTRUE, // The timers will auto-reload themselves when they expire.\r
- * ( void * ) x, // Assign each timer a unique id equal to its array index.\r
- * vTimerCallback // Each timer calls the same callback when it expires.\r
- * );\r
- *\r
- * if( xTimers[ x ] == NULL )\r
- * {\r
- * // The timer was not created.\r
- * }\r
- * else\r
- * {\r
- * // Start the timer. No block time is specified, and even if one was\r
- * // it would be ignored because the scheduler has not yet been\r
- * // started.\r
- * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS )\r
- * {\r
- * // The timer could not be set into the Active state.\r
- * }\r
- * }\r
- * }\r
- *\r
- * // ...\r
- * // Create tasks here.\r
- * // ...\r
- *\r
- * // Starting the scheduler will start the timers running as they have already\r
- * // been set into the active state.\r
- * xTaskStartScheduler();\r
- *\r
- * // Should not reach here.\r
- * for( ;; );\r
- * }\r
- */\r
-xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * void *pvTimerGetTimerID( xTimerHandle xTimer );\r
- *\r
- * Returns the ID assigned to the timer.\r
- *\r
- * IDs are assigned to timers using the pvTimerID parameter of the call to\r
- * xTimerCreated() that was used to create the timer.\r
- *\r
- * If the same callback function is assigned to multiple timers then the timer\r
- * ID can be used within the callback function to identify which timer actually\r
- * expired.\r
- *\r
- * @param xTimer The timer being queried.\r
- *\r
- * @return The ID assigned to the timer being queried.\r
- *\r
- * Example usage:\r
- *\r
- * See the xTimerCreate() API function example usage scenario.\r
- */\r
-void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer );\r
- *\r
- * Queries a timer to see if it is active or dormant.\r
- *\r
- * A timer will be dormant if:\r
- * 1) It has been created but not started, or\r
- * 2) It is an expired on-shot timer that has not been restarted.\r
- *\r
- * Timers are created in the dormant state. The xTimerStart(), xTimerReset(),\r
- * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and\r
- * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the\r
- * active state.\r
- *\r
- * @param xTimer The timer being queried.\r
- *\r
- * @return pdFALSE will be returned if the timer is dormant. A value other than\r
- * pdFALSE will be returned if the timer is active.\r
- *\r
- * Example usage:\r
- *\r
- * // This function assumes xTimer has already been created.\r
- * void vAFunction( xTimerHandle xTimer )\r
- * {\r
- * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"\r
- * {\r
- * // xTimer is active, do something.\r
- * }\r
- * else\r
- * {\r
- * // xTimer is not active, do something else.\r
- * }\r
- * }\r
- */\r
-portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * xTimerGetTimerDaemonTaskHandle() is only available if \r
- * INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h.\r
- *\r
- * Simply returns the handle of the timer service/daemon task. It it not valid\r
- * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.\r
- */\r
-xTaskHandle xTimerGetTimerDaemonTaskHandle( void );\r
-\r
-/**\r
- * portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime );\r
- *\r
- * Timer functionality is provided by a timer service/daemon task. Many of the\r
- * public FreeRTOS timer API functions send commands to the timer service task\r
- * though a queue called the timer command queue. The timer command queue is\r
- * private to the kernel itself and is not directly accessible to application\r
- * code. The length of the timer command queue is set by the\r
- * configTIMER_QUEUE_LENGTH configuration constant.\r
- *\r
- * xTimerStart() starts a timer that was previously created using the\r
- * xTimerCreate() API function. If the timer had already been started and was\r
- * already in the active state, then xTimerStart() has equivalent functionality\r
- * to the xTimerReset() API function.\r
- *\r
- * Starting a timer ensures the timer is in the active state. If the timer\r
- * is not stopped, deleted, or reset in the mean time, the callback function\r
- * associated with the timer will get called 'n' ticks after xTimerStart() was\r
- * called, where 'n' is the timers defined period.\r
- *\r
- * It is valid to call xTimerStart() before the scheduler has been started, but\r
- * when this is done the timer will not actually start until the scheduler is\r
- * started, and the timers expiry time will be relative to when the scheduler is\r
- * started, not relative to when xTimerStart() was called.\r
- *\r
- * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart()\r
- * to be available.\r
- *\r
- * @param xTimer The handle of the timer being started/restarted.\r
- *\r
- * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
- * be held in the Blocked state to wait for the start command to be successfully\r
- * sent to the timer command queue, should the queue already be full when\r
- * xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called\r
- * before the scheduler is started.\r
- *\r
- * @return pdFAIL will be returned if the start command could not be sent to\r
- * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
- * be returned if the command was successfully sent to the timer command queue.\r
- * When the command is actually processed will depend on the priority of the\r
- * timer service/daemon task relative to other tasks in the system, although the\r
- * timers expiry time is relative to when xTimerStart() is actually called. The\r
- * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
- * configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * See the xTimerCreate() API function example usage scenario.\r
- *\r
- */\r
-#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )\r
-\r
-/**\r
- * portBASE_TYPE xTimerStop( xTimerHandle xTimer, portTickType xBlockTime );\r
- *\r
- * Timer functionality is provided by a timer service/daemon task. Many of the\r
- * public FreeRTOS timer API functions send commands to the timer service task\r
- * though a queue called the timer command queue. The timer command queue is\r
- * private to the kernel itself and is not directly accessible to application\r
- * code. The length of the timer command queue is set by the\r
- * configTIMER_QUEUE_LENGTH configuration constant.\r
- *\r
- * xTimerStop() stops a timer that was previously started using either of the\r
- * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(),\r
- * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions.\r
- *\r
- * Stopping a timer ensures the timer is not in the active state.\r
- *\r
- * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop()\r
- * to be available.\r
- *\r
- * @param xTimer The handle of the timer being stopped.\r
- *\r
- * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
- * be held in the Blocked state to wait for the stop command to be successfully\r
- * sent to the timer command queue, should the queue already be full when\r
- * xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called\r
- * before the scheduler is started.\r
- *\r
- * @return pdFAIL will be returned if the stop command could not be sent to\r
- * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
- * be returned if the command was successfully sent to the timer command queue.\r
- * When the command is actually processed will depend on the priority of the\r
- * timer service/daemon task relative to other tasks in the system. The timer\r
- * service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
- * configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * See the xTimerCreate() API function example usage scenario.\r
- *\r
- */\r
-#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) )\r
-\r
-/**\r
- * portBASE_TYPE xTimerChangePeriod( xTimerHandle xTimer,\r
- * portTickType xNewPeriod,\r
- * portTickType xBlockTime );\r
- *\r
- * Timer functionality is provided by a timer service/daemon task. Many of the\r
- * public FreeRTOS timer API functions send commands to the timer service task\r
- * though a queue called the timer command queue. The timer command queue is\r
- * private to the kernel itself and is not directly accessible to application\r
- * code. The length of the timer command queue is set by the\r
- * configTIMER_QUEUE_LENGTH configuration constant.\r
- *\r
- * xTimerChangePeriod() changes the period of a timer that was previously\r
- * created using the xTimerCreate() API function.\r
- *\r
- * xTimerChangePeriod() can be called to change the period of an active or\r
- * dormant state timer.\r
- *\r
- * The configUSE_TIMERS configuration constant must be set to 1 for\r
- * xTimerChangePeriod() to be available.\r
- *\r
- * @param xTimer The handle of the timer that is having its period changed.\r
- *\r
- * @param xNewPeriod The new period for xTimer. Timer periods are specified in\r
- * tick periods, so the constant portTICK_RATE_MS can be used to convert a time\r
- * that has been specified in milliseconds. For example, if the timer must\r
- * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,\r
- * if the timer must expire after 500ms, then xNewPeriod can be set to\r
- * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than\r
- * or equal to 1000.\r
- *\r
- * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
- * be held in the Blocked state to wait for the change period command to be\r
- * successfully sent to the timer command queue, should the queue already be\r
- * full when xTimerChangePeriod() was called. xBlockTime is ignored if\r
- * xTimerChangePeriod() is called before the scheduler is started.\r
- *\r
- * @return pdFAIL will be returned if the change period command could not be\r
- * sent to the timer command queue even after xBlockTime ticks had passed.\r
- * pdPASS will be returned if the command was successfully sent to the timer\r
- * command queue. When the command is actually processed will depend on the\r
- * priority of the timer service/daemon task relative to other tasks in the\r
- * system. The timer service/daemon task priority is set by the\r
- * configTIMER_TASK_PRIORITY configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * // This function assumes xTimer has already been created. If the timer\r
- * // referenced by xTimer is already active when it is called, then the timer\r
- * // is deleted. If the timer referenced by xTimer is not active when it is\r
- * // called, then the period of the timer is set to 500ms and the timer is\r
- * // started.\r
- * void vAFunction( xTimerHandle xTimer )\r
- * {\r
- * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"\r
- * {\r
- * // xTimer is already active - delete it.\r
- * xTimerDelete( xTimer );\r
- * }\r
- * else\r
- * {\r
- * // xTimer is not active, change its period to 500ms. This will also\r
- * // cause the timer to start. Block for a maximum of 100 ticks if the\r
- * // change period command cannot immediately be sent to the timer\r
- * // command queue.\r
- * if( xTimerChangePeriod( xTimer, 500 / portTICK_RATE_MS, 100 ) == pdPASS )\r
- * {\r
- * // The command was successfully sent.\r
- * }\r
- * else\r
- * {\r
- * // The command could not be sent, even after waiting for 100 ticks\r
- * // to pass. Take appropriate action here.\r
- * }\r
- * }\r
- * }\r
- */\r
- #define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) )\r
-\r
-/**\r
- * portBASE_TYPE xTimerDelete( xTimerHandle xTimer, portTickType xBlockTime );\r
- *\r
- * Timer functionality is provided by a timer service/daemon task. Many of the\r
- * public FreeRTOS timer API functions send commands to the timer service task\r
- * though a queue called the timer command queue. The timer command queue is\r
- * private to the kernel itself and is not directly accessible to application\r
- * code. The length of the timer command queue is set by the\r
- * configTIMER_QUEUE_LENGTH configuration constant.\r
- *\r
- * xTimerDelete() deletes a timer that was previously created using the\r
- * xTimerCreate() API function.\r
- *\r
- * The configUSE_TIMERS configuration constant must be set to 1 for\r
- * xTimerDelete() to be available.\r
- *\r
- * @param xTimer The handle of the timer being deleted.\r
- *\r
- * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
- * be held in the Blocked state to wait for the delete command to be\r
- * successfully sent to the timer command queue, should the queue already be\r
- * full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete()\r
- * is called before the scheduler is started.\r
- *\r
- * @return pdFAIL will be returned if the delete command could not be sent to\r
- * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
- * be returned if the command was successfully sent to the timer command queue.\r
- * When the command is actually processed will depend on the priority of the\r
- * timer service/daemon task relative to other tasks in the system. The timer\r
- * service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
- * configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * See the xTimerChangePeriod() API function example usage scenario.\r
- */\r
-#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) )\r
-\r
-/**\r
- * portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType xBlockTime );\r
- *\r
- * Timer functionality is provided by a timer service/daemon task. Many of the\r
- * public FreeRTOS timer API functions send commands to the timer service task\r
- * though a queue called the timer command queue. The timer command queue is\r
- * private to the kernel itself and is not directly accessible to application\r
- * code. The length of the timer command queue is set by the\r
- * configTIMER_QUEUE_LENGTH configuration constant.\r
- *\r
- * xTimerReset() re-starts a timer that was previously created using the\r
- * xTimerCreate() API function. If the timer had already been started and was\r
- * already in the active state, then xTimerReset() will cause the timer to\r
- * re-evaluate its expiry time so that it is relative to when xTimerReset() was\r
- * called. If the timer was in the dormant state then xTimerReset() has\r
- * equivalent functionality to the xTimerStart() API function.\r
- *\r
- * Resetting a timer ensures the timer is in the active state. If the timer\r
- * is not stopped, deleted, or reset in the mean time, the callback function\r
- * associated with the timer will get called 'n' ticks after xTimerReset() was\r
- * called, where 'n' is the timers defined period.\r
- *\r
- * It is valid to call xTimerReset() before the scheduler has been started, but\r
- * when this is done the timer will not actually start until the scheduler is\r
- * started, and the timers expiry time will be relative to when the scheduler is\r
- * started, not relative to when xTimerReset() was called.\r
- *\r
- * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset()\r
- * to be available.\r
- *\r
- * @param xTimer The handle of the timer being reset/started/restarted.\r
- *\r
- * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
- * be held in the Blocked state to wait for the reset command to be successfully\r
- * sent to the timer command queue, should the queue already be full when\r
- * xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called\r
- * before the scheduler is started.\r
- *\r
- * @return pdFAIL will be returned if the reset command could not be sent to\r
- * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
- * be returned if the command was successfully sent to the timer command queue.\r
- * When the command is actually processed will depend on the priority of the\r
- * timer service/daemon task relative to other tasks in the system, although the\r
- * timers expiry time is relative to when xTimerStart() is actually called. The\r
- * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
- * configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass\r
- * // without a key being pressed, then the LCD back-light is switched off. In\r
- * // this case, the timer is a one-shot timer.\r
- *\r
- * xTimerHandle xBacklightTimer = NULL;\r
- *\r
- * // The callback function assigned to the one-shot timer. In this case the\r
- * // parameter is not used.\r
- * void vBacklightTimerCallback( xTimerHandle pxTimer )\r
- * {\r
- * // The timer expired, therefore 5 seconds must have passed since a key\r
- * // was pressed. Switch off the LCD back-light.\r
- * vSetBacklightState( BACKLIGHT_OFF );\r
- * }\r
- *\r
- * // The key press event handler.\r
- * void vKeyPressEventHandler( char cKey )\r
- * {\r
- * // Ensure the LCD back-light is on, then reset the timer that is\r
- * // responsible for turning the back-light off after 5 seconds of\r
- * // key inactivity. Wait 10 ticks for the command to be successfully sent\r
- * // if it cannot be sent immediately.\r
- * vSetBacklightState( BACKLIGHT_ON );\r
- * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS )\r
- * {\r
- * // The reset command was not executed successfully. Take appropriate\r
- * // action here.\r
- * }\r
- *\r
- * // Perform the rest of the key processing here.\r
- * }\r
- *\r
- * void main( void )\r
- * {\r
- * long x;\r
- *\r
- * // Create then start the one-shot timer that is responsible for turning\r
- * // the back-light off if no keys are pressed within a 5 second period.\r
- * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel.\r
- * ( 5000 / portTICK_RATE_MS), // The timer period in ticks.\r
- * pdFALSE, // The timer is a one-shot timer.\r
- * 0, // The id is not used by the callback so can take any value.\r
- * vBacklightTimerCallback // The callback function that switches the LCD back-light off.\r
- * );\r
- *\r
- * if( xBacklightTimer == NULL )\r
- * {\r
- * // The timer was not created.\r
- * }\r
- * else\r
- * {\r
- * // Start the timer. No block time is specified, and even if one was\r
- * // it would be ignored because the scheduler has not yet been\r
- * // started.\r
- * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS )\r
- * {\r
- * // The timer could not be set into the Active state.\r
- * }\r
- * }\r
- *\r
- * // ...\r
- * // Create tasks here.\r
- * // ...\r
- *\r
- * // Starting the scheduler will start the timer running as it has already\r
- * // been set into the active state.\r
- * xTaskStartScheduler();\r
- *\r
- * // Should not reach here.\r
- * for( ;; );\r
- * }\r
- */\r
-#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )\r
-\r
-/**\r
- * portBASE_TYPE xTimerStartFromISR( xTimerHandle xTimer,\r
- * portBASE_TYPE *pxHigherPriorityTaskWoken );\r
- *\r
- * A version of xTimerStart() that can be called from an interrupt service\r
- * routine.\r
- *\r
- * @param xTimer The handle of the timer being started/restarted.\r
- *\r
- * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
- * of its time in the Blocked state, waiting for messages to arrive on the timer\r
- * command queue. Calling xTimerStartFromISR() writes a message to the timer\r
- * command queue, so has the potential to transition the timer service/daemon\r
- * task out of the Blocked state. If calling xTimerStartFromISR() causes the\r
- * timer service/daemon task to leave the Blocked state, and the timer service/\r
- * daemon task has a priority equal to or greater than the currently executing\r
- * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will\r
- * get set to pdTRUE internally within the xTimerStartFromISR() function. If\r
- * xTimerStartFromISR() sets this value to pdTRUE then a context switch should\r
- * be performed before the interrupt exits.\r
- *\r
- * @return pdFAIL will be returned if the start command could not be sent to\r
- * the timer command queue. pdPASS will be returned if the command was\r
- * successfully sent to the timer command queue. When the command is actually\r
- * processed will depend on the priority of the timer service/daemon task\r
- * relative to other tasks in the system, although the timers expiry time is\r
- * relative to when xTimerStartFromISR() is actually called. The timer service/daemon\r
- * task priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * // This scenario assumes xBacklightTimer has already been created. When a\r
- * // key is pressed, an LCD back-light is switched on. If 5 seconds pass\r
- * // without a key being pressed, then the LCD back-light is switched off. In\r
- * // this case, the timer is a one-shot timer, and unlike the example given for\r
- * // the xTimerReset() function, the key press event handler is an interrupt\r
- * // service routine.\r
- *\r
- * // The callback function assigned to the one-shot timer. In this case the\r
- * // parameter is not used.\r
- * void vBacklightTimerCallback( xTimerHandle pxTimer )\r
- * {\r
- * // The timer expired, therefore 5 seconds must have passed since a key\r
- * // was pressed. Switch off the LCD back-light.\r
- * vSetBacklightState( BACKLIGHT_OFF );\r
- * }\r
- *\r
- * // The key press interrupt service routine.\r
- * void vKeyPressEventInterruptHandler( void )\r
- * {\r
- * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
- *\r
- * // Ensure the LCD back-light is on, then restart the timer that is\r
- * // responsible for turning the back-light off after 5 seconds of\r
- * // key inactivity. This is an interrupt service routine so can only\r
- * // call FreeRTOS API functions that end in "FromISR".\r
- * vSetBacklightState( BACKLIGHT_ON );\r
- *\r
- * // xTimerStartFromISR() or xTimerResetFromISR() could be called here\r
- * // as both cause the timer to re-calculate its expiry time.\r
- * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was\r
- * // declared (in this function).\r
- * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
- * {\r
- * // The start command was not executed successfully. Take appropriate\r
- * // action here.\r
- * }\r
- *\r
- * // Perform the rest of the key processing here.\r
- *\r
- * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
- * // should be performed. The syntax required to perform a context switch\r
- * // from inside an ISR varies from port to port, and from compiler to\r
- * // compiler. Inspect the demos for the port you are using to find the\r
- * // actual syntax required.\r
- * if( xHigherPriorityTaskWoken != pdFALSE )\r
- * {\r
- * // Call the interrupt safe yield function here (actual function\r
- * // depends on the FreeRTOS port being used.\r
- * }\r
- * }\r
- */\r
-#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )\r
-\r
-/**\r
- * portBASE_TYPE xTimerStopFromISR( xTimerHandle xTimer,\r
- * portBASE_TYPE *pxHigherPriorityTaskWoken );\r
- *\r
- * A version of xTimerStop() that can be called from an interrupt service\r
- * routine.\r
- *\r
- * @param xTimer The handle of the timer being stopped.\r
- *\r
- * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
- * of its time in the Blocked state, waiting for messages to arrive on the timer\r
- * command queue. Calling xTimerStopFromISR() writes a message to the timer\r
- * command queue, so has the potential to transition the timer service/daemon\r
- * task out of the Blocked state. If calling xTimerStopFromISR() causes the\r
- * timer service/daemon task to leave the Blocked state, and the timer service/\r
- * daemon task has a priority equal to or greater than the currently executing\r
- * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will\r
- * get set to pdTRUE internally within the xTimerStopFromISR() function. If\r
- * xTimerStopFromISR() sets this value to pdTRUE then a context switch should\r
- * be performed before the interrupt exits.\r
- *\r
- * @return pdFAIL will be returned if the stop command could not be sent to\r
- * the timer command queue. pdPASS will be returned if the command was\r
- * successfully sent to the timer command queue. When the command is actually\r
- * processed will depend on the priority of the timer service/daemon task\r
- * relative to other tasks in the system. The timer service/daemon task\r
- * priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * // This scenario assumes xTimer has already been created and started. When\r
- * // an interrupt occurs, the timer should be simply stopped.\r
- *\r
- * // The interrupt service routine that stops the timer.\r
- * void vAnExampleInterruptServiceRoutine( void )\r
- * {\r
- * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
- *\r
- * // The interrupt has occurred - simply stop the timer.\r
- * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined\r
- * // (within this function). As this is an interrupt service routine, only\r
- * // FreeRTOS API functions that end in "FromISR" can be used.\r
- * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
- * {\r
- * // The stop command was not executed successfully. Take appropriate\r
- * // action here.\r
- * }\r
- *\r
- * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
- * // should be performed. The syntax required to perform a context switch\r
- * // from inside an ISR varies from port to port, and from compiler to\r
- * // compiler. Inspect the demos for the port you are using to find the\r
- * // actual syntax required.\r
- * if( xHigherPriorityTaskWoken != pdFALSE )\r
- * {\r
- * // Call the interrupt safe yield function here (actual function\r
- * // depends on the FreeRTOS port being used.\r
- * }\r
- * }\r
- */\r
-#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U )\r
-\r
-/**\r
- * portBASE_TYPE xTimerChangePeriodFromISR( xTimerHandle xTimer,\r
- * portTickType xNewPeriod,\r
- * portBASE_TYPE *pxHigherPriorityTaskWoken );\r
- *\r
- * A version of xTimerChangePeriod() that can be called from an interrupt\r
- * service routine.\r
- *\r
- * @param xTimer The handle of the timer that is having its period changed.\r
- *\r
- * @param xNewPeriod The new period for xTimer. Timer periods are specified in\r
- * tick periods, so the constant portTICK_RATE_MS can be used to convert a time\r
- * that has been specified in milliseconds. For example, if the timer must\r
- * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,\r
- * if the timer must expire after 500ms, then xNewPeriod can be set to\r
- * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than\r
- * or equal to 1000.\r
- *\r
- * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
- * of its time in the Blocked state, waiting for messages to arrive on the timer\r
- * command queue. Calling xTimerChangePeriodFromISR() writes a message to the\r
- * timer command queue, so has the potential to transition the timer service/\r
- * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR()\r
- * causes the timer service/daemon task to leave the Blocked state, and the\r
- * timer service/daemon task has a priority equal to or greater than the\r
- * currently executing task (the task that was interrupted), then\r
- * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the\r
- * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets\r
- * this value to pdTRUE then a context switch should be performed before the\r
- * interrupt exits.\r
- *\r
- * @return pdFAIL will be returned if the command to change the timers period\r
- * could not be sent to the timer command queue. pdPASS will be returned if the\r
- * command was successfully sent to the timer command queue. When the command\r
- * is actually processed will depend on the priority of the timer service/daemon\r
- * task relative to other tasks in the system. The timer service/daemon task\r
- * priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * // This scenario assumes xTimer has already been created and started. When\r
- * // an interrupt occurs, the period of xTimer should be changed to 500ms.\r
- *\r
- * // The interrupt service routine that changes the period of xTimer.\r
- * void vAnExampleInterruptServiceRoutine( void )\r
- * {\r
- * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
- *\r
- * // The interrupt has occurred - change the period of xTimer to 500ms.\r
- * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined\r
- * // (within this function). As this is an interrupt service routine, only\r
- * // FreeRTOS API functions that end in "FromISR" can be used.\r
- * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
- * {\r
- * // The command to change the timers period was not executed\r
- * // successfully. Take appropriate action here.\r
- * }\r
- *\r
- * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
- * // should be performed. The syntax required to perform a context switch\r
- * // from inside an ISR varies from port to port, and from compiler to\r
- * // compiler. Inspect the demos for the port you are using to find the\r
- * // actual syntax required.\r
- * if( xHigherPriorityTaskWoken != pdFALSE )\r
- * {\r
- * // Call the interrupt safe yield function here (actual function\r
- * // depends on the FreeRTOS port being used.\r
- * }\r
- * }\r
- */\r
-#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )\r
-\r
-/**\r
- * portBASE_TYPE xTimerResetFromISR( xTimerHandle xTimer,\r
- * portBASE_TYPE *pxHigherPriorityTaskWoken );\r
- *\r
- * A version of xTimerReset() that can be called from an interrupt service\r
- * routine.\r
- *\r
- * @param xTimer The handle of the timer that is to be started, reset, or\r
- * restarted.\r
- *\r
- * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
- * of its time in the Blocked state, waiting for messages to arrive on the timer\r
- * command queue. Calling xTimerResetFromISR() writes a message to the timer\r
- * command queue, so has the potential to transition the timer service/daemon\r
- * task out of the Blocked state. If calling xTimerResetFromISR() causes the\r
- * timer service/daemon task to leave the Blocked state, and the timer service/\r
- * daemon task has a priority equal to or greater than the currently executing\r
- * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will\r
- * get set to pdTRUE internally within the xTimerResetFromISR() function. If\r
- * xTimerResetFromISR() sets this value to pdTRUE then a context switch should\r
- * be performed before the interrupt exits.\r
- *\r
- * @return pdFAIL will be returned if the reset command could not be sent to\r
- * the timer command queue. pdPASS will be returned if the command was\r
- * successfully sent to the timer command queue. When the command is actually\r
- * processed will depend on the priority of the timer service/daemon task\r
- * relative to other tasks in the system, although the timers expiry time is\r
- * relative to when xTimerResetFromISR() is actually called. The timer service/daemon\r
- * task priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * // This scenario assumes xBacklightTimer has already been created. When a\r
- * // key is pressed, an LCD back-light is switched on. If 5 seconds pass\r
- * // without a key being pressed, then the LCD back-light is switched off. In\r
- * // this case, the timer is a one-shot timer, and unlike the example given for\r
- * // the xTimerReset() function, the key press event handler is an interrupt\r
- * // service routine.\r
- *\r
- * // The callback function assigned to the one-shot timer. In this case the\r
- * // parameter is not used.\r
- * void vBacklightTimerCallback( xTimerHandle pxTimer )\r
- * {\r
- * // The timer expired, therefore 5 seconds must have passed since a key\r
- * // was pressed. Switch off the LCD back-light.\r
- * vSetBacklightState( BACKLIGHT_OFF );\r
- * }\r
- *\r
- * // The key press interrupt service routine.\r
- * void vKeyPressEventInterruptHandler( void )\r
- * {\r
- * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
- *\r
- * // Ensure the LCD back-light is on, then reset the timer that is\r
- * // responsible for turning the back-light off after 5 seconds of\r
- * // key inactivity. This is an interrupt service routine so can only\r
- * // call FreeRTOS API functions that end in "FromISR".\r
- * vSetBacklightState( BACKLIGHT_ON );\r
- *\r
- * // xTimerStartFromISR() or xTimerResetFromISR() could be called here\r
- * // as both cause the timer to re-calculate its expiry time.\r
- * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was\r
- * // declared (in this function).\r
- * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
- * {\r
- * // The reset command was not executed successfully. Take appropriate\r
- * // action here.\r
- * }\r
- *\r
- * // Perform the rest of the key processing here.\r
- *\r
- * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
- * // should be performed. The syntax required to perform a context switch\r
- * // from inside an ISR varies from port to port, and from compiler to\r
- * // compiler. Inspect the demos for the port you are using to find the\r
- * // actual syntax required.\r
- * if( xHigherPriorityTaskWoken != pdFALSE )\r
- * {\r
- * // Call the interrupt safe yield function here (actual function\r
- * // depends on the FreeRTOS port being used.\r
- * }\r
- * }\r
- */\r
-#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )\r
-\r
-/*\r
- * Functions beyond this part are not part of the public API and are intended\r
- * for use by the kernel only.\r
- */\r
-portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;\r
-portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION;\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-#endif /* TIMERS_H */\r
-\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-\r
-#include <stdlib.h>\r
-#include "FreeRTOS.h"\r
-#include "list.h"\r
-\r
-/*-----------------------------------------------------------\r
- * PUBLIC LIST API documented in list.h\r
- *----------------------------------------------------------*/\r
-\r
-void vListInitialise( xList *pxList )\r
-{\r
- /* The list structure contains a list item which is used to mark the\r
- end of the list. To initialise the list the list end is inserted\r
- as the only list entry. */\r
- pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd );\r
-\r
- /* The list end value is the highest possible value in the list to\r
- ensure it remains at the end of the list. */\r
- pxList->xListEnd.xItemValue = portMAX_DELAY;\r
-\r
- /* The list end next and previous pointers point to itself so we know\r
- when the list is empty. */\r
- pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd );\r
- pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );\r
-\r
- pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vListInitialiseItem( xListItem *pxItem )\r
-{\r
- /* Make sure the list item is not recorded as being on a list. */\r
- pxItem->pvContainer = NULL;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vListInsertEnd( xList *pxList, xListItem *pxNewListItem )\r
-{\r
-volatile xListItem * pxIndex;\r
-\r
- /* Insert a new list item into pxList, but rather than sort the list,\r
- makes the new list item the last item to be removed by a call to\r
- pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by\r
- the pxIndex member. */\r
- pxIndex = pxList->pxIndex;\r
-\r
- pxNewListItem->pxNext = pxIndex->pxNext;\r
- pxNewListItem->pxPrevious = pxList->pxIndex;\r
- pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;\r
- pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem;\r
- pxList->pxIndex = ( volatile xListItem * ) pxNewListItem;\r
-\r
- /* Remember which list the item is in. */\r
- pxNewListItem->pvContainer = ( void * ) pxList;\r
-\r
- ( pxList->uxNumberOfItems )++;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vListInsert( xList *pxList, xListItem *pxNewListItem )\r
-{\r
-volatile xListItem *pxIterator;\r
-portTickType xValueOfInsertion;\r
-\r
- /* Insert the new list item into the list, sorted in ulListItem order. */\r
- xValueOfInsertion = pxNewListItem->xItemValue;\r
-\r
- /* If the list already contains a list item with the same item value then\r
- the new list item should be placed after it. This ensures that TCB's which\r
- are stored in ready lists (all of which have the same ulListItem value)\r
- get an equal share of the CPU. However, if the xItemValue is the same as\r
- the back marker the iteration loop below will not end. This means we need\r
- to guard against this by checking the value first and modifying the\r
- algorithm slightly if necessary. */\r
- if( xValueOfInsertion == portMAX_DELAY )\r
- {\r
- pxIterator = pxList->xListEnd.pxPrevious;\r
- }\r
- else\r
- {\r
- /* *** NOTE ***********************************************************\r
- If you find your application is crashing here then likely causes are:\r
- 1) Stack overflow -\r
- see http://www.freertos.org/Stacks-and-stack-overflow-checking.html\r
- 2) Incorrect interrupt priority assignment, especially on Cortex-M3\r
- parts where numerically high priority values denote low actual\r
- interrupt priories, which can seem counter intuitive. See\r
- configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html\r
- 3) Calling an API function from within a critical section or when\r
- the scheduler is suspended.\r
- 4) Using a queue or semaphore before it has been initialised or\r
- before the scheduler has been started (are interrupts firing\r
- before vTaskStartScheduler() has been called?).\r
- See http://www.freertos.org/FAQHelp.html for more tips.\r
- **********************************************************************/\r
- \r
- for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )\r
- {\r
- /* There is nothing to do here, we are just iterating to the\r
- wanted insertion position. */\r
- }\r
- }\r
-\r
- pxNewListItem->pxNext = pxIterator->pxNext;\r
- pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;\r
- pxNewListItem->pxPrevious = pxIterator;\r
- pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;\r
-\r
- /* Remember which list the item is in. This allows fast removal of the\r
- item later. */\r
- pxNewListItem->pvContainer = ( void * ) pxList;\r
-\r
- ( pxList->uxNumberOfItems )++;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vListRemove( xListItem *pxItemToRemove )\r
-{\r
-xList * pxList;\r
-\r
- pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;\r
- pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;\r
- \r
- /* The list item knows which list it is in. Obtain the list from the list\r
- item. */\r
- pxList = ( xList * ) pxItemToRemove->pvContainer;\r
-\r
- /* Make sure the index is left pointing to a valid item. */\r
- if( pxList->pxIndex == pxItemToRemove )\r
- {\r
- pxList->pxIndex = pxItemToRemove->pxPrevious;\r
- }\r
-\r
- pxItemToRemove->pvContainer = NULL;\r
- ( pxList->uxNumberOfItems )--;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-/*-----------------------------------------------------------\r
- * Implementation of functions defined in portable.h for the ARM CM0 port.\r
- *----------------------------------------------------------*/\r
-\r
-/* Scheduler includes. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-\r
-/* Constants required to manipulate the NVIC. */\r
-#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned long *) 0xe000e010 )\r
-#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned long *) 0xe000e014 )\r
-#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 )\r
-#define portNVIC_SYSPRI2 ( ( volatile unsigned long *) 0xe000ed20 )\r
-#define portNVIC_SYSTICK_CLK 0x00000004\r
-#define portNVIC_SYSTICK_INT 0x00000002\r
-#define portNVIC_SYSTICK_ENABLE 0x00000001\r
-#define portNVIC_PENDSVSET 0x10000000\r
-#define portMIN_INTERRUPT_PRIORITY ( 255UL )\r
-#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )\r
-#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )\r
-\r
-/* Constants required to set up the initial stack. */\r
-#define portINITIAL_XPSR ( 0x01000000 )\r
-\r
-/* Each task maintains its own interrupt status in the critical nesting\r
-variable. */\r
-static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;\r
-\r
-/*\r
- * Setup the timer to generate the tick interrupts.\r
- */\r
-static void prvSetupTimerInterrupt( void );\r
-\r
-/*\r
- * Exception handlers.\r
- */\r
-void PendSV_Handler( void ) __attribute__ (( naked ));\r
-void SysTick_Handler( void );\r
-void SVCall_Handler( void ) __attribute__ (( naked ));\r
-\r
-/*\r
- * Start first task is a separate function so it can be tested in isolation.\r
- */\r
-static void vPortStartFirstTask( void ) __attribute__ (( naked ));\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * See header file for description.\r
- */\r
-portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
-{\r
- /* Simulate the stack frame as it would be created by a context switch\r
- interrupt. */\r
- pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */\r
- *pxTopOfStack = portINITIAL_XPSR; /* xPSR */\r
- pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */\r
- pxTopOfStack -= 6; /* LR, R12, R3..R1 */\r
- *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */\r
- pxTopOfStack -= 8; /* R11..R4. */\r
-\r
- return pxTopOfStack;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void SVCall_Handler( void )\r
-{\r
- __asm volatile (\r
- " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */\r
- " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */\r
- " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */\r
- " add r0, r0, #16 \n" /* Move to the high registers. */\r
- " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */\r
- " mov r8, r4 \n"\r
- " mov r9, r5 \n"\r
- " mov r10, r6 \n"\r
- " mov r11, r7 \n"\r
- " \n"\r
- " msr psp, r0 \n" /* Remember the new top of stack for the task. */\r
- " \n"\r
- " sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */\r
- " ldmia r0!, {r4-r7} \n" /* Pop low registers. */\r
- " mov r1, r14 \n" /* OR R14 with 0x0d. */\r
- " mov r0, #0x0d \n"\r
- " orr r1, r0 \n"\r
- " bx r1 \n"\r
- " \n"\r
- " .align 2 \n"\r
- "pxCurrentTCBConst2: .word pxCurrentTCB \n"\r
- );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vPortStartFirstTask( void )\r
-{\r
- __asm volatile(\r
- " mov r0, #0x00 \n" /* Locate the top of stack. */\r
- " ldr r0, [r0] \n"\r
- " msr msp, r0 \n" /* Set the msp back to the start of the stack. */\r
- " cpsie i \n" /* Globally enable interrupts. */\r
- " svc 0 \n" /* System call to start first task. */\r
- " nop \n"\r
- );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * See header file for description.\r
- */\r
-portBASE_TYPE xPortStartScheduler( void )\r
-{\r
- /* Make PendSV, CallSV and SysTick the same priroity as the kernel. */\r
- *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;\r
- *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;\r
-\r
- /* Start the timer that generates the tick ISR. Interrupts are disabled\r
- here already. */\r
- prvSetupTimerInterrupt();\r
-\r
- /* Initialise the critical nesting count ready for the first task. */\r
- uxCriticalNesting = 0;\r
-\r
- /* Start the first task. */\r
- vPortStartFirstTask();\r
-\r
- /* Should not get here! */\r
- return 0;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vPortEndScheduler( void )\r
-{\r
- /* It is unlikely that the CM0 port will require this function as there\r
- is nothing to return to. */\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vPortYieldFromISR( void )\r
-{\r
- /* Set a PendSV to request a context switch. */\r
- *( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vPortEnterCritical( void )\r
-{\r
- portDISABLE_INTERRUPTS();\r
- uxCriticalNesting++;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vPortExitCritical( void )\r
-{\r
- uxCriticalNesting--;\r
- if( uxCriticalNesting == 0 )\r
- {\r
- portENABLE_INTERRUPTS();\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void PendSV_Handler( void )\r
-{\r
- /* This is a naked function. */\r
-\r
- __asm volatile\r
- (\r
- " mrs r0, psp \n"\r
- " \n"\r
- " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */\r
- " ldr r2, [r3] \n"\r
- " \n"\r
- " sub r0, r0, #32 \n" /* Make space for the remaining low registers. */\r
- " str r0, [r2] \n" /* Save the new top of stack. */\r
- " stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */\r
- " mov r4, r8 \n" /* Store the high registers. */\r
- " mov r5, r9 \n"\r
- " mov r6, r10 \n"\r
- " mov r7, r11 \n"\r
- " stmia r0!, {r4-r7} \n"\r
- " \n"\r
- " push {r3, r14} \n"\r
- " cpsid i \n"\r
- " bl vTaskSwitchContext \n"\r
- " cpsie i \n"\r
- " pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */\r
- " \n"\r
- " ldr r1, [r2] \n"\r
- " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */\r
- " add r0, r0, #16 \n" /* Move to the high registers. */\r
- " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */\r
- " mov r8, r4 \n"\r
- " mov r9, r5 \n"\r
- " mov r10, r6 \n"\r
- " mov r11, r7 \n"\r
- " \n"\r
- " msr psp, r0 \n" /* Remember the new top of stack for the task. */\r
- " \n"\r
- " sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */\r
- " ldmia r0!, {r4-r7} \n" /* Pop low registers. */\r
- " \n"\r
- " bx r3 \n"\r
- " \n"\r
- " .align 2 \n"\r
- "pxCurrentTCBConst: .word pxCurrentTCB "\r
- );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void SysTick_Handler( void )\r
-{\r
-unsigned long ulDummy;\r
-\r
- /* If using preemption, also force a context switch. */\r
- #if configUSE_PREEMPTION == 1\r
- *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
- #endif\r
-\r
- ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();\r
- {\r
- vTaskIncrementTick();\r
- }\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Setup the systick timer to generate the tick interrupts at the required\r
- * frequency.\r
- */\r
-void prvSetupTimerInterrupt( void )\r
-{\r
- /* Configure SysTick to interrupt at the requested rate. */\r
- *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
- *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
- Giancarlo version (corrects inappropriate use of BASEPRI)\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-\r
-#ifndef PORTMACRO_H\r
-#define PORTMACRO_H\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/*-----------------------------------------------------------\r
- * Port specific definitions.\r
- *\r
- * The settings in this file configure FreeRTOS correctly for the\r
- * given hardware and compiler.\r
- *\r
- * These settings should not be altered.\r
- *-----------------------------------------------------------\r
- */\r
-\r
-/* Type definitions. */\r
-#define portCHAR char\r
-#define portFLOAT float\r
-#define portDOUBLE double\r
-#define portLONG long\r
-#define portSHORT short\r
-#define portSTACK_TYPE unsigned portLONG\r
-#define portBASE_TYPE long\r
-\r
-#if( configUSE_16_BIT_TICKS == 1 )\r
- typedef unsigned portSHORT portTickType;\r
- #define portMAX_DELAY ( portTickType ) 0xffff\r
-#else\r
- typedef unsigned portLONG portTickType;\r
- #define portMAX_DELAY ( portTickType ) 0xffffffff\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-/* Architecture specifics. */\r
-#define portSTACK_GROWTH ( -1 )\r
-#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )\r
-#define portBYTE_ALIGNMENT 8\r
-/*-----------------------------------------------------------*/\r
-\r
-\r
-/* Scheduler utilities. */\r
-extern void vPortYieldFromISR( void );\r
-#define portYIELD() vPortYieldFromISR()\r
-#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()\r
-/*-----------------------------------------------------------*/\r
-\r
-\r
-/* Critical section management. */\r
-extern void vPortEnterCritical( void );\r
-extern void vPortExitCritical( void );\r
-#define portSET_INTERRUPT_MASK() __asm volatile ( " cpsid i " )\r
-#define portCLEAR_INTERRUPT_MASK() __asm volatile ( " cpsie i " )\r
-#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()\r
-#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x\r
-#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()\r
-#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()\r
-#define portENTER_CRITICAL() vPortEnterCritical()\r
-#define portEXIT_CRITICAL() vPortExitCritical()\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* Task function macros as described on the FreeRTOS.org WEB site. */\r
-#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
-#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
-\r
-#define portNOP()\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* PORTMACRO_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-\r
-/*\r
- * The simplest possible implementation of pvPortMalloc(). Note that this\r
- * implementation does NOT allow allocated memory to be freed again.\r
- *\r
- * See heap_2.c and heap_3.c for alternative implementations, and the memory\r
- * management pages of http://www.FreeRTOS.org for more information.\r
- */\r
-#include <stdlib.h>\r
-\r
-/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
-all the API functions to use the MPU wrappers. That should only be done when\r
-task.h is included from an application file. */\r
-#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
-\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-\r
-#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
-\r
-/* Allocate the memory for the heap. The struct is used to force byte\r
-alignment without using any non-portable code. */\r
-static union xRTOS_HEAP\r
-{\r
- #if portBYTE_ALIGNMENT == 8\r
- volatile portDOUBLE dDummy;\r
- #else\r
- volatile unsigned long ulDummy;\r
- #endif \r
- unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];\r
-} xHeap;\r
-\r
-static size_t xNextFreeByte = ( size_t ) 0;\r
-/*-----------------------------------------------------------*/\r
-\r
-void *pvPortMalloc( size_t xWantedSize )\r
-{\r
-void *pvReturn = NULL; \r
-\r
- /* Ensure that blocks are always aligned to the required number of bytes. */\r
- #if portBYTE_ALIGNMENT != 1\r
- if( xWantedSize & portBYTE_ALIGNMENT_MASK )\r
- {\r
- /* Byte alignment required. */\r
- xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );\r
- }\r
- #endif\r
-\r
- vTaskSuspendAll();\r
- {\r
- /* Check there is enough room left for the allocation. */\r
- if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) &&\r
- ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */\r
- {\r
- /* Return the next free byte then increment the index past this\r
- block. */\r
- pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] );\r
- xNextFreeByte += xWantedSize; \r
- } \r
- }\r
- xTaskResumeAll();\r
- \r
- #if( configUSE_MALLOC_FAILED_HOOK == 1 )\r
- {\r
- if( pvReturn == NULL )\r
- {\r
- extern void vApplicationMallocFailedHook( void );\r
- vApplicationMallocFailedHook();\r
- }\r
- }\r
- #endif \r
-\r
- return pvReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vPortFree( void *pv )\r
-{\r
- /* Memory cannot be freed using this scheme. See heap_2.c and heap_3.c \r
- for alternative implementations, and the memory management pages of \r
- http://www.FreeRTOS.org for more information. */\r
- ( void ) pv;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vPortInitialiseBlocks( void )\r
-{\r
- /* Only required when static memory is not cleared. */\r
- xNextFreeByte = ( size_t ) 0;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-size_t xPortGetFreeHeapSize( void )\r
-{\r
- return ( configTOTAL_HEAP_SIZE - xNextFreeByte );\r
-}\r
-\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
-all the API functions to use the MPU wrappers. That should only be done when\r
-task.h is included from an application file. */\r
-#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
-\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-\r
-#if ( configUSE_CO_ROUTINES == 1 )\r
- #include "croutine.h"\r
-#endif\r
-\r
-#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
-\r
-/*-----------------------------------------------------------\r
- * PUBLIC LIST API documented in list.h\r
- *----------------------------------------------------------*/\r
-\r
-/* Constants used with the cRxLock and cTxLock structure members. */\r
-#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )\r
-#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )\r
-\r
-#define queueERRONEOUS_UNBLOCK ( -1 )\r
-\r
-/* For internal use only. */\r
-#define queueSEND_TO_BACK ( 0 )\r
-#define queueSEND_TO_FRONT ( 1 )\r
-\r
-/* Effectively make a union out of the xQUEUE structure. */\r
-#define pxMutexHolder pcTail\r
-#define uxQueueType pcHead\r
-#define uxRecursiveCallCount pcReadFrom\r
-#define queueQUEUE_IS_MUTEX NULL\r
-\r
-/* Semaphores do not actually store or copy data, so have an items size of\r
-zero. */\r
-#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 )\r
-#define queueDONT_BLOCK ( ( portTickType ) 0U )\r
-#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0U )\r
-\r
-/* These definitions *must* match those in queue.h. */\r
-#define queueQUEUE_TYPE_BASE ( 0U )\r
-#define queueQUEUE_TYPE_MUTEX ( 1U )\r
-#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )\r
-#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )\r
-#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )\r
-\r
-/*\r
- * Definition of the queue used by the scheduler.\r
- * Items are queued by copy, not reference.\r
- */\r
-typedef struct QueueDefinition\r
-{\r
- signed char *pcHead; /*< Points to the beginning of the queue storage area. */\r
- signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */\r
-\r
- signed char *pcWriteTo; /*< Points to the free next place in the storage area. */\r
- signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */\r
-\r
- xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */\r
- xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */\r
-\r
- volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */\r
- unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */\r
- unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */\r
-\r
- signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */\r
- signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */\r
- \r
- #if ( configUSE_TRACE_FACILITY == 1 )\r
- unsigned char ucQueueNumber;\r
- unsigned char ucQueueType;\r
- #endif\r
-\r
-} xQUEUE;\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Inside this file xQueueHandle is a pointer to a xQUEUE structure.\r
- * To keep the definition private the API header file defines it as a\r
- * pointer to void.\r
- */\r
-typedef xQUEUE * xQueueHandle;\r
-\r
-/*\r
- * Prototypes for public functions are included here so we don't have to\r
- * include the API header file (as it defines xQueueHandle differently). These\r
- * functions are documented in the API header file.\r
- */\r
-xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION;\r
-signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
-unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
-void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;\r
-signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
-signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;\r
-signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;\r
-xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ) PRIVILEGED_FUNCTION;\r
-xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION;\r
-portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION;\r
-portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) PRIVILEGED_FUNCTION;\r
-signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
-signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;\r
-signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
-signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
-unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
-void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
-unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
-void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber ) PRIVILEGED_FUNCTION;\r
-unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
-portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Co-routine queue functions differ from task queue functions. Co-routines are\r
- * an optional component.\r
- */\r
-#if configUSE_CO_ROUTINES == 1\r
- signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION;\r
- signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;\r
- signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
- signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
-#endif\r
-\r
-/*\r
- * The queue registry is just a means for kernel aware debuggers to locate\r
- * queue structures. It has no other purpose so is an optional component.\r
- */\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
-\r
- /* The type stored within the queue registry array. This allows a name\r
- to be assigned to each queue making kernel aware debugging a little\r
- more user friendly. */\r
- typedef struct QUEUE_REGISTRY_ITEM\r
- {\r
- signed char *pcQueueName;\r
- xQueueHandle xHandle;\r
- } xQueueRegistryItem;\r
-\r
- /* The queue registry is simply an array of xQueueRegistryItem structures.\r
- The pcQueueName member of a structure being NULL is indicative of the\r
- array position being vacant. */\r
- xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];\r
-\r
- /* Removes a queue from the registry by simply setting the pcQueueName\r
- member to NULL. */\r
- static void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;\r
- void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) PRIVILEGED_FUNCTION;\r
-#endif\r
-\r
-/*\r
- * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not\r
- * prevent an ISR from adding or removing items to the queue, but does prevent\r
- * an ISR from removing tasks from the queue event lists. If an ISR finds a\r
- * queue is locked it will instead increment the appropriate queue lock count\r
- * to indicate that a task may require unblocking. When the queue in unlocked\r
- * these lock counts are inspected, and the appropriate action taken.\r
- */\r
-static void prvUnlockQueue( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Uses a critical section to determine if there is any data in a queue.\r
- *\r
- * @return pdTRUE if the queue contains no items, otherwise pdFALSE.\r
- */\r
-static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Uses a critical section to determine if there is any space in a queue.\r
- *\r
- * @return pdTRUE if there is no space, otherwise pdFALSE;\r
- */\r
-static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Copies an item into the queue, either at the front of the queue or the\r
- * back of the queue.\r
- */\r
-static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Copies an item out of a queue.\r
- */\r
-static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Macro to mark a queue as locked. Locking a queue prevents an ISR from\r
- * accessing the queue event lists.\r
- */\r
-#define prvLockQueue( pxQueue ) \\r
- taskENTER_CRITICAL(); \\r
- { \\r
- if( ( pxQueue )->xRxLock == queueUNLOCKED ) \\r
- { \\r
- ( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \\r
- } \\r
- if( ( pxQueue )->xTxLock == queueUNLOCKED ) \\r
- { \\r
- ( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \\r
- } \\r
- } \\r
- taskEXIT_CRITICAL()\r
-/*-----------------------------------------------------------*/\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * PUBLIC QUEUE MANAGEMENT API documented in queue.h\r
- *----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue )\r
-{\r
-portBASE_TYPE xReturn = pdPASS;\r
-\r
- configASSERT( pxQueue );\r
-\r
- /* If the queue being reset has already been used (has not just been\r
- created), then only reset the queue if its event lists are empty. */\r
- if( xNewQueue != pdTRUE )\r
- {\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
- {\r
- xReturn = pdFAIL;\r
- }\r
- }\r
-\r
- if( xReturn == pdPASS )\r
- {\r
- pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );\r
- pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;\r
- pxQueue->pcWriteTo = pxQueue->pcHead;\r
- pxQueue->pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize );\r
- pxQueue->xRxLock = queueUNLOCKED;\r
- pxQueue->xTxLock = queueUNLOCKED;\r
-\r
- /* Ensure the event queues start with the correct state. */\r
- vListInitialise( &( pxQueue->xTasksWaitingToSend ) );\r
- vListInitialise( &( pxQueue->xTasksWaitingToReceive ) );\r
- }\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType )\r
-{\r
-xQUEUE *pxNewQueue;\r
-size_t xQueueSizeInBytes;\r
-xQueueHandle xReturn = NULL;\r
-\r
- /* Remove compiler warnings about unused parameters should \r
- configUSE_TRACE_FACILITY not be set to 1. */\r
- ( void ) ucQueueType;\r
-\r
- /* Allocate the new queue structure. */\r
- if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )\r
- {\r
- pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );\r
- if( pxNewQueue != NULL )\r
- {\r
- /* Create the list of pointers to queue items. The queue is one byte\r
- longer than asked for to make wrap checking easier/faster. */\r
- xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1;\r
-\r
- pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes );\r
- if( pxNewQueue->pcHead != NULL )\r
- {\r
- /* Initialise the queue members as described above where the\r
- queue type is defined. */\r
- pxNewQueue->uxLength = uxQueueLength;\r
- pxNewQueue->uxItemSize = uxItemSize;\r
- xQueueGenericReset( pxNewQueue, pdTRUE );\r
- #if ( configUSE_TRACE_FACILITY == 1 )\r
- {\r
- pxNewQueue->ucQueueType = ucQueueType;\r
- }\r
- #endif /* configUSE_TRACE_FACILITY */\r
-\r
- traceQUEUE_CREATE( pxNewQueue );\r
- xReturn = pxNewQueue;\r
- }\r
- else\r
- {\r
- traceQUEUE_CREATE_FAILED( ucQueueType );\r
- vPortFree( pxNewQueue );\r
- }\r
- }\r
- }\r
-\r
- configASSERT( xReturn );\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_MUTEXES == 1 )\r
-\r
- xQueueHandle xQueueCreateMutex( unsigned char ucQueueType )\r
- {\r
- xQUEUE *pxNewQueue;\r
-\r
- /* Prevent compiler warnings about unused parameters if\r
- configUSE_TRACE_FACILITY does not equal 1. */\r
- ( void ) ucQueueType;\r
- \r
- /* Allocate the new queue structure. */\r
- pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );\r
- if( pxNewQueue != NULL )\r
- {\r
- /* Information required for priority inheritance. */\r
- pxNewQueue->pxMutexHolder = NULL;\r
- pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;\r
-\r
- /* Queues used as a mutex no data is actually copied into or out\r
- of the queue. */\r
- pxNewQueue->pcWriteTo = NULL;\r
- pxNewQueue->pcReadFrom = NULL;\r
-\r
- /* Each mutex has a length of 1 (like a binary semaphore) and\r
- an item size of 0 as nothing is actually copied into or out\r
- of the mutex. */\r
- pxNewQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;\r
- pxNewQueue->uxLength = ( unsigned portBASE_TYPE ) 1U;\r
- pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U;\r
- pxNewQueue->xRxLock = queueUNLOCKED;\r
- pxNewQueue->xTxLock = queueUNLOCKED;\r
- \r
- #if ( configUSE_TRACE_FACILITY == 1 )\r
- {\r
- pxNewQueue->ucQueueType = ucQueueType;\r
- }\r
- #endif\r
-\r
- /* Ensure the event queues start with the correct state. */\r
- vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
- vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
-\r
- traceCREATE_MUTEX( pxNewQueue );\r
-\r
- /* Start with the semaphore in the expected state. */\r
- xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK );\r
- }\r
- else\r
- {\r
- traceCREATE_MUTEX_FAILED();\r
- }\r
-\r
- configASSERT( pxNewQueue );\r
- return pxNewQueue;\r
- }\r
-\r
-#endif /* configUSE_MUTEXES */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configUSE_RECURSIVE_MUTEXES == 1\r
-\r
- portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex )\r
- {\r
- portBASE_TYPE xReturn;\r
-\r
- configASSERT( pxMutex );\r
-\r
- /* If this is the task that holds the mutex then pxMutexHolder will not\r
- change outside of this task. If this task does not hold the mutex then\r
- pxMutexHolder can never coincidentally equal the tasks handle, and as\r
- this is the only condition we are interested in it does not matter if\r
- pxMutexHolder is accessed simultaneously by another task. Therefore no\r
- mutual exclusion is required to test the pxMutexHolder variable. */\r
- if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )\r
- {\r
- traceGIVE_MUTEX_RECURSIVE( pxMutex );\r
-\r
- /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to\r
- the task handle, therefore no underflow check is required. Also,\r
- uxRecursiveCallCount is only modified by the mutex holder, and as\r
- there can only be one, no mutual exclusion is required to modify the\r
- uxRecursiveCallCount member. */\r
- ( pxMutex->uxRecursiveCallCount )--;\r
-\r
- /* Have we unwound the call count? */\r
- if( pxMutex->uxRecursiveCallCount == 0 )\r
- {\r
- /* Return the mutex. This will automatically unblock any other\r
- task that might be waiting to access the mutex. */\r
- xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );\r
- }\r
-\r
- xReturn = pdPASS;\r
- }\r
- else\r
- {\r
- /* We cannot give the mutex because we are not the holder. */\r
- xReturn = pdFAIL;\r
-\r
- traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex );\r
- }\r
-\r
- return xReturn;\r
- }\r
-\r
-#endif /* configUSE_RECURSIVE_MUTEXES */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configUSE_RECURSIVE_MUTEXES == 1\r
-\r
- portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime )\r
- {\r
- portBASE_TYPE xReturn;\r
-\r
- configASSERT( pxMutex );\r
-\r
- /* Comments regarding mutual exclusion as per those within\r
- xQueueGiveMutexRecursive(). */\r
-\r
- traceTAKE_MUTEX_RECURSIVE( pxMutex );\r
-\r
- if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )\r
- {\r
- ( pxMutex->uxRecursiveCallCount )++;\r
- xReturn = pdPASS;\r
- }\r
- else\r
- {\r
- xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE );\r
-\r
- /* pdPASS will only be returned if we successfully obtained the mutex,\r
- we may have blocked to reach here. */\r
- if( xReturn == pdPASS )\r
- {\r
- ( pxMutex->uxRecursiveCallCount )++;\r
- }\r
- else\r
- {\r
- traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex );\r
- }\r
- }\r
-\r
- return xReturn;\r
- }\r
-\r
-#endif /* configUSE_RECURSIVE_MUTEXES */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configUSE_COUNTING_SEMAPHORES == 1\r
-\r
- xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )\r
- {\r
- xQueueHandle pxHandle;\r
-\r
- pxHandle = xQueueGenericCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE );\r
-\r
- if( pxHandle != NULL )\r
- {\r
- pxHandle->uxMessagesWaiting = uxInitialCount;\r
-\r
- traceCREATE_COUNTING_SEMAPHORE();\r
- }\r
- else\r
- {\r
- traceCREATE_COUNTING_SEMAPHORE_FAILED();\r
- }\r
-\r
- configASSERT( pxHandle );\r
- return pxHandle;\r
- }\r
-\r
-#endif /* configUSE_COUNTING_SEMAPHORES */\r
-/*-----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
-{\r
-signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
-xTimeOutType xTimeOut;\r
-\r
- configASSERT( pxQueue );\r
- configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
-\r
- /* This function relaxes the coding standard somewhat to allow return\r
- statements within the function itself. This is done in the interest\r
- of execution time efficiency. */\r
- for( ;; )\r
- {\r
- taskENTER_CRITICAL();\r
- {\r
- /* Is there room on the queue now? To be running we must be\r
- the highest priority task wanting to access the queue. */\r
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
- {\r
- traceQUEUE_SEND( pxQueue );\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
-\r
- /* If there was a task waiting for data to arrive on the\r
- queue then unblock it now. */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
- {\r
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )\r
- {\r
- /* The unblocked task has a priority higher than\r
- our own so yield immediately. Yes it is ok to do\r
- this from within the critical section - the kernel\r
- takes care of that. */\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
-\r
- taskEXIT_CRITICAL();\r
-\r
- /* Return to the original privilege level before exiting the\r
- function. */\r
- return pdPASS;\r
- }\r
- else\r
- {\r
- if( xTicksToWait == ( portTickType ) 0 )\r
- {\r
- /* The queue was full and no block time is specified (or\r
- the block time has expired) so leave now. */\r
- taskEXIT_CRITICAL();\r
-\r
- /* Return to the original privilege level before exiting\r
- the function. */\r
- traceQUEUE_SEND_FAILED( pxQueue );\r
- return errQUEUE_FULL;\r
- }\r
- else if( xEntryTimeSet == pdFALSE )\r
- {\r
- /* The queue was full and a block time was specified so\r
- configure the timeout structure. */\r
- vTaskSetTimeOutState( &xTimeOut );\r
- xEntryTimeSet = pdTRUE;\r
- }\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- /* Interrupts and other tasks can send to and receive from the queue\r
- now the critical section has been exited. */\r
-\r
- vTaskSuspendAll();\r
- prvLockQueue( pxQueue );\r
-\r
- /* Update the timeout state to see if it has expired yet. */\r
- if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
- {\r
- if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
- {\r
- traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
- vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
-\r
- /* Unlocking the queue means queue events can effect the\r
- event list. It is possible that interrupts occurring now\r
- remove this task from the event list again - but as the\r
- scheduler is suspended the task will go onto the pending\r
- ready last instead of the actual ready list. */\r
- prvUnlockQueue( pxQueue );\r
-\r
- /* Resuming the scheduler will move tasks from the pending\r
- ready list into the ready list - so it is feasible that this\r
- task is already in a ready list before it yields - in which\r
- case the yield will not cause a context switch unless there\r
- is also a higher priority task in the pending ready list. */\r
- if( xTaskResumeAll() == pdFALSE )\r
- {\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- else\r
- {\r
- /* Try again. */\r
- prvUnlockQueue( pxQueue );\r
- ( void ) xTaskResumeAll();\r
- }\r
- }\r
- else\r
- {\r
- /* The timeout has expired. */\r
- prvUnlockQueue( pxQueue );\r
- ( void ) xTaskResumeAll();\r
-\r
- /* Return to the original privilege level before exiting the\r
- function. */\r
- traceQUEUE_SEND_FAILED( pxQueue );\r
- return errQUEUE_FULL;\r
- }\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configUSE_ALTERNATIVE_API == 1\r
-\r
- signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
- {\r
- signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
- xTimeOutType xTimeOut;\r
-\r
- configASSERT( pxQueue );\r
- configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
-\r
- for( ;; )\r
- {\r
- taskENTER_CRITICAL();\r
- {\r
- /* Is there room on the queue now? To be running we must be\r
- the highest priority task wanting to access the queue. */\r
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
- {\r
- traceQUEUE_SEND( pxQueue );\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
-\r
- /* If there was a task waiting for data to arrive on the\r
- queue then unblock it now. */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
- {\r
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )\r
- {\r
- /* The unblocked task has a priority higher than\r
- our own so yield immediately. */\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
-\r
- taskEXIT_CRITICAL();\r
- return pdPASS;\r
- }\r
- else\r
- {\r
- if( xTicksToWait == ( portTickType ) 0 )\r
- {\r
- taskEXIT_CRITICAL();\r
- return errQUEUE_FULL;\r
- }\r
- else if( xEntryTimeSet == pdFALSE )\r
- {\r
- vTaskSetTimeOutState( &xTimeOut );\r
- xEntryTimeSet = pdTRUE;\r
- }\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- taskENTER_CRITICAL();\r
- {\r
- if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
- {\r
- if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
- {\r
- traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
- vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- else\r
- {\r
- taskEXIT_CRITICAL();\r
- traceQUEUE_SEND_FAILED( pxQueue );\r
- return errQUEUE_FULL;\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
- }\r
- }\r
-\r
-#endif /* configUSE_ALTERNATIVE_API */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configUSE_ALTERNATIVE_API == 1\r
-\r
- signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
- {\r
- signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
- xTimeOutType xTimeOut;\r
- signed char *pcOriginalReadPosition;\r
-\r
- configASSERT( pxQueue );\r
- configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
-\r
- for( ;; )\r
- {\r
- taskENTER_CRITICAL();\r
- {\r
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
- {\r
- /* Remember our read position in case we are just peeking. */\r
- pcOriginalReadPosition = pxQueue->pcReadFrom;\r
-\r
- prvCopyDataFromQueue( pxQueue, pvBuffer );\r
-\r
- if( xJustPeeking == pdFALSE )\r
- {\r
- traceQUEUE_RECEIVE( pxQueue );\r
-\r
- /* We are actually removing data. */\r
- --( pxQueue->uxMessagesWaiting );\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- {\r
- if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
- {\r
- /* Record the information required to implement\r
- priority inheritance should it become necessary. */\r
- pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();\r
- }\r
- }\r
- #endif\r
-\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
- {\r
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
- {\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- }\r
- else\r
- {\r
- traceQUEUE_PEEK( pxQueue );\r
-\r
- /* We are not removing the data, so reset our read\r
- pointer. */\r
- pxQueue->pcReadFrom = pcOriginalReadPosition;\r
-\r
- /* The data is being left in the queue, so see if there are\r
- any other tasks waiting for the data. */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
- {\r
- /* Tasks that are removed from the event list will get added to\r
- the pending ready list as the scheduler is still suspended. */\r
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
- {\r
- /* The task waiting has a higher priority than this task. */\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
-\r
- }\r
-\r
- taskEXIT_CRITICAL();\r
- return pdPASS;\r
- }\r
- else\r
- {\r
- if( xTicksToWait == ( portTickType ) 0 )\r
- {\r
- taskEXIT_CRITICAL();\r
- traceQUEUE_RECEIVE_FAILED( pxQueue );\r
- return errQUEUE_EMPTY;\r
- }\r
- else if( xEntryTimeSet == pdFALSE )\r
- {\r
- vTaskSetTimeOutState( &xTimeOut );\r
- xEntryTimeSet = pdTRUE;\r
- }\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- taskENTER_CRITICAL();\r
- {\r
- if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
- {\r
- if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
- {\r
- traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- {\r
- if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
- {\r
- portENTER_CRITICAL();\r
- vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
- portEXIT_CRITICAL();\r
- }\r
- }\r
- #endif\r
-\r
- vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- else\r
- {\r
- taskEXIT_CRITICAL();\r
- traceQUEUE_RECEIVE_FAILED( pxQueue );\r
- return errQUEUE_EMPTY;\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
- }\r
- }\r
-\r
-\r
-#endif /* configUSE_ALTERNATIVE_API */\r
-/*-----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-unsigned portBASE_TYPE uxSavedInterruptStatus;\r
-\r
- configASSERT( pxQueue );\r
- configASSERT( pxHigherPriorityTaskWoken );\r
- configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
-\r
- /* Similar to xQueueGenericSend, except we don't block if there is no room\r
- in the queue. Also we don't directly wake a task that was blocked on a\r
- queue read, instead we return a flag to say whether a context switch is\r
- required or not (i.e. has a task with a higher priority than us been woken\r
- by this post). */\r
- uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
- {\r
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
- {\r
- traceQUEUE_SEND_FROM_ISR( pxQueue );\r
-\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
-\r
- /* If the queue is locked we do not alter the event list. This will\r
- be done when the queue is unlocked later. */\r
- if( pxQueue->xTxLock == queueUNLOCKED )\r
- {\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
- {\r
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
- {\r
- /* The task waiting has a higher priority so record that a\r
- context switch is required. */\r
- *pxHigherPriorityTaskWoken = pdTRUE;\r
- }\r
- }\r
- }\r
- else\r
- {\r
- /* Increment the lock count so the task that unlocks the queue\r
- knows that data was posted while it was locked. */\r
- ++( pxQueue->xTxLock );\r
- }\r
-\r
- xReturn = pdPASS;\r
- }\r
- else\r
- {\r
- traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );\r
- xReturn = errQUEUE_FULL;\r
- }\r
- }\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
-{\r
-signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
-xTimeOutType xTimeOut;\r
-signed char *pcOriginalReadPosition;\r
-\r
- configASSERT( pxQueue );\r
- configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
-\r
- /* This function relaxes the coding standard somewhat to allow return\r
- statements within the function itself. This is done in the interest\r
- of execution time efficiency. */\r
-\r
- for( ;; )\r
- {\r
- taskENTER_CRITICAL();\r
- {\r
- /* Is there data in the queue now? To be running we must be\r
- the highest priority task wanting to access the queue. */\r
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
- {\r
- /* Remember our read position in case we are just peeking. */\r
- pcOriginalReadPosition = pxQueue->pcReadFrom;\r
-\r
- prvCopyDataFromQueue( pxQueue, pvBuffer );\r
-\r
- if( xJustPeeking == pdFALSE )\r
- {\r
- traceQUEUE_RECEIVE( pxQueue );\r
-\r
- /* We are actually removing data. */\r
- --( pxQueue->uxMessagesWaiting );\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- {\r
- if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
- {\r
- /* Record the information required to implement\r
- priority inheritance should it become necessary. */\r
- pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();\r
- }\r
- }\r
- #endif\r
-\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
- {\r
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
- {\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- }\r
- else\r
- {\r
- traceQUEUE_PEEK( pxQueue );\r
-\r
- /* We are not removing the data, so reset our read\r
- pointer. */\r
- pxQueue->pcReadFrom = pcOriginalReadPosition;\r
-\r
- /* The data is being left in the queue, so see if there are\r
- any other tasks waiting for the data. */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
- {\r
- /* Tasks that are removed from the event list will get added to\r
- the pending ready list as the scheduler is still suspended. */\r
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
- {\r
- /* The task waiting has a higher priority than this task. */\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
-\r
- }\r
-\r
- taskEXIT_CRITICAL();\r
- return pdPASS;\r
- }\r
- else\r
- {\r
- if( xTicksToWait == ( portTickType ) 0 )\r
- {\r
- /* The queue was empty and no block time is specified (or\r
- the block time has expired) so leave now. */\r
- taskEXIT_CRITICAL();\r
- traceQUEUE_RECEIVE_FAILED( pxQueue );\r
- return errQUEUE_EMPTY;\r
- }\r
- else if( xEntryTimeSet == pdFALSE )\r
- {\r
- /* The queue was empty and a block time was specified so\r
- configure the timeout structure. */\r
- vTaskSetTimeOutState( &xTimeOut );\r
- xEntryTimeSet = pdTRUE;\r
- }\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- /* Interrupts and other tasks can send to and receive from the queue\r
- now the critical section has been exited. */\r
-\r
- vTaskSuspendAll();\r
- prvLockQueue( pxQueue );\r
-\r
- /* Update the timeout state to see if it has expired yet. */\r
- if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
- {\r
- if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
- {\r
- traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- {\r
- if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
- {\r
- portENTER_CRITICAL();\r
- {\r
- vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
- }\r
- portEXIT_CRITICAL();\r
- }\r
- }\r
- #endif\r
-\r
- vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
- prvUnlockQueue( pxQueue );\r
- if( xTaskResumeAll() == pdFALSE )\r
- {\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- else\r
- {\r
- /* Try again. */\r
- prvUnlockQueue( pxQueue );\r
- ( void ) xTaskResumeAll();\r
- }\r
- }\r
- else\r
- {\r
- prvUnlockQueue( pxQueue );\r
- ( void ) xTaskResumeAll();\r
- traceQUEUE_RECEIVE_FAILED( pxQueue );\r
- return errQUEUE_EMPTY;\r
- }\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-unsigned portBASE_TYPE uxSavedInterruptStatus;\r
-\r
- configASSERT( pxQueue );\r
- configASSERT( pxTaskWoken );\r
- configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
-\r
- uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
- {\r
- /* We cannot block from an ISR, so check there is data available. */\r
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
- {\r
- traceQUEUE_RECEIVE_FROM_ISR( pxQueue );\r
-\r
- prvCopyDataFromQueue( pxQueue, pvBuffer );\r
- --( pxQueue->uxMessagesWaiting );\r
-\r
- /* If the queue is locked we will not modify the event list. Instead\r
- we update the lock count so the task that unlocks the queue will know\r
- that an ISR has removed data while the queue was locked. */\r
- if( pxQueue->xRxLock == queueUNLOCKED )\r
- {\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
- {\r
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
- {\r
- /* The task waiting has a higher priority than us so\r
- force a context switch. */\r
- *pxTaskWoken = pdTRUE;\r
- }\r
- }\r
- }\r
- else\r
- {\r
- /* Increment the lock count so the task that unlocks the queue\r
- knows that data was removed while it was locked. */\r
- ++( pxQueue->xRxLock );\r
- }\r
-\r
- xReturn = pdPASS;\r
- }\r
- else\r
- {\r
- xReturn = pdFAIL;\r
- traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue );\r
- }\r
- }\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue )\r
-{\r
-unsigned portBASE_TYPE uxReturn;\r
-\r
- configASSERT( pxQueue );\r
-\r
- taskENTER_CRITICAL();\r
- uxReturn = pxQueue->uxMessagesWaiting;\r
- taskEXIT_CRITICAL();\r
-\r
- return uxReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue )\r
-{\r
-unsigned portBASE_TYPE uxReturn;\r
-\r
- configASSERT( pxQueue );\r
-\r
- uxReturn = pxQueue->uxMessagesWaiting;\r
-\r
- return uxReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vQueueDelete( xQueueHandle pxQueue )\r
-{\r
- configASSERT( pxQueue );\r
-\r
- traceQUEUE_DELETE( pxQueue );\r
- vQueueUnregisterQueue( pxQueue );\r
- vPortFree( pxQueue->pcHead );\r
- vPortFree( pxQueue );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-\r
- unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue )\r
- {\r
- return pxQueue->ucQueueNumber;\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-\r
- void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber )\r
- {\r
- pxQueue->ucQueueNumber = ucQueueNumber;\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-\r
- unsigned char ucQueueGetQueueType( xQueueHandle pxQueue )\r
- {\r
- return pxQueue->ucQueueType;\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )\r
-{\r
- if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 )\r
- {\r
- #if ( configUSE_MUTEXES == 1 )\r
- {\r
- if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
- {\r
- /* The mutex is no longer being held. */\r
- vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );\r
- pxQueue->pxMutexHolder = NULL;\r
- }\r
- }\r
- #endif\r
- }\r
- else if( xPosition == queueSEND_TO_BACK )\r
- {\r
- memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );\r
- pxQueue->pcWriteTo += pxQueue->uxItemSize;\r
- if( pxQueue->pcWriteTo >= pxQueue->pcTail )\r
- {\r
- pxQueue->pcWriteTo = pxQueue->pcHead;\r
- }\r
- }\r
- else\r
- {\r
- memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );\r
- pxQueue->pcReadFrom -= pxQueue->uxItemSize;\r
- if( pxQueue->pcReadFrom < pxQueue->pcHead )\r
- {\r
- pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );\r
- }\r
- }\r
-\r
- ++( pxQueue->uxMessagesWaiting );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )\r
-{\r
- if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )\r
- {\r
- pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
- {\r
- pxQueue->pcReadFrom = pxQueue->pcHead;\r
- }\r
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvUnlockQueue( xQueueHandle pxQueue )\r
-{\r
- /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */\r
-\r
- /* The lock counts contains the number of extra data items placed or\r
- removed from the queue while the queue was locked. When a queue is\r
- locked items can be added or removed, but the event lists cannot be\r
- updated. */\r
- taskENTER_CRITICAL();\r
- {\r
- /* See if data was added to the queue while it was locked. */\r
- while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )\r
- {\r
- /* Data was posted while the queue was locked. Are any tasks\r
- blocked waiting for data to become available? */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
- {\r
- /* Tasks that are removed from the event list will get added to\r
- the pending ready list as the scheduler is still suspended. */\r
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
- {\r
- /* The task waiting has a higher priority so record that a\r
- context switch is required. */\r
- vTaskMissedYield();\r
- }\r
-\r
- --( pxQueue->xTxLock );\r
- }\r
- else\r
- {\r
- break;\r
- }\r
- }\r
-\r
- pxQueue->xTxLock = queueUNLOCKED;\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- /* Do the same for the Rx lock. */\r
- taskENTER_CRITICAL();\r
- {\r
- while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )\r
- {\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
- {\r
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
- {\r
- vTaskMissedYield();\r
- }\r
-\r
- --( pxQueue->xRxLock );\r
- }\r
- else\r
- {\r
- break;\r
- }\r
- }\r
-\r
- pxQueue->xRxLock = queueUNLOCKED;\r
- }\r
- taskEXIT_CRITICAL();\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-\r
- taskENTER_CRITICAL();\r
- xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );\r
- taskEXIT_CRITICAL();\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-\r
- configASSERT( pxQueue );\r
- xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-\r
- taskENTER_CRITICAL();\r
- xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );\r
- taskEXIT_CRITICAL();\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-\r
- configASSERT( pxQueue );\r
- xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-\r
- /* If the queue is already full we may have to block. A critical section\r
- is required to prevent an interrupt removing something from the queue\r
- between the check to see if the queue is full and blocking on the queue. */\r
- portDISABLE_INTERRUPTS();\r
- {\r
- if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
- {\r
- /* The queue is full - do we want to block or just leave without\r
- posting? */\r
- if( xTicksToWait > ( portTickType ) 0 )\r
- {\r
- /* As this is called from a coroutine we cannot block directly, but\r
- return indicating that we need to block. */\r
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_BLOCKED;\r
- }\r
- else\r
- {\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_FULL;\r
- }\r
- }\r
- }\r
- portENABLE_INTERRUPTS();\r
-\r
- portNOP();\r
-\r
- portDISABLE_INTERRUPTS();\r
- {\r
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
- {\r
- /* There is room in the queue, copy the data into the queue. */\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
- xReturn = pdPASS;\r
-\r
- /* Were any co-routines waiting for data to become available? */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
- {\r
- /* In this instance the co-routine could be placed directly\r
- into the ready list as we are within a critical section.\r
- Instead the same pending ready list mechanism is used as if\r
- the event were caused from within an interrupt. */\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
- {\r
- /* The co-routine waiting has a higher priority so record\r
- that a yield might be appropriate. */\r
- xReturn = errQUEUE_YIELD;\r
- }\r
- }\r
- }\r
- else\r
- {\r
- xReturn = errQUEUE_FULL;\r
- }\r
- }\r
- portENABLE_INTERRUPTS();\r
-\r
- return xReturn;\r
-}\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-\r
- /* If the queue is already empty we may have to block. A critical section\r
- is required to prevent an interrupt adding something to the queue\r
- between the check to see if the queue is empty and blocking on the queue. */\r
- portDISABLE_INTERRUPTS();\r
- {\r
- if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
- {\r
- /* There are no messages in the queue, do we want to block or just\r
- leave with nothing? */\r
- if( xTicksToWait > ( portTickType ) 0 )\r
- {\r
- /* As this is a co-routine we cannot block directly, but return\r
- indicating that we need to block. */\r
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_BLOCKED;\r
- }\r
- else\r
- {\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_FULL;\r
- }\r
- }\r
- }\r
- portENABLE_INTERRUPTS();\r
-\r
- portNOP();\r
-\r
- portDISABLE_INTERRUPTS();\r
- {\r
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
- {\r
- /* Data is available from the queue. */\r
- pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
- {\r
- pxQueue->pcReadFrom = pxQueue->pcHead;\r
- }\r
- --( pxQueue->uxMessagesWaiting );\r
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
-\r
- xReturn = pdPASS;\r
-\r
- /* Were any co-routines waiting for space to become available? */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
- {\r
- /* In this instance the co-routine could be placed directly\r
- into the ready list as we are within a critical section.\r
- Instead the same pending ready list mechanism is used as if\r
- the event were caused from within an interrupt. */\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
- {\r
- xReturn = errQUEUE_YIELD;\r
- }\r
- }\r
- }\r
- else\r
- {\r
- xReturn = pdFAIL;\r
- }\r
- }\r
- portENABLE_INTERRUPTS();\r
-\r
- return xReturn;\r
-}\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-\r
-\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )\r
-{\r
- /* Cannot block within an ISR so if there is no space on the queue then\r
- exit without doing anything. */\r
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
- {\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
-\r
- /* We only want to wake one co-routine per ISR, so check that a\r
- co-routine has not already been woken. */\r
- if( xCoRoutinePreviouslyWoken == pdFALSE )\r
- {\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
- {\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
- {\r
- return pdTRUE;\r
- }\r
- }\r
- }\r
- }\r
-\r
- return xCoRoutinePreviouslyWoken;\r
-}\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-\r
- /* We cannot block from an ISR, so check there is data available. If\r
- not then just leave without doing anything. */\r
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
- {\r
- /* Copy the data from the queue. */\r
- pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
- {\r
- pxQueue->pcReadFrom = pxQueue->pcHead;\r
- }\r
- --( pxQueue->uxMessagesWaiting );\r
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
-\r
- if( ( *pxCoRoutineWoken ) == pdFALSE )\r
- {\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
- {\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
- {\r
- *pxCoRoutineWoken = pdTRUE;\r
- }\r
- }\r
- }\r
-\r
- xReturn = pdPASS;\r
- }\r
- else\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- return xReturn;\r
-}\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
-\r
- void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )\r
- {\r
- unsigned portBASE_TYPE ux;\r
-\r
- /* See if there is an empty space in the registry. A NULL name denotes\r
- a free slot. */\r
- for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ )\r
- {\r
- if( xQueueRegistry[ ux ].pcQueueName == NULL )\r
- {\r
- /* Store the information on this queue. */\r
- xQueueRegistry[ ux ].pcQueueName = pcQueueName;\r
- xQueueRegistry[ ux ].xHandle = xQueue;\r
- break;\r
- }\r
- }\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
-\r
- static void vQueueUnregisterQueue( xQueueHandle xQueue )\r
- {\r
- unsigned portBASE_TYPE ux;\r
-\r
- /* See if the handle of the queue being unregistered in actually in the\r
- registry. */\r
- for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ )\r
- {\r
- if( xQueueRegistry[ ux ].xHandle == xQueue )\r
- {\r
- /* Set the name to NULL to show that this slot if free again. */\r
- xQueueRegistry[ ux ].pcQueueName = NULL;\r
- break;\r
- }\r
- }\r
-\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configUSE_TIMERS == 1\r
-\r
- void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait )\r
- {\r
- /* This function should not be called by application code hence the\r
- 'Restricted' in its name. It is not part of the public API. It is\r
- designed for use by kernel code, and has special calling requirements.\r
- It can result in vListInsert() being called on a list that can only\r
- possibly ever have one item in it, so the list will be fast, but even\r
- so it should be called with the scheduler locked and not from a critical\r
- section. */\r
-\r
- /* Only do anything if there are no messages in the queue. This function\r
- will not actually cause the task to block, just place it on a blocked\r
- list. It will not block until the scheduler is unlocked - at which\r
- time a yield will be performed. If an item is added to the queue while\r
- the queue is locked, and the calling task blocks on the queue, then the\r
- calling task will be immediately unblocked when the queue is unlocked. */\r
- prvLockQueue( pxQueue );\r
- if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0U )\r
- {\r
- /* There is nothing in the queue, block for the specified period. */\r
- vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
- }\r
- prvUnlockQueue( pxQueue );\r
- }\r
-\r
-#endif\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
-all the API functions to use the MPU wrappers. That should only be done when\r
-task.h is included from an application file. */\r
-#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
-\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "timers.h"\r
-#include "StackMacros.h"\r
-\r
-#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
-\r
-/*\r
- * Macro to define the amount of stack available to the idle task.\r
- */\r
-#define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE\r
-\r
-/*\r
- * Task control block. A task control block (TCB) is allocated to each task,\r
- * and stores the context of the task.\r
- */\r
-typedef struct tskTaskControlBlock\r
-{\r
- volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */\r
-\r
- #if ( portUSING_MPU_WRAPPERS == 1 )\r
- xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */\r
- #endif \r
- \r
- xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */\r
- xListItem xEventListItem; /*< List item used to place the TCB in event lists. */\r
- unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */\r
- portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */\r
- signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */\r
-\r
- #if ( portSTACK_GROWTH > 0 )\r
- portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */\r
- #endif\r
-\r
- #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
- unsigned portBASE_TYPE uxCriticalNesting;\r
- #endif\r
-\r
- #if ( configUSE_TRACE_FACILITY == 1 )\r
- unsigned portBASE_TYPE uxTCBNumber; /*< This 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. */\r
- unsigned portBASE_TYPE uxTaskNumber; /*< This stores a number specifically for use by third party trace code. */\r
- #endif\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */\r
- #endif\r
-\r
- #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
- pdTASK_HOOK_CODE pxTaskTag;\r
- #endif\r
-\r
- #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
- unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */\r
- #endif\r
-\r
-} tskTCB;\r
-\r
-\r
-/*\r
- * Some kernel aware debuggers require data to be viewed to be global, rather\r
- * than file scope.\r
- */\r
-#ifdef portREMOVE_STATIC_QUALIFIER\r
- #define static\r
-#endif\r
-\r
-/*lint -e956 */\r
-PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL;\r
-\r
-/* Lists for ready and blocked tasks. --------------------*/\r
-\r
-PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */\r
-PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */\r
-PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */\r
-PRIVILEGED_DATA static xList * volatile pxDelayedTaskList ; /*< Points to the delayed task list currently being used. */\r
-PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */\r
-PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready queue when the scheduler is resumed. */\r
-\r
-#if ( INCLUDE_vTaskDelete == 1 )\r
-\r
- PRIVILEGED_DATA static xList xTasksWaitingTermination; /*< Tasks that have been deleted - but the their memory not yet freed. */\r
- PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0U;\r
-\r
-#endif\r
-\r
-#if ( INCLUDE_vTaskSuspend == 1 )\r
-\r
- PRIVILEGED_DATA static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */\r
-\r
-#endif\r
-\r
-#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
- \r
- PRIVILEGED_DATA static xTaskHandle xIdleTaskHandle = NULL;\r
- \r
-#endif\r
-\r
-/* File private variables. --------------------------------*/\r
-PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0U;\r
-PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0U;\r
-PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;\r
-PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;\r
-PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;\r
-PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE;\r
-PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0U;\r
-PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;\r
-PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;\r
-PRIVILEGED_DATA static unsigned portBASE_TYPE uxTCBNumber = ( unsigned portBASE_TYPE ) 0U;\r
-PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY;\r
-\r
-#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
-\r
- PRIVILEGED_DATA static char pcStatsString[ 50 ] ;\r
- PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */\r
- static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime ) PRIVILEGED_FUNCTION;\r
-\r
-#endif\r
-\r
-/* Debugging and trace facilities private variables and macros. ------------*/\r
-\r
-/*\r
- * The value used to fill the stack of a task when the task is created. This\r
- * is used purely for checking the high water mark for tasks.\r
- */\r
-#define tskSTACK_FILL_BYTE ( 0xa5U )\r
-\r
-/*\r
- * Macros used by vListTask to indicate which state a task is in.\r
- */\r
-#define tskBLOCKED_CHAR ( ( signed char ) 'B' )\r
-#define tskREADY_CHAR ( ( signed char ) 'R' )\r
-#define tskDELETED_CHAR ( ( signed char ) 'D' )\r
-#define tskSUSPENDED_CHAR ( ( signed char ) 'S' )\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Place the task represented by pxTCB into the appropriate ready queue for\r
- * the task. It is inserted at the end of the list. One quirk of this is\r
- * that if the task being inserted is at the same priority as the currently\r
- * executing task, then it will only be rescheduled after the currently\r
- * executing task has been rescheduled.\r
- */\r
-#define prvAddTaskToReadyQueue( pxTCB ) \\r
- if( ( pxTCB )->uxPriority > uxTopReadyPriority ) \\r
- { \\r
- uxTopReadyPriority = ( pxTCB )->uxPriority; \\r
- } \\r
- vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Macro that looks at the list of tasks that are currently delayed to see if\r
- * any require waking.\r
- *\r
- * Tasks are stored in the queue in the order of their wake time - meaning\r
- * once one tasks has been found whose timer has not expired we need not look\r
- * any further down the list.\r
- */\r
-#define prvCheckDelayedTasks() \\r
-{ \\r
-portTickType xItemValue; \\r
- \\r
- /* Is the tick count greater than or equal to the wake time of the first \\r
- task referenced from the delayed tasks list? */ \\r
- if( xTickCount >= xNextTaskUnblockTime ) \\r
- { \\r
- for( ;; ) \\r
- { \\r
- if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \\r
- { \\r
- /* The delayed list is empty. Set xNextTaskUnblockTime to the \\r
- maximum possible value so it is extremely unlikely that the \\r
- if( xTickCount >= xNextTaskUnblockTime ) test will pass next \\r
- time through. */ \\r
- xNextTaskUnblockTime = portMAX_DELAY; \\r
- break; \\r
- } \\r
- else \\r
- { \\r
- /* The delayed list is not empty, get the value of the item at \\r
- the head of the delayed list. This is the time at which the \\r
- task at the head of the delayed list should be removed from \\r
- the Blocked state. */ \\r
- pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \\r
- xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); \\r
- \\r
- if( xTickCount < xItemValue ) \\r
- { \\r
- /* It is not time to unblock this item yet, but the item \\r
- value is the time at which the task at the head of the \\r
- blocked list should be removed from the Blocked state - \\r
- so record the item value in xNextTaskUnblockTime. */ \\r
- xNextTaskUnblockTime = xItemValue; \\r
- break; \\r
- } \\r
- \\r
- /* It is time to remove the item from the Blocked state. */ \\r
- vListRemove( &( pxTCB->xGenericListItem ) ); \\r
- \\r
- /* Is the task waiting on an event also? */ \\r
- if( pxTCB->xEventListItem.pvContainer != NULL ) \\r
- { \\r
- vListRemove( &( pxTCB->xEventListItem ) ); \\r
- } \\r
- prvAddTaskToReadyQueue( pxTCB ); \\r
- } \\r
- } \\r
- } \\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Several functions take an xTaskHandle parameter that can optionally be NULL,\r
- * where NULL is used to indicate that the handle of the currently executing\r
- * task should be used in place of the parameter. This macro simply checks to\r
- * see if the parameter is NULL and returns a pointer to the appropriate TCB.\r
- */\r
-#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) ( pxHandle ) )\r
-\r
-/* Callback function prototypes. --------------------------*/\r
-extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName );\r
-extern void vApplicationTickHook( void );\r
- \r
-/* File private functions. --------------------------------*/\r
-\r
-/*\r
- * Utility to ready a TCB for a given task. Mainly just copies the parameters\r
- * into the TCB structure.\r
- */\r
-static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Utility to ready all the lists used by the scheduler. This is called\r
- * automatically upon the creation of the first task.\r
- */\r
-static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * The idle task, which as all tasks is implemented as a never ending loop.\r
- * The idle task is automatically created and added to the ready lists upon\r
- * creation of the first user task.\r
- *\r
- * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific\r
- * language extensions. The equivalent prototype for this function is:\r
- *\r
- * void prvIdleTask( void *pvParameters );\r
- *\r
- */\r
-static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );\r
-\r
-/*\r
- * Utility to free all memory allocated by the scheduler to hold a TCB,\r
- * including the stack pointed to by the TCB.\r
- *\r
- * This does not free memory allocated by the task itself (i.e. memory\r
- * allocated by calls to pvPortMalloc from within the tasks application code).\r
- */\r
-#if ( INCLUDE_vTaskDelete == 1 )\r
-\r
- static void prvDeleteTCB( tskTCB *pxTCB ) PRIVILEGED_FUNCTION;\r
-\r
-#endif\r
-\r
-/*\r
- * Used only by the idle task. This checks to see if anything has been placed\r
- * in the list of tasks waiting to be deleted. If so the task is cleaned up\r
- * and its TCB deleted.\r
- */\r
-static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * The currently executing task is entering the Blocked state. Add the task to\r
- * either the current or the overflow delayed task list.\r
- */\r
-static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Allocates memory from the heap for a TCB and associated stack. Checks the\r
- * allocation was successful.\r
- */\r
-static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Called from vTaskList. vListTasks details all the tasks currently under\r
- * control of the scheduler. The tasks may be in one of a number of lists.\r
- * prvListTaskWithinSingleList accepts a list and details the tasks from\r
- * within just that list.\r
- *\r
- * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM\r
- * NORMAL APPLICATION CODE.\r
- */\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-\r
- static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) PRIVILEGED_FUNCTION;\r
-\r
-#endif\r
-\r
-/*\r
- * When a task is created, the stack of the task is filled with a known value.\r
- * This function determines the 'high water mark' of the task stack by\r
- * determining how much of the stack remains at the original preset value.\r
- */\r
-#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
-\r
- static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) PRIVILEGED_FUNCTION;\r
-\r
-#endif\r
-\r
-\r
-/*lint +e956 */\r
-\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * TASK CREATION API documented in task.h\r
- *----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-tskTCB * pxNewTCB;\r
-\r
- configASSERT( pxTaskCode );\r
- configASSERT( ( uxPriority < configMAX_PRIORITIES ) );\r
-\r
- /* Allocate the memory required by the TCB and stack for the new task,\r
- checking that the allocation was successful. */\r
- pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );\r
-\r
- if( pxNewTCB != NULL )\r
- {\r
- portSTACK_TYPE *pxTopOfStack;\r
-\r
- #if( portUSING_MPU_WRAPPERS == 1 )\r
- /* Should the task be created in privileged mode? */\r
- portBASE_TYPE xRunPrivileged;\r
- if( ( uxPriority & portPRIVILEGE_BIT ) != 0U )\r
- {\r
- xRunPrivileged = pdTRUE;\r
- }\r
- else\r
- {\r
- xRunPrivileged = pdFALSE;\r
- }\r
- uxPriority &= ~portPRIVILEGE_BIT;\r
- #endif /* portUSING_MPU_WRAPPERS == 1 */\r
-\r
- /* Calculate the top of stack address. This depends on whether the\r
- stack grows from high memory to low (as per the 80x86) or visa versa.\r
- portSTACK_GROWTH is used to make the result positive or negative as\r
- required by the port. */\r
- #if( portSTACK_GROWTH < 0 )\r
- {\r
- pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( unsigned short ) 1 );\r
- pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) );\r
-\r
- /* Check the alignment of the calculated top of stack is correct. */\r
- configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
- }\r
- #else\r
- {\r
- pxTopOfStack = pxNewTCB->pxStack;\r
- \r
- /* Check the alignment of the stack buffer is correct. */\r
- configASSERT( ( ( ( unsigned long ) pxNewTCB->pxStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
-\r
- /* If we want to use stack checking on architectures that use\r
- a positive stack growth direction then we also need to store the\r
- other extreme of the stack space. */\r
- pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );\r
- }\r
- #endif\r
-\r
- /* Setup the newly allocated TCB with the initial state of the task. */\r
- prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );\r
-\r
- /* Initialize the TCB stack to look as if the task was already running,\r
- but had been interrupted by the scheduler. The return address is set\r
- to the start of the task function. Once the stack has been initialised\r
- the top of stack variable is updated. */\r
- #if( portUSING_MPU_WRAPPERS == 1 )\r
- {\r
- pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );\r
- }\r
- #else\r
- {\r
- pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );\r
- }\r
- #endif\r
-\r
- /* Check the alignment of the initialised stack. */\r
- portALIGNMENT_ASSERT_pxCurrentTCB( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
-\r
- if( ( void * ) pxCreatedTask != NULL )\r
- {\r
- /* Pass the TCB out - in an anonymous way. The calling function/\r
- task can use this as a handle to delete the task later if\r
- required.*/\r
- *pxCreatedTask = ( xTaskHandle ) pxNewTCB;\r
- }\r
- \r
- /* We are going to manipulate the task queues to add this task to a\r
- ready list, so must make sure no interrupts occur. */\r
- taskENTER_CRITICAL();\r
- {\r
- uxCurrentNumberOfTasks++;\r
- if( pxCurrentTCB == NULL )\r
- {\r
- /* There are no other tasks, or all the other tasks are in\r
- the suspended state - make this the current task. */\r
- pxCurrentTCB = pxNewTCB;\r
-\r
- if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 )\r
- {\r
- /* This is the first task to be created so do the preliminary\r
- initialisation required. We will not recover if this call\r
- fails, but we will report the failure. */\r
- prvInitialiseTaskLists();\r
- }\r
- }\r
- else\r
- {\r
- /* If the scheduler is not already running, make this task the\r
- current task if it is the highest priority task to be created\r
- so far. */\r
- if( xSchedulerRunning == pdFALSE )\r
- {\r
- if( pxCurrentTCB->uxPriority <= uxPriority )\r
- {\r
- pxCurrentTCB = pxNewTCB;\r
- }\r
- }\r
- }\r
-\r
- /* Remember the top priority to make context switching faster. Use\r
- the priority in pxNewTCB as this has been capped to a valid value. */\r
- if( pxNewTCB->uxPriority > uxTopUsedPriority )\r
- {\r
- uxTopUsedPriority = pxNewTCB->uxPriority;\r
- }\r
-\r
- #if ( configUSE_TRACE_FACILITY == 1 )\r
- {\r
- /* Add a counter into the TCB for tracing only. */\r
- pxNewTCB->uxTCBNumber = uxTCBNumber;\r
- }\r
- #endif\r
- uxTCBNumber++;\r
-\r
- prvAddTaskToReadyQueue( pxNewTCB );\r
-\r
- xReturn = pdPASS;\r
- traceTASK_CREATE( pxNewTCB );\r
- }\r
- taskEXIT_CRITICAL();\r
- }\r
- else\r
- {\r
- xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;\r
- traceTASK_CREATE_FAILED();\r
- }\r
-\r
- if( xReturn == pdPASS )\r
- {\r
- if( xSchedulerRunning != pdFALSE )\r
- {\r
- /* If the created task is of a higher priority than the current task\r
- then it should run now. */\r
- if( pxCurrentTCB->uxPriority < uxPriority )\r
- {\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- }\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_vTaskDelete == 1 )\r
-\r
- void vTaskDelete( xTaskHandle pxTaskToDelete )\r
- {\r
- tskTCB *pxTCB;\r
-\r
- taskENTER_CRITICAL();\r
- {\r
- /* Ensure a yield is performed if the current task is being\r
- deleted. */\r
- if( pxTaskToDelete == pxCurrentTCB )\r
- {\r
- pxTaskToDelete = NULL;\r
- }\r
-\r
- /* If null is passed in here then we are deleting ourselves. */\r
- pxTCB = prvGetTCBFromHandle( pxTaskToDelete );\r
-\r
- /* Remove task from the ready list and place in the termination list.\r
- This will stop the task from be scheduled. The idle task will check\r
- the termination list and free up any memory allocated by the\r
- scheduler for the TCB and stack. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
-\r
- /* Is the task waiting on an event also? */\r
- if( pxTCB->xEventListItem.pvContainer != NULL )\r
- {\r
- vListRemove( &( pxTCB->xEventListItem ) );\r
- }\r
-\r
- vListInsertEnd( ( xList * ) &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) );\r
-\r
- /* Increment the ucTasksDeleted variable so the idle task knows\r
- there is a task that has been deleted and that it should therefore\r
- check the xTasksWaitingTermination list. */\r
- ++uxTasksDeleted;\r
-\r
- /* Increment the uxTaskNumberVariable also so kernel aware debuggers\r
- can detect that the task lists need re-generating. */\r
- uxTCBNumber++;\r
-\r
- traceTASK_DELETE( pxTCB );\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- /* Force a reschedule if we have just deleted the current task. */\r
- if( xSchedulerRunning != pdFALSE )\r
- {\r
- if( ( void * ) pxTaskToDelete == NULL )\r
- {\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- }\r
-\r
-#endif\r
-\r
-\r
-\r
-\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * TASK CONTROL API documented in task.h\r
- *----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_vTaskDelayUntil == 1 )\r
-\r
- void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement )\r
- {\r
- portTickType xTimeToWake;\r
- portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;\r
-\r
- configASSERT( pxPreviousWakeTime );\r
- configASSERT( ( xTimeIncrement > 0U ) );\r
-\r
- vTaskSuspendAll();\r
- {\r
- /* Generate the tick time at which the task wants to wake. */\r
- xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;\r
-\r
- if( xTickCount < *pxPreviousWakeTime )\r
- {\r
- /* The tick count has overflowed since this function was\r
- lasted called. In this case the only time we should ever\r
- actually delay is if the wake time has also overflowed,\r
- and the wake time is greater than the tick time. When this\r
- is the case it is as if neither time had overflowed. */\r
- if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xTickCount ) )\r
- {\r
- xShouldDelay = pdTRUE;\r
- }\r
- }\r
- else\r
- {\r
- /* The tick time has not overflowed. In this case we will\r
- delay if either the wake time has overflowed, and/or the\r
- tick time is less than the wake time. */\r
- if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) )\r
- {\r
- xShouldDelay = pdTRUE;\r
- }\r
- }\r
-\r
- /* Update the wake time ready for the next call. */\r
- *pxPreviousWakeTime = xTimeToWake;\r
-\r
- if( xShouldDelay != pdFALSE )\r
- {\r
- traceTASK_DELAY_UNTIL();\r
-\r
- /* We must remove ourselves from the ready list before adding\r
- ourselves to the blocked list as the same list item is used for\r
- both lists. */\r
- vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- prvAddCurrentTaskToDelayedList( xTimeToWake );\r
- }\r
- }\r
- xAlreadyYielded = xTaskResumeAll();\r
-\r
- /* Force a reschedule if xTaskResumeAll has not already done so, we may\r
- have put ourselves to sleep. */\r
- if( xAlreadyYielded == pdFALSE )\r
- {\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_vTaskDelay == 1 )\r
-\r
- void vTaskDelay( portTickType xTicksToDelay )\r
- {\r
- portTickType xTimeToWake;\r
- signed portBASE_TYPE xAlreadyYielded = pdFALSE;\r
-\r
- /* A delay time of zero just forces a reschedule. */\r
- if( xTicksToDelay > ( portTickType ) 0U )\r
- {\r
- vTaskSuspendAll();\r
- {\r
- traceTASK_DELAY();\r
-\r
- /* A task that is removed from the event list while the\r
- scheduler is suspended will not get placed in the ready\r
- list or removed from the blocked list until the scheduler\r
- is resumed.\r
-\r
- This task cannot be in an event list as it is the currently\r
- executing task. */\r
-\r
- /* Calculate the time to wake - this may overflow but this is\r
- not a problem. */\r
- xTimeToWake = xTickCount + xTicksToDelay;\r
-\r
- /* We must remove ourselves from the ready list before adding\r
- ourselves to the blocked list as the same list item is used for\r
- both lists. */\r
- vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- prvAddCurrentTaskToDelayedList( xTimeToWake );\r
- }\r
- xAlreadyYielded = xTaskResumeAll();\r
- }\r
-\r
- /* Force a reschedule if xTaskResumeAll has not already done so, we may\r
- have put ourselves to sleep. */\r
- if( xAlreadyYielded == pdFALSE )\r
- {\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_uxTaskPriorityGet == 1 )\r
-\r
- unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask )\r
- {\r
- tskTCB *pxTCB;\r
- unsigned portBASE_TYPE uxReturn;\r
-\r
- taskENTER_CRITICAL();\r
- {\r
- /* If null is passed in here then we are changing the\r
- priority of the calling function. */\r
- pxTCB = prvGetTCBFromHandle( pxTask );\r
- uxReturn = pxTCB->uxPriority;\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- return uxReturn;\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_vTaskPrioritySet == 1 )\r
-\r
- void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )\r
- {\r
- tskTCB *pxTCB;\r
- unsigned portBASE_TYPE uxCurrentPriority;\r
- portBASE_TYPE xYieldRequired = pdFALSE;\r
-\r
- configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );\r
-\r
- /* Ensure the new priority is valid. */\r
- if( uxNewPriority >= configMAX_PRIORITIES )\r
- {\r
- uxNewPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U;\r
- }\r
-\r
- taskENTER_CRITICAL();\r
- {\r
- if( pxTask == pxCurrentTCB )\r
- {\r
- pxTask = NULL;\r
- }\r
-\r
- /* If null is passed in here then we are changing the\r
- priority of the calling function. */\r
- pxTCB = prvGetTCBFromHandle( pxTask );\r
-\r
- traceTASK_PRIORITY_SET( pxTCB, uxNewPriority );\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- {\r
- uxCurrentPriority = pxTCB->uxBasePriority;\r
- }\r
- #else\r
- {\r
- uxCurrentPriority = pxTCB->uxPriority;\r
- }\r
- #endif\r
-\r
- if( uxCurrentPriority != uxNewPriority )\r
- {\r
- /* The priority change may have readied a task of higher\r
- priority than the calling task. */\r
- if( uxNewPriority > uxCurrentPriority )\r
- {\r
- if( pxTask != NULL )\r
- {\r
- /* The priority of another task is being raised. If we\r
- were raising the priority of the currently running task\r
- there would be no need to switch as it must have already\r
- been the highest priority task. */\r
- xYieldRequired = pdTRUE;\r
- }\r
- }\r
- else if( pxTask == NULL )\r
- {\r
- /* Setting our own priority down means there may now be another\r
- task of higher priority that is ready to execute. */\r
- xYieldRequired = pdTRUE;\r
- }\r
-\r
-\r
-\r
- #if ( configUSE_MUTEXES == 1 )\r
- {\r
- /* Only change the priority being used if the task is not\r
- currently using an inherited priority. */\r
- if( pxTCB->uxBasePriority == pxTCB->uxPriority )\r
- {\r
- pxTCB->uxPriority = uxNewPriority;\r
- }\r
-\r
- /* The base priority gets set whatever. */\r
- pxTCB->uxBasePriority = uxNewPriority;\r
- }\r
- #else\r
- {\r
- pxTCB->uxPriority = uxNewPriority;\r
- }\r
- #endif\r
-\r
- listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) );\r
-\r
- /* If the task is in the blocked or suspended list we need do\r
- nothing more than change it's priority variable. However, if\r
- the task is in a ready list it needs to be removed and placed\r
- in the queue appropriate to its new priority. */\r
- if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxCurrentPriority ] ), &( pxTCB->xGenericListItem ) ) )\r
- {\r
- /* The task is currently in its ready list - remove before adding\r
- it to it's new ready list. As we are in a critical section we\r
- can do this even if the scheduler is suspended. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
- prvAddTaskToReadyQueue( pxTCB );\r
- }\r
-\r
- if( xYieldRequired == pdTRUE )\r
- {\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_vTaskSuspend == 1 )\r
-\r
- void vTaskSuspend( xTaskHandle pxTaskToSuspend )\r
- {\r
- tskTCB *pxTCB;\r
-\r
- taskENTER_CRITICAL();\r
- {\r
- /* Ensure a yield is performed if the current task is being\r
- suspended. */\r
- if( pxTaskToSuspend == pxCurrentTCB )\r
- {\r
- pxTaskToSuspend = NULL;\r
- }\r
-\r
- /* If null is passed in here then we are suspending ourselves. */\r
- pxTCB = prvGetTCBFromHandle( pxTaskToSuspend );\r
-\r
- traceTASK_SUSPEND( pxTCB );\r
-\r
- /* Remove task from the ready/delayed list and place in the suspended list. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
-\r
- /* Is the task waiting on an event also? */\r
- if( pxTCB->xEventListItem.pvContainer != NULL )\r
- {\r
- vListRemove( &( pxTCB->xEventListItem ) );\r
- }\r
-\r
- vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- if( ( void * ) pxTaskToSuspend == NULL )\r
- {\r
- if( xSchedulerRunning != pdFALSE )\r
- {\r
- /* We have just suspended the current task. */\r
- portYIELD_WITHIN_API();\r
- }\r
- else\r
- {\r
- /* The scheduler is not running, but the task that was pointed\r
- to by pxCurrentTCB has just been suspended and pxCurrentTCB\r
- must be adjusted to point to a different task. */\r
- if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )\r
- {\r
- /* No other tasks are ready, so set pxCurrentTCB back to\r
- NULL so when the next task is created pxCurrentTCB will\r
- be set to point to it no matter what its relative priority\r
- is. */\r
- pxCurrentTCB = NULL;\r
- }\r
- else\r
- {\r
- vTaskSwitchContext();\r
- }\r
- }\r
- }\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_vTaskSuspend == 1 )\r
-\r
- signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask )\r
- {\r
- portBASE_TYPE xReturn = pdFALSE;\r
- const tskTCB * const pxTCB = ( tskTCB * ) xTask;\r
-\r
- /* It does not make sense to check if the calling task is suspended. */\r
- configASSERT( xTask );\r
-\r
- /* Is the task we are attempting to resume actually in the\r
- suspended list? */\r
- if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
- {\r
- /* Has the task already been resumed from within an ISR? */\r
- if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
- {\r
- /* Is it in the suspended list because it is in the\r
- Suspended state? It is possible to be in the suspended\r
- list because it is blocked on a task with no timeout\r
- specified. */\r
- if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE )\r
- {\r
- xReturn = pdTRUE;\r
- }\r
- }\r
- }\r
-\r
- return xReturn;\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_vTaskSuspend == 1 )\r
-\r
- void vTaskResume( xTaskHandle pxTaskToResume )\r
- {\r
- tskTCB *pxTCB;\r
-\r
- /* It does not make sense to resume the calling task. */\r
- configASSERT( pxTaskToResume );\r
-\r
- /* Remove the task from whichever list it is currently in, and place\r
- it in the ready list. */\r
- pxTCB = ( tskTCB * ) pxTaskToResume;\r
-\r
- /* The parameter cannot be NULL as it is impossible to resume the\r
- currently executing task. */\r
- if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )\r
- {\r
- taskENTER_CRITICAL();\r
- {\r
- if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )\r
- {\r
- traceTASK_RESUME( pxTCB );\r
-\r
- /* As we are in a critical section we can access the ready\r
- lists even if the scheduler is suspended. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
- prvAddTaskToReadyQueue( pxTCB );\r
-\r
- /* We may have just resumed a higher priority task. */\r
- if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
- {\r
- /* This yield may not cause the task just resumed to run, but\r
- will leave the lists in the correct state for the next yield. */\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
- }\r
- }\r
-\r
-#endif\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )\r
-\r
- portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume )\r
- {\r
- portBASE_TYPE xYieldRequired = pdFALSE;\r
- tskTCB *pxTCB;\r
- unsigned portBASE_TYPE uxSavedInterruptStatus;\r
-\r
- configASSERT( pxTaskToResume );\r
-\r
- pxTCB = ( tskTCB * ) pxTaskToResume;\r
-\r
- uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
- {\r
- if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )\r
- {\r
- traceTASK_RESUME_FROM_ISR( pxTCB );\r
-\r
- if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
- {\r
- xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
- prvAddTaskToReadyQueue( pxTCB );\r
- }\r
- else\r
- {\r
- /* We cannot access the delayed or ready lists, so will hold this\r
- task pending until the scheduler is resumed, at which point a\r
- yield will be performed if necessary. */\r
- vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
- }\r
- }\r
- }\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
-\r
- return xYieldRequired;\r
- }\r
-\r
-#endif\r
-\r
-\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * PUBLIC SCHEDULER CONTROL documented in task.h\r
- *----------------------------------------------------------*/\r
-\r
-\r
-void vTaskStartScheduler( void )\r
-{\r
-portBASE_TYPE xReturn;\r
-\r
- /* Add the idle task at the lowest priority. */\r
- #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
- {\r
- /* Create the idle task, storing its handle in xIdleTaskHandle so it can\r
- be returned by the xTaskGetIdleTaskHandle() function. */\r
- xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle );\r
- }\r
- #else\r
- {\r
- /* Create the idle task without storing its handle. */\r
- xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL );\r
- }\r
- #endif\r
-\r
- #if ( configUSE_TIMERS == 1 )\r
- {\r
- if( xReturn == pdPASS )\r
- {\r
- xReturn = xTimerCreateTimerTask();\r
- }\r
- }\r
- #endif\r
-\r
- if( xReturn == pdPASS )\r
- {\r
- /* Interrupts are turned off here, to ensure a tick does not occur\r
- before or during the call to xPortStartScheduler(). The stacks of\r
- the created tasks contain a status word with interrupts switched on\r
- so interrupts will automatically get re-enabled when the first task\r
- starts to run.\r
-\r
- STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE\r
- DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */\r
- portDISABLE_INTERRUPTS();\r
-\r
- xSchedulerRunning = pdTRUE;\r
- xTickCount = ( portTickType ) 0U;\r
-\r
- /* If configGENERATE_RUN_TIME_STATS is defined then the following\r
- macro must be defined to configure the timer/counter used to generate\r
- the run time counter time base. */\r
- portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();\r
- \r
- /* Setting up the timer tick is hardware specific and thus in the\r
- portable interface. */\r
- if( xPortStartScheduler() != pdFALSE )\r
- {\r
- /* Should not reach here as if the scheduler is running the\r
- function will not return. */\r
- }\r
- else\r
- {\r
- /* Should only reach here if a task calls xTaskEndScheduler(). */\r
- }\r
- }\r
-\r
- /* This line will only be reached if the kernel could not be started. */\r
- configASSERT( xReturn );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vTaskEndScheduler( void )\r
-{\r
- /* Stop the scheduler interrupts and call the portable scheduler end\r
- routine so the original ISRs can be restored if necessary. The port\r
- layer must ensure interrupts enable bit is left in the correct state. */\r
- portDISABLE_INTERRUPTS();\r
- xSchedulerRunning = pdFALSE;\r
- vPortEndScheduler();\r
-}\r
-/*----------------------------------------------------------*/\r
-\r
-void vTaskSuspendAll( void )\r
-{\r
- /* A critical section is not required as the variable is of type\r
- portBASE_TYPE. */\r
- ++uxSchedulerSuspended;\r
-}\r
-/*----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xTaskResumeAll( void )\r
-{\r
-register tskTCB *pxTCB;\r
-signed portBASE_TYPE xAlreadyYielded = pdFALSE;\r
-\r
- /* If uxSchedulerSuspended is zero then this function does not match a\r
- previous call to vTaskSuspendAll(). */\r
- configASSERT( uxSchedulerSuspended );\r
-\r
- /* It is possible that an ISR caused a task to be removed from an event\r
- list while the scheduler was suspended. If this was the case then the\r
- removed task will have been added to the xPendingReadyList. Once the\r
- scheduler has been resumed it is safe to move all the pending ready\r
- tasks from this list into their appropriate ready list. */\r
- taskENTER_CRITICAL();\r
- {\r
- --uxSchedulerSuspended;\r
-\r
- if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
- {\r
- if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0U )\r
- {\r
- portBASE_TYPE xYieldRequired = pdFALSE;\r
-\r
- /* Move any readied tasks from the pending list into the\r
- appropriate ready list. */\r
- while( listLIST_IS_EMPTY( ( xList * ) &xPendingReadyList ) == pdFALSE )\r
- {\r
- pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) );\r
- vListRemove( &( pxTCB->xEventListItem ) );\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
- prvAddTaskToReadyQueue( pxTCB );\r
-\r
- /* If we have moved a task that has a priority higher than\r
- the current task then we should yield. */\r
- if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
- {\r
- xYieldRequired = pdTRUE;\r
- }\r
- }\r
-\r
- /* If any ticks occurred while the scheduler was suspended then\r
- they should be processed now. This ensures the tick count does not\r
- slip, and that any delayed tasks are resumed at the correct time. */\r
- if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0U )\r
- {\r
- while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0U )\r
- {\r
- vTaskIncrementTick();\r
- --uxMissedTicks;\r
- }\r
-\r
- /* As we have processed some ticks it is appropriate to yield\r
- to ensure the highest priority task that is ready to run is\r
- the task actually running. */\r
- #if configUSE_PREEMPTION == 1\r
- {\r
- xYieldRequired = pdTRUE;\r
- }\r
- #endif\r
- }\r
-\r
- if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) )\r
- {\r
- xAlreadyYielded = pdTRUE;\r
- xMissedYield = pdFALSE;\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- return xAlreadyYielded;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * PUBLIC TASK UTILITIES documented in task.h\r
- *----------------------------------------------------------*/\r
-\r
-\r
-\r
-portTickType xTaskGetTickCount( void )\r
-{\r
-portTickType xTicks;\r
-\r
- /* Critical section required if running on a 16 bit processor. */\r
- taskENTER_CRITICAL();\r
- {\r
- xTicks = xTickCount;\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- return xTicks;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portTickType xTaskGetTickCountFromISR( void )\r
-{\r
-portTickType xReturn;\r
-unsigned portBASE_TYPE uxSavedInterruptStatus;\r
-\r
- uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
- xReturn = xTickCount;\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )\r
-{\r
- /* A critical section is not required because the variables are of type\r
- portBASE_TYPE. */\r
- return uxCurrentNumberOfTasks;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_pcTaskGetTaskName == 1 )\r
-\r
- signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery )\r
- {\r
- tskTCB *pxTCB;\r
-\r
- /* If null is passed in here then the name of the calling task is being queried. */\r
- pxTCB = prvGetTCBFromHandle( xTaskToQuery );\r
- configASSERT( pxTCB );\r
- return &( pxTCB->pcTaskName[ 0 ] );\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-\r
- void vTaskList( signed char *pcWriteBuffer )\r
- {\r
- unsigned portBASE_TYPE uxQueue;\r
-\r
- /* This is a VERY costly function that should be used for debug only.\r
- It leaves interrupts disabled for a LONG time. */\r
-\r
- vTaskSuspendAll();\r
- {\r
- /* Run through all the lists that could potentially contain a TCB and\r
- report the task name, state and stack high water mark. */\r
-\r
- *pcWriteBuffer = ( signed char ) 0x00;\r
- strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );\r
-\r
- uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U;\r
-\r
- do\r
- {\r
- uxQueue--;\r
-\r
- if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE )\r
- {\r
- prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR );\r
- }\r
- }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );\r
-\r
- if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE )\r
- {\r
- prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR );\r
- }\r
-\r
- if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE )\r
- {\r
- prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR );\r
- }\r
-\r
- #if( INCLUDE_vTaskDelete == 1 )\r
- {\r
- if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE )\r
- {\r
- prvListTaskWithinSingleList( pcWriteBuffer, &xTasksWaitingTermination, tskDELETED_CHAR );\r
- }\r
- }\r
- #endif\r
-\r
- #if ( INCLUDE_vTaskSuspend == 1 )\r
- {\r
- if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE )\r
- {\r
- prvListTaskWithinSingleList( pcWriteBuffer, &xSuspendedTaskList, tskSUSPENDED_CHAR );\r
- }\r
- }\r
- #endif\r
- }\r
- xTaskResumeAll();\r
- }\r
-\r
-#endif\r
-/*----------------------------------------------------------*/\r
-\r
-#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
-\r
- void vTaskGetRunTimeStats( signed char *pcWriteBuffer )\r
- {\r
- unsigned portBASE_TYPE uxQueue;\r
- unsigned long ulTotalRunTime;\r
-\r
- /* This is a VERY costly function that should be used for debug only.\r
- It leaves interrupts disabled for a LONG time. */\r
-\r
- vTaskSuspendAll();\r
- {\r
- #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
- portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );\r
- #else\r
- ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();\r
- #endif\r
-\r
- /* Divide ulTotalRunTime by 100 to make the percentage caluclations\r
- simpler in the prvGenerateRunTimeStatsForTasksInList() function. */\r
- ulTotalRunTime /= 100UL;\r
- \r
- /* Run through all the lists that could potentially contain a TCB,\r
- generating a table of run timer percentages in the provided\r
- buffer. */\r
-\r
- *pcWriteBuffer = ( signed char ) 0x00;\r
- strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );\r
-\r
- uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U;\r
-\r
- do\r
- {\r
- uxQueue--;\r
-\r
- if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE )\r
- {\r
- prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), ulTotalRunTime );\r
- }\r
- }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );\r
-\r
- if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE )\r
- {\r
- prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, ulTotalRunTime );\r
- }\r
-\r
- if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE )\r
- {\r
- prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, ulTotalRunTime );\r
- }\r
-\r
- #if ( INCLUDE_vTaskDelete == 1 )\r
- {\r
- if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE )\r
- {\r
- prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, &xTasksWaitingTermination, ulTotalRunTime );\r
- }\r
- }\r
- #endif\r
-\r
- #if ( INCLUDE_vTaskSuspend == 1 )\r
- {\r
- if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE )\r
- {\r
- prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, &xSuspendedTaskList, ulTotalRunTime );\r
- }\r
- }\r
- #endif\r
- }\r
- xTaskResumeAll();\r
- }\r
-\r
-#endif\r
-/*----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
-\r
- xTaskHandle xTaskGetIdleTaskHandle( void )\r
- {\r
- /* If xTaskGetIdleTaskHandle() is called before the scheduler has been\r
- started, then xIdleTaskHandle will be NULL. */\r
- configASSERT( ( xIdleTaskHandle != NULL ) );\r
- return xIdleTaskHandle;\r
- }\r
- \r
-#endif\r
-\r
-/*-----------------------------------------------------------\r
- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES\r
- * documented in task.h\r
- *----------------------------------------------------------*/\r
-\r
-void vTaskIncrementTick( void )\r
-{\r
-tskTCB * pxTCB;\r
-\r
- /* Called by the portable layer each time a tick interrupt occurs.\r
- Increments the tick then checks to see if the new tick value will cause any\r
- tasks to be unblocked. */\r
- if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
- {\r
- ++xTickCount;\r
- if( xTickCount == ( portTickType ) 0U )\r
- {\r
- xList *pxTemp;\r
-\r
- /* Tick count has overflowed so we need to swap the delay lists.\r
- If there are any items in pxDelayedTaskList here then there is\r
- an error! */\r
- configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) );\r
- \r
- pxTemp = pxDelayedTaskList;\r
- pxDelayedTaskList = pxOverflowDelayedTaskList;\r
- pxOverflowDelayedTaskList = pxTemp;\r
- xNumOfOverflows++;\r
- \r
- if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )\r
- {\r
- /* The new current delayed list is empty. Set\r
- xNextTaskUnblockTime to the maximum possible value so it is\r
- extremely unlikely that the \r
- if( xTickCount >= xNextTaskUnblockTime ) test will pass until\r
- there is an item in the delayed list. */\r
- xNextTaskUnblockTime = portMAX_DELAY;\r
- }\r
- else\r
- {\r
- /* The new current delayed list is not empty, get the value of\r
- the item at the head of the delayed list. This is the time at\r
- which the task at the head of the delayed list should be removed\r
- from the Blocked state. */\r
- pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );\r
- xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );\r
- }\r
- }\r
-\r
- /* See if this tick has made a timeout expire. */\r
- prvCheckDelayedTasks();\r
- }\r
- else\r
- {\r
- ++uxMissedTicks;\r
-\r
- /* The tick hook gets called at regular intervals, even if the\r
- scheduler is locked. */\r
- #if ( configUSE_TICK_HOOK == 1 )\r
- {\r
- vApplicationTickHook();\r
- }\r
- #endif\r
- }\r
-\r
- #if ( configUSE_TICK_HOOK == 1 )\r
- {\r
- /* Guard against the tick hook being called when the missed tick\r
- count is being unwound (when the scheduler is being unlocked. */\r
- if( uxMissedTicks == ( unsigned portBASE_TYPE ) 0U )\r
- {\r
- vApplicationTickHook();\r
- }\r
- }\r
- #endif\r
-\r
- traceTASK_INCREMENT_TICK( xTickCount );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
-\r
- void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction )\r
- {\r
- tskTCB *xTCB;\r
-\r
- /* If xTask is NULL then we are setting our own task hook. */\r
- if( xTask == NULL )\r
- {\r
- xTCB = ( tskTCB * ) pxCurrentTCB;\r
- }\r
- else\r
- {\r
- xTCB = ( tskTCB * ) xTask;\r
- }\r
-\r
- /* Save the hook function in the TCB. A critical section is required as\r
- the value can be accessed from an interrupt. */\r
- taskENTER_CRITICAL();\r
- xTCB->pxTaskTag = pxHookFunction;\r
- taskEXIT_CRITICAL();\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
-\r
- pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask )\r
- {\r
- tskTCB *xTCB;\r
- pdTASK_HOOK_CODE xReturn;\r
-\r
- /* If xTask is NULL then we are setting our own task hook. */\r
- if( xTask == NULL )\r
- {\r
- xTCB = ( tskTCB * ) pxCurrentTCB;\r
- }\r
- else\r
- {\r
- xTCB = ( tskTCB * ) xTask;\r
- }\r
-\r
- /* Save the hook function in the TCB. A critical section is required as\r
- the value can be accessed from an interrupt. */\r
- taskENTER_CRITICAL();\r
- xReturn = xTCB->pxTaskTag;\r
- taskEXIT_CRITICAL();\r
-\r
- return xReturn;\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
-\r
- portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter )\r
- {\r
- tskTCB *xTCB;\r
- portBASE_TYPE xReturn;\r
-\r
- /* If xTask is NULL then we are calling our own task hook. */\r
- if( xTask == NULL )\r
- {\r
- xTCB = ( tskTCB * ) pxCurrentTCB;\r
- }\r
- else\r
- {\r
- xTCB = ( tskTCB * ) xTask;\r
- }\r
-\r
- if( xTCB->pxTaskTag != NULL )\r
- {\r
- xReturn = xTCB->pxTaskTag( pvParameter );\r
- }\r
- else\r
- {\r
- xReturn = pdFAIL;\r
- }\r
-\r
- return xReturn;\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-void vTaskSwitchContext( void )\r
-{\r
- if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE )\r
- {\r
- /* The scheduler is currently suspended - do not allow a context\r
- switch. */\r
- xMissedYield = pdTRUE;\r
- }\r
- else\r
- {\r
- traceTASK_SWITCHED_OUT();\r
- \r
- #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
- {\r
- unsigned long ulTempCounter;\r
- \r
- #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
- portALT_GET_RUN_TIME_COUNTER_VALUE( ulTempCounter );\r
- #else\r
- ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE();\r
- #endif\r
- \r
- /* Add the amount of time the task has been running to the accumulated\r
- time so far. The time the task started running was stored in\r
- ulTaskSwitchedInTime. Note that there is no overflow protection here\r
- so count values are only valid until the timer overflows. Generally\r
- this will be about 1 hour assuming a 1uS timer increment. */\r
- pxCurrentTCB->ulRunTimeCounter += ( ulTempCounter - ulTaskSwitchedInTime );\r
- ulTaskSwitchedInTime = ulTempCounter;\r
- }\r
- #endif\r
- \r
- taskFIRST_CHECK_FOR_STACK_OVERFLOW();\r
- taskSECOND_CHECK_FOR_STACK_OVERFLOW();\r
- \r
- /* Find the highest priority queue that contains ready tasks. */\r
- while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )\r
- {\r
- configASSERT( uxTopReadyPriority );\r
- --uxTopReadyPriority;\r
- }\r
- \r
- /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the\r
- same priority get an equal share of the processor time. */\r
- listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );\r
- \r
- traceTASK_SWITCHED_IN();\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )\r
-{\r
-portTickType xTimeToWake;\r
-\r
- configASSERT( pxEventList );\r
-\r
- /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE\r
- SCHEDULER SUSPENDED. */\r
-\r
- /* Place the event list item of the TCB in the appropriate event list.\r
- This is placed in the list in priority order so the highest priority task\r
- is the first to be woken by the event. */\r
- vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) );\r
-\r
- /* We must remove ourselves from the ready list before adding ourselves\r
- to the blocked list as the same list item is used for both lists. We have\r
- exclusive access to the ready lists as the scheduler is locked. */\r
- vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
-\r
-\r
- #if ( INCLUDE_vTaskSuspend == 1 )\r
- {\r
- if( xTicksToWait == portMAX_DELAY )\r
- {\r
- /* Add ourselves to the suspended task list instead of a delayed task\r
- list to ensure we are not woken by a timing event. We will block\r
- indefinitely. */\r
- vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- }\r
- else\r
- {\r
- /* Calculate the time at which the task should be woken if the event does\r
- not occur. This may overflow but this doesn't matter. */\r
- xTimeToWake = xTickCount + xTicksToWait;\r
- prvAddCurrentTaskToDelayedList( xTimeToWake );\r
- }\r
- }\r
- #else\r
- {\r
- /* Calculate the time at which the task should be woken if the event does\r
- not occur. This may overflow but this doesn't matter. */\r
- xTimeToWake = xTickCount + xTicksToWait;\r
- prvAddCurrentTaskToDelayedList( xTimeToWake );\r
- }\r
- #endif\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if configUSE_TIMERS == 1\r
-\r
- void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait )\r
- {\r
- portTickType xTimeToWake;\r
-\r
- configASSERT( pxEventList );\r
-\r
- /* This function should not be called by application code hence the\r
- 'Restricted' in its name. It is not part of the public API. It is\r
- designed for use by kernel code, and has special calling requirements -\r
- it should be called from a critical section. */\r
-\r
- \r
- /* Place the event list item of the TCB in the appropriate event list.\r
- In this case it is assume that this is the only task that is going to\r
- be waiting on this event list, so the faster vListInsertEnd() function\r
- can be used in place of vListInsert. */\r
- vListInsertEnd( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) );\r
-\r
- /* We must remove this task from the ready list before adding it to the\r
- blocked list as the same list item is used for both lists. This\r
- function is called form a critical section. */\r
- vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
-\r
- /* Calculate the time at which the task should be woken if the event does\r
- not occur. This may overflow but this doesn't matter. */\r
- xTimeToWake = xTickCount + xTicksToWait;\r
- prvAddCurrentTaskToDelayedList( xTimeToWake );\r
- }\r
- \r
-#endif /* configUSE_TIMERS */\r
-/*-----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )\r
-{\r
-tskTCB *pxUnblockedTCB;\r
-portBASE_TYPE xReturn;\r
-\r
- /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE\r
- SCHEDULER SUSPENDED. It can also be called from within an ISR. */\r
-\r
- /* The event list is sorted in priority order, so we can remove the\r
- first in the list, remove the TCB from the delayed list, and add\r
- it to the ready list.\r
-\r
- If an event is for a queue that is locked then this function will never\r
- get called - the lock count on the queue will get modified instead. This\r
- means we can always expect exclusive access to the event list here.\r
- \r
- This function assumes that a check has already been made to ensure that\r
- pxEventList is not empty. */\r
- pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );\r
- configASSERT( pxUnblockedTCB );\r
- vListRemove( &( pxUnblockedTCB->xEventListItem ) );\r
-\r
- if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
- {\r
- vListRemove( &( pxUnblockedTCB->xGenericListItem ) );\r
- prvAddTaskToReadyQueue( pxUnblockedTCB );\r
- }\r
- else\r
- {\r
- /* We cannot access the delayed or ready lists, so will hold this\r
- task pending until the scheduler is resumed. */\r
- vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );\r
- }\r
-\r
- if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
- {\r
- /* Return true if the task removed from the event list has\r
- a higher priority than the calling task. This allows\r
- the calling task to know if it should force a context\r
- switch now. */\r
- xReturn = pdTRUE;\r
- }\r
- else\r
- {\r
- xReturn = pdFALSE;\r
- }\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut )\r
-{\r
- configASSERT( pxTimeOut );\r
- pxTimeOut->xOverflowCount = xNumOfOverflows;\r
- pxTimeOut->xTimeOnEntering = xTickCount;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait )\r
-{\r
-portBASE_TYPE xReturn;\r
-\r
- configASSERT( pxTimeOut );\r
- configASSERT( pxTicksToWait );\r
-\r
- taskENTER_CRITICAL();\r
- {\r
- #if ( INCLUDE_vTaskSuspend == 1 )\r
- /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is\r
- the maximum block time then the task should block indefinitely, and\r
- therefore never time out. */\r
- if( *pxTicksToWait == portMAX_DELAY )\r
- {\r
- xReturn = pdFALSE;\r
- }\r
- else /* We are not blocking indefinitely, perform the checks below. */\r
- #endif\r
-\r
- if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) )\r
- {\r
- /* The tick count is greater than the time at which vTaskSetTimeout()\r
- was called, but has also overflowed since vTaskSetTimeOut() was called.\r
- It must have wrapped all the way around and gone past us again. This\r
- passed since vTaskSetTimeout() was called. */\r
- xReturn = pdTRUE;\r
- }\r
- else if( ( ( portTickType ) ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait )\r
- {\r
- /* Not a genuine timeout. Adjust parameters for time remaining. */\r
- *pxTicksToWait -= ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering );\r
- vTaskSetTimeOutState( pxTimeOut );\r
- xReturn = pdFALSE;\r
- }\r
- else\r
- {\r
- xReturn = pdTRUE;\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vTaskMissedYield( void )\r
-{\r
- xMissedYield = pdTRUE;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
- unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask )\r
- {\r
- unsigned portBASE_TYPE uxReturn;\r
- tskTCB *pxTCB;\r
- \r
- if( xTask != NULL )\r
- {\r
- pxTCB = ( tskTCB * ) xTask;\r
- uxReturn = pxTCB->uxTaskNumber;\r
- }\r
- else\r
- {\r
- uxReturn = 0U;\r
- }\r
- \r
- return uxReturn;\r
- }\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
- void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle )\r
- {\r
- tskTCB *pxTCB;\r
- \r
- if( xTask != NULL )\r
- {\r
- pxTCB = ( tskTCB * ) xTask;\r
- pxTCB->uxTaskNumber = uxHandle;\r
- }\r
- }\r
-#endif\r
-\r
-\r
-/*\r
- * -----------------------------------------------------------\r
- * The Idle task.\r
- * ----------------------------------------------------------\r
- *\r
- * The portTASK_FUNCTION() macro is used to allow port/compiler specific\r
- * language extensions. The equivalent prototype for this function is:\r
- *\r
- * void prvIdleTask( void *pvParameters );\r
- *\r
- */\r
-static portTASK_FUNCTION( prvIdleTask, pvParameters )\r
-{\r
- /* Stop warnings. */\r
- ( void ) pvParameters;\r
-\r
- for( ;; )\r
- {\r
- /* See if any tasks have been deleted. */\r
- prvCheckTasksWaitingTermination();\r
-\r
- #if ( configUSE_PREEMPTION == 0 )\r
- {\r
- /* If we are not using preemption we keep forcing a task switch to\r
- see if any other task has become available. If we are using\r
- preemption we don't need to do this as any task becoming available\r
- will automatically get the processor anyway. */\r
- taskYIELD();\r
- }\r
- #endif\r
-\r
- #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )\r
- {\r
- /* When using preemption tasks of equal priority will be\r
- timesliced. If a task that is sharing the idle priority is ready\r
- to run then the idle task should yield before the end of the\r
- timeslice.\r
-\r
- A critical region is not required here as we are just reading from\r
- the list, and an occasional incorrect value will not matter. If\r
- the ready list at the idle priority contains more than one task\r
- then a task other than the idle task is ready to execute. */\r
- if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( unsigned portBASE_TYPE ) 1 )\r
- {\r
- taskYIELD();\r
- }\r
- }\r
- #endif\r
-\r
- #if ( configUSE_IDLE_HOOK == 1 )\r
- {\r
- extern void vApplicationIdleHook( void );\r
-\r
- /* Call the user defined function from within the idle task. This\r
- allows the application designer to add background functionality\r
- without the overhead of a separate task.\r
- NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,\r
- CALL A FUNCTION THAT MIGHT BLOCK. */\r
- vApplicationIdleHook();\r
- }\r
- #endif\r
- }\r
-} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * File private functions documented at the top of the file.\r
- *----------------------------------------------------------*/\r
-\r
-\r
-\r
-static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth )\r
-{\r
- /* Store the function name in the TCB. */\r
- #if configMAX_TASK_NAME_LEN > 1\r
- {\r
- /* Don't bring strncpy into the build unnecessarily. */\r
- strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN );\r
- }\r
- #endif\r
- pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = ( signed char ) '\0';\r
-\r
- /* This is used as an array index so must ensure it's not too large. First\r
- remove the privilege bit if one is present. */\r
- if( uxPriority >= configMAX_PRIORITIES )\r
- {\r
- uxPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U;\r
- }\r
-\r
- pxTCB->uxPriority = uxPriority;\r
- #if ( configUSE_MUTEXES == 1 )\r
- {\r
- pxTCB->uxBasePriority = uxPriority;\r
- }\r
- #endif\r
-\r
- vListInitialiseItem( &( pxTCB->xGenericListItem ) );\r
- vListInitialiseItem( &( pxTCB->xEventListItem ) );\r
-\r
- /* Set the pxTCB as a link back from the xListItem. This is so we can get\r
- back to the containing TCB from a generic item in a list. */\r
- listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB );\r
-\r
- /* Event lists are always in priority order. */\r
- listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );\r
- listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB );\r
-\r
- #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
- {\r
- pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0U;\r
- }\r
- #endif\r
-\r
- #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
- {\r
- pxTCB->pxTaskTag = NULL;\r
- }\r
- #endif\r
-\r
- #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
- {\r
- pxTCB->ulRunTimeCounter = 0UL;\r
- }\r
- #endif\r
-\r
- #if ( portUSING_MPU_WRAPPERS == 1 )\r
- {\r
- vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth );\r
- }\r
- #else\r
- {\r
- ( void ) xRegions;\r
- ( void ) usStackDepth;\r
- }\r
- #endif\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( portUSING_MPU_WRAPPERS == 1 )\r
-\r
- void vTaskAllocateMPURegions( xTaskHandle xTaskToModify, const xMemoryRegion * const xRegions )\r
- {\r
- tskTCB *pxTCB;\r
- \r
- if( xTaskToModify == pxCurrentTCB )\r
- {\r
- xTaskToModify = NULL;\r
- }\r
-\r
- /* If null is passed in here then we are deleting ourselves. */\r
- pxTCB = prvGetTCBFromHandle( xTaskToModify );\r
-\r
- vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );\r
- }\r
- /*-----------------------------------------------------------*/\r
-#endif\r
-\r
-static void prvInitialiseTaskLists( void )\r
-{\r
-unsigned portBASE_TYPE uxPriority;\r
-\r
- for( uxPriority = ( unsigned portBASE_TYPE ) 0U; uxPriority < configMAX_PRIORITIES; uxPriority++ )\r
- {\r
- vListInitialise( ( xList * ) &( pxReadyTasksLists[ uxPriority ] ) );\r
- }\r
-\r
- vListInitialise( ( xList * ) &xDelayedTaskList1 );\r
- vListInitialise( ( xList * ) &xDelayedTaskList2 );\r
- vListInitialise( ( xList * ) &xPendingReadyList );\r
-\r
- #if ( INCLUDE_vTaskDelete == 1 )\r
- {\r
- vListInitialise( ( xList * ) &xTasksWaitingTermination );\r
- }\r
- #endif\r
-\r
- #if ( INCLUDE_vTaskSuspend == 1 )\r
- {\r
- vListInitialise( ( xList * ) &xSuspendedTaskList );\r
- }\r
- #endif\r
-\r
- /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList\r
- using list2. */\r
- pxDelayedTaskList = &xDelayedTaskList1;\r
- pxOverflowDelayedTaskList = &xDelayedTaskList2;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckTasksWaitingTermination( void )\r
-{\r
- #if ( INCLUDE_vTaskDelete == 1 )\r
- {\r
- portBASE_TYPE xListIsEmpty;\r
-\r
- /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called\r
- too often in the idle task. */\r
- if( uxTasksDeleted > ( unsigned portBASE_TYPE ) 0U )\r
- {\r
- vTaskSuspendAll();\r
- xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );\r
- xTaskResumeAll();\r
-\r
- if( xListIsEmpty == pdFALSE )\r
- {\r
- tskTCB *pxTCB;\r
-\r
- taskENTER_CRITICAL();\r
- {\r
- pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) );\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
- --uxCurrentNumberOfTasks;\r
- --uxTasksDeleted;\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- prvDeleteTCB( pxTCB );\r
- }\r
- }\r
- }\r
- #endif\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake )\r
-{\r
- /* The list item will be inserted in wake time order. */\r
- listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
-\r
- if( xTimeToWake < xTickCount )\r
- {\r
- /* Wake time has overflowed. Place this item in the overflow list. */\r
- vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
- }\r
- else\r
- {\r
- /* The wake time has not overflowed, so we can use the current block list. */\r
- vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
-\r
- /* If the task entering the blocked state was placed at the head of the\r
- list of blocked tasks then xNextTaskUnblockTime needs to be updated\r
- too. */\r
- if( xTimeToWake < xNextTaskUnblockTime )\r
- {\r
- xNextTaskUnblockTime = xTimeToWake;\r
- }\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer )\r
-{\r
-tskTCB *pxNewTCB;\r
-\r
- /* Allocate space for the TCB. Where the memory comes from depends on\r
- the implementation of the port malloc function. */\r
- pxNewTCB = ( tskTCB * ) pvPortMalloc( sizeof( tskTCB ) );\r
-\r
- if( pxNewTCB != NULL )\r
- {\r
- /* Allocate space for the stack used by the task being created.\r
- The base of the stack memory stored in the TCB so the task can\r
- be deleted later if required. */\r
- pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer );\r
-\r
- if( pxNewTCB->pxStack == NULL )\r
- {\r
- /* Could not allocate the stack. Delete the allocated TCB. */\r
- vPortFree( pxNewTCB );\r
- pxNewTCB = NULL;\r
- }\r
- else\r
- {\r
- /* Just to help debugging. */\r
- memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( portSTACK_TYPE ) );\r
- }\r
- }\r
-\r
- return pxNewTCB;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-\r
- static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus )\r
- {\r
- volatile tskTCB *pxNextTCB, *pxFirstTCB;\r
- unsigned short usStackRemaining;\r
- PRIVILEGED_DATA static char pcStatusString[ 50 ];\r
-\r
- /* Write the details of all the TCB's in pxList into the buffer. */\r
- listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );\r
- do\r
- {\r
- listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );\r
- #if ( portSTACK_GROWTH > 0 )\r
- {\r
- usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack );\r
- }\r
- #else\r
- {\r
- usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack );\r
- }\r
- #endif \r
- \r
- sprintf( pcStatusString, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, ( unsigned int ) pxNextTCB->uxPriority, usStackRemaining, ( unsigned int ) pxNextTCB->uxTCBNumber );\r
- strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatusString );\r
-\r
- } while( pxNextTCB != pxFirstTCB );\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
-\r
- static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime )\r
- {\r
- volatile tskTCB *pxNextTCB, *pxFirstTCB;\r
- unsigned long ulStatsAsPercentage;\r
-\r
- /* Write the run time stats of all the TCB's in pxList into the buffer. */\r
- listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );\r
- do\r
- {\r
- /* Get next TCB in from the list. */\r
- listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );\r
-\r
- /* Divide by zero check. */\r
- if( ulTotalRunTime > 0UL )\r
- {\r
- /* Has the task run at all? */\r
- if( pxNextTCB->ulRunTimeCounter == 0UL )\r
- {\r
- /* The task has used no CPU time at all. */\r
- sprintf( pcStatsString, ( char * ) "%s\t\t0\t\t0%%\r\n", pxNextTCB->pcTaskName );\r
- }\r
- else\r
- {\r
- /* What percentage of the total run time has the task used?\r
- This will always be rounded down to the nearest integer.\r
- ulTotalRunTime has already been divided by 100. */\r
- ulStatsAsPercentage = pxNextTCB->ulRunTimeCounter / ulTotalRunTime;\r
-\r
- if( ulStatsAsPercentage > 0UL )\r
- {\r
- #ifdef portLU_PRINTF_SPECIFIER_REQUIRED\r
- {\r
- sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter, ulStatsAsPercentage ); \r
- }\r
- #else\r
- {\r
- /* sizeof( int ) == sizeof( long ) so a smaller\r
- printf() library can be used. */\r
- sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );\r
- }\r
- #endif\r
- }\r
- else\r
- {\r
- /* If the percentage is zero here then the task has\r
- consumed less than 1% of the total run time. */\r
- #ifdef portLU_PRINTF_SPECIFIER_REQUIRED\r
- {\r
- sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter ); \r
- }\r
- #else\r
- {\r
- /* sizeof( int ) == sizeof( long ) so a smaller\r
- printf() library can be used. */\r
- sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter );\r
- }\r
- #endif\r
- }\r
- }\r
-\r
- strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatsString );\r
- }\r
-\r
- } while( pxNextTCB != pxFirstTCB );\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
-\r
- static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte )\r
- {\r
- register unsigned short usCount = 0U;\r
-\r
- while( *pucStackByte == tskSTACK_FILL_BYTE )\r
- {\r
- pucStackByte -= portSTACK_GROWTH;\r
- usCount++;\r
- }\r
-\r
- usCount /= sizeof( portSTACK_TYPE );\r
-\r
- return usCount;\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )\r
-\r
- unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask )\r
- {\r
- tskTCB *pxTCB;\r
- unsigned char *pcEndOfStack;\r
- unsigned portBASE_TYPE uxReturn;\r
-\r
- pxTCB = prvGetTCBFromHandle( xTask );\r
-\r
- #if portSTACK_GROWTH < 0\r
- {\r
- pcEndOfStack = ( unsigned char * ) pxTCB->pxStack;\r
- }\r
- #else\r
- {\r
- pcEndOfStack = ( unsigned char * ) pxTCB->pxEndOfStack;\r
- }\r
- #endif\r
-\r
- uxReturn = ( unsigned portBASE_TYPE ) usTaskCheckFreeStackSpace( pcEndOfStack );\r
-\r
- return uxReturn;\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_vTaskDelete == 1 )\r
-\r
- static void prvDeleteTCB( tskTCB *pxTCB )\r
- {\r
- /* This call is required specifically for the TriCore port. It must be\r
- above the vPortFree() calls. */\r
- portCLEAN_UP_TCB( pxTCB );\r
-\r
- /* Free up the memory allocated by the scheduler for the task. It is up to\r
- the task to free any memory allocated at the application level. */\r
- vPortFreeAligned( pxTCB->pxStack );\r
- vPortFree( pxTCB );\r
- }\r
-\r
-#endif\r
-\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )\r
-\r
- xTaskHandle xTaskGetCurrentTaskHandle( void )\r
- {\r
- xTaskHandle xReturn;\r
-\r
- /* A critical section is not required as this is not called from\r
- an interrupt and the current TCB will always be the same for any\r
- individual execution thread. */\r
- xReturn = pxCurrentTCB;\r
-\r
- return xReturn;\r
- }\r
-\r
-#endif\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )\r
-\r
- portBASE_TYPE xTaskGetSchedulerState( void )\r
- {\r
- portBASE_TYPE xReturn;\r
-\r
- if( xSchedulerRunning == pdFALSE )\r
- {\r
- xReturn = taskSCHEDULER_NOT_STARTED;\r
- }\r
- else\r
- {\r
- if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
- {\r
- xReturn = taskSCHEDULER_RUNNING;\r
- }\r
- else\r
- {\r
- xReturn = taskSCHEDULER_SUSPENDED;\r
- }\r
- }\r
-\r
- return xReturn;\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_MUTEXES == 1 )\r
-\r
- void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder )\r
- {\r
- tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
-\r
- configASSERT( pxMutexHolder );\r
-\r
- if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )\r
- {\r
- /* Adjust the mutex holder state to account for its new priority. */\r
- listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority );\r
-\r
- /* If the task being modified is in the ready state it will need to\r
- be moved in to a new list. */\r
- if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
- {\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
-\r
- /* Inherit the priority before being moved into the new list. */\r
- pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
- prvAddTaskToReadyQueue( pxTCB );\r
- }\r
- else\r
- {\r
- /* Just inherit the priority. */\r
- pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
- }\r
-\r
- traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority );\r
- }\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( configUSE_MUTEXES == 1 )\r
-\r
- void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder )\r
- {\r
- tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
-\r
- if( pxMutexHolder != NULL )\r
- {\r
- if( pxTCB->uxPriority != pxTCB->uxBasePriority )\r
- {\r
- /* We must be the running task to be able to give the mutex back.\r
- Remove ourselves from the ready list we currently appear in. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
-\r
- /* Disinherit the priority before adding the task into the new\r
- ready list. */\r
- traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );\r
- pxTCB->uxPriority = pxTCB->uxBasePriority;\r
- listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority );\r
- prvAddTaskToReadyQueue( pxTCB );\r
- }\r
- }\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
-\r
- void vTaskEnterCritical( void )\r
- {\r
- portDISABLE_INTERRUPTS();\r
-\r
- if( xSchedulerRunning != pdFALSE )\r
- {\r
- ( pxCurrentTCB->uxCriticalNesting )++;\r
- }\r
- }\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
-\r
-void vTaskExitCritical( void )\r
-{\r
- if( xSchedulerRunning != pdFALSE )\r
- {\r
- if( pxCurrentTCB->uxCriticalNesting > 0U )\r
- {\r
- ( pxCurrentTCB->uxCriticalNesting )--;\r
-\r
- if( pxCurrentTCB->uxCriticalNesting == 0U )\r
- {\r
- portENABLE_INTERRUPTS();\r
- }\r
- }\r
- }\r
-}\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\r
- ***************************************************************************\r
-\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
-\r
- 1 tab == 4 spaces!\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/\r
-\r
-/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
-all the API functions to use the MPU wrappers. That should only be done when\r
-task.h is included from an application file. */\r
-#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
-\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "queue.h"\r
-#include "timers.h"\r
-\r
-#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
-\r
-/* This entire source file will be skipped if the application is not configured\r
-to include software timer functionality. This #if is closed at the very bottom\r
-of this file. If you want to include software timer functionality then ensure\r
-configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */\r
-#if ( configUSE_TIMERS == 1 )\r
-\r
-/* Misc definitions. */\r
-#define tmrNO_DELAY ( portTickType ) 0U\r
-\r
-/* The definition of the timers themselves. */\r
-typedef struct tmrTimerControl\r
-{\r
- const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */\r
- xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */\r
- portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */\r
- unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */\r
- void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */\r
- tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */\r
-} xTIMER;\r
-\r
-/* The definition of messages that can be sent and received on the timer\r
-queue. */\r
-typedef struct tmrTimerQueueMessage\r
-{\r
- portBASE_TYPE xMessageID; /*<< The command being sent to the timer service task. */\r
- portTickType xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */\r
- xTIMER * pxTimer; /*<< The timer to which the command will be applied. */\r
-} xTIMER_MESSAGE;\r
-\r
-\r
-/* The list in which active timers are stored. Timers are referenced in expire\r
-time order, with the nearest expiry time at the front of the list. Only the\r
-timer service task is allowed to access xActiveTimerList. */\r
-PRIVILEGED_DATA static xList xActiveTimerList1;\r
-PRIVILEGED_DATA static xList xActiveTimerList2;\r
-PRIVILEGED_DATA static xList *pxCurrentTimerList;\r
-PRIVILEGED_DATA static xList *pxOverflowTimerList;\r
-\r
-/* A queue that is used to send commands to the timer service task. */\r
-PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL;\r
-\r
-#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
- \r
- PRIVILEGED_DATA static xTaskHandle xTimerTaskHandle = NULL;\r
- \r
-#endif\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Initialise the infrastructure used by the timer service task if it has not\r
- * been initialised already.\r
- */\r
-static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * The timer service task (daemon). Timer functionality is controlled by this\r
- * task. Other tasks communicate with the timer service task using the\r
- * xTimerQueue queue.\r
- */\r
-static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Called by the timer service task to interpret and process a command it\r
- * received on the timer queue.\r
- */\r
-static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Insert the timer into either xActiveTimerList1, or xActiveTimerList2,\r
- * depending on if the expire time causes a timer counter overflow.\r
- */\r
-static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * An active timer has reached its expire time. Reload the timer if it is an\r
- * auto reload timer, then call its callback.\r
- */\r
-static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * The tick count has overflowed. Switch the timer lists after ensuring the\r
- * current timer list does not still reference some timers.\r
- */\r
-static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE\r
- * if a tick count overflow occurred since prvSampleTimeNow() was last called.\r
- */\r
-static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * If the timer list contains any active timers then return the expire time of\r
- * the timer that will expire first and set *pxListWasEmpty to false. If the\r
- * timer list does not contain any timers then return 0 and set *pxListWasEmpty\r
- * to pdTRUE.\r
- */\r
-static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * If a timer has expired, process it. Otherwise, block the timer service task\r
- * until either a timer does expire or a command is received.\r
- */\r
-static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xTimerCreateTimerTask( void )\r
-{\r
-portBASE_TYPE xReturn = pdFAIL;\r
-\r
- /* This function is called when the scheduler is started if\r
- configUSE_TIMERS is set to 1. Check that the infrastructure used by the\r
- timer service task has been created/initialised. If timers have already\r
- been created then the initialisation will already have been performed. */\r
- prvCheckForValidListAndQueue();\r
-\r
- if( xTimerQueue != NULL )\r
- {\r
- #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
- {\r
- /* Create the timer task, storing its handle in xTimerTaskHandle so\r
- it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */\r
- xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY, &xTimerTaskHandle ); \r
- }\r
- #else\r
- {\r
- /* Create the timer task without storing its handle. */\r
- xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY, NULL);\r
- }\r
- #endif\r
- }\r
-\r
- configASSERT( xReturn );\r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction )\r
-{\r
-xTIMER *pxNewTimer;\r
-\r
- /* Allocate the timer structure. */\r
- if( xTimerPeriodInTicks == ( portTickType ) 0U )\r
- {\r
- pxNewTimer = NULL;\r
- configASSERT( ( xTimerPeriodInTicks > 0 ) );\r
- }\r
- else\r
- {\r
- pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) );\r
- if( pxNewTimer != NULL )\r
- {\r
- /* Ensure the infrastructure used by the timer service task has been\r
- created/initialised. */\r
- prvCheckForValidListAndQueue();\r
- \r
- /* Initialise the timer structure members using the function parameters. */\r
- pxNewTimer->pcTimerName = pcTimerName;\r
- pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;\r
- pxNewTimer->uxAutoReload = uxAutoReload;\r
- pxNewTimer->pvTimerID = pvTimerID;\r
- pxNewTimer->pxCallbackFunction = pxCallbackFunction;\r
- vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );\r
- \r
- traceTIMER_CREATE( pxNewTimer );\r
- }\r
- else\r
- {\r
- traceTIMER_CREATE_FAILED();\r
- }\r
- }\r
- \r
- return ( xTimerHandle ) pxNewTimer;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime )\r
-{\r
-portBASE_TYPE xReturn = pdFAIL;\r
-xTIMER_MESSAGE xMessage;\r
-\r
- /* Send a message to the timer service task to perform a particular action\r
- on a particular timer definition. */\r
- if( xTimerQueue != NULL )\r
- {\r
- /* Send a command to the timer service task to start the xTimer timer. */\r
- xMessage.xMessageID = xCommandID;\r
- xMessage.xMessageValue = xOptionalValue;\r
- xMessage.pxTimer = ( xTIMER * ) xTimer;\r
-\r
- if( pxHigherPriorityTaskWoken == NULL )\r
- {\r
- if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )\r
- {\r
- xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime );\r
- }\r
- else\r
- {\r
- xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY );\r
- }\r
- }\r
- else\r
- {\r
- xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );\r
- }\r
- \r
- traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );\r
- }\r
- \r
- return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
-\r
- xTaskHandle xTimerGetTimerDaemonTaskHandle( void )\r
- {\r
- /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been\r
- started, then xTimerTaskHandle will be NULL. */\r
- configASSERT( ( xTimerTaskHandle != NULL ) );\r
- return xTimerTaskHandle;\r
- }\r
- \r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow )\r
-{\r
-xTIMER *pxTimer;\r
-portBASE_TYPE xResult;\r
-\r
- /* Remove the timer from the list of active timers. A check has already\r
- been performed to ensure the list is not empty. */\r
- pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );\r
- vListRemove( &( pxTimer->xTimerListItem ) );\r
- traceTIMER_EXPIRED( pxTimer );\r
-\r
- /* If the timer is an auto reload timer then calculate the next\r
- expiry time and re-insert the timer in the list of active timers. */\r
- if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )\r
- {\r
- /* This is the only time a timer is inserted into a list using\r
- a time relative to anything other than the current time. It\r
- will therefore be inserted into the correct list relative to\r
- the time this task thinks it is now, even if a command to\r
- switch lists due to a tick count overflow is already waiting in\r
- the timer queue. */\r
- if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )\r
- {\r
- /* The timer expired before it was added to the active timer\r
- list. Reload it now. */\r
- xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );\r
- configASSERT( xResult );\r
- ( void ) xResult;\r
- }\r
- }\r
-\r
- /* Call the timer callback. */\r
- pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvTimerTask( void *pvParameters )\r
-{\r
-portTickType xNextExpireTime;\r
-portBASE_TYPE xListWasEmpty;\r
-\r
- /* Just to avoid compiler warnings. */\r
- ( void ) pvParameters;\r
-\r
- for( ;; )\r
- {\r
- /* Query the timers list to see if it contains any timers, and if so,\r
- obtain the time at which the next timer will expire. */\r
- xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
-\r
- /* If a timer has expired, process it. Otherwise, block this task\r
- until either a timer does expire, or a command is received. */\r
- prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
- \r
- /* Empty the command queue. */\r
- prvProcessReceivedCommands(); \r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty )\r
-{\r
-portTickType xTimeNow;\r
-portBASE_TYPE xTimerListsWereSwitched;\r
-\r
- vTaskSuspendAll();\r
- {\r
- /* Obtain the time now to make an assessment as to whether the timer\r
- has expired or not. If obtaining the time causes the lists to switch\r
- then don't process this timer as any timers that remained in the list\r
- when the lists were switched will have been processed within the\r
- prvSampelTimeNow() function. */\r
- xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );\r
- if( xTimerListsWereSwitched == pdFALSE )\r
- {\r
- /* The tick count has not overflowed, has the timer expired? */\r
- if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )\r
- {\r
- xTaskResumeAll();\r
- prvProcessExpiredTimer( xNextExpireTime, xTimeNow );\r
- }\r
- else\r
- {\r
- /* The tick count has not overflowed, and the next expire\r
- time has not been reached yet. This task should therefore\r
- block to wait for the next expire time or a command to be\r
- received - whichever comes first. The following line cannot\r
- be reached unless xNextExpireTime > xTimeNow, except in the\r
- case when the current timer list is empty. */\r
- vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) );\r
-\r
- if( xTaskResumeAll() == pdFALSE )\r
- {\r
- /* Yield to wait for either a command to arrive, or the block time\r
- to expire. If a command arrived between the critical section being\r
- exited and this yield then the yield will not cause the task\r
- to block. */\r
- portYIELD_WITHIN_API();\r
- }\r
- }\r
- }\r
- else\r
- {\r
- xTaskResumeAll();\r
- }\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty )\r
-{\r
-portTickType xNextExpireTime;\r
-\r
- /* Timers are listed in expiry time order, with the head of the list\r
- referencing the task that will expire first. Obtain the time at which\r
- the timer with the nearest expiry time will expire. If there are no\r
- active timers then just set the next expire time to 0. That will cause\r
- this task to unblock when the tick count overflows, at which point the\r
- timer lists will be switched and the next expiry time can be\r
- re-assessed. */\r
- *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList );\r
- if( *pxListWasEmpty == pdFALSE )\r
- {\r
- xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );\r
- }\r
- else\r
- {\r
- /* Ensure the task unblocks when the tick count rolls over. */\r
- xNextExpireTime = ( portTickType ) 0U;\r
- }\r
-\r
- return xNextExpireTime;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched )\r
-{\r
-portTickType xTimeNow;\r
-static portTickType xLastTime = ( portTickType ) 0U;\r
-\r
- xTimeNow = xTaskGetTickCount();\r
- \r
- if( xTimeNow < xLastTime )\r
- {\r
- prvSwitchTimerLists( xLastTime );\r
- *pxTimerListsWereSwitched = pdTRUE;\r
- }\r
- else\r
- {\r
- *pxTimerListsWereSwitched = pdFALSE;\r
- }\r
- \r
- xLastTime = xTimeNow;\r
- \r
- return xTimeNow;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime )\r
-{\r
-portBASE_TYPE xProcessTimerNow = pdFALSE;\r
-\r
- listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime );\r
- listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );\r
- \r
- if( xNextExpiryTime <= xTimeNow )\r
- {\r
- /* Has the expiry time elapsed between the command to start/reset a\r
- timer was issued, and the time the command was processed? */\r
- if( ( ( portTickType ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks )\r
- {\r
- /* The time between a command being issued and the command being\r
- processed actually exceeds the timers period. */\r
- xProcessTimerNow = pdTRUE;\r
- }\r
- else\r
- {\r
- vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) );\r
- }\r
- }\r
- else\r
- {\r
- if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) )\r
- {\r
- /* If, since the command was issued, the tick count has overflowed\r
- but the expiry time has not, then the timer must have already passed\r
- its expiry time and should be processed immediately. */\r
- xProcessTimerNow = pdTRUE;\r
- }\r
- else\r
- {\r
- vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );\r
- }\r
- }\r
-\r
- return xProcessTimerNow;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvProcessReceivedCommands( void )\r
-{\r
-xTIMER_MESSAGE xMessage;\r
-xTIMER *pxTimer;\r
-portBASE_TYPE xTimerListsWereSwitched, xResult;\r
-portTickType xTimeNow;\r
-\r
- /* In this case the xTimerListsWereSwitched parameter is not used, but it\r
- must be present in the function call. */\r
- xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );\r
-\r
- while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL )\r
- {\r
- pxTimer = xMessage.pxTimer;\r
-\r
- /* Is the timer already in a list of active timers? When the command\r
- is trmCOMMAND_PROCESS_TIMER_OVERFLOW, the timer will be NULL as the\r
- command is to the task rather than to an individual timer. */\r
- if( pxTimer != NULL )\r
- {\r
- if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )\r
- {\r
- /* The timer is in a list, remove it. */\r
- vListRemove( &( pxTimer->xTimerListItem ) );\r
- }\r
- }\r
-\r
- traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue );\r
- \r
- switch( xMessage.xMessageID )\r
- {\r
- case tmrCOMMAND_START : \r
- /* Start or restart a timer. */\r
- if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE )\r
- {\r
- /* The timer expired before it was added to the active timer\r
- list. Process it now. */\r
- pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
-\r
- if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )\r
- {\r
- xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );\r
- configASSERT( xResult );\r
- ( void ) xResult;\r
- }\r
- }\r
- break;\r
-\r
- case tmrCOMMAND_STOP : \r
- /* The timer has already been removed from the active list.\r
- There is nothing to do here. */\r
- break;\r
-\r
- case tmrCOMMAND_CHANGE_PERIOD :\r
- pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue;\r
- configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );\r
- prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );\r
- break;\r
-\r
- case tmrCOMMAND_DELETE :\r
- /* The timer has already been removed from the active list,\r
- just free up the memory. */\r
- vPortFree( pxTimer );\r
- break;\r
-\r
- default : \r
- /* Don't expect to get here. */\r
- break;\r
- }\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvSwitchTimerLists( portTickType xLastTime )\r
-{\r
-portTickType xNextExpireTime, xReloadTime;\r
-xList *pxTemp;\r
-xTIMER *pxTimer;\r
-portBASE_TYPE xResult;\r
-\r
- /* Remove compiler warnings if configASSERT() is not defined. */\r
- ( void ) xLastTime;\r
- \r
- /* The tick count has overflowed. The timer lists must be switched.\r
- If there are any timers still referenced from the current timer list\r
- then they must have expired and should be processed before the lists\r
- are switched. */\r
- while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE )\r
- {\r
- xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );\r
-\r
- /* Remove the timer from the list. */\r
- pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );\r
- vListRemove( &( pxTimer->xTimerListItem ) );\r
-\r
- /* Execute its callback, then send a command to restart the timer if\r
- it is an auto-reload timer. It cannot be restarted here as the lists\r
- have not yet been switched. */\r
- pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
-\r
- if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )\r
- {\r
- /* Calculate the reload value, and if the reload value results in\r
- the timer going into the same timer list then it has already expired\r
- and the timer should be re-inserted into the current list so it is\r
- processed again within this loop. Otherwise a command should be sent\r
- to restart the timer to ensure it is only inserted into a list after\r
- the lists have been swapped. */\r
- xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks );\r
- if( xReloadTime > xNextExpireTime )\r
- {\r
- listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime );\r
- listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );\r
- vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );\r
- }\r
- else\r
- {\r
- xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );\r
- configASSERT( xResult );\r
- ( void ) xResult;\r
- }\r
- }\r
- }\r
-\r
- pxTemp = pxCurrentTimerList;\r
- pxCurrentTimerList = pxOverflowTimerList;\r
- pxOverflowTimerList = pxTemp;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckForValidListAndQueue( void )\r
-{\r
- /* Check that the list from which active timers are referenced, and the\r
- queue used to communicate with the timer service, have been\r
- initialised. */\r
- taskENTER_CRITICAL();\r
- {\r
- if( xTimerQueue == NULL )\r
- {\r
- vListInitialise( &xActiveTimerList1 );\r
- vListInitialise( &xActiveTimerList2 );\r
- pxCurrentTimerList = &xActiveTimerList1;\r
- pxOverflowTimerList = &xActiveTimerList2;\r
- xTimerQueue = xQueueCreate( ( unsigned portBASE_TYPE ) configTIMER_QUEUE_LENGTH, sizeof( xTIMER_MESSAGE ) );\r
- }\r
- }\r
- taskEXIT_CRITICAL();\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer )\r
-{\r
-portBASE_TYPE xTimerIsInActiveList;\r
-xTIMER *pxTimer = ( xTIMER * ) xTimer;\r
-\r
- /* Is the timer in the list of active timers? */\r
- taskENTER_CRITICAL();\r
- {\r
- /* Checking to see if it is in the NULL list in effect checks to see if\r
- it is referenced from either the current or the overflow timer lists in\r
- one go, but the logic has to be reversed, hence the '!'. */\r
- xTimerIsInActiveList = !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) );\r
- }\r
- taskEXIT_CRITICAL();\r
-\r
- return xTimerIsInActiveList;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void *pvTimerGetTimerID( xTimerHandle xTimer )\r
-{\r
-xTIMER *pxTimer = ( xTIMER * ) xTimer;\r
-\r
- return pxTimer->pvTimerID;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-/* This entire source file will be skipped if the application is not configured\r
-to include software timer functionality. If you want to include software timer\r
-functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */\r
-#endif /* configUSE_TIMERS == 1 */\r
--- /dev/null
+/*\r
+ FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+/*-----------------------------------------------------------\r
+ * Implementation of functions defined in portable.h for the ARM CM0 port.\r
+ *----------------------------------------------------------*/\r
+\r
+/* Scheduler includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Constants required to manipulate the NVIC. */\r
+#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned long *) 0xe000e010 )\r
+#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned long *) 0xe000e014 )\r
+#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 )\r
+#define portNVIC_SYSPRI2 ( ( volatile unsigned long *) 0xe000ed20 )\r
+#define portNVIC_SYSTICK_CLK 0x00000004\r
+#define portNVIC_SYSTICK_INT 0x00000002\r
+#define portNVIC_SYSTICK_ENABLE 0x00000001\r
+#define portNVIC_PENDSVSET 0x10000000\r
+#define portMIN_INTERRUPT_PRIORITY ( 255UL )\r
+#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )\r
+#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )\r
+\r
+/* Constants required to set up the initial stack. */\r
+#define portINITIAL_XPSR ( 0x01000000 )\r
+\r
+/* Each task maintains its own interrupt status in the critical nesting\r
+variable. */\r
+static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;\r
+\r
+/*\r
+ * Setup the timer to generate the tick interrupts.\r
+ */\r
+static void prvSetupTimerInterrupt( void );\r
+\r
+/*\r
+ * Exception handlers.\r
+ */\r
+void PendSV_Handler( void ) __attribute__ (( naked ));\r
+void SysTick_Handler( void );\r
+void SVCall_Handler( void ) __attribute__ (( naked ));\r
+\r
+/*\r
+ * Start first task is a separate function so it can be tested in isolation.\r
+ */\r
+static void vPortStartFirstTask( void ) __attribute__ (( naked ));\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * See header file for description.\r
+ */\r
+portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
+{\r
+ /* Simulate the stack frame as it would be created by a context switch\r
+ interrupt. */\r
+ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */\r
+ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */\r
+ pxTopOfStack -= 6; /* LR, R12, R3..R1 */\r
+ *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */\r
+ pxTopOfStack -= 8; /* R11..R4. */\r
+\r
+ return pxTopOfStack;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void SVCall_Handler( void )\r
+{\r
+ __asm volatile (\r
+ " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */\r
+ " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */\r
+ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */\r
+ " add r0, r0, #16 \n" /* Move to the high registers. */\r
+ " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */\r
+ " mov r8, r4 \n"\r
+ " mov r9, r5 \n"\r
+ " mov r10, r6 \n"\r
+ " mov r11, r7 \n"\r
+ " \n"\r
+ " msr psp, r0 \n" /* Remember the new top of stack for the task. */\r
+ " \n"\r
+ " sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */\r
+ " ldmia r0!, {r4-r7} \n" /* Pop low registers. */\r
+ " mov r1, r14 \n" /* OR R14 with 0x0d. */\r
+ " mov r0, #0x0d \n"\r
+ " orr r1, r0 \n"\r
+ " bx r1 \n"\r
+ " \n"\r
+ " .align 2 \n"\r
+ "pxCurrentTCBConst2: .word pxCurrentTCB \n"\r
+ );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortStartFirstTask( void )\r
+{\r
+ __asm volatile(\r
+ " mov r0, #0x00 \n" /* Locate the top of stack. */\r
+ " ldr r0, [r0] \n"\r
+ " msr msp, r0 \n" /* Set the msp back to the start of the stack. */\r
+ " cpsie i \n" /* Globally enable interrupts. */\r
+ " svc 0 \n" /* System call to start first task. */\r
+ " nop \n"\r
+ );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * See header file for description.\r
+ */\r
+portBASE_TYPE xPortStartScheduler( void )\r
+{\r
+ /* Make PendSV, CallSV and SysTick the same priroity as the kernel. */\r
+ *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;\r
+ *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;\r
+\r
+ /* Start the timer that generates the tick ISR. Interrupts are disabled\r
+ here already. */\r
+ prvSetupTimerInterrupt();\r
+\r
+ /* Initialise the critical nesting count ready for the first task. */\r
+ uxCriticalNesting = 0;\r
+\r
+ /* Start the first task. */\r
+ vPortStartFirstTask();\r
+\r
+ /* Should not get here! */\r
+ return 0;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortEndScheduler( void )\r
+{\r
+ /* It is unlikely that the CM0 port will require this function as there\r
+ is nothing to return to. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortYieldFromISR( void )\r
+{\r
+ /* Set a PendSV to request a context switch. */\r
+ *( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortEnterCritical( void )\r
+{\r
+ portDISABLE_INTERRUPTS();\r
+ uxCriticalNesting++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortExitCritical( void )\r
+{\r
+ uxCriticalNesting--;\r
+ if( uxCriticalNesting == 0 )\r
+ {\r
+ portENABLE_INTERRUPTS();\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void PendSV_Handler( void )\r
+{\r
+ /* This is a naked function. */\r
+\r
+ __asm volatile\r
+ (\r
+ " mrs r0, psp \n"\r
+ " \n"\r
+ " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */\r
+ " ldr r2, [r3] \n"\r
+ " \n"\r
+ " sub r0, r0, #32 \n" /* Make space for the remaining low registers. */\r
+ " str r0, [r2] \n" /* Save the new top of stack. */\r
+ " stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */\r
+ " mov r4, r8 \n" /* Store the high registers. */\r
+ " mov r5, r9 \n"\r
+ " mov r6, r10 \n"\r
+ " mov r7, r11 \n"\r
+ " stmia r0!, {r4-r7} \n"\r
+ " \n"\r
+ " push {r3, r14} \n"\r
+ " cpsid i \n"\r
+ " bl vTaskSwitchContext \n"\r
+ " cpsie i \n"\r
+ " pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */\r
+ " \n"\r
+ " ldr r1, [r2] \n"\r
+ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */\r
+ " add r0, r0, #16 \n" /* Move to the high registers. */\r
+ " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */\r
+ " mov r8, r4 \n"\r
+ " mov r9, r5 \n"\r
+ " mov r10, r6 \n"\r
+ " mov r11, r7 \n"\r
+ " \n"\r
+ " msr psp, r0 \n" /* Remember the new top of stack for the task. */\r
+ " \n"\r
+ " sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */\r
+ " ldmia r0!, {r4-r7} \n" /* Pop low registers. */\r
+ " \n"\r
+ " bx r3 \n"\r
+ " \n"\r
+ " .align 2 \n"\r
+ "pxCurrentTCBConst: .word pxCurrentTCB "\r
+ );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void SysTick_Handler( void )\r
+{\r
+unsigned long ulDummy;\r
+\r
+ /* If using preemption, also force a context switch. */\r
+ #if configUSE_PREEMPTION == 1\r
+ *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
+ #endif\r
+\r
+ ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();\r
+ {\r
+ vTaskIncrementTick();\r
+ }\r
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Setup the systick timer to generate the tick interrupts at the required\r
+ * frequency.\r
+ */\r
+void prvSetupTimerInterrupt( void )\r
+{\r
+ /* Configure SysTick to interrupt at the requested rate. */\r
+ *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
+ *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+\r
+ Giancarlo version (corrects inappropriate use of BASEPRI)\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+\r
+#ifndef PORTMACRO_H\r
+#define PORTMACRO_H\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*-----------------------------------------------------------\r
+ * Port specific definitions.\r
+ *\r
+ * The settings in this file configure FreeRTOS correctly for the\r
+ * given hardware and compiler.\r
+ *\r
+ * These settings should not be altered.\r
+ *-----------------------------------------------------------\r
+ */\r
+\r
+/* Type definitions. */\r
+#define portCHAR char\r
+#define portFLOAT float\r
+#define portDOUBLE double\r
+#define portLONG long\r
+#define portSHORT short\r
+#define portSTACK_TYPE unsigned portLONG\r
+#define portBASE_TYPE long\r
+\r
+#if( configUSE_16_BIT_TICKS == 1 )\r
+ typedef unsigned portSHORT portTickType;\r
+ #define portMAX_DELAY ( portTickType ) 0xffff\r
+#else\r
+ typedef unsigned portLONG portTickType;\r
+ #define portMAX_DELAY ( portTickType ) 0xffffffff\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Architecture specifics. */\r
+#define portSTACK_GROWTH ( -1 )\r
+#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )\r
+#define portBYTE_ALIGNMENT 8\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/* Scheduler utilities. */\r
+extern void vPortYieldFromISR( void );\r
+#define portYIELD() vPortYieldFromISR()\r
+#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/* Critical section management. */\r
+extern void vPortEnterCritical( void );\r
+extern void vPortExitCritical( void );\r
+#define portSET_INTERRUPT_MASK() __asm volatile ( " cpsid i " )\r
+#define portCLEAR_INTERRUPT_MASK() __asm volatile ( " cpsie i " )\r
+#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()\r
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x\r
+#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()\r
+#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()\r
+#define portENTER_CRITICAL() vPortEnterCritical()\r
+#define portEXIT_CRITICAL() vPortExitCritical()\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Task function macros as described on the FreeRTOS.org WEB site. */\r
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
+\r
+#define portNOP()\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* PORTMACRO_H */\r
+\r