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 26 /* Include necessary system files. */ 27 28 #include "tx_api.h" 29 #include "tx_timer.h" 30 31 32 /**************************************************************************/ 33 /* */ 34 /* FUNCTION RELEASE */ 35 /* */ 36 /* _tx_timer_system_activate PORTABLE C */ 37 /* 6.1 */ 38 /* AUTHOR */ 39 /* */ 40 /* William E. Lamie, Microsoft Corporation */ 41 /* */ 42 /* DESCRIPTION */ 43 /* */ 44 /* This function places the specified internal timer in the proper */ 45 /* place in the timer expiration list. If the timer is already active */ 46 /* this function does nothing. */ 47 /* */ 48 /* INPUT */ 49 /* */ 50 /* timer_ptr Pointer to timer control block */ 51 /* */ 52 /* OUTPUT */ 53 /* */ 54 /* TX_SUCCESS Always returns success */ 55 /* */ 56 /* CALLS */ 57 /* */ 58 /* None */ 59 /* */ 60 /* CALLED BY */ 61 /* */ 62 /* _tx_thread_system_suspend Thread suspend function */ 63 /* _tx_thread_system_ni_suspend Non-interruptable suspend thread */ 64 /* _tx_timer_thread_entry Timer thread processing */ 65 /* _tx_timer_activate Application timer activate */ 66 /* */ 67 /* RELEASE HISTORY */ 68 /* */ 69 /* DATE NAME DESCRIPTION */ 70 /* */ 71 /* 09-30-2020 William E. Lamie Initial Version 6.1 */ 72 /* */ 73 /**************************************************************************/ _tx_timer_system_activate(TX_TIMER_INTERNAL * timer_ptr)74VOID _tx_timer_system_activate(TX_TIMER_INTERNAL *timer_ptr) 75 { 76 77 TX_TIMER_INTERNAL **timer_list; 78 TX_TIMER_INTERNAL *next_timer; 79 TX_TIMER_INTERNAL *previous_timer; 80 ULONG delta; 81 ULONG remaining_ticks; 82 ULONG expiration_time; 83 84 85 /* Pickup the remaining ticks. */ 86 remaining_ticks = timer_ptr -> tx_timer_internal_remaining_ticks; 87 88 /* Determine if there is a timer to activate. */ 89 if (remaining_ticks != ((ULONG) 0)) 90 { 91 92 /* Determine if the timer is set to wait forever. */ 93 if (remaining_ticks != TX_WAIT_FOREVER) 94 { 95 96 /* Valid timer activate request. */ 97 98 /* Determine if the timer still needs activation. */ 99 if (timer_ptr -> tx_timer_internal_list_head == TX_NULL) 100 { 101 102 /* Activate the timer. */ 103 104 /* Calculate the amount of time remaining for the timer. */ 105 if (remaining_ticks > TX_TIMER_ENTRIES) 106 { 107 108 /* Set expiration time to the maximum number of entries. */ 109 expiration_time = TX_TIMER_ENTRIES - ((ULONG) 1); 110 } 111 else 112 { 113 114 /* Timer value fits in the timer entries. */ 115 116 /* Set the expiration time. */ 117 expiration_time = (remaining_ticks - ((ULONG) 1)); 118 } 119 120 /* At this point, we are ready to put the timer on one of 121 the timer lists. */ 122 123 /* Calculate the proper place for the timer. */ 124 timer_list = TX_TIMER_POINTER_ADD(_tx_timer_current_ptr, expiration_time); 125 if (TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(timer_list) >= TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(_tx_timer_list_end)) 126 { 127 128 /* Wrap from the beginning of the list. */ 129 delta = TX_TIMER_POINTER_DIF(timer_list, _tx_timer_list_end); 130 timer_list = TX_TIMER_POINTER_ADD(_tx_timer_list_start, delta); 131 } 132 133 /* Now put the timer on this list. */ 134 if ((*timer_list) == TX_NULL) 135 { 136 137 /* This list is NULL, just put the new timer on it. */ 138 139 /* Setup the links in this timer. */ 140 timer_ptr -> tx_timer_internal_active_next = timer_ptr; 141 timer_ptr -> tx_timer_internal_active_previous = timer_ptr; 142 143 /* Setup the list head pointer. */ 144 *timer_list = timer_ptr; 145 } 146 else 147 { 148 149 /* This list is not NULL, add current timer to the end. */ 150 next_timer = *timer_list; 151 previous_timer = next_timer -> tx_timer_internal_active_previous; 152 previous_timer -> tx_timer_internal_active_next = timer_ptr; 153 next_timer -> tx_timer_internal_active_previous = timer_ptr; 154 timer_ptr -> tx_timer_internal_active_next = next_timer; 155 timer_ptr -> tx_timer_internal_active_previous = previous_timer; 156 } 157 158 /* Setup list head pointer. */ 159 timer_ptr -> tx_timer_internal_list_head = timer_list; 160 } 161 } 162 } 163 } 164 165