+/*-----------------------------------------------------------*/\r
+\r
+unsigned long ulMainGetRunTimeCounterValue( void )\r
+{\r
+unsigned long ulSysTickCounts, ulTickCount, ulReturn;\r
+const unsigned long ulSysTickReloadValue = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
+volatile unsigned long * const pulCurrentSysTickCount = ( ( volatile unsigned long *) 0xe000e018 );\r
+volatile unsigned long * const pulInterruptCTRLState = ( ( volatile unsigned long *) 0xe000ed04 );\r
+const unsigned long ulSysTickPendingBit = 0x04000000UL;\r
+\r
+ /* Used by the optional run-time stats gathering functionality. */\r
+\r
+\r
+ /* NOTE: There are potentially race conditions here. However, it is used\r
+ anyway to keep the examples simple, and to avoid reliance on a separate\r
+ timer peripheral. */\r
+\r
+\r
+ /* The SysTick is a down counter. How many clocks have passed since it was\r
+ last reloaded? */\r
+ ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount;\r
+ \r
+ /* How many times has it overflowed? */\r
+ ulTickCount = xTaskGetTickCountFromISR();\r
+\r
+ /* This is called from the context switch, so will be called from a\r
+ critical section. xTaskGetTickCountFromISR() contains its own critical\r
+ section, and the ISR safe critical sections are not designed to nest,\r
+ so reset the critical section. */\r
+ portSET_INTERRUPT_MASK_FROM_ISR();\r
+ \r
+ /* Is there a SysTick interrupt pending? */\r
+ if( ( *pulInterruptCTRLState & ulSysTickPendingBit ) != 0UL )\r
+ {\r
+ /* There is a SysTick interrupt pending, so the SysTick has overflowed\r
+ but the tick count not yet incremented. */\r
+ ulTickCount++;\r
+ \r
+ /* Read the SysTick again, as the overflow might have occurred since\r
+ it was read last. */\r
+ ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount;\r
+ } \r
+ \r
+ /* Convert the tick count into tenths of a millisecond. THIS ASSUMES\r
+ configTICK_RATE_HZ is 1000! */\r
+ ulReturn = ( ulTickCount * 10UL ) ;\r
+ \r
+ /* Add on the number of tenths of a millisecond that have passed since the\r
+ tick count last got updated. */\r
+ ulReturn += ( ulSysTickCounts / ulClocksPer10thOfAMilliSecond );\r
+ \r
+ return ulReturn; \r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#ifdef JUST_AN_EXAMPLE_ISR\r
+\r
+void Dummy_IRQHandler(void)\r
+{\r
+long lHigherPriorityTaskWoken = pdFALSE;\r
+\r
+ /* Clear the interrupt if necessary. */\r
+ Dummy_ClearITPendingBit();\r
+\r
+ /* This interrupt does nothing more than demonstrate how to synchronise a\r
+ task with an interrupt. A semaphore is used for this purpose. Note\r
+ lHigherPriorityTaskWoken is initialised to zero. Only FreeRTOS API functions\r
+ that end in "FromISR" can be called from an ISR. */\r
+ xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );\r
+\r
+ /* If there was a task that was blocked on the semaphore, and giving the\r
+ semaphore caused the task to unblock, and the unblocked task has a priority\r
+ higher than the current Running state task (the task that this interrupt\r
+ interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE\r
+ internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the\r
+ portEND_SWITCHING_ISR() macro will result in a context switch being pended to\r
+ ensure this interrupt returns directly to the unblocked, higher priority,\r
+ task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */\r
+ portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );\r
+}\r
+\r
+#endif /* JUST_AN_EXAMPLE_ISR */\r