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;/** Thread */ 18;/** */ 19;/**************************************************************************/ 20;/**************************************************************************/ 21 22 extern __tx_thread_execute_ptr 23 extern __tx_thread_current_ptr 24 extern __tx_timer_time_slice 25#if (TX_LOW_POWER == 1) 26 extern _tx_low_power_enter 27 extern _tx_low_power_exit 28 extern __tx_thread_preempt_disable 29#endif 30 31 section .text:CODE:ROOT 32 33;/**************************************************************************/ 34;/* */ 35;/* FUNCTION RELEASE */ 36;/* */ 37;/* _tx_thread_schedule RXv1/IAR */ 38;/* 6.1.11 */ 39;/* AUTHOR */ 40;/* */ 41;/* William E. Lamie, Microsoft Corporation */ 42;/* */ 43;/* DESCRIPTION */ 44;/* */ 45;/* This function waits for a thread control block pointer to appear in */ 46;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */ 47;/* in the variable, the corresponding thread is resumed. */ 48;/* */ 49;/* INPUT */ 50;/* */ 51;/* None */ 52;/* */ 53;/* OUTPUT */ 54;/* */ 55;/* None */ 56;/* */ 57;/* CALLS */ 58;/* */ 59;/* None */ 60;/* */ 61;/* CALLED BY */ 62;/* */ 63;/* _tx_initialize_kernel_enter ThreadX entry function */ 64;/* _tx_thread_system_return Return to system from thread */ 65;/* _tx_thread_context_restore Restore thread's context */ 66;/* */ 67;/* RELEASE HISTORY */ 68;/* */ 69;/* DATE NAME DESCRIPTION */ 70;/* */ 71;/* 08-02-2021 William E. Lamie Initial Version 6.1.8 */ 72;/* 10-15-2021 William E. Lamie Modified comment(s), and */ 73;/* removed unnecessary stack */ 74;/* type checking, */ 75;/* resulting in version 6.1.9 */ 76;/* 01-31-2022 William E. Lamie Modified comment(s), */ 77;/* resulting in version 6.1.10 */ 78;/* 04-25-2022 William E. Lamie Modified comment(s), and */ 79;/* added low power support, */ 80;/* resulting in version 6.1.11 */ 81;/* */ 82;/**************************************************************************/ 83;VOID _tx_thread_schedule(VOID) 84;{ 85 public __tx_thread_schedule 86 87__tx_thread_schedule: 88; 89; 90; /* Wait for a thread to execute. */ 91; do 92; { 93 MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr 94__tx_thread_schedule_loop: 95 SETPSW I ; Enable interrupts 96 CLRPSW I ; Disable interrupts 97 MOV.L [R1],R2 ; Pickup next thread to execute 98 CMP #0,R2 ; Is it NULL? 99 BNE __tx_thread_thread_ready ; Not NULL, schedule the thread 100 ; Idle system - no thread is ready 101#if (TX_LOW_POWER == 1) 102 MOV.L #__tx_thread_preempt_disable, R1 ; Load prempt disable flag. 103 MOV.L [R1], R2 104 ADD #1, R2 ; Disable preemption while enter/exit 105 MOV.L R2, [R1] 106 BSR _tx_low_power_enter ; Possibly enter low power mode 107#endif 108 109#if (TX_ENABLE_WAIT == 1) 110 WAIT ; Wait for interrupt 111#endif 112 113#if (TX_LOW_POWER == 1) 114 CLRPSW I ; Disable interrupts (because WAIT enables interrupts) 115 BSR _tx_low_power_exit ; Possibly exit low power mode 116 MOV.L #__tx_thread_preempt_disable, R1 ; Load prempt disable flag. 117 MOV.L [R1], R2 118 SUB #1, R2 ; Enable preemption 119 MOV.L R2, [R1] 120 MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr 121#endif 122 123 BRA __tx_thread_schedule_loop ; Idle system, keep checking 124 125__tx_thread_thread_ready: 126; 127; } 128; while(_tx_thread_execute_ptr == TX_NULL); 129; 130; /* Yes! We have a thread to execute. Note that interrupts are locked out at this point. */ 131; 132; /* Setup the current thread pointer. */ 133; _tx_thread_current_ptr = _tx_thread_execute_ptr; 134; 135 MOV.L #__tx_thread_current_ptr, R3 136 MOV.L R2,[R3] ; Setup current thread pointer 137; 138; /* Increment the run count for this thread. */ 139; _tx_thread_current_ptr -> tx_thread_run_count++; 140; 141 MOV.L 4[R2],R3 ; Pickup run count 142 ADD #1,R3 ; Increment run counter 143 MOV.L R3,4[R2] ; Store it back in control block 144; 145; /* Setup time-slice, if present. */ 146; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; 147; 148 MOV.L 24[R2],R3 ; Pickup thread time-slice 149 MOV.L #__tx_timer_time_slice,R4 ; Pickup pointer to time-slice 150 MOV.L R3, [R4] ; Setup time-slice 151; 152; /* Switch to the thread's stack. */ 153; SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr; 154 SETPSW U ; User stack mode 155 MOV.L 8[R2],R0 ; Pickup stack pointer 156; 157; /* Determine if an interrupt frame or a synchronous task suspension frame 158; is present. */ 159; 160 POPM R1-R2 ; Restore accumulator. 161 MVTACLO R2 162 MVTACHI R1 163 164 POPM R6-R13 ; Recover interrupt stack frame 165 POPM R14-R15 166 POPM R3-R5 167 POPM R1-R2 168 RTE ; Return to point of interrupt, this restores PC and PSW 169 170; 171;} 172 173 extern __tx_thread_context_save 174 extern __tx_thread_context_restore 175 176; Software triggered interrupt used to perform context switches. 177; The priority of this interrupt is set to the lowest priority within 178; tx_initialize_low_level() and triggered by ThreadX when calling 179; _tx_thread_system_return(). 180 public ___interrupt_27 181___interrupt_27: 182 183 PUSHM R1-R2 184 185 BSR __tx_thread_context_save 186 187 BRA __tx_thread_context_restore 188 189 END 190