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 .global __tx_thread_execute_ptr 24 .global __tx_thread_current_ptr 25 .global __tx_timer_time_slice 26#if (TX_LOW_POWER == 1) 27 .global _tx_low_power_enter 28 .global _tx_low_power_exit 29 .global __tx_thread_preempt_disable 30#endif 31; 32 .text 33 34;/**************************************************************************/ 35;/* */ 36;/* FUNCTION RELEASE */ 37;/* */ 38;/* _tx_thread_schedule RXv1/GNURX */ 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 .global __tx_thread_schedule 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 POPM R1-R2 ; Restore accumulator. 158 MVTACLO R2 159 MVTACHI R1 160 161 POPM R6-R13 ; Recover interrupt stack frame 162 POPM R14-R15 163 POPM R3-R5 164 POPM R1-R2 165 RTE ; Return to point of interrupt, this restores PC and PSW 166 167;} 168 169 170.global __tx_thread_context_save 171.global __tx_thread_context_restore 172 173 174; Software triggered interrupt used to perform context switches. 175; The priority of this interrupt is set to the lowest priority within 176; tx_initialize_low_level() and triggered by ThreadX when calling 177; _tx_thread_system_return(). 178.global $tableentry$27$.rvectors 179$tableentry$27$.rvectors: 180 181 PUSHM R1-R2 182 183 BSR __tx_thread_context_save 184 185 BRA __tx_thread_context_restore 186 187 .end 188