--- /dev/null
+/*\r
+ FreeRTOS.org V4.0.5 - Copyright (C) 2003-2006 Richard Barry.\r
+\r
+ This file is part of the FreeRTOS.org distribution.\r
+\r
+ FreeRTOS.org is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ FreeRTOS.org is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with FreeRTOS.org; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+\r
+ A special exception to the GPL can be applied should you wish to distribute\r
+ a combined work that includes FreeRTOS.org, without being obliged to provide\r
+ the source code for any proprietary components. See the licensing section \r
+ of http://www.FreeRTOS.org for full details of how and when the exception\r
+ can be applied.\r
+\r
+ ***************************************************************************\r
+ See http://www.FreeRTOS.org for documentation, latest information, license \r
+ and contact details. Please ensure to read the configuration and relevant \r
+ port sections of the online documentation.\r
+ ***************************************************************************\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
+/* Task priorities. */\r
+#define bktPRIMARY_PRIORITY ( 3 )\r
+#define bktSECONDARY_PRIORITY ( 2 )\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 ( 12 )\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 portBASE_TYPE xPrimaryCycles = 0, xSecondaryCycles = 0;\r
+static 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
+ /* Create the two test tasks. */\r
+ xTaskCreate( vPrimaryBlockTimeTestTask, "BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );\r
+ xTaskCreate( vSecondaryBlockTimeTestTask, "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
+ 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
+ /* A critical section is used to minimise the jitter in the time\r
+ measurements. */\r
+ portENTER_CRITICAL();\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
+ portEXIT_CRITICAL();\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
+\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
+ portENTER_CRITICAL();\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
+ portEXIT_CRITICAL();\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
+ /*********************************************************************\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
+ 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
+ portENTER_CRITICAL();\r
+ {\r
+ xTimeWhenBlocking = xTaskGetTickCount();\r
+ \r
+ /* We should unblock after bktTIME_TO_BLOCK having not received\r
+ anything on 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
+ portEXIT_CRITICAL();\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
+ portENTER_CRITICAL();\r
+ {\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
+ portEXIT_CRITICAL();\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.org V4.0.5 - Copyright (C) 2003-2006 Richard Barry.\r
+\r
+ This file is part of the FreeRTOS.org distribution.\r
+\r
+ FreeRTOS.org is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ FreeRTOS.org is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with FreeRTOS.org; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+\r
+ A special exception to the GPL can be applied should you wish to distribute\r
+ a combined work that includes FreeRTOS.org, without being obliged to provide\r
+ the source code for any proprietary components. See the licensing section \r
+ of http://www.FreeRTOS.org for full details of how and when the exception\r
+ can be applied.\r
+\r
+ ***************************************************************************\r
+ See http://www.FreeRTOS.org for documentation, latest information, license \r
+ and contact details. Please ensure to read the configuration and relevant \r
+ port sections of the online documentation.\r
+ ***************************************************************************\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
#include "dynamic.h"\r
#include "mevents.h"\r
#include "crhook.h"\r
+#include "blocktim.h"\r
\r
/* Priority definitions for the tasks in the demo application. */\r
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
vStartComTestTasks( mainCOM_TEST_PRIORITY, serCOM1, ser115200 );\r
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
vStartBlockingQueueTasks( mainQUEUE_BLOCK_PRIORITY );\r
+ vCreateBlockTimeTasks();\r
\r
vStartSemaphoreTasks( mainSEMAPHORE_TASK_PRIORITY );\r
vStartDynamicPriorityTasks();\r
sErrorHasOccurred = pdTRUE;\r
}\r
\r
+ if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )\r
+ {\r
+ vDisplayMessage( "Error in block time test tasks!\r\n" );\r
+ sErrorHasOccurred = pdTRUE;\r
+ }\r
+\r
if( sErrorHasOccurred == pdFALSE )\r
{\r
vDisplayMessage( "OK " );\r
0\r
19\r
WPickList\r
-48\r
+50\r
20\r
MItem\r
3\r
0\r
168\r
MItem\r
-27\r
-..\COMMON\MINIMAL\crflash.c\r
+28\r
+..\COMMON\MINIMAL\blocktim.c\r
169\r
WString\r
4\r
0\r
172\r
MItem\r
-26\r
-..\COMMON\MINIMAL\crhook.c\r
+27\r
+..\COMMON\MINIMAL\crflash.c\r
173\r
WString\r
4\r
0\r
176\r
MItem\r
-15\r
-fileio\fileio.c\r
+26\r
+..\COMMON\MINIMAL\crhook.c\r
177\r
WString\r
4\r
0\r
180\r
MItem\r
-6\r
-main.c\r
+15\r
+fileio\fileio.c\r
181\r
WString\r
4\r
0\r
184\r
MItem\r
-17\r
-partest\partest.c\r
+6\r
+main.c\r
185\r
WString\r
4\r
0\r
188\r
MItem\r
-15\r
-serial\serial.c\r
+17\r
+partest\partest.c\r
189\r
WString\r
4\r
0\r
192\r
MItem\r
-3\r
-*.h\r
+15\r
+serial\serial.c\r
193\r
WString\r
-3\r
-NIL\r
+4\r
+COBJ\r
194\r
WVList\r
0\r
195\r
WVList\r
0\r
--1\r
+20\r
1\r
1\r
0\r
196\r
MItem\r
-31\r
-..\..\SOURCE\INCLUDE\croutine.h\r
+3\r
+*.h\r
197\r
WString\r
3\r
199\r
WVList\r
0\r
-192\r
-1\r
+-1\r
1\r
0\r
+0\r
200\r
MItem\r
-27\r
-..\..\source\include\list.h\r
+31\r
+..\..\SOURCE\INCLUDE\croutine.h\r
201\r
WString\r
3\r
203\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
204\r
MItem\r
-31\r
-..\..\source\include\portable.h\r
+27\r
+..\..\source\include\list.h\r
205\r
WString\r
3\r
207\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
208\r
MItem\r
31\r
-..\..\source\include\projdefs.h\r
+..\..\source\include\portable.h\r
209\r
WString\r
3\r
211\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
212\r
MItem\r
-28\r
-..\..\source\include\queue.h\r
+31\r
+..\..\source\include\projdefs.h\r
213\r
WString\r
3\r
215\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
216\r
MItem\r
-29\r
-..\..\source\include\semphr.h\r
+28\r
+..\..\source\include\queue.h\r
217\r
WString\r
3\r
219\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
220\r
MItem\r
-27\r
-..\..\source\include\task.h\r
+29\r
+..\..\source\include\semphr.h\r
221\r
WString\r
3\r
223\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
224\r
MItem\r
-55\r
-..\..\source\portable\owatcom\16bitdos\common\portasm.h\r
+27\r
+..\..\source\include\task.h\r
225\r
WString\r
3\r
227\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
228\r
MItem\r
-53\r
-..\..\source\portable\owatcom\16bitdos\pc\portmacro.h\r
+55\r
+..\..\source\portable\owatcom\16bitdos\common\portasm.h\r
229\r
WString\r
3\r
231\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
232\r
MItem\r
-26\r
-..\common\include\blockq.h\r
+53\r
+..\..\source\portable\owatcom\16bitdos\pc\portmacro.h\r
233\r
WString\r
3\r
235\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
236\r
MItem\r
-27\r
-..\common\include\comtest.h\r
+26\r
+..\common\include\blockq.h\r
237\r
WString\r
3\r
239\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
240\r
MItem\r
-26\r
-..\COMMON\INCLUDE\crhook.h\r
+28\r
+..\COMMON\INCLUDE\blocktim.h\r
241\r
WString\r
3\r
243\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
244\r
MItem\r
-25\r
-..\common\include\death.h\r
+27\r
+..\common\include\comtest.h\r
245\r
WString\r
3\r
247\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
248\r
MItem\r
-27\r
-..\COMMON\INCLUDE\dynamic.h\r
+26\r
+..\COMMON\INCLUDE\crhook.h\r
249\r
WString\r
3\r
251\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
252\r
MItem\r
-26\r
-..\common\include\fileio.h\r
+25\r
+..\common\include\death.h\r
253\r
WString\r
3\r
255\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
256\r
MItem\r
-25\r
-..\common\include\flash.h\r
+27\r
+..\COMMON\INCLUDE\dynamic.h\r
257\r
WString\r
3\r
259\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
260\r
MItem\r
-24\r
-..\common\include\flop.h\r
+26\r
+..\common\include\fileio.h\r
261\r
WString\r
3\r
263\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
264\r
MItem\r
-27\r
-..\common\include\partest.h\r
+25\r
+..\common\include\flash.h\r
265\r
WString\r
3\r
267\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
268\r
MItem\r
-25\r
-..\common\include\pollq.h\r
+24\r
+..\common\include\flop.h\r
269\r
WString\r
3\r
271\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
272\r
MItem\r
-25\r
-..\common\include\print.h\r
+27\r
+..\common\include\partest.h\r
273\r
WString\r
3\r
275\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
276\r
MItem\r
-27\r
-..\common\include\semtest.h\r
+25\r
+..\common\include\pollq.h\r
277\r
WString\r
3\r
279\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
280\r
MItem\r
-26\r
-..\common\include\serial.h\r
+25\r
+..\common\include\print.h\r
281\r
WString\r
3\r
283\r
WVList\r
0\r
-192\r
+196\r
1\r
1\r
0\r
284\r
MItem\r
-16\r
-FreeRTOSConfig.h\r
+27\r
+..\common\include\semtest.h\r
285\r
WString\r
3\r
287\r
WVList\r
0\r
-192\r
+196\r
+1\r
+1\r
+0\r
+288\r
+MItem\r
+26\r
+..\common\include\serial.h\r
+289\r
+WString\r
+3\r
+NIL\r
+290\r
+WVList\r
+0\r
+291\r
+WVList\r
+0\r
+196\r
+1\r
+1\r
+0\r
+292\r
+MItem\r
+16\r
+FreeRTOSConfig.h\r
+293\r
+WString\r
+3\r
+NIL\r
+294\r
+WVList\r
+0\r
+295\r
+WVList\r
+0\r
+196\r
1\r
1\r
0\r
0\r
0\r
7168\r
-7353\r
+7168\r
0\r
0\r
9\r
12\r
rtosdemo.tgt\r
0\r
-19\r
+25\r
7\r
#define pdTRUE ( 1 )\r
#define pdFALSE ( 0 )\r
\r
-#define pdPASS ( 1 )\r
-#define pdFAIL ( 0 )\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_FULL ( -3 )\r
#define errQUEUE_BLOCKED ( -4 )\r
#define errQUEUE_YIELD ( -5 )\r
\r
-#endif\r
+#endif /* PROJDEFS_H */\r
+\r
\r
\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 priority used by the idle task. This must not be modified.\r
*\r
*/\r
xTaskHandle xTaskGetCurrentTaskHandle( void );\r
\r
+/*\r
+ * Capture the current time status for future reference.\r
+ */\r
+void vTaskSetTimeOutState( xTimeOutType *pxTimeOut );\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 *pxTimeOut, portTickType *pxTicksToWait );\r
+\r
+/*\r
+ * Shortcut used by the queue implementation to prevent unnecessary call to\r
+ * taskYIELD();\r
+ */\r
+void vTaskMissedYield( void );\r
\r
#endif /* TASK_H */\r
\r
\r
+ Added the queue functions that can be used from co-routines.\r
\r
+Changes from V4.0.5\r
+\r
+ + Added a loop within xQueueSend() and xQueueReceive() to prevent the\r
+ functions exiting when a block time remains and the function has\r
+ not completed.\r
+\r
*/\r
\r
#include <stdlib.h>\r
\r
/* Constants used with the cRxLock and cTxLock structure members. */\r
#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )\r
+#define queueERRONEOUS_UNBLOCK ( -1 )\r
\r
/*\r
* Definition of the queue used by the scheduler.\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 signed portBASE_TYPE prvUnlockQueue( xQueueHandle pxQueue );\r
+static void prvUnlockQueue( xQueueHandle pxQueue );\r
\r
/*\r
* Uses a critical section to determine if there is any data in a queue.\r
signed portBASE_TYPE xQueueSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
{\r
signed portBASE_TYPE xReturn;\r
+xTimeOutType xTimeOut;\r
\r
/* Make sure other tasks do not access the queue. */\r
vTaskSuspendAll();\r
\r
+ /* Capture the current time status for future reference. */\r
+ vTaskSetTimeOutState( &xTimeOut );\r
+\r
/* It is important that this is the only thread/ISR that modifies the\r
ready or delayed lists until xTaskResumeAll() is called. Places where\r
the ready/delayed lists are modified include:\r
*/\r
\r
/* If the queue is already full we may have to block. */\r
- if( prvIsQueueFull( pxQueue ) )\r
+ do\r
{\r
- /* The queue is full - do we want to block or just leave without\r
- posting? */\r
- if( xTicksToWait > ( portTickType ) 0 )\r
+ if( prvIsQueueFull( pxQueue ) )\r
{\r
- /* We are going to place ourselves on the xTasksWaitingToSend event\r
- list, and will get woken should the delay expire, or space become\r
- available on the queue.\r
- \r
- As detailed above we do not require mutual exclusion on the event\r
- list as nothing else can modify it or the ready lists while we\r
- have the scheduler suspended and queue locked.\r
- \r
- It is possible that an ISR has removed data from the queue since we\r
- checked if any was available. If this is the case then the data\r
- will have been copied from the queue, and the queue variables\r
- updated, but the event list will not yet have been checked to see if\r
- anything is waiting as the queue is locked. */\r
- vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
-\r
- /* Force a context switch now as we are blocked. We can do\r
- this from within a critical section as the task we are\r
- switching to has its own context. When we return here (i.e. we\r
- unblock) we will leave the critical section as normal.\r
- \r
- It is possible that an ISR has caused an event on an unrelated and\r
- unlocked queue. If this was the case then the event list for that\r
- queue will have been updated but the ready lists left unchanged -\r
- instead the readied task will have been added to the pending ready\r
- list. */\r
- taskENTER_CRITICAL();\r
+ /* The queue is full - do we want to block or just leave without\r
+ posting? */\r
+ if( xTicksToWait > ( portTickType ) 0 )\r
{\r
- /* We can safely unlock the queue and scheduler here as\r
- interrupts are disabled. We must not yield with anything\r
- locked, but we can yield from within a critical section.\r
+ /* We are going to place ourselves on the xTasksWaitingToSend event\r
+ list, and will get woken should the delay expire, or space become\r
+ available on the queue.\r
+ \r
+ As detailed above we do not require mutual exclusion on the event\r
+ list as nothing else can modify it or the ready lists while we\r
+ have the scheduler suspended and queue locked.\r
+ \r
+ It is possible that an ISR has removed data from the queue since we\r
+ checked if any was available. If this is the case then the data\r
+ will have been copied from the queue, and the queue variables\r
+ updated, but the event list will not yet have been checked to see if\r
+ anything is waiting as the queue is locked. */\r
+ vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
+ \r
+ /* Force a context switch now as we are blocked. We can do\r
+ this from within a critical section as the task we are\r
+ switching to has its own context. When we return here (i.e. we\r
+ unblock) we will leave the critical section as normal.\r
\r
- Tasks that have been placed on the pending ready list cannot\r
- be tasks that are waiting for events on this queue. See\r
- in comment xTaskRemoveFromEventList(). */\r
- prvUnlockQueue( pxQueue );\r
-\r
- /* Resuming the scheduler may cause a yield. If so then there\r
- is no point yielding again here. */\r
- if( !xTaskResumeAll() )\r
+ It is possible that an ISR has caused an event on an unrelated and\r
+ unlocked queue. If this was the case then the event list for that\r
+ queue will have been updated but the ready lists left unchanged -\r
+ instead the readied task will have been added to the pending ready\r
+ list. */\r
+ taskENTER_CRITICAL();\r
{\r
- taskYIELD();\r
+ /* We can safely unlock the queue and scheduler here as\r
+ interrupts are disabled. We must not yield with anything\r
+ locked, but we can yield from within a critical section.\r
+ \r
+ Tasks that have been placed on the pending ready list cannot\r
+ be tasks that are waiting for events on this queue. See\r
+ in comment xTaskRemoveFromEventList(). */\r
+ prvUnlockQueue( pxQueue );\r
+ \r
+ /* Resuming the scheduler may cause a yield. If so then there\r
+ is no point yielding again here. */\r
+ if( !xTaskResumeAll() )\r
+ {\r
+ taskYIELD();\r
+ }\r
+ \r
+ /* Before leaving the critical section we have to ensure\r
+ exclusive access again. */\r
+ vTaskSuspendAll();\r
+ prvLockQueue( pxQueue ); \r
}\r
-\r
- /* Before leaving the critical section we have to ensure\r
- exclusive access again. */\r
- vTaskSuspendAll();\r
- prvLockQueue( pxQueue ); \r
+ taskEXIT_CRITICAL();\r
}\r
- taskEXIT_CRITICAL();\r
}\r
- }\r
- \r
- /* When we are here it is possible that we unblocked as space became\r
- available on the queue. It is also possible that an ISR posted to the\r
- queue since we left the critical section, so it may be that again there\r
- is no space. This would only happen if a task and ISR post onto the\r
- same queue. */\r
- taskENTER_CRITICAL();\r
- {\r
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
- {\r
- /* There is room in the queue, copy the data into the queue. */ \r
- prvCopyQueueData( pxQueue, pvItemToQueue ); \r
- xReturn = pdPASS;\r
-\r
- /* Update the TxLock count so prvUnlockQueue knows to check for\r
- tasks waiting for data to become available in the queue. */\r
- ++( pxQueue->xTxLock );\r
- }\r
- else\r
+ \r
+ /* When we are here it is possible that we unblocked as space became\r
+ available on the queue. It is also possible that an ISR posted to the\r
+ queue since we left the critical section, so it may be that again there\r
+ is no space. This would only happen if a task and ISR post onto the\r
+ same queue. */\r
+ taskENTER_CRITICAL();\r
{\r
- xReturn = errQUEUE_FULL;\r
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+ {\r
+ /* There is room in the queue, copy the data into the queue. */ \r
+ prvCopyQueueData( pxQueue, pvItemToQueue ); \r
+ xReturn = pdPASS;\r
+ \r
+ /* Update the TxLock count so prvUnlockQueue knows to check for\r
+ tasks waiting for data to become available in the queue. */\r
+ ++( pxQueue->xTxLock );\r
+ }\r
+ else\r
+ {\r
+ xReturn = errQUEUE_FULL;\r
+ }\r
}\r
- }\r
- taskEXIT_CRITICAL();\r
+ taskEXIT_CRITICAL();\r
\r
- /* We no longer require exclusive access to the queue. prvUnlockQueue\r
- will remove any tasks suspended on a receive if either this function\r
- or an ISR has posted onto the queue. */\r
- if( prvUnlockQueue( pxQueue ) )\r
- {\r
- /* Resume the scheduler - making ready any tasks that were woken\r
- by an event while the scheduler was locked. Resuming the\r
- scheduler may cause a yield, in which case there is no point\r
- yielding again here. */\r
- if( !xTaskResumeAll() )\r
+ if( xReturn == errQUEUE_FULL )\r
{\r
- taskYIELD();\r
+ if( xTicksToWait > 0 )\r
+ {\r
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+ {\r
+ xReturn = queueERRONEOUS_UNBLOCK;\r
+ }\r
+ }\r
}\r
}\r
- else\r
- {\r
- /* Resume the scheduler - making ready any tasks that were woken\r
- by an event while the scheduler was locked. */\r
- xTaskResumeAll();\r
- }\r
+ while( xReturn == queueERRONEOUS_UNBLOCK );\r
+\r
+ prvUnlockQueue( pxQueue );\r
+ xTaskResumeAll();\r
\r
return xReturn;\r
}\r
signed portBASE_TYPE xQueueReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )\r
{\r
signed portBASE_TYPE xReturn;\r
+xTimeOutType xTimeOut;\r
\r
/* This function is very similar to xQueueSend(). See comments within\r
xQueueSend() for a more detailed explanation.\r
Make sure other tasks do not access the queue. */\r
vTaskSuspendAll();\r
\r
+ /* Capture the current time status for future reference. */\r
+ vTaskSetTimeOutState( &xTimeOut );\r
+\r
/* Make sure interrupts do not access the queue. */\r
prvLockQueue( pxQueue );\r
\r
- /* If there are no messages in the queue we may have to block. */\r
- if( prvIsQueueEmpty( pxQueue ) )\r
+ do\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
+ /* If there are no messages in the queue we may have to block. */\r
+ if( prvIsQueueEmpty( pxQueue ) )\r
{\r
- vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
- taskENTER_CRITICAL();\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
- prvUnlockQueue( pxQueue );\r
- if( !xTaskResumeAll() )\r
+ vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+ taskENTER_CRITICAL();\r
{\r
- taskYIELD();\r
+ prvUnlockQueue( pxQueue );\r
+ if( !xTaskResumeAll() )\r
+ {\r
+ taskYIELD();\r
+ }\r
+ \r
+ vTaskSuspendAll();\r
+ prvLockQueue( pxQueue );\r
}\r
-\r
- vTaskSuspendAll();\r
- prvLockQueue( pxQueue );\r
+ taskEXIT_CRITICAL();\r
}\r
- taskEXIT_CRITICAL();\r
}\r
- }\r
-\r
- taskENTER_CRITICAL();\r
- {\r
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+ \r
+ taskENTER_CRITICAL();\r
{\r
- pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
- pxQueue->pcReadFrom = pxQueue->pcHead;\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
+ /* Increment the lock count so prvUnlockQueue knows to check for\r
+ tasks waiting for space to become available on the queue. */\r
+ ++( pxQueue->xRxLock );\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = errQUEUE_EMPTY;\r
}\r
- --( pxQueue->uxMessagesWaiting );\r
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
-\r
- /* Increment the lock count so prvUnlockQueue knows to check for\r
- tasks waiting for space to become available on the queue. */\r
- ++( pxQueue->xRxLock );\r
- xReturn = pdPASS;\r
}\r
- else\r
+ taskEXIT_CRITICAL();\r
+\r
+ if( xReturn == errQUEUE_EMPTY )\r
{\r
- xReturn = pdFAIL;\r
+ if( xTicksToWait > 0 )\r
+ {\r
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+ {\r
+ xReturn = queueERRONEOUS_UNBLOCK;\r
+ }\r
+ }\r
}\r
- }\r
- taskEXIT_CRITICAL();\r
+ } while( xReturn == queueERRONEOUS_UNBLOCK );\r
\r
/* We no longer require exclusive access to the queue. */\r
- if( prvUnlockQueue( pxQueue ) )\r
- {\r
- if( !xTaskResumeAll() )\r
- {\r
- taskYIELD();\r
- }\r
- }\r
- else\r
- {\r
- xTaskResumeAll();\r
- }\r
+ prvUnlockQueue( pxQueue );\r
+ xTaskResumeAll();\r
\r
return xReturn;\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static signed portBASE_TYPE prvUnlockQueue( xQueueHandle pxQueue )\r
+static void prvUnlockQueue( xQueueHandle pxQueue )\r
{\r
-signed portBASE_TYPE xYieldRequired = pdFALSE;\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
{\r
/* The task waiting has a higher priority so record that a\r
context switch is required. */\r
- xYieldRequired = pdTRUE;\r
+ vTaskMissedYield();\r
}\r
} \r
}\r
{\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
{\r
- xYieldRequired = pdTRUE;\r
+ vTaskMissedYield();\r
}\r
} \r
}\r
}\r
taskEXIT_CRITICAL();\r
-\r
- return xYieldRequired;\r
}\r
/*-----------------------------------------------------------*/\r
\r
This has not been necessary since V4.0.1 when the xMissedYield handling\r
was added.\r
+ Implement xTaskResumeFromISR().\r
+\r
+Changes from V4.0.5\r
+\r
+ + Added utility functions and xOverflowCount variable to facilitate the\r
+ queue.c changes.\r
*/\r
\r
#include <stdio.h>\r
/* File private variables. --------------------------------*/\r
static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0;\r
static volatile portTickType xTickCount = ( portTickType ) 0;\r
-static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;\r
+static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;\r
static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;\r
static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;\r
static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE;\r
static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0;\r
static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;\r
-\r
+static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;\r
/* Debugging and trace facilities private variables and macros. ------------*/\r
\r
/*\r
pxTemp = pxDelayedTaskList;\r
pxDelayedTaskList = pxOverflowDelayedTaskList;\r
pxOverflowDelayedTaskList = pxTemp;\r
+ xNumOfOverflows++;\r
}\r
\r
/* See if this tick has made a timeout expire. */\r
\r
return xReturn;\r
}\r
+/*-----------------------------------------------------------*/\r
\r
+void vTaskSetTimeOutState( xTimeOutType *pxTimeOut )\r
+{\r
+ pxTimeOut->xOverflowCount = xNumOfOverflows;\r
+ pxTimeOut->xTimeOnEntering = xTickCount;\r
+}\r
+/*-----------------------------------------------------------*/\r
\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType *pxTicksToWait )\r
+{\r
+portBASE_TYPE xReturn;\r
\r
+ if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xTickCount > 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( ( xTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )\r
+ {\r
+ /* Not a genuine timeout. Adjust parameters for time remaining. */\r
+ *pxTicksToWait -= ( xTickCount - pxTimeOut->xTimeOnEntering );\r
+ vTaskSetTimeOutState( pxTimeOut );\r
+ xReturn = pdFALSE;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdTRUE;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
\r
+void vTaskMissedYield( void )\r
+{\r
+ xMissedYield = pdTRUE;\r
+}\r
\r
/*\r
* -----------------------------------------------------------\r