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#ifdef TX_INCLUDE_USER_DEFINE_FILE 24#include "tx_user.h" 25#endif 26 27 EXTERN _tx_timer_time_slice 28 EXTERN _tx_timer_system_clock 29 EXTERN _tx_timer_current_ptr 30 EXTERN _tx_timer_list_start 31 EXTERN _tx_timer_list_end 32 EXTERN _tx_timer_expired_time_slice 33 EXTERN _tx_timer_expired 34 EXTERN _tx_thread_time_slice 35 EXTERN _tx_timer_expiration_process 36 EXTERN _tx_thread_current_ptr 37 EXTERN _tx_thread_execute_ptr 38 EXTERN _tx_thread_preempt_disable 39 40 SECTION `.text`:CODE:NOROOT(2) 41 THUMB 42/**************************************************************************/ 43/* */ 44/* FUNCTION RELEASE */ 45/* */ 46/* _tx_timer_interrupt Cortex-Mx/IAR */ 47/* 6.3.0 */ 48/* AUTHOR */ 49/* */ 50/* Scott Larson, Microsoft Corporation */ 51/* */ 52/* DESCRIPTION */ 53/* */ 54/* This function processes the hardware timer interrupt. This */ 55/* processing includes incrementing the system clock and checking for */ 56/* time slice and/or timer expiration. If either is found, the */ 57/* expiration functions are called. */ 58/* */ 59/* INPUT */ 60/* */ 61/* None */ 62/* */ 63/* OUTPUT */ 64/* */ 65/* None */ 66/* */ 67/* CALLS */ 68/* */ 69/* _tx_timer_expiration_process Timer expiration processing */ 70/* _tx_thread_time_slice Time slice interrupted thread */ 71/* */ 72/* CALLED BY */ 73/* */ 74/* interrupt vector */ 75/* */ 76/* RELEASE HISTORY */ 77/* */ 78/* DATE NAME DESCRIPTION */ 79/* */ 80/* 06-02-2021 Scott Larson Initial Version 6.1.7 */ 81/* 01-31-2022 Scott Larson Modified comment(s), added */ 82/* TX_NO_TIMER support, */ 83/* resulting in version 6.1.10 */ 84/* 10-31-2023 Tiejun Zhou Included tx_user.h, */ 85/* resulting in version 6.3.0 */ 86/* */ 87/**************************************************************************/ 88// VOID _tx_timer_interrupt(VOID) 89// { 90#ifndef TX_NO_TIMER 91 PUBLIC _tx_timer_interrupt 92_tx_timer_interrupt: 93 94 /* Upon entry to this routine, it is assumed that the compiler scratch registers are available 95 for use. */ 96 97 /* Increment the system clock. */ 98 // _tx_timer_system_clock++; 99 100 LDR r1, =_tx_timer_system_clock // Pickup address of system clock 101 LDR r0, [r1, #0] // Pickup system clock 102 ADD r0, r0, #1 // Increment system clock 103 STR r0, [r1, #0] // Store new system clock 104 105 /* Test for time-slice expiration. */ 106 // if (_tx_timer_time_slice) 107 // { 108 109 LDR r3, =_tx_timer_time_slice // Pickup address of time-slice 110 LDR r2, [r3, #0] // Pickup time-slice 111 CBZ r2, __tx_timer_no_time_slice // Is it non-active? 112 // Yes, skip time-slice processing 113 114 /* Decrement the time_slice. */ 115 // _tx_timer_time_slice--; 116 117 SUB r2, r2, #1 // Decrement the time-slice 118 STR r2, [r3, #0] // Store new time-slice value 119 120 /* Check for expiration. */ 121 // if (__tx_timer_time_slice == 0) 122 123 CBNZ r2, __tx_timer_no_time_slice // Has it expired? 124 // No, skip expiration processing 125 126 /* Set the time-slice expired flag. */ 127 // _tx_timer_expired_time_slice = TX_TRUE; 128 129 LDR r3, =_tx_timer_expired_time_slice // Pickup address of expired flag 130 MOV r0, #1 // Build expired value 131 STR r0, [r3, #0] // Set time-slice expiration flag 132 133 // } 134 135__tx_timer_no_time_slice: 136 137 /* Test for timer expiration. */ 138 // if (*_tx_timer_current_ptr) 139 // { 140 141 LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address 142 LDR r0, [r1, #0] // Pickup current timer 143 LDR r2, [r0, #0] // Pickup timer list entry 144 CBZ r2, __tx_timer_no_timer // Is there anything in the list? 145 // No, just increment the timer 146 147 /* Set expiration flag. */ 148 // _tx_timer_expired = TX_TRUE; 149 150 LDR r3, =_tx_timer_expired // Pickup expiration flag address 151 MOV r2, #1 // Build expired value 152 STR r2, [r3, #0] // Set expired flag 153 B __tx_timer_done // Finished timer processing 154 155 // } 156 // else 157 // { 158__tx_timer_no_timer: 159 160 /* No timer expired, increment the timer pointer. */ 161 // _tx_timer_current_ptr++; 162 163 ADD r0, r0, #4 // Move to next timer 164 165 /* Check for wrap-around. */ 166 // if (_tx_timer_current_ptr == _tx_timer_list_end) 167 168 LDR r3, =_tx_timer_list_end // Pickup addr of timer list end 169 LDR r2, [r3, #0] // Pickup list end 170 CMP r0, r2 // Are we at list end? 171 BNE __tx_timer_skip_wrap // No, skip wrap-around logic 172 173 /* Wrap to beginning of list. */ 174 // _tx_timer_current_ptr = _tx_timer_list_start; 175 176 LDR r3, =_tx_timer_list_start // Pickup addr of timer list start 177 LDR r0, [r3, #0] // Set current pointer to list start 178 179__tx_timer_skip_wrap: 180 181 STR r0, [r1, #0] // Store new current timer pointer 182 // } 183 184__tx_timer_done: 185 186 /* See if anything has expired. */ 187 // if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) 188 // { 189 190 LDR r3, =_tx_timer_expired_time_slice // Pickup addr of expired flag 191 LDR r2, [r3, #0] // Pickup time-slice expired flag 192 CBNZ r2, __tx_something_expired // Did a time-slice expire? 193 // If non-zero, time-slice expired 194 LDR r1, =_tx_timer_expired // Pickup addr of other expired flag 195 LDR r0, [r1, #0] // Pickup timer expired flag 196 CBZ r0, __tx_timer_nothing_expired // Did a timer expire? 197 // No, nothing expired 198 199__tx_something_expired: 200 201 STMDB sp!, {r0, lr} // Save the lr register on the stack 202 // and save r0 just to keep 8-byte alignment 203 204 /* Did a timer expire? */ 205 // if (_tx_timer_expired) 206 // { 207 208 LDR r1, =_tx_timer_expired // Pickup addr of expired flag 209 LDR r0, [r1, #0] // Pickup timer expired flag 210 CBZ r0, __tx_timer_dont_activate // Check for timer expiration 211 // If not set, skip timer activation 212 213 /* Process timer expiration. */ 214 // _tx_timer_expiration_process(); 215 216 BL _tx_timer_expiration_process // Call the timer expiration handling routine 217 218 // } 219__tx_timer_dont_activate: 220 221 /* Did time slice expire? */ 222 // if (_tx_timer_expired_time_slice) 223 // { 224 225 LDR r3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired 226 LDR r2, [r3, #0] // Pickup the actual flag 227 CBZ r2, __tx_timer_not_ts_expiration // See if the flag is set 228 // No, skip time-slice processing 229 230 /* Time slice interrupted thread. */ 231 // _tx_thread_time_slice(); 232 233 BL _tx_thread_time_slice // Call time-slice processing 234 LDR r0, =_tx_thread_preempt_disable // Build address of preempt disable flag 235 LDR r1, [r0] // Is the preempt disable flag set? 236 CBNZ r1, __tx_timer_skip_time_slice // Yes, skip the PendSV logic 237 LDR r0, =_tx_thread_current_ptr // Build current thread pointer address 238 LDR r1, [r0] // Pickup the current thread pointer 239 LDR r2, =_tx_thread_execute_ptr // Build execute thread pointer address 240 LDR r3, [r2] // Pickup the execute thread pointer 241 LDR r0, =0xE000ED04 // Build address of control register 242 LDR r2, =0x10000000 // Build value for PendSV bit 243 CMP r1, r3 // Are they the same? 244 BEQ __tx_timer_skip_time_slice // If the same, there was no time-slice performed 245 STR r2, [r0] // Not the same, issue the PendSV for preemption 246__tx_timer_skip_time_slice: 247 248 // } 249 250__tx_timer_not_ts_expiration: 251 252 LDMIA sp!, {r0, lr} // Recover lr register (r0 is just there for 253 // the 8-byte stack alignment 254 255 // } 256 257__tx_timer_nothing_expired: 258 259 DSB // Complete all memory access 260 BX lr // Return to caller 261// } 262#endif 263 END 264