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