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