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