David Fletcher / Mbed 2 deprecated cc3100_Test_mqtt_CM4F

Dependencies:   mbed

Committer:
dflet
Date:
Thu Sep 03 14:07:01 2015 +0000
Revision:
0:1e7b5dd9edb4
First commit, it's been hanging around for a while. Updated SPI mode change 1 to 0.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dflet 0:1e7b5dd9edb4 1 /*
dflet 0:1e7b5dd9edb4 2 FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
dflet 0:1e7b5dd9edb4 3 All rights reserved
dflet 0:1e7b5dd9edb4 4
dflet 0:1e7b5dd9edb4 5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
dflet 0:1e7b5dd9edb4 6
dflet 0:1e7b5dd9edb4 7 This file is part of the FreeRTOS distribution.
dflet 0:1e7b5dd9edb4 8
dflet 0:1e7b5dd9edb4 9 FreeRTOS is free software; you can redistribute it and/or modify it under
dflet 0:1e7b5dd9edb4 10 the terms of the GNU General Public License (version 2) as published by the
dflet 0:1e7b5dd9edb4 11 Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
dflet 0:1e7b5dd9edb4 12
dflet 0:1e7b5dd9edb4 13 ***************************************************************************
dflet 0:1e7b5dd9edb4 14 >>! NOTE: The modification to the GPL is included to allow you to !<<
dflet 0:1e7b5dd9edb4 15 >>! distribute a combined work that includes FreeRTOS without being !<<
dflet 0:1e7b5dd9edb4 16 >>! obliged to provide the source code for proprietary components !<<
dflet 0:1e7b5dd9edb4 17 >>! outside of the FreeRTOS kernel. !<<
dflet 0:1e7b5dd9edb4 18 ***************************************************************************
dflet 0:1e7b5dd9edb4 19
dflet 0:1e7b5dd9edb4 20 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
dflet 0:1e7b5dd9edb4 21 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dflet 0:1e7b5dd9edb4 22 FOR A PARTICULAR PURPOSE. Full license text is available on the following
dflet 0:1e7b5dd9edb4 23 link: http://www.freertos.org/a00114.html
dflet 0:1e7b5dd9edb4 24
dflet 0:1e7b5dd9edb4 25 ***************************************************************************
dflet 0:1e7b5dd9edb4 26 * *
dflet 0:1e7b5dd9edb4 27 * FreeRTOS provides completely free yet professionally developed, *
dflet 0:1e7b5dd9edb4 28 * robust, strictly quality controlled, supported, and cross *
dflet 0:1e7b5dd9edb4 29 * platform software that is more than just the market leader, it *
dflet 0:1e7b5dd9edb4 30 * is the industry's de facto standard. *
dflet 0:1e7b5dd9edb4 31 * *
dflet 0:1e7b5dd9edb4 32 * Help yourself get started quickly while simultaneously helping *
dflet 0:1e7b5dd9edb4 33 * to support the FreeRTOS project by purchasing a FreeRTOS *
dflet 0:1e7b5dd9edb4 34 * tutorial book, reference manual, or both: *
dflet 0:1e7b5dd9edb4 35 * http://www.FreeRTOS.org/Documentation *
dflet 0:1e7b5dd9edb4 36 * *
dflet 0:1e7b5dd9edb4 37 ***************************************************************************
dflet 0:1e7b5dd9edb4 38
dflet 0:1e7b5dd9edb4 39 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
dflet 0:1e7b5dd9edb4 40 the FAQ page "My application does not run, what could be wrong?". Have you
dflet 0:1e7b5dd9edb4 41 defined configASSERT()?
dflet 0:1e7b5dd9edb4 42
dflet 0:1e7b5dd9edb4 43 http://www.FreeRTOS.org/support - In return for receiving this top quality
dflet 0:1e7b5dd9edb4 44 embedded software for free we request you assist our global community by
dflet 0:1e7b5dd9edb4 45 participating in the support forum.
dflet 0:1e7b5dd9edb4 46
dflet 0:1e7b5dd9edb4 47 http://www.FreeRTOS.org/training - Investing in training allows your team to
dflet 0:1e7b5dd9edb4 48 be as productive as possible as early as possible. Now you can receive
dflet 0:1e7b5dd9edb4 49 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
dflet 0:1e7b5dd9edb4 50 Ltd, and the world's leading authority on the world's leading RTOS.
dflet 0:1e7b5dd9edb4 51
dflet 0:1e7b5dd9edb4 52 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
dflet 0:1e7b5dd9edb4 53 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
dflet 0:1e7b5dd9edb4 54 compatible FAT file system, and our tiny thread aware UDP/IP stack.
dflet 0:1e7b5dd9edb4 55
dflet 0:1e7b5dd9edb4 56 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
dflet 0:1e7b5dd9edb4 57 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
dflet 0:1e7b5dd9edb4 58
dflet 0:1e7b5dd9edb4 59 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
dflet 0:1e7b5dd9edb4 60 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
dflet 0:1e7b5dd9edb4 61 licenses offer ticketed support, indemnification and commercial middleware.
dflet 0:1e7b5dd9edb4 62
dflet 0:1e7b5dd9edb4 63 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
dflet 0:1e7b5dd9edb4 64 engineered and independently SIL3 certified version for use in safety and
dflet 0:1e7b5dd9edb4 65 mission critical applications that require provable dependability.
dflet 0:1e7b5dd9edb4 66
dflet 0:1e7b5dd9edb4 67 1 tab == 4 spaces!
dflet 0:1e7b5dd9edb4 68 */
dflet 0:1e7b5dd9edb4 69
dflet 0:1e7b5dd9edb4 70 /* Standard includes. */
dflet 0:1e7b5dd9edb4 71 #include <stdlib.h>
dflet 0:1e7b5dd9edb4 72
dflet 0:1e7b5dd9edb4 73 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
dflet 0:1e7b5dd9edb4 74 all the API functions to use the MPU wrappers. That should only be done when
dflet 0:1e7b5dd9edb4 75 task.h is included from an application file. */
dflet 0:1e7b5dd9edb4 76 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
dflet 0:1e7b5dd9edb4 77
dflet 0:1e7b5dd9edb4 78 #include "FreeRTOS.h"
dflet 0:1e7b5dd9edb4 79 #include "task.h"
dflet 0:1e7b5dd9edb4 80 #include "queue.h"
dflet 0:1e7b5dd9edb4 81 #include "timers.h"
dflet 0:1e7b5dd9edb4 82
dflet 0:1e7b5dd9edb4 83 #if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 )
dflet 0:1e7b5dd9edb4 84 #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.
dflet 0:1e7b5dd9edb4 85 #endif
dflet 0:1e7b5dd9edb4 86
dflet 0:1e7b5dd9edb4 87 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
dflet 0:1e7b5dd9edb4 88 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
dflet 0:1e7b5dd9edb4 89 header files above, but not in this file, in order to generate the correct
dflet 0:1e7b5dd9edb4 90 privileged Vs unprivileged linkage and placement. */
dflet 0:1e7b5dd9edb4 91 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
dflet 0:1e7b5dd9edb4 92
dflet 0:1e7b5dd9edb4 93
dflet 0:1e7b5dd9edb4 94 /* This entire source file will be skipped if the application is not configured
dflet 0:1e7b5dd9edb4 95 to include software timer functionality. This #if is closed at the very bottom
dflet 0:1e7b5dd9edb4 96 of this file. If you want to include software timer functionality then ensure
dflet 0:1e7b5dd9edb4 97 configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
dflet 0:1e7b5dd9edb4 98 #if ( configUSE_TIMERS == 1 )
dflet 0:1e7b5dd9edb4 99
dflet 0:1e7b5dd9edb4 100 /* Misc definitions. */
dflet 0:1e7b5dd9edb4 101 #define tmrNO_DELAY ( TickType_t ) 0U
dflet 0:1e7b5dd9edb4 102
dflet 0:1e7b5dd9edb4 103 /* The definition of the timers themselves. */
dflet 0:1e7b5dd9edb4 104 typedef struct tmrTimerControl
dflet 0:1e7b5dd9edb4 105 {
dflet 0:1e7b5dd9edb4 106 const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
dflet 0:1e7b5dd9edb4 107 ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */
dflet 0:1e7b5dd9edb4 108 TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
dflet 0:1e7b5dd9edb4 109 UBaseType_t 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. */
dflet 0:1e7b5dd9edb4 110 void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
dflet 0:1e7b5dd9edb4 111 TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */
dflet 0:1e7b5dd9edb4 112 #if( configUSE_TRACE_FACILITY == 1 )
dflet 0:1e7b5dd9edb4 113 UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */
dflet 0:1e7b5dd9edb4 114 #endif
dflet 0:1e7b5dd9edb4 115 } xTIMER;
dflet 0:1e7b5dd9edb4 116
dflet 0:1e7b5dd9edb4 117 /* The old xTIMER name is maintained above then typedefed to the new Timer_t
dflet 0:1e7b5dd9edb4 118 name below to enable the use of older kernel aware debuggers. */
dflet 0:1e7b5dd9edb4 119 typedef xTIMER Timer_t;
dflet 0:1e7b5dd9edb4 120
dflet 0:1e7b5dd9edb4 121 /* The definition of messages that can be sent and received on the timer queue.
dflet 0:1e7b5dd9edb4 122 Two types of message can be queued - messages that manipulate a software timer,
dflet 0:1e7b5dd9edb4 123 and messages that request the execution of a non-timer related callback. The
dflet 0:1e7b5dd9edb4 124 two message types are defined in two separate structures, xTimerParametersType
dflet 0:1e7b5dd9edb4 125 and xCallbackParametersType respectively. */
dflet 0:1e7b5dd9edb4 126 typedef struct tmrTimerParameters
dflet 0:1e7b5dd9edb4 127 {
dflet 0:1e7b5dd9edb4 128 TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */
dflet 0:1e7b5dd9edb4 129 Timer_t * pxTimer; /*<< The timer to which the command will be applied. */
dflet 0:1e7b5dd9edb4 130 } TimerParameter_t;
dflet 0:1e7b5dd9edb4 131
dflet 0:1e7b5dd9edb4 132
dflet 0:1e7b5dd9edb4 133 typedef struct tmrCallbackParameters
dflet 0:1e7b5dd9edb4 134 {
dflet 0:1e7b5dd9edb4 135 PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */
dflet 0:1e7b5dd9edb4 136 void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */
dflet 0:1e7b5dd9edb4 137 uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */
dflet 0:1e7b5dd9edb4 138 } CallbackParameters_t;
dflet 0:1e7b5dd9edb4 139
dflet 0:1e7b5dd9edb4 140 /* The structure that contains the two message types, along with an identifier
dflet 0:1e7b5dd9edb4 141 that is used to determine which message type is valid. */
dflet 0:1e7b5dd9edb4 142 typedef struct tmrTimerQueueMessage
dflet 0:1e7b5dd9edb4 143 {
dflet 0:1e7b5dd9edb4 144 BaseType_t xMessageID; /*<< The command being sent to the timer service task. */
dflet 0:1e7b5dd9edb4 145 union
dflet 0:1e7b5dd9edb4 146 {
dflet 0:1e7b5dd9edb4 147 TimerParameter_t xTimerParameters;
dflet 0:1e7b5dd9edb4 148
dflet 0:1e7b5dd9edb4 149 /* Don't include xCallbackParameters if it is not going to be used as
dflet 0:1e7b5dd9edb4 150 it makes the structure (and therefore the timer queue) larger. */
dflet 0:1e7b5dd9edb4 151 #if ( INCLUDE_xTimerPendFunctionCall == 1 )
dflet 0:1e7b5dd9edb4 152 CallbackParameters_t xCallbackParameters;
dflet 0:1e7b5dd9edb4 153 #endif /* INCLUDE_xTimerPendFunctionCall */
dflet 0:1e7b5dd9edb4 154 } u;
dflet 0:1e7b5dd9edb4 155 } DaemonTaskMessage_t;
dflet 0:1e7b5dd9edb4 156
dflet 0:1e7b5dd9edb4 157 /*lint -e956 A manual analysis and inspection has been used to determine which
dflet 0:1e7b5dd9edb4 158 static variables must be declared volatile. */
dflet 0:1e7b5dd9edb4 159
dflet 0:1e7b5dd9edb4 160 /* The list in which active timers are stored. Timers are referenced in expire
dflet 0:1e7b5dd9edb4 161 time order, with the nearest expiry time at the front of the list. Only the
dflet 0:1e7b5dd9edb4 162 timer service task is allowed to access these lists. */
dflet 0:1e7b5dd9edb4 163 PRIVILEGED_DATA static List_t xActiveTimerList1;
dflet 0:1e7b5dd9edb4 164 PRIVILEGED_DATA static List_t xActiveTimerList2;
dflet 0:1e7b5dd9edb4 165 PRIVILEGED_DATA static List_t *pxCurrentTimerList;
dflet 0:1e7b5dd9edb4 166 PRIVILEGED_DATA static List_t *pxOverflowTimerList;
dflet 0:1e7b5dd9edb4 167
dflet 0:1e7b5dd9edb4 168 /* A queue that is used to send commands to the timer service task. */
dflet 0:1e7b5dd9edb4 169 PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;
dflet 0:1e7b5dd9edb4 170
dflet 0:1e7b5dd9edb4 171 #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
dflet 0:1e7b5dd9edb4 172
dflet 0:1e7b5dd9edb4 173 PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;
dflet 0:1e7b5dd9edb4 174
dflet 0:1e7b5dd9edb4 175 #endif
dflet 0:1e7b5dd9edb4 176
dflet 0:1e7b5dd9edb4 177 /*lint +e956 */
dflet 0:1e7b5dd9edb4 178
dflet 0:1e7b5dd9edb4 179 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 180
dflet 0:1e7b5dd9edb4 181 /*
dflet 0:1e7b5dd9edb4 182 * Initialise the infrastructure used by the timer service task if it has not
dflet 0:1e7b5dd9edb4 183 * been initialised already.
dflet 0:1e7b5dd9edb4 184 */
dflet 0:1e7b5dd9edb4 185 static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;
dflet 0:1e7b5dd9edb4 186
dflet 0:1e7b5dd9edb4 187 /*
dflet 0:1e7b5dd9edb4 188 * The timer service task (daemon). Timer functionality is controlled by this
dflet 0:1e7b5dd9edb4 189 * task. Other tasks communicate with the timer service task using the
dflet 0:1e7b5dd9edb4 190 * xTimerQueue queue.
dflet 0:1e7b5dd9edb4 191 */
dflet 0:1e7b5dd9edb4 192 static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;
dflet 0:1e7b5dd9edb4 193
dflet 0:1e7b5dd9edb4 194 /*
dflet 0:1e7b5dd9edb4 195 * Called by the timer service task to interpret and process a command it
dflet 0:1e7b5dd9edb4 196 * received on the timer queue.
dflet 0:1e7b5dd9edb4 197 */
dflet 0:1e7b5dd9edb4 198 static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;
dflet 0:1e7b5dd9edb4 199
dflet 0:1e7b5dd9edb4 200 /*
dflet 0:1e7b5dd9edb4 201 * Insert the timer into either xActiveTimerList1, or xActiveTimerList2,
dflet 0:1e7b5dd9edb4 202 * depending on if the expire time causes a timer counter overflow.
dflet 0:1e7b5dd9edb4 203 */
dflet 0:1e7b5dd9edb4 204 static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION;
dflet 0:1e7b5dd9edb4 205
dflet 0:1e7b5dd9edb4 206 /*
dflet 0:1e7b5dd9edb4 207 * An active timer has reached its expire time. Reload the timer if it is an
dflet 0:1e7b5dd9edb4 208 * auto reload timer, then call its callback.
dflet 0:1e7b5dd9edb4 209 */
dflet 0:1e7b5dd9edb4 210 static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION;
dflet 0:1e7b5dd9edb4 211
dflet 0:1e7b5dd9edb4 212 /*
dflet 0:1e7b5dd9edb4 213 * The tick count has overflowed. Switch the timer lists after ensuring the
dflet 0:1e7b5dd9edb4 214 * current timer list does not still reference some timers.
dflet 0:1e7b5dd9edb4 215 */
dflet 0:1e7b5dd9edb4 216 static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION;
dflet 0:1e7b5dd9edb4 217
dflet 0:1e7b5dd9edb4 218 /*
dflet 0:1e7b5dd9edb4 219 * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE
dflet 0:1e7b5dd9edb4 220 * if a tick count overflow occurred since prvSampleTimeNow() was last called.
dflet 0:1e7b5dd9edb4 221 */
dflet 0:1e7b5dd9edb4 222 static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION;
dflet 0:1e7b5dd9edb4 223
dflet 0:1e7b5dd9edb4 224 /*
dflet 0:1e7b5dd9edb4 225 * If the timer list contains any active timers then return the expire time of
dflet 0:1e7b5dd9edb4 226 * the timer that will expire first and set *pxListWasEmpty to false. If the
dflet 0:1e7b5dd9edb4 227 * timer list does not contain any timers then return 0 and set *pxListWasEmpty
dflet 0:1e7b5dd9edb4 228 * to pdTRUE.
dflet 0:1e7b5dd9edb4 229 */
dflet 0:1e7b5dd9edb4 230 static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION;
dflet 0:1e7b5dd9edb4 231
dflet 0:1e7b5dd9edb4 232 /*
dflet 0:1e7b5dd9edb4 233 * If a timer has expired, process it. Otherwise, block the timer service task
dflet 0:1e7b5dd9edb4 234 * until either a timer does expire or a command is received.
dflet 0:1e7b5dd9edb4 235 */
dflet 0:1e7b5dd9edb4 236 static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, const BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION;
dflet 0:1e7b5dd9edb4 237
dflet 0:1e7b5dd9edb4 238 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 239
dflet 0:1e7b5dd9edb4 240 BaseType_t xTimerCreateTimerTask( void )
dflet 0:1e7b5dd9edb4 241 {
dflet 0:1e7b5dd9edb4 242 BaseType_t xReturn = pdFAIL;
dflet 0:1e7b5dd9edb4 243
dflet 0:1e7b5dd9edb4 244 /* This function is called when the scheduler is started if
dflet 0:1e7b5dd9edb4 245 configUSE_TIMERS is set to 1. Check that the infrastructure used by the
dflet 0:1e7b5dd9edb4 246 timer service task has been created/initialised. If timers have already
dflet 0:1e7b5dd9edb4 247 been created then the initialisation will already have been performed. */
dflet 0:1e7b5dd9edb4 248 prvCheckForValidListAndQueue();
dflet 0:1e7b5dd9edb4 249
dflet 0:1e7b5dd9edb4 250 if( xTimerQueue != NULL )
dflet 0:1e7b5dd9edb4 251 {
dflet 0:1e7b5dd9edb4 252 #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
dflet 0:1e7b5dd9edb4 253 {
dflet 0:1e7b5dd9edb4 254 /* Create the timer task, storing its handle in xTimerTaskHandle so
dflet 0:1e7b5dd9edb4 255 it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */
dflet 0:1e7b5dd9edb4 256 xReturn = xTaskCreate( prvTimerTask, "Tmr Svc", ( uint16_t ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );
dflet 0:1e7b5dd9edb4 257 }
dflet 0:1e7b5dd9edb4 258 #else
dflet 0:1e7b5dd9edb4 259 {
dflet 0:1e7b5dd9edb4 260 /* Create the timer task without storing its handle. */
dflet 0:1e7b5dd9edb4 261 xReturn = xTaskCreate( prvTimerTask, "Tmr Svc", ( uint16_t ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL);
dflet 0:1e7b5dd9edb4 262 }
dflet 0:1e7b5dd9edb4 263 #endif
dflet 0:1e7b5dd9edb4 264 }
dflet 0:1e7b5dd9edb4 265 else
dflet 0:1e7b5dd9edb4 266 {
dflet 0:1e7b5dd9edb4 267 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 268 }
dflet 0:1e7b5dd9edb4 269
dflet 0:1e7b5dd9edb4 270 configASSERT( xReturn );
dflet 0:1e7b5dd9edb4 271 return xReturn;
dflet 0:1e7b5dd9edb4 272 }
dflet 0:1e7b5dd9edb4 273 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 274
dflet 0:1e7b5dd9edb4 275 TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
dflet 0:1e7b5dd9edb4 276 {
dflet 0:1e7b5dd9edb4 277 Timer_t *pxNewTimer;
dflet 0:1e7b5dd9edb4 278
dflet 0:1e7b5dd9edb4 279 /* Allocate the timer structure. */
dflet 0:1e7b5dd9edb4 280 if( xTimerPeriodInTicks == ( TickType_t ) 0U )
dflet 0:1e7b5dd9edb4 281 {
dflet 0:1e7b5dd9edb4 282 pxNewTimer = NULL;
dflet 0:1e7b5dd9edb4 283 }
dflet 0:1e7b5dd9edb4 284 else
dflet 0:1e7b5dd9edb4 285 {
dflet 0:1e7b5dd9edb4 286 pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );
dflet 0:1e7b5dd9edb4 287 if( pxNewTimer != NULL )
dflet 0:1e7b5dd9edb4 288 {
dflet 0:1e7b5dd9edb4 289 /* Ensure the infrastructure used by the timer service task has been
dflet 0:1e7b5dd9edb4 290 created/initialised. */
dflet 0:1e7b5dd9edb4 291 prvCheckForValidListAndQueue();
dflet 0:1e7b5dd9edb4 292
dflet 0:1e7b5dd9edb4 293 /* Initialise the timer structure members using the function parameters. */
dflet 0:1e7b5dd9edb4 294 pxNewTimer->pcTimerName = pcTimerName;
dflet 0:1e7b5dd9edb4 295 pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
dflet 0:1e7b5dd9edb4 296 pxNewTimer->uxAutoReload = uxAutoReload;
dflet 0:1e7b5dd9edb4 297 pxNewTimer->pvTimerID = pvTimerID;
dflet 0:1e7b5dd9edb4 298 pxNewTimer->pxCallbackFunction = pxCallbackFunction;
dflet 0:1e7b5dd9edb4 299 vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
dflet 0:1e7b5dd9edb4 300
dflet 0:1e7b5dd9edb4 301 traceTIMER_CREATE( pxNewTimer );
dflet 0:1e7b5dd9edb4 302 }
dflet 0:1e7b5dd9edb4 303 else
dflet 0:1e7b5dd9edb4 304 {
dflet 0:1e7b5dd9edb4 305 traceTIMER_CREATE_FAILED();
dflet 0:1e7b5dd9edb4 306 }
dflet 0:1e7b5dd9edb4 307 }
dflet 0:1e7b5dd9edb4 308
dflet 0:1e7b5dd9edb4 309 /* 0 is not a valid value for xTimerPeriodInTicks. */
dflet 0:1e7b5dd9edb4 310 configASSERT( ( xTimerPeriodInTicks > 0 ) );
dflet 0:1e7b5dd9edb4 311
dflet 0:1e7b5dd9edb4 312 return ( TimerHandle_t ) pxNewTimer;
dflet 0:1e7b5dd9edb4 313 }
dflet 0:1e7b5dd9edb4 314 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 315
dflet 0:1e7b5dd9edb4 316 BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait )
dflet 0:1e7b5dd9edb4 317 {
dflet 0:1e7b5dd9edb4 318 BaseType_t xReturn = pdFAIL;
dflet 0:1e7b5dd9edb4 319 DaemonTaskMessage_t xMessage;
dflet 0:1e7b5dd9edb4 320
dflet 0:1e7b5dd9edb4 321 /* Send a message to the timer service task to perform a particular action
dflet 0:1e7b5dd9edb4 322 on a particular timer definition. */
dflet 0:1e7b5dd9edb4 323 if( xTimerQueue != NULL )
dflet 0:1e7b5dd9edb4 324 {
dflet 0:1e7b5dd9edb4 325 /* Send a command to the timer service task to start the xTimer timer. */
dflet 0:1e7b5dd9edb4 326 xMessage.xMessageID = xCommandID;
dflet 0:1e7b5dd9edb4 327 xMessage.u.xTimerParameters.xMessageValue = xOptionalValue;
dflet 0:1e7b5dd9edb4 328 xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer;
dflet 0:1e7b5dd9edb4 329
dflet 0:1e7b5dd9edb4 330 if( xCommandID < tmrFIRST_FROM_ISR_COMMAND )
dflet 0:1e7b5dd9edb4 331 {
dflet 0:1e7b5dd9edb4 332 if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )
dflet 0:1e7b5dd9edb4 333 {
dflet 0:1e7b5dd9edb4 334 xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );
dflet 0:1e7b5dd9edb4 335 }
dflet 0:1e7b5dd9edb4 336 else
dflet 0:1e7b5dd9edb4 337 {
dflet 0:1e7b5dd9edb4 338 xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY );
dflet 0:1e7b5dd9edb4 339 }
dflet 0:1e7b5dd9edb4 340 }
dflet 0:1e7b5dd9edb4 341 else
dflet 0:1e7b5dd9edb4 342 {
dflet 0:1e7b5dd9edb4 343 xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
dflet 0:1e7b5dd9edb4 344 }
dflet 0:1e7b5dd9edb4 345
dflet 0:1e7b5dd9edb4 346 traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );
dflet 0:1e7b5dd9edb4 347 }
dflet 0:1e7b5dd9edb4 348 else
dflet 0:1e7b5dd9edb4 349 {
dflet 0:1e7b5dd9edb4 350 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 351 }
dflet 0:1e7b5dd9edb4 352
dflet 0:1e7b5dd9edb4 353 return xReturn;
dflet 0:1e7b5dd9edb4 354 }
dflet 0:1e7b5dd9edb4 355 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 356
dflet 0:1e7b5dd9edb4 357 #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
dflet 0:1e7b5dd9edb4 358
dflet 0:1e7b5dd9edb4 359 TaskHandle_t xTimerGetTimerDaemonTaskHandle( void )
dflet 0:1e7b5dd9edb4 360 {
dflet 0:1e7b5dd9edb4 361 /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been
dflet 0:1e7b5dd9edb4 362 started, then xTimerTaskHandle will be NULL. */
dflet 0:1e7b5dd9edb4 363 configASSERT( ( xTimerTaskHandle != NULL ) );
dflet 0:1e7b5dd9edb4 364 return xTimerTaskHandle;
dflet 0:1e7b5dd9edb4 365 }
dflet 0:1e7b5dd9edb4 366
dflet 0:1e7b5dd9edb4 367 #endif
dflet 0:1e7b5dd9edb4 368 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 369
dflet 0:1e7b5dd9edb4 370 const char * pcTimerGetTimerName( TimerHandle_t xTimer )
dflet 0:1e7b5dd9edb4 371 {
dflet 0:1e7b5dd9edb4 372 Timer_t *pxTimer = ( Timer_t * ) xTimer;
dflet 0:1e7b5dd9edb4 373
dflet 0:1e7b5dd9edb4 374 return pxTimer->pcTimerName;
dflet 0:1e7b5dd9edb4 375 }
dflet 0:1e7b5dd9edb4 376 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 377
dflet 0:1e7b5dd9edb4 378 static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow )
dflet 0:1e7b5dd9edb4 379 {
dflet 0:1e7b5dd9edb4 380 BaseType_t xResult;
dflet 0:1e7b5dd9edb4 381 Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
dflet 0:1e7b5dd9edb4 382
dflet 0:1e7b5dd9edb4 383 /* Remove the timer from the list of active timers. A check has already
dflet 0:1e7b5dd9edb4 384 been performed to ensure the list is not empty. */
dflet 0:1e7b5dd9edb4 385 ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
dflet 0:1e7b5dd9edb4 386 traceTIMER_EXPIRED( pxTimer );
dflet 0:1e7b5dd9edb4 387
dflet 0:1e7b5dd9edb4 388 /* If the timer is an auto reload timer then calculate the next
dflet 0:1e7b5dd9edb4 389 expiry time and re-insert the timer in the list of active timers. */
dflet 0:1e7b5dd9edb4 390 if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
dflet 0:1e7b5dd9edb4 391 {
dflet 0:1e7b5dd9edb4 392 /* The timer is inserted into a list using a time relative to anything
dflet 0:1e7b5dd9edb4 393 other than the current time. It will therefore be inserted into the
dflet 0:1e7b5dd9edb4 394 correct list relative to the time this task thinks it is now. */
dflet 0:1e7b5dd9edb4 395 if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )
dflet 0:1e7b5dd9edb4 396 {
dflet 0:1e7b5dd9edb4 397 /* The timer expired before it was added to the active timer
dflet 0:1e7b5dd9edb4 398 list. Reload it now. */
dflet 0:1e7b5dd9edb4 399 xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );
dflet 0:1e7b5dd9edb4 400 configASSERT( xResult );
dflet 0:1e7b5dd9edb4 401 ( void ) xResult;
dflet 0:1e7b5dd9edb4 402 }
dflet 0:1e7b5dd9edb4 403 else
dflet 0:1e7b5dd9edb4 404 {
dflet 0:1e7b5dd9edb4 405 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 406 }
dflet 0:1e7b5dd9edb4 407 }
dflet 0:1e7b5dd9edb4 408 else
dflet 0:1e7b5dd9edb4 409 {
dflet 0:1e7b5dd9edb4 410 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 411 }
dflet 0:1e7b5dd9edb4 412
dflet 0:1e7b5dd9edb4 413 /* Call the timer callback. */
dflet 0:1e7b5dd9edb4 414 pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
dflet 0:1e7b5dd9edb4 415 }
dflet 0:1e7b5dd9edb4 416 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 417
dflet 0:1e7b5dd9edb4 418 static void prvTimerTask( void *pvParameters )
dflet 0:1e7b5dd9edb4 419 {
dflet 0:1e7b5dd9edb4 420 TickType_t xNextExpireTime;
dflet 0:1e7b5dd9edb4 421 BaseType_t xListWasEmpty;
dflet 0:1e7b5dd9edb4 422
dflet 0:1e7b5dd9edb4 423 /* Just to avoid compiler warnings. */
dflet 0:1e7b5dd9edb4 424 ( void ) pvParameters;
dflet 0:1e7b5dd9edb4 425
dflet 0:1e7b5dd9edb4 426 for( ;; )
dflet 0:1e7b5dd9edb4 427 {
dflet 0:1e7b5dd9edb4 428 /* Query the timers list to see if it contains any timers, and if so,
dflet 0:1e7b5dd9edb4 429 obtain the time at which the next timer will expire. */
dflet 0:1e7b5dd9edb4 430 xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );
dflet 0:1e7b5dd9edb4 431
dflet 0:1e7b5dd9edb4 432 /* If a timer has expired, process it. Otherwise, block this task
dflet 0:1e7b5dd9edb4 433 until either a timer does expire, or a command is received. */
dflet 0:1e7b5dd9edb4 434 prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );
dflet 0:1e7b5dd9edb4 435
dflet 0:1e7b5dd9edb4 436 /* Empty the command queue. */
dflet 0:1e7b5dd9edb4 437 prvProcessReceivedCommands();
dflet 0:1e7b5dd9edb4 438 }
dflet 0:1e7b5dd9edb4 439 }
dflet 0:1e7b5dd9edb4 440 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 441
dflet 0:1e7b5dd9edb4 442 static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, const BaseType_t xListWasEmpty )
dflet 0:1e7b5dd9edb4 443 {
dflet 0:1e7b5dd9edb4 444 TickType_t xTimeNow;
dflet 0:1e7b5dd9edb4 445 BaseType_t xTimerListsWereSwitched;
dflet 0:1e7b5dd9edb4 446
dflet 0:1e7b5dd9edb4 447 vTaskSuspendAll();
dflet 0:1e7b5dd9edb4 448 {
dflet 0:1e7b5dd9edb4 449 /* Obtain the time now to make an assessment as to whether the timer
dflet 0:1e7b5dd9edb4 450 has expired or not. If obtaining the time causes the lists to switch
dflet 0:1e7b5dd9edb4 451 then don't process this timer as any timers that remained in the list
dflet 0:1e7b5dd9edb4 452 when the lists were switched will have been processed within the
dflet 0:1e7b5dd9edb4 453 prvSampleTimeNow() function. */
dflet 0:1e7b5dd9edb4 454 xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
dflet 0:1e7b5dd9edb4 455 if( xTimerListsWereSwitched == pdFALSE )
dflet 0:1e7b5dd9edb4 456 {
dflet 0:1e7b5dd9edb4 457 /* The tick count has not overflowed, has the timer expired? */
dflet 0:1e7b5dd9edb4 458 if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )
dflet 0:1e7b5dd9edb4 459 {
dflet 0:1e7b5dd9edb4 460 ( void ) xTaskResumeAll();
dflet 0:1e7b5dd9edb4 461 prvProcessExpiredTimer( xNextExpireTime, xTimeNow );
dflet 0:1e7b5dd9edb4 462 }
dflet 0:1e7b5dd9edb4 463 else
dflet 0:1e7b5dd9edb4 464 {
dflet 0:1e7b5dd9edb4 465 /* The tick count has not overflowed, and the next expire
dflet 0:1e7b5dd9edb4 466 time has not been reached yet. This task should therefore
dflet 0:1e7b5dd9edb4 467 block to wait for the next expire time or a command to be
dflet 0:1e7b5dd9edb4 468 received - whichever comes first. The following line cannot
dflet 0:1e7b5dd9edb4 469 be reached unless xNextExpireTime > xTimeNow, except in the
dflet 0:1e7b5dd9edb4 470 case when the current timer list is empty. */
dflet 0:1e7b5dd9edb4 471 vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) );
dflet 0:1e7b5dd9edb4 472
dflet 0:1e7b5dd9edb4 473 if( xTaskResumeAll() == pdFALSE )
dflet 0:1e7b5dd9edb4 474 {
dflet 0:1e7b5dd9edb4 475 /* Yield to wait for either a command to arrive, or the
dflet 0:1e7b5dd9edb4 476 block time to expire. If a command arrived between the
dflet 0:1e7b5dd9edb4 477 critical section being exited and this yield then the yield
dflet 0:1e7b5dd9edb4 478 will not cause the task to block. */
dflet 0:1e7b5dd9edb4 479 portYIELD_WITHIN_API();
dflet 0:1e7b5dd9edb4 480 }
dflet 0:1e7b5dd9edb4 481 else
dflet 0:1e7b5dd9edb4 482 {
dflet 0:1e7b5dd9edb4 483 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 484 }
dflet 0:1e7b5dd9edb4 485 }
dflet 0:1e7b5dd9edb4 486 }
dflet 0:1e7b5dd9edb4 487 else
dflet 0:1e7b5dd9edb4 488 {
dflet 0:1e7b5dd9edb4 489 ( void ) xTaskResumeAll();
dflet 0:1e7b5dd9edb4 490 }
dflet 0:1e7b5dd9edb4 491 }
dflet 0:1e7b5dd9edb4 492 }
dflet 0:1e7b5dd9edb4 493 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 494
dflet 0:1e7b5dd9edb4 495 static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty )
dflet 0:1e7b5dd9edb4 496 {
dflet 0:1e7b5dd9edb4 497 TickType_t xNextExpireTime;
dflet 0:1e7b5dd9edb4 498
dflet 0:1e7b5dd9edb4 499 /* Timers are listed in expiry time order, with the head of the list
dflet 0:1e7b5dd9edb4 500 referencing the task that will expire first. Obtain the time at which
dflet 0:1e7b5dd9edb4 501 the timer with the nearest expiry time will expire. If there are no
dflet 0:1e7b5dd9edb4 502 active timers then just set the next expire time to 0. That will cause
dflet 0:1e7b5dd9edb4 503 this task to unblock when the tick count overflows, at which point the
dflet 0:1e7b5dd9edb4 504 timer lists will be switched and the next expiry time can be
dflet 0:1e7b5dd9edb4 505 re-assessed. */
dflet 0:1e7b5dd9edb4 506 *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList );
dflet 0:1e7b5dd9edb4 507 if( *pxListWasEmpty == pdFALSE )
dflet 0:1e7b5dd9edb4 508 {
dflet 0:1e7b5dd9edb4 509 xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
dflet 0:1e7b5dd9edb4 510 }
dflet 0:1e7b5dd9edb4 511 else
dflet 0:1e7b5dd9edb4 512 {
dflet 0:1e7b5dd9edb4 513 /* Ensure the task unblocks when the tick count rolls over. */
dflet 0:1e7b5dd9edb4 514 xNextExpireTime = ( TickType_t ) 0U;
dflet 0:1e7b5dd9edb4 515 }
dflet 0:1e7b5dd9edb4 516
dflet 0:1e7b5dd9edb4 517 return xNextExpireTime;
dflet 0:1e7b5dd9edb4 518 }
dflet 0:1e7b5dd9edb4 519 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 520
dflet 0:1e7b5dd9edb4 521 static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched )
dflet 0:1e7b5dd9edb4 522 {
dflet 0:1e7b5dd9edb4 523 TickType_t xTimeNow;
dflet 0:1e7b5dd9edb4 524 PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */
dflet 0:1e7b5dd9edb4 525
dflet 0:1e7b5dd9edb4 526 xTimeNow = xTaskGetTickCount();
dflet 0:1e7b5dd9edb4 527
dflet 0:1e7b5dd9edb4 528 if( xTimeNow < xLastTime )
dflet 0:1e7b5dd9edb4 529 {
dflet 0:1e7b5dd9edb4 530 prvSwitchTimerLists();
dflet 0:1e7b5dd9edb4 531 *pxTimerListsWereSwitched = pdTRUE;
dflet 0:1e7b5dd9edb4 532 }
dflet 0:1e7b5dd9edb4 533 else
dflet 0:1e7b5dd9edb4 534 {
dflet 0:1e7b5dd9edb4 535 *pxTimerListsWereSwitched = pdFALSE;
dflet 0:1e7b5dd9edb4 536 }
dflet 0:1e7b5dd9edb4 537
dflet 0:1e7b5dd9edb4 538 xLastTime = xTimeNow;
dflet 0:1e7b5dd9edb4 539
dflet 0:1e7b5dd9edb4 540 return xTimeNow;
dflet 0:1e7b5dd9edb4 541 }
dflet 0:1e7b5dd9edb4 542 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 543
dflet 0:1e7b5dd9edb4 544 static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime )
dflet 0:1e7b5dd9edb4 545 {
dflet 0:1e7b5dd9edb4 546 BaseType_t xProcessTimerNow = pdFALSE;
dflet 0:1e7b5dd9edb4 547
dflet 0:1e7b5dd9edb4 548 listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime );
dflet 0:1e7b5dd9edb4 549 listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
dflet 0:1e7b5dd9edb4 550
dflet 0:1e7b5dd9edb4 551 if( xNextExpiryTime <= xTimeNow )
dflet 0:1e7b5dd9edb4 552 {
dflet 0:1e7b5dd9edb4 553 /* Has the expiry time elapsed between the command to start/reset a
dflet 0:1e7b5dd9edb4 554 timer was issued, and the time the command was processed? */
dflet 0:1e7b5dd9edb4 555 if( ( xTimeNow - xCommandTime ) >= pxTimer->xTimerPeriodInTicks )
dflet 0:1e7b5dd9edb4 556 {
dflet 0:1e7b5dd9edb4 557 /* The time between a command being issued and the command being
dflet 0:1e7b5dd9edb4 558 processed actually exceeds the timers period. */
dflet 0:1e7b5dd9edb4 559 xProcessTimerNow = pdTRUE;
dflet 0:1e7b5dd9edb4 560 }
dflet 0:1e7b5dd9edb4 561 else
dflet 0:1e7b5dd9edb4 562 {
dflet 0:1e7b5dd9edb4 563 vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) );
dflet 0:1e7b5dd9edb4 564 }
dflet 0:1e7b5dd9edb4 565 }
dflet 0:1e7b5dd9edb4 566 else
dflet 0:1e7b5dd9edb4 567 {
dflet 0:1e7b5dd9edb4 568 if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) )
dflet 0:1e7b5dd9edb4 569 {
dflet 0:1e7b5dd9edb4 570 /* If, since the command was issued, the tick count has overflowed
dflet 0:1e7b5dd9edb4 571 but the expiry time has not, then the timer must have already passed
dflet 0:1e7b5dd9edb4 572 its expiry time and should be processed immediately. */
dflet 0:1e7b5dd9edb4 573 xProcessTimerNow = pdTRUE;
dflet 0:1e7b5dd9edb4 574 }
dflet 0:1e7b5dd9edb4 575 else
dflet 0:1e7b5dd9edb4 576 {
dflet 0:1e7b5dd9edb4 577 vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
dflet 0:1e7b5dd9edb4 578 }
dflet 0:1e7b5dd9edb4 579 }
dflet 0:1e7b5dd9edb4 580
dflet 0:1e7b5dd9edb4 581 return xProcessTimerNow;
dflet 0:1e7b5dd9edb4 582 }
dflet 0:1e7b5dd9edb4 583 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 584
dflet 0:1e7b5dd9edb4 585 static void prvProcessReceivedCommands( void )
dflet 0:1e7b5dd9edb4 586 {
dflet 0:1e7b5dd9edb4 587 DaemonTaskMessage_t xMessage;
dflet 0:1e7b5dd9edb4 588 Timer_t *pxTimer;
dflet 0:1e7b5dd9edb4 589 BaseType_t xTimerListsWereSwitched, xResult;
dflet 0:1e7b5dd9edb4 590 TickType_t xTimeNow;
dflet 0:1e7b5dd9edb4 591
dflet 0:1e7b5dd9edb4 592 while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */
dflet 0:1e7b5dd9edb4 593 {
dflet 0:1e7b5dd9edb4 594 #if ( INCLUDE_xTimerPendFunctionCall == 1 )
dflet 0:1e7b5dd9edb4 595 {
dflet 0:1e7b5dd9edb4 596 /* Negative commands are pended function calls rather than timer
dflet 0:1e7b5dd9edb4 597 commands. */
dflet 0:1e7b5dd9edb4 598 if( xMessage.xMessageID < ( BaseType_t ) 0 )
dflet 0:1e7b5dd9edb4 599 {
dflet 0:1e7b5dd9edb4 600 const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters );
dflet 0:1e7b5dd9edb4 601
dflet 0:1e7b5dd9edb4 602 /* The timer uses the xCallbackParameters member to request a
dflet 0:1e7b5dd9edb4 603 callback be executed. Check the callback is not NULL. */
dflet 0:1e7b5dd9edb4 604 configASSERT( pxCallback );
dflet 0:1e7b5dd9edb4 605
dflet 0:1e7b5dd9edb4 606 /* Call the function. */
dflet 0:1e7b5dd9edb4 607 pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 );
dflet 0:1e7b5dd9edb4 608 }
dflet 0:1e7b5dd9edb4 609 else
dflet 0:1e7b5dd9edb4 610 {
dflet 0:1e7b5dd9edb4 611 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 612 }
dflet 0:1e7b5dd9edb4 613 }
dflet 0:1e7b5dd9edb4 614 #endif /* INCLUDE_xTimerPendFunctionCall */
dflet 0:1e7b5dd9edb4 615
dflet 0:1e7b5dd9edb4 616 /* Commands that are positive are timer commands rather than pended
dflet 0:1e7b5dd9edb4 617 function calls. */
dflet 0:1e7b5dd9edb4 618 if( xMessage.xMessageID >= ( BaseType_t ) 0 )
dflet 0:1e7b5dd9edb4 619 {
dflet 0:1e7b5dd9edb4 620 /* The messages uses the xTimerParameters member to work on a
dflet 0:1e7b5dd9edb4 621 software timer. */
dflet 0:1e7b5dd9edb4 622 pxTimer = xMessage.u.xTimerParameters.pxTimer;
dflet 0:1e7b5dd9edb4 623
dflet 0:1e7b5dd9edb4 624 if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )
dflet 0:1e7b5dd9edb4 625 {
dflet 0:1e7b5dd9edb4 626 /* The timer is in a list, remove it. */
dflet 0:1e7b5dd9edb4 627 ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
dflet 0:1e7b5dd9edb4 628 }
dflet 0:1e7b5dd9edb4 629 else
dflet 0:1e7b5dd9edb4 630 {
dflet 0:1e7b5dd9edb4 631 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 632 }
dflet 0:1e7b5dd9edb4 633
dflet 0:1e7b5dd9edb4 634 traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue );
dflet 0:1e7b5dd9edb4 635
dflet 0:1e7b5dd9edb4 636 /* In this case the xTimerListsWereSwitched parameter is not used, but
dflet 0:1e7b5dd9edb4 637 it must be present in the function call. prvSampleTimeNow() must be
dflet 0:1e7b5dd9edb4 638 called after the message is received from xTimerQueue so there is no
dflet 0:1e7b5dd9edb4 639 possibility of a higher priority task adding a message to the message
dflet 0:1e7b5dd9edb4 640 queue with a time that is ahead of the timer daemon task (because it
dflet 0:1e7b5dd9edb4 641 pre-empted the timer daemon task after the xTimeNow value was set). */
dflet 0:1e7b5dd9edb4 642 xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
dflet 0:1e7b5dd9edb4 643
dflet 0:1e7b5dd9edb4 644 switch( xMessage.xMessageID )
dflet 0:1e7b5dd9edb4 645 {
dflet 0:1e7b5dd9edb4 646 case tmrCOMMAND_START :
dflet 0:1e7b5dd9edb4 647 case tmrCOMMAND_START_FROM_ISR :
dflet 0:1e7b5dd9edb4 648 case tmrCOMMAND_RESET :
dflet 0:1e7b5dd9edb4 649 case tmrCOMMAND_RESET_FROM_ISR :
dflet 0:1e7b5dd9edb4 650 case tmrCOMMAND_START_DONT_TRACE :
dflet 0:1e7b5dd9edb4 651 /* Start or restart a timer. */
dflet 0:1e7b5dd9edb4 652 if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) == pdTRUE )
dflet 0:1e7b5dd9edb4 653 {
dflet 0:1e7b5dd9edb4 654 /* The timer expired before it was added to the active
dflet 0:1e7b5dd9edb4 655 timer list. Process it now. */
dflet 0:1e7b5dd9edb4 656 pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
dflet 0:1e7b5dd9edb4 657 traceTIMER_EXPIRED( pxTimer );
dflet 0:1e7b5dd9edb4 658
dflet 0:1e7b5dd9edb4 659 if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
dflet 0:1e7b5dd9edb4 660 {
dflet 0:1e7b5dd9edb4 661 xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );
dflet 0:1e7b5dd9edb4 662 configASSERT( xResult );
dflet 0:1e7b5dd9edb4 663 ( void ) xResult;
dflet 0:1e7b5dd9edb4 664 }
dflet 0:1e7b5dd9edb4 665 else
dflet 0:1e7b5dd9edb4 666 {
dflet 0:1e7b5dd9edb4 667 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 668 }
dflet 0:1e7b5dd9edb4 669 }
dflet 0:1e7b5dd9edb4 670 else
dflet 0:1e7b5dd9edb4 671 {
dflet 0:1e7b5dd9edb4 672 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 673 }
dflet 0:1e7b5dd9edb4 674 break;
dflet 0:1e7b5dd9edb4 675
dflet 0:1e7b5dd9edb4 676 case tmrCOMMAND_STOP :
dflet 0:1e7b5dd9edb4 677 case tmrCOMMAND_STOP_FROM_ISR :
dflet 0:1e7b5dd9edb4 678 /* The timer has already been removed from the active list.
dflet 0:1e7b5dd9edb4 679 There is nothing to do here. */
dflet 0:1e7b5dd9edb4 680 break;
dflet 0:1e7b5dd9edb4 681
dflet 0:1e7b5dd9edb4 682 case tmrCOMMAND_CHANGE_PERIOD :
dflet 0:1e7b5dd9edb4 683 case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR :
dflet 0:1e7b5dd9edb4 684 pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue;
dflet 0:1e7b5dd9edb4 685 configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
dflet 0:1e7b5dd9edb4 686
dflet 0:1e7b5dd9edb4 687 /* The new period does not really have a reference, and can be
dflet 0:1e7b5dd9edb4 688 longer or shorter than the old one. The command time is
dflet 0:1e7b5dd9edb4 689 therefore set to the current time, and as the period cannot be
dflet 0:1e7b5dd9edb4 690 zero the next expiry time can only be in the future, meaning
dflet 0:1e7b5dd9edb4 691 (unlike for the xTimerStart() case above) there is no fail case
dflet 0:1e7b5dd9edb4 692 that needs to be handled here. */
dflet 0:1e7b5dd9edb4 693 ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
dflet 0:1e7b5dd9edb4 694 break;
dflet 0:1e7b5dd9edb4 695
dflet 0:1e7b5dd9edb4 696 case tmrCOMMAND_DELETE :
dflet 0:1e7b5dd9edb4 697 /* The timer has already been removed from the active list,
dflet 0:1e7b5dd9edb4 698 just free up the memory. */
dflet 0:1e7b5dd9edb4 699 vPortFree( pxTimer );
dflet 0:1e7b5dd9edb4 700 break;
dflet 0:1e7b5dd9edb4 701
dflet 0:1e7b5dd9edb4 702 default :
dflet 0:1e7b5dd9edb4 703 /* Don't expect to get here. */
dflet 0:1e7b5dd9edb4 704 break;
dflet 0:1e7b5dd9edb4 705 }
dflet 0:1e7b5dd9edb4 706 }
dflet 0:1e7b5dd9edb4 707 }
dflet 0:1e7b5dd9edb4 708 }
dflet 0:1e7b5dd9edb4 709 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 710
dflet 0:1e7b5dd9edb4 711 static void prvSwitchTimerLists( void )
dflet 0:1e7b5dd9edb4 712 {
dflet 0:1e7b5dd9edb4 713 TickType_t xNextExpireTime, xReloadTime;
dflet 0:1e7b5dd9edb4 714 List_t *pxTemp;
dflet 0:1e7b5dd9edb4 715 Timer_t *pxTimer;
dflet 0:1e7b5dd9edb4 716 BaseType_t xResult;
dflet 0:1e7b5dd9edb4 717
dflet 0:1e7b5dd9edb4 718 /* The tick count has overflowed. The timer lists must be switched.
dflet 0:1e7b5dd9edb4 719 If there are any timers still referenced from the current timer list
dflet 0:1e7b5dd9edb4 720 then they must have expired and should be processed before the lists
dflet 0:1e7b5dd9edb4 721 are switched. */
dflet 0:1e7b5dd9edb4 722 while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE )
dflet 0:1e7b5dd9edb4 723 {
dflet 0:1e7b5dd9edb4 724 xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
dflet 0:1e7b5dd9edb4 725
dflet 0:1e7b5dd9edb4 726 /* Remove the timer from the list. */
dflet 0:1e7b5dd9edb4 727 pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
dflet 0:1e7b5dd9edb4 728 ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
dflet 0:1e7b5dd9edb4 729 traceTIMER_EXPIRED( pxTimer );
dflet 0:1e7b5dd9edb4 730
dflet 0:1e7b5dd9edb4 731 /* Execute its callback, then send a command to restart the timer if
dflet 0:1e7b5dd9edb4 732 it is an auto-reload timer. It cannot be restarted here as the lists
dflet 0:1e7b5dd9edb4 733 have not yet been switched. */
dflet 0:1e7b5dd9edb4 734 pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
dflet 0:1e7b5dd9edb4 735
dflet 0:1e7b5dd9edb4 736 if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
dflet 0:1e7b5dd9edb4 737 {
dflet 0:1e7b5dd9edb4 738 /* Calculate the reload value, and if the reload value results in
dflet 0:1e7b5dd9edb4 739 the timer going into the same timer list then it has already expired
dflet 0:1e7b5dd9edb4 740 and the timer should be re-inserted into the current list so it is
dflet 0:1e7b5dd9edb4 741 processed again within this loop. Otherwise a command should be sent
dflet 0:1e7b5dd9edb4 742 to restart the timer to ensure it is only inserted into a list after
dflet 0:1e7b5dd9edb4 743 the lists have been swapped. */
dflet 0:1e7b5dd9edb4 744 xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks );
dflet 0:1e7b5dd9edb4 745 if( xReloadTime > xNextExpireTime )
dflet 0:1e7b5dd9edb4 746 {
dflet 0:1e7b5dd9edb4 747 listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime );
dflet 0:1e7b5dd9edb4 748 listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
dflet 0:1e7b5dd9edb4 749 vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
dflet 0:1e7b5dd9edb4 750 }
dflet 0:1e7b5dd9edb4 751 else
dflet 0:1e7b5dd9edb4 752 {
dflet 0:1e7b5dd9edb4 753 xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );
dflet 0:1e7b5dd9edb4 754 configASSERT( xResult );
dflet 0:1e7b5dd9edb4 755 ( void ) xResult;
dflet 0:1e7b5dd9edb4 756 }
dflet 0:1e7b5dd9edb4 757 }
dflet 0:1e7b5dd9edb4 758 else
dflet 0:1e7b5dd9edb4 759 {
dflet 0:1e7b5dd9edb4 760 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 761 }
dflet 0:1e7b5dd9edb4 762 }
dflet 0:1e7b5dd9edb4 763
dflet 0:1e7b5dd9edb4 764 pxTemp = pxCurrentTimerList;
dflet 0:1e7b5dd9edb4 765 pxCurrentTimerList = pxOverflowTimerList;
dflet 0:1e7b5dd9edb4 766 pxOverflowTimerList = pxTemp;
dflet 0:1e7b5dd9edb4 767 }
dflet 0:1e7b5dd9edb4 768 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 769
dflet 0:1e7b5dd9edb4 770 static void prvCheckForValidListAndQueue( void )
dflet 0:1e7b5dd9edb4 771 {
dflet 0:1e7b5dd9edb4 772 /* Check that the list from which active timers are referenced, and the
dflet 0:1e7b5dd9edb4 773 queue used to communicate with the timer service, have been
dflet 0:1e7b5dd9edb4 774 initialised. */
dflet 0:1e7b5dd9edb4 775 taskENTER_CRITICAL();
dflet 0:1e7b5dd9edb4 776 {
dflet 0:1e7b5dd9edb4 777 if( xTimerQueue == NULL )
dflet 0:1e7b5dd9edb4 778 {
dflet 0:1e7b5dd9edb4 779 vListInitialise( &xActiveTimerList1 );
dflet 0:1e7b5dd9edb4 780 vListInitialise( &xActiveTimerList2 );
dflet 0:1e7b5dd9edb4 781 pxCurrentTimerList = &xActiveTimerList1;
dflet 0:1e7b5dd9edb4 782 pxOverflowTimerList = &xActiveTimerList2;
dflet 0:1e7b5dd9edb4 783 xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );
dflet 0:1e7b5dd9edb4 784 configASSERT( xTimerQueue );
dflet 0:1e7b5dd9edb4 785
dflet 0:1e7b5dd9edb4 786 #if ( configQUEUE_REGISTRY_SIZE > 0 )
dflet 0:1e7b5dd9edb4 787 {
dflet 0:1e7b5dd9edb4 788 if( xTimerQueue != NULL )
dflet 0:1e7b5dd9edb4 789 {
dflet 0:1e7b5dd9edb4 790 vQueueAddToRegistry( xTimerQueue, "TmrQ" );
dflet 0:1e7b5dd9edb4 791 }
dflet 0:1e7b5dd9edb4 792 else
dflet 0:1e7b5dd9edb4 793 {
dflet 0:1e7b5dd9edb4 794 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 795 }
dflet 0:1e7b5dd9edb4 796 }
dflet 0:1e7b5dd9edb4 797 #endif /* configQUEUE_REGISTRY_SIZE */
dflet 0:1e7b5dd9edb4 798 }
dflet 0:1e7b5dd9edb4 799 else
dflet 0:1e7b5dd9edb4 800 {
dflet 0:1e7b5dd9edb4 801 mtCOVERAGE_TEST_MARKER();
dflet 0:1e7b5dd9edb4 802 }
dflet 0:1e7b5dd9edb4 803 }
dflet 0:1e7b5dd9edb4 804 taskEXIT_CRITICAL();
dflet 0:1e7b5dd9edb4 805 }
dflet 0:1e7b5dd9edb4 806 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 807
dflet 0:1e7b5dd9edb4 808 BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )
dflet 0:1e7b5dd9edb4 809 {
dflet 0:1e7b5dd9edb4 810 BaseType_t xTimerIsInActiveList;
dflet 0:1e7b5dd9edb4 811 Timer_t *pxTimer = ( Timer_t * ) xTimer;
dflet 0:1e7b5dd9edb4 812
dflet 0:1e7b5dd9edb4 813 /* Is the timer in the list of active timers? */
dflet 0:1e7b5dd9edb4 814 taskENTER_CRITICAL();
dflet 0:1e7b5dd9edb4 815 {
dflet 0:1e7b5dd9edb4 816 /* Checking to see if it is in the NULL list in effect checks to see if
dflet 0:1e7b5dd9edb4 817 it is referenced from either the current or the overflow timer lists in
dflet 0:1e7b5dd9edb4 818 one go, but the logic has to be reversed, hence the '!'. */
dflet 0:1e7b5dd9edb4 819 xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) );
dflet 0:1e7b5dd9edb4 820 }
dflet 0:1e7b5dd9edb4 821 taskEXIT_CRITICAL();
dflet 0:1e7b5dd9edb4 822
dflet 0:1e7b5dd9edb4 823 return xTimerIsInActiveList;
dflet 0:1e7b5dd9edb4 824 } /*lint !e818 Can't be pointer to const due to the typedef. */
dflet 0:1e7b5dd9edb4 825 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 826
dflet 0:1e7b5dd9edb4 827 void *pvTimerGetTimerID( const TimerHandle_t xTimer )
dflet 0:1e7b5dd9edb4 828 {
dflet 0:1e7b5dd9edb4 829 Timer_t * const pxTimer = ( Timer_t * ) xTimer;
dflet 0:1e7b5dd9edb4 830 void *pvReturn;
dflet 0:1e7b5dd9edb4 831
dflet 0:1e7b5dd9edb4 832 configASSERT( xTimer );
dflet 0:1e7b5dd9edb4 833
dflet 0:1e7b5dd9edb4 834 taskENTER_CRITICAL();
dflet 0:1e7b5dd9edb4 835 {
dflet 0:1e7b5dd9edb4 836 pvReturn = pxTimer->pvTimerID;
dflet 0:1e7b5dd9edb4 837 }
dflet 0:1e7b5dd9edb4 838 taskEXIT_CRITICAL();
dflet 0:1e7b5dd9edb4 839
dflet 0:1e7b5dd9edb4 840 return pvReturn;
dflet 0:1e7b5dd9edb4 841 }
dflet 0:1e7b5dd9edb4 842 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 843
dflet 0:1e7b5dd9edb4 844 void vTimerSetTimerID( const TimerHandle_t xTimer, void *pvNewID )
dflet 0:1e7b5dd9edb4 845 {
dflet 0:1e7b5dd9edb4 846 Timer_t * const pxTimer = ( Timer_t * ) xTimer;
dflet 0:1e7b5dd9edb4 847
dflet 0:1e7b5dd9edb4 848 configASSERT( xTimer );
dflet 0:1e7b5dd9edb4 849
dflet 0:1e7b5dd9edb4 850 taskENTER_CRITICAL();
dflet 0:1e7b5dd9edb4 851 {
dflet 0:1e7b5dd9edb4 852 pxTimer->pvTimerID = pvNewID;
dflet 0:1e7b5dd9edb4 853 }
dflet 0:1e7b5dd9edb4 854 taskEXIT_CRITICAL();
dflet 0:1e7b5dd9edb4 855 }
dflet 0:1e7b5dd9edb4 856 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 857
dflet 0:1e7b5dd9edb4 858 #if( INCLUDE_xTimerPendFunctionCall == 1 )
dflet 0:1e7b5dd9edb4 859
dflet 0:1e7b5dd9edb4 860 BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken )
dflet 0:1e7b5dd9edb4 861 {
dflet 0:1e7b5dd9edb4 862 DaemonTaskMessage_t xMessage;
dflet 0:1e7b5dd9edb4 863 BaseType_t xReturn;
dflet 0:1e7b5dd9edb4 864
dflet 0:1e7b5dd9edb4 865 /* Complete the message with the function parameters and post it to the
dflet 0:1e7b5dd9edb4 866 daemon task. */
dflet 0:1e7b5dd9edb4 867 xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR;
dflet 0:1e7b5dd9edb4 868 xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
dflet 0:1e7b5dd9edb4 869 xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
dflet 0:1e7b5dd9edb4 870 xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;
dflet 0:1e7b5dd9edb4 871
dflet 0:1e7b5dd9edb4 872 xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
dflet 0:1e7b5dd9edb4 873
dflet 0:1e7b5dd9edb4 874 tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn );
dflet 0:1e7b5dd9edb4 875
dflet 0:1e7b5dd9edb4 876 return xReturn;
dflet 0:1e7b5dd9edb4 877 }
dflet 0:1e7b5dd9edb4 878
dflet 0:1e7b5dd9edb4 879 #endif /* INCLUDE_xTimerPendFunctionCall */
dflet 0:1e7b5dd9edb4 880 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 881
dflet 0:1e7b5dd9edb4 882 #if( INCLUDE_xTimerPendFunctionCall == 1 )
dflet 0:1e7b5dd9edb4 883
dflet 0:1e7b5dd9edb4 884 BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait )
dflet 0:1e7b5dd9edb4 885 {
dflet 0:1e7b5dd9edb4 886 DaemonTaskMessage_t xMessage;
dflet 0:1e7b5dd9edb4 887 BaseType_t xReturn;
dflet 0:1e7b5dd9edb4 888
dflet 0:1e7b5dd9edb4 889 /* This function can only be called after a timer has been created or
dflet 0:1e7b5dd9edb4 890 after the scheduler has been started because, until then, the timer
dflet 0:1e7b5dd9edb4 891 queue does not exist. */
dflet 0:1e7b5dd9edb4 892 configASSERT( xTimerQueue );
dflet 0:1e7b5dd9edb4 893
dflet 0:1e7b5dd9edb4 894 /* Complete the message with the function parameters and post it to the
dflet 0:1e7b5dd9edb4 895 daemon task. */
dflet 0:1e7b5dd9edb4 896 xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK;
dflet 0:1e7b5dd9edb4 897 xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
dflet 0:1e7b5dd9edb4 898 xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
dflet 0:1e7b5dd9edb4 899 xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;
dflet 0:1e7b5dd9edb4 900
dflet 0:1e7b5dd9edb4 901 xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );
dflet 0:1e7b5dd9edb4 902
dflet 0:1e7b5dd9edb4 903 tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn );
dflet 0:1e7b5dd9edb4 904
dflet 0:1e7b5dd9edb4 905 return xReturn;
dflet 0:1e7b5dd9edb4 906 }
dflet 0:1e7b5dd9edb4 907
dflet 0:1e7b5dd9edb4 908 #endif /* INCLUDE_xTimerPendFunctionCall */
dflet 0:1e7b5dd9edb4 909 /*-----------------------------------------------------------*/
dflet 0:1e7b5dd9edb4 910
dflet 0:1e7b5dd9edb4 911 /* This entire source file will be skipped if the application is not configured
dflet 0:1e7b5dd9edb4 912 to include software timer functionality. If you want to include software timer
dflet 0:1e7b5dd9edb4 913 functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
dflet 0:1e7b5dd9edb4 914 #endif /* configUSE_TIMERS == 1 */
dflet 0:1e7b5dd9edb4 915
dflet 0:1e7b5dd9edb4 916
dflet 0:1e7b5dd9edb4 917
dflet 0:1e7b5dd9edb4 918