1/*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12/**************************************************************************/ 13/**************************************************************************/ 14/** */ 15/** ThreadX Component */ 16/** */ 17/** Timer */ 18/** */ 19/**************************************************************************/ 20/**************************************************************************/ 21 22/* #define TX_SOURCE_CODE */ 23 24 25/* Include necessary system files. */ 26 27/* #include "tx_api.h" 28 #include "tx_timer.h" 29 #include "tx_thread.h" */ 30 31 EXTERN _tx_timer_system_clock 32 EXTERN _tx_timer_time_slice 33 EXTERN _tx_timer_expired_time_slice 34 EXTERN _tx_timer_current_ptr 35 EXTERN _tx_timer_expired 36 EXTERN _tx_timer_list_end 37 EXTERN _tx_timer_list_start 38 EXTERN _tx_timer_expiration_process 39 EXTERN _tx_thread_time_slice 40 41 42 SECTION `.mtext`:CODE:REORDER:NOROOT(2) 43 CODE 44/**************************************************************************/ 45/* */ 46/* FUNCTION RELEASE */ 47/* */ 48/* _tx_timer_interrupt RISC-V32/IAR */ 49/* 6.1 */ 50/* AUTHOR */ 51/* */ 52/* William E. Lamie, Microsoft Corporation */ 53/* Tom van Leeuwen, Technolution B.V. */ 54/* */ 55/* DESCRIPTION */ 56/* */ 57/* This function processes the hardware timer interrupt. This */ 58/* processing includes incrementing the system clock and checking for */ 59/* time slice and/or timer expiration. If either is found, the */ 60/* interrupt context save/restore functions are called along with the */ 61/* expiration functions. */ 62/* */ 63/* INPUT */ 64/* */ 65/* None */ 66/* */ 67/* OUTPUT */ 68/* */ 69/* None */ 70/* */ 71/* CALLS */ 72/* */ 73/* _tx_timer_expiration_process Timer expiration processing */ 74/* _tx_thread_time_slice Time slice interrupted thread */ 75/* */ 76/* CALLED BY */ 77/* */ 78/* interrupt vector */ 79/* */ 80/* RELEASE HISTORY */ 81/* */ 82/* DATE NAME DESCRIPTION */ 83/* */ 84/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 85/* */ 86/**************************************************************************/ 87/* VOID _tx_timer_interrupt(VOID) 88{ */ 89 PUBLIC _tx_timer_interrupt 90_tx_timer_interrupt: 91 92 /* Increment the system clock. */ 93 /* _tx_timer_system_clock++; */ 94 95 la t0, _tx_timer_system_clock ; Pickup address of system clock 96 lw t1, 0(t0) ; Pickup system clock 97 la t2, _tx_timer_time_slice ; Pickup address of time slice 98 lw t3, 0(t2) ; Pickup time slice 99 addi t1, t1, 1 ; Increment system clock 100 sw t1, 0(t0) ; Store new system clock 101 li t6, 0 ; Clear local expired flag 102 103 /* Test for time-slice expiration. */ 104 /* if (_tx_timer_time_slice) 105 { */ 106 107 beqz t3, _tx_timer_no_time_slice ; If 0, skip time slice processing 108 addi t3, t3, -1 ; Decrement the time slice 109 110 /* Decrement the time_slice. */ 111 /* _tx_timer_time_slice--; */ 112 113 sw t3, 0(t2) ; Store new time slice 114 115 /* Check for expiration. */ 116 /* if (__tx_timer_time_slice == 0) */ 117 118 bgtz t3, _tx_timer_no_time_slice ; If not 0, has not expired yet 119 li t1, 1 ; Build expired flag 120 121 /* Set the time-slice expired flag. */ 122 /* _tx_timer_expired_time_slice = TX_TRUE; */ 123 124 la t4, _tx_timer_expired_time_slice ; Get address of expired flag 125 sw t1, 0(t4) ; Set expired flag 126 ori t6, t6, 1 ; Set local expired flag 127 128 /* } */ 129 130_tx_timer_no_time_slice: 131 132 /* Test for timer expiration. */ 133 /* if (*_tx_timer_current_ptr) 134 { */ 135 136 la t0, _tx_timer_current_ptr ; Pickup address of current ptr 137 lw t1, 0(t0) ; Pickup current pointer 138 lw t3, 0(t1) ; Pickup the current timer entry 139 la t2, _tx_timer_expired ; Pickup address of timer expired flag 140 li t4, 1 ; Build TX_TRUE flag 141 beqz t3, _tx_timer_no_timer ; If NULL, no timer has expired 142 143 /* Set expiration flag. */ 144 /* _tx_timer_expired = TX_TRUE; */ 145 146 ori t6, t6, 2 ; Set local expired flag 147 sw t4, 0(t2) ; Set expired flag in memory 148 j _tx_timer_done ; Finished timer processing 149 150 151 /* } 152 else 153 { */ 154_tx_timer_no_timer: 155 156 /* No timer expired, increment the timer pointer. */ 157 /* _tx_timer_current_ptr++; */ 158 159 /* Check for wrap-around. */ 160 /* if (_tx_timer_current_ptr == _tx_timer_list_end) */ 161 162 la t2, _tx_timer_list_end ; Pickup address of list end pointer 163 lw t3, 0(t2) ; Pickup actual list end 164 addi t1, t1, 4 ; Point to next timer entry 165 sw t1, 0(t0) ; Store new timer pointer 166 bne t1, t3, _tx_timer_skip_wrap ; If not same, good pointer 167 168 /* Wrap to beginning of list. */ 169 /* _tx_timer_current_ptr = _tx_timer_list_start; */ 170 171 la t2, _tx_timer_list_start ; Pickup address of list start pointer 172 lw t4, 0(t2) ; Pickup start of the list 173 sw t4, 0(t0) ; Store new timer pointer*/ 174 175 176_tx_timer_skip_wrap: 177 /* } */ 178 179_tx_timer_done: 180 181 182 /* See if anything has expired. */ 183 /* if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) 184 { */ 185 186 beqz t6, _tx_timer_nothing_expired ; If nothing expired skip the rest 187 and t2, t6, 2 ; Isolate the timer expired bit 188 addi sp, sp, -16 ; Allocate some storage on the stack 189 sw t6, 0(sp) ; Save local expired flag 190 sw ra, 4(sp) ; Save ra 191 192 /* Did a timer expire? */ 193 /* if (_tx_timer_expired) 194 { */ 195 196 beqz t2, _tx_timer_dont_activate ; No, timer not expired 197 198 /* Call the timer expiration processing. */ 199 /* _tx_timer_expiration_process(void); */ 200 201 call _tx_timer_expiration_process ; Call _tx_timer_expiration_process 202 lw t6, 0(sp) ; Recover local expired flag 203 204 /* } */ 205_tx_timer_dont_activate: 206 207 /* Did time slice expire? */ 208 /* if (_tx_timer_expired_time_slice) 209 { */ 210 211 and t2, t6, 1 ; Is the timer expired bit set? 212 beqz t2, _tx_timer_not_ts_expiration ; If not, skip time slice processing 213 214 /* Time slice interrupted thread. */ 215 /* _tx_thread_time_slice(); */ 216 217 call _tx_thread_time_slice ; Call time slice 218 219 /* } */ 220 221_tx_timer_not_ts_expiration: 222 223 lw ra, 4(sp) ; Recover ra 224 addi sp, sp, 16 ; Recover stack space 225 /* } */ 226 227_tx_timer_nothing_expired: 228 229 ret 230 231/* } */ 232 END 233