1 /**************************************************************************/ 2 /* */ 3 /* Copyright (c) Microsoft Corporation. All rights reserved. */ 4 /* */ 5 /* This software is licensed under the Microsoft Software License */ 6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8 /* and in the root directory of this software. */ 9 /* */ 10 /**************************************************************************/ 11 12 13 /**************************************************************************/ 14 /**************************************************************************/ 15 /** */ 16 /** ThreadX Component */ 17 /** */ 18 /** Timer */ 19 /** */ 20 /**************************************************************************/ 21 /**************************************************************************/ 22 23 #define TX_SOURCE_CODE 24 25 #ifndef TX_NO_TIMER 26 27 /* Include necessary system files. */ 28 29 #include "tx_api.h" 30 #include "tx_timer.h" 31 32 33 /**************************************************************************/ 34 /* */ 35 /* FUNCTION RELEASE */ 36 /* */ 37 /* _tx_timer_system_activate PORTABLE C */ 38 /* 6.1 */ 39 /* AUTHOR */ 40 /* */ 41 /* William E. Lamie, Microsoft Corporation */ 42 /* */ 43 /* DESCRIPTION */ 44 /* */ 45 /* This function places the specified internal timer in the proper */ 46 /* place in the timer expiration list. If the timer is already active */ 47 /* this function does nothing. */ 48 /* */ 49 /* INPUT */ 50 /* */ 51 /* timer_ptr Pointer to timer control block */ 52 /* */ 53 /* OUTPUT */ 54 /* */ 55 /* TX_SUCCESS Always returns success */ 56 /* */ 57 /* CALLS */ 58 /* */ 59 /* None */ 60 /* */ 61 /* CALLED BY */ 62 /* */ 63 /* _tx_thread_system_suspend Thread suspend function */ 64 /* _tx_thread_system_ni_suspend Non-interruptable suspend thread */ 65 /* _tx_timer_thread_entry Timer thread processing */ 66 /* _tx_timer_activate Application timer activate */ 67 /* */ 68 /* RELEASE HISTORY */ 69 /* */ 70 /* DATE NAME DESCRIPTION */ 71 /* */ 72 /* 05-19-2020 William E. Lamie Initial Version 6.0 */ 73 /* 09-30-2020 Scott Larson Modified comment(s), and */ 74 /* opt out of function when */ 75 /* TX_NO_TIMER is defined, */ 76 /* resulting in version 6.1 */ 77 /* */ 78 /**************************************************************************/ _tx_timer_system_activate(TX_TIMER_INTERNAL * timer_ptr)79VOID _tx_timer_system_activate(TX_TIMER_INTERNAL *timer_ptr) 80 { 81 82 TX_TIMER_INTERNAL **timer_list; 83 TX_TIMER_INTERNAL *next_timer; 84 TX_TIMER_INTERNAL *previous_timer; 85 ULONG delta; 86 ULONG remaining_ticks; 87 ULONG expiration_time; 88 89 90 /* Pickup the remaining ticks. */ 91 remaining_ticks = timer_ptr -> tx_timer_internal_remaining_ticks; 92 93 /* Determine if there is a timer to activate. */ 94 if (remaining_ticks != ((ULONG) 0)) 95 { 96 97 /* Determine if the timer is set to wait forever. */ 98 if (remaining_ticks != TX_WAIT_FOREVER) 99 { 100 101 /* Valid timer activate request. */ 102 103 /* Determine if the timer still needs activation. */ 104 if (timer_ptr -> tx_timer_internal_list_head == TX_NULL) 105 { 106 107 /* Activate the timer. */ 108 109 /* Calculate the amount of time remaining for the timer. */ 110 if (remaining_ticks > TX_TIMER_ENTRIES) 111 { 112 113 /* Set expiration time to the maximum number of entries. */ 114 expiration_time = TX_TIMER_ENTRIES - ((ULONG) 1); 115 } 116 else 117 { 118 119 /* Timer value fits in the timer entries. */ 120 121 /* Set the expiration time. */ 122 expiration_time = (remaining_ticks - ((ULONG) 1)); 123 } 124 125 /* At this point, we are ready to put the timer on one of 126 the timer lists. */ 127 128 /* Calculate the proper place for the timer. */ 129 timer_list = TX_TIMER_POINTER_ADD(_tx_timer_current_ptr, expiration_time); 130 if (TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(timer_list) >= TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(_tx_timer_list_end)) 131 { 132 133 /* Wrap from the beginning of the list. */ 134 delta = TX_TIMER_POINTER_DIF(timer_list, _tx_timer_list_end); 135 timer_list = TX_TIMER_POINTER_ADD(_tx_timer_list_start, delta); 136 } 137 138 /* Now put the timer on this list. */ 139 if ((*timer_list) == TX_NULL) 140 { 141 142 /* This list is NULL, just put the new timer on it. */ 143 144 /* Setup the links in this timer. */ 145 timer_ptr -> tx_timer_internal_active_next = timer_ptr; 146 timer_ptr -> tx_timer_internal_active_previous = timer_ptr; 147 148 /* Setup the list head pointer. */ 149 *timer_list = timer_ptr; 150 } 151 else 152 { 153 154 /* This list is not NULL, add current timer to the end. */ 155 next_timer = *timer_list; 156 previous_timer = next_timer -> tx_timer_internal_active_previous; 157 previous_timer -> tx_timer_internal_active_next = timer_ptr; 158 next_timer -> tx_timer_internal_active_previous = timer_ptr; 159 timer_ptr -> tx_timer_internal_active_next = next_timer; 160 timer_ptr -> tx_timer_internal_active_previous = previous_timer; 161 } 162 163 /* Setup list head pointer. */ 164 timer_ptr -> tx_timer_internal_list_head = timer_list; 165 } 166 } 167 } 168 } 169 170 #endif 171