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