6.1 minor release

This commit is contained in:
Scott Larson
2020-09-30 15:42:41 -07:00
parent 7287542cc8
commit 1b5816a206
3038 changed files with 377204 additions and 8606 deletions

View File

@@ -0,0 +1,259 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 # Disable IRQ and FIQ interrupts
#else
DISABLE_INTS = 0x80 # Disable IRQ interrupts
#endif
SVC_MODE = (0x13 | DISABLE_INTS) # SVC mode
IRQ_MODE = (0x12 | DISABLE_INTS) # IRQ mode
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function restores the interrupt context if it is processing a */
/* nested interrupt. If not, it returns to the interrupt thread if no */
/* preemption is necessary. Otherwise, if preemption is necessary or */
/* if no thread was running, the function returns to the scheduler. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_schedule Thread scheduling routine */
/* */
/* CALLED BY */
/* */
/* ISRs Interrupt Service Routines */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_restore(VOID)
{ */
.globl _tx_thread_context_restore
_tx_thread_context_restore:
/* Lockout interrupts. */
#ifdef TX_BEFORE_ARMV6
MRS r3, CPSR # Pickup current CPSR
ORR r0, r3, DISABLE_INTS # Build interrupt disable value
MSR CPSR_c, r0 # Lockout interrupts
#else
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if # Disable IRQ and FIQ interrupts
#else
CPSID i # Disable IRQ interrupts
#endif
#endif
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR exit function to indicate an ISR is complete. */
BL _tx_execution_isr_exit # Call the ISR exit function
#endif
/* Determine if interrupts are nested. */
/* if (--_tx_thread_system_state)
{ */
LDR r3, =_tx_thread_system_state # Pickup address of system state var
LDR r2, [r3] # Pickup system state
SUB r2, r2, 1 # Decrement the counter
STR r2, [r3] # Store the counter
CMP r2, 0 # Was this the first interrupt?
BEQ __tx_thread_not_nested_restore # If so, not a nested restore
/* Interrupts are nested. */
/* Just recover the saved registers and return to the point of
interrupt. */
LDMIA sp!, {r0, r10, r12, lr} # Recover SPSR, POI, and scratch regs
MSR SPSR_cxsf, r0 # Put SPSR back
LDMIA sp!, {r0-r3} # Recover r0-r3
MOVS pc, lr # Return to point of interrupt
/* } */
__tx_thread_not_nested_restore:
/* Determine if a thread was interrupted and no preemption is required. */
/* else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
|| (_tx_thread_preempt_disable))
{ */
LDR r1, =_tx_thread_current_ptr # Pickup address of current thread ptr
LDR r0, [r1] # Pickup actual current thread pointer
CMP r0, 0 # Is it NULL?
BEQ __tx_thread_idle_system_restore # Yes, idle system was interrupted
LDR r3, =_tx_thread_preempt_disable # Pickup preempt disable address
LDR r2, [r3] # Pickup actual preempt disable flag
CMP r2, 0 # Is it set?
BNE __tx_thread_no_preempt_restore # Yes, don't preempt this thread
LDR r3, =_tx_thread_execute_ptr # Pickup address of execute thread ptr
LDR r2, [r3] # Pickup actual execute thread pointer
CMP r0, r2 # Is the same thread highest priority?
BNE __tx_thread_preempt_restore # No, preemption needs to happen
__tx_thread_no_preempt_restore:
/* Restore interrupted thread or ISR. */
/* Pickup the saved stack pointer. */
/* tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr; */
/* Recover the saved context and return to the point of interrupt. */
LDMIA sp!, {r0, r10, r12, lr} # Recover SPSR, POI, and scratch regs
MSR SPSR_cxsf, r0 # Put SPSR back
LDMIA sp!, {r0-r3} # Recover r0-r3
MOVS pc, lr # Return to point of interrupt
/* }
else
{ */
__tx_thread_preempt_restore:
LDMIA sp!, {r3, r10, r12, lr} # Recover temporarily saved registers
MOV r1, lr # Save lr (point of interrupt)
MOV r2, SVC_MODE # Build SVC mode CPSR
MSR CPSR_c, r2 # Enter SVC mode
STR r1, [sp, -4]! # Save point of interrupt
STMDB sp!, {r4-r12, lr} # Save upper half of registers
MOV r4, r3 # Save SPSR in r4
MOV r2, IRQ_MODE # Build IRQ mode CPSR
MSR CPSR_c, r2 # Re-enter IRQ mode
LDMIA sp!, {r0-r3} # Recover r0-r3
MOV r5, SVC_MODE # Build SVC mode CPSR
MSR CPSR_c, r5 # Enter SVC mode
STMDB sp!, {r0-r3} # Save r0-r3 on thread's stack
LDR r1, =_tx_thread_current_ptr # Pickup address of current thread ptr
LDR r0, [r1] # Pickup current thread pointer
#ifdef __VFP__
LDR r2, [r0, 144] # Pickup the VFP enabled flag
CMP r2, 0 # Is the VFP enabled?
BEQ _tx_skip_irq_vfp_save # No, skip VFP IRQ save
VMRS r2, FPSCR # Pickup the FPSCR
STR r2, [sp, -4]! # Save FPSCR
VSTMDB sp!, {D16-D31} # Save D16-D31
VSTMDB sp!, {D0-D15} # Save D0-D15
_tx_skip_irq_vfp_save:
#endif
MOV r3, 1 # Build interrupt stack type
STMDB sp!, {r3, r4} # Save interrupt stack type and SPSR
STR sp, [r0, 8] # Save stack pointer in thread control
/* # block */
#ifdef TX_ENABLE_EVENT_LOGGING
MOV r4, r0 # Save r0
MOV r5, r1 # Save r1
BL _tx_el_thread_preempted # Call thread preempted routine
MOV r0, r4 # Restore r0
MOV r1, r5 # Restore r1
#endif
/* Save the remaining time-slice and disable it. */
/* if (_tx_timer_time_slice)
{ */
LDR r3, =_tx_timer_time_slice # Pickup time-slice variable address
LDR r2, [r3] # Pickup time-slice
CMP r2, 0 # Is it active?
BEQ __tx_thread_dont_save_ts # No, don't save it
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
_tx_timer_time_slice = 0; */
STR r2, [r0, 24] # Save thread's time-slice
MOV r2, 0 # Clear value
STR r2, [r3] # Disable global time-slice flag
/* } */
__tx_thread_dont_save_ts:
/* Clear the current task pointer. */
/* _tx_thread_current_ptr = TX_NULL; */
MOV r0, 0 # NULL value
STR r0, [r1] # Clear current thread pointer
/* Return to the scheduler. */
/* _tx_thread_schedule(); */
B _tx_thread_schedule # Return to scheduler
/* } */
__tx_thread_idle_system_restore:
/* Just return back to the scheduler! */
MOV r3, SVC_MODE # Build SVC mode CPSR
MSR CPSR_c, r3 # Lockout interrupts
B _tx_thread_schedule # Return to scheduler
.type _tx_thread_context_restore,$function
.size _tx_thread_context_restore,.-_tx_thread_context_restore
/* } */

View File

@@ -0,0 +1,207 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 # IRQ & FIQ interrupts disabled
#else
DISABLE_INTS = 0x80 # IRQ interrupts disabled
#endif
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function saves the context of an executing thread in the */
/* beginning of interrupt processing. The function also ensures that */
/* the system stack is used upon return to the calling ISR. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_save(VOID)
{ */
.globl _tx_thread_context_save
_tx_thread_context_save:
/* Upon entry to this routine, it is assumed that IRQ interrupts are locked
out, we are in IRQ mode, and all registers are intact. */
/* Check for a nested interrupt condition. */
/* if (_tx_thread_system_state++)
{ */
STMDB sp!, {r0-r3} # Save some working registers
#ifdef TX_ENABLE_FIQ_SUPPORT
#ifdef TX_BEFORE_ARMV6
MRS r0, CPSR # Pickup the CPSR
ORR r0, r0, DISABLE_INTS # Build disable interrupt CPSR
MSR CPSR_c, r0 # Disable interrupts
#else
CPSID if # Disable FIQ interrupts
#endif
#endif
LDR r3, =_tx_thread_system_state # Pickup address of system state var
LDR r2, [r3] # Pickup system state
CMP r2, 0 # Is this the first interrupt?
BEQ __tx_thread_not_nested_save # Yes, not a nested context save
/* Nested interrupt condition. */
ADD r2, r2, 1 # Increment the interrupt counter
STR r2, [r3] # Store it back in the variable
/* Save the rest of the scratch registers on the stack and return to the
calling ISR. */
MRS r0, SPSR # Pickup saved SPSR
SUB lr, lr, 4 # Adjust point of interrupt
STMDB sp!, {r0, r10, r12, lr} # Store other registers
/* Return to the ISR. */
MOV r10, 0 # Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
PUSH {lr} # Save ISR lr
BL _tx_execution_isr_enter # Call the ISR enter function
POP {lr} # Recover ISR lr
#endif
B __tx_irq_processing_return # Continue IRQ processing
__tx_thread_not_nested_save:
/* } */
/* Otherwise, not nested, check to see if a thread was running. */
/* else if (_tx_thread_current_ptr)
{ */
ADD r2, r2, 1 # Increment the interrupt counter
STR r2, [r3] # Store it back in the variable
LDR r1, =_tx_thread_current_ptr # Pickup address of current thread ptr
LDR r0, [r1] # Pickup current thread pointer
CMP r0, 0 # Is it NULL?
BEQ __tx_thread_idle_system_save # If so, interrupt occurred in
/* # scheduling loop - nothing needs saving! */
/* Save minimal context of interrupted thread. */
MRS r2, SPSR # Pickup saved SPSR
SUB lr, lr, 4 # Adjust point of interrupt
STMDB sp!, {r2, r10, r12, lr} # Store other registers
/* Save the current stack pointer in the thread's control block. */
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; */
/* Switch to the system stack. */
/* sp = _tx_thread_system_stack_ptr; */
MOV r10, 0 # Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
PUSH {lr} # Save ISR lr
BL _tx_execution_isr_enter # Call the ISR enter function
POP {lr} # Recover ISR lr
#endif
B __tx_irq_processing_return # Continue IRQ processing
/* }
else
{ */
__tx_thread_idle_system_save:
/* Interrupt occurred in the scheduling loop. */
/* Not much to do here, just adjust the stack pointer, and return to IRQ
processing. */
MOV r10, 0 # Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
PUSH {lr} # Save ISR lr
BL _tx_execution_isr_enter # Call the ISR enter function
POP {lr} # Recover ISR lr
#endif
ADD sp, sp, 16 # Recover saved registers
B __tx_irq_processing_return # Continue IRQ processing
.type _tx_thread_context_save,$function
.size _tx_thread_context_save,.-_tx_thread_context_save
/* }
} */

View File

@@ -0,0 +1,264 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
SVC_MODE = 0xD3 # SVC mode
FIQ_MODE = 0xD1 # FIQ mode
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 # Disable IRQ and FIQ interrupts
#else
DISABLE_INTS = 0x80 # Disable IRQ interrupts
#endif
MODE_MASK = 0x1F # Mode mask
IRQ_MODE_BITS = 0x12 # IRQ mode bits
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_context_restore Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function restores the fiq interrupt context when processing a */
/* nested interrupt. If not, it returns to the interrupt thread if no */
/* preemption is necessary. Otherwise, if preemption is necessary or */
/* if no thread was running, the function returns to the scheduler. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_schedule Thread scheduling routine */
/* */
/* CALLED BY */
/* */
/* FIQ ISR Interrupt Service Routines */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_context_restore(VOID)
{ */
.globl _tx_thread_fiq_context_restore
_tx_thread_fiq_context_restore:
/* Lockout interrupts. */
#ifdef TX_BEFORE_ARMV6
MRS r3, CPSR # Pickup current CPSR
ORR r0, r3, DISABLE_INTS # Build interrupt disable value
MSR CPSR_c, r0 # Lockout interrupts
#else
CPSID if # Disable IRQ and FIQ interrupts
#endif
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR exit function to indicate an ISR is complete. */
BL _tx_execution_isr_exit # Call the ISR exit function
#endif
/* Determine if interrupts are nested. */
/* if (--_tx_thread_system_state)
{ */
LDR r3, =_tx_thread_system_state # Pickup address of system state var
LDR r2, [r3] # Pickup system state
SUB r2, r2, 1 # Decrement the counter
STR r2, [r3] # Store the counter
CMP r2, 0 # Was this the first interrupt?
BEQ __tx_thread_fiq_not_nested_restore # If so, not a nested restore
/* Interrupts are nested. */
/* Just recover the saved registers and return to the point of
interrupt. */
LDMIA sp!, {r0, r10, r12, lr} # Recover SPSR, POI, and scratch regs
MSR SPSR_cxsf, r0 # Put SPSR back
LDMIA sp!, {r0-r3} # Recover r0-r3
MOVS pc, lr # Return to point of interrupt
/* } */
__tx_thread_fiq_not_nested_restore:
/* Determine if a thread was interrupted and no preemption is required. */
/* else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
|| (_tx_thread_preempt_disable))
{ */
LDR r1, [sp] # Pickup the saved SPSR
MOV r2, MODE_MASK # Build mask to isolate the interrupted mode
AND r1, r1, r2 # Isolate mode bits
CMP r1, IRQ_MODE_BITS # Was an interrupt taken in IRQ mode before we
/* # got to context save? */
BEQ __tx_thread_fiq_no_preempt_restore # Yes, just go back to point of interrupt
LDR r1, =_tx_thread_current_ptr # Pickup address of current thread ptr
LDR r0, [r1] # Pickup actual current thread pointer
CMP r0, 0 # Is it NULL?
BEQ __tx_thread_fiq_idle_system_restore # Yes, idle system was interrupted
LDR r3, =_tx_thread_preempt_disable # Pickup preempt disable address
LDR r2, [r3] # Pickup actual preempt disable flag
CMP r2, 0 # Is it set?
BNE __tx_thread_fiq_no_preempt_restore # Yes, don't preempt this thread
LDR r3, =_tx_thread_execute_ptr # Pickup address of execute thread ptr
LDR r2, [r3] # Pickup actual execute thread pointer
CMP r0, r2 # Is the same thread highest priority?
BNE __tx_thread_fiq_preempt_restore # No, preemption needs to happen
__tx_thread_fiq_no_preempt_restore:
/* Restore interrupted thread or ISR. */
/* Pickup the saved stack pointer. */
/* tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr; */
/* Recover the saved context and return to the point of interrupt. */
LDMIA sp!, {r0, lr} # Recover SPSR, POI, and scratch regs
MSR SPSR_cxsf, r0 # Put SPSR back
LDMIA sp!, {r0-r3} # Recover r0-r3
MOVS pc, lr # Return to point of interrupt
/* }
else
{ */
__tx_thread_fiq_preempt_restore:
LDMIA sp!, {r3, lr} # Recover temporarily saved registers
MOV r1, lr # Save lr (point of interrupt)
MOV r2, SVC_MODE # Build SVC mode CPSR
MSR CPSR_c, r2 # Enter SVC mode
STR r1, [sp, -4]! # Save point of interrupt
STMDB sp!, {r4-r12, lr} # Save upper half of registers
MOV r4, r3 # Save SPSR in r4
MOV r2, FIQ_MODE # Build FIQ mode CPSR
MSR CPSR_c, r2 # Re-enter FIQ mode
LDMIA sp!, {r0-r3} # Recover r0-r3
MOV r5, SVC_MODE # Build SVC mode CPSR
MSR CPSR_c, r5 # Enter SVC mode
STMDB sp!, {r0-r3} # Save r0-r3 on thread's stack
LDR r1, =_tx_thread_current_ptr # Pickup address of current thread ptr
LDR r0, [r1] # Pickup current thread pointer
#ifdef __VFP__
LDR r2, [r0, 144] # Pickup the VFP enabled flag
CMP r2, 0 # Is the VFP enabled?
BEQ _tx_skip_fiq_vfp_save # No, skip VFP IRQ save
VMRS r2, FPSCR # Pickup the FPSCR
STR r2, [sp, -4]! # Save FPSCR
VSTMDB sp!, {D16-D31} # Save D16-D31
VSTMDB sp!, {D0-D15} # Save D0-D15
_tx_skip_fiq_vfp_save:
#endif
MOV r3, 1 # Build interrupt stack type
STMDB sp!, {r3, r4} # Save interrupt stack type and SPSR
STR sp, [r0, 8] # Save stack pointer in thread control
/* # block */
#ifdef TX_ENABLE_EVENT_LOGGING
MOV r4, r0 # Save r0
MOV r5, r1 # Save r1
BL _tx_el_thread_preempted # Call thread preempted routine
MOV r0, r4 # Restore r0
MOV r1, r5 # Restore r1
#endif
/* Save the remaining time-slice and disable it. */
/* if (_tx_timer_time_slice)
{ */
LDR r3, =_tx_timer_time_slice # Pickup time-slice variable address
LDR r2, [r3] # Pickup time-slice
CMP r2, 0 # Is it active?
BEQ __tx_thread_fiq_dont_save_ts # No, don't save it
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
_tx_timer_time_slice = 0; */
STR r2, [r0, 24] # Save thread's time-slice
MOV r2, 0 # Clear value
STR r2, [r3] # Disable global time-slice flag
/* } */
__tx_thread_fiq_dont_save_ts:
/* Clear the current task pointer. */
/* _tx_thread_current_ptr = TX_NULL; */
MOV r0, 0 # NULL value
STR r0, [r1] # Clear current thread pointer
/* Return to the scheduler. */
/* _tx_thread_schedule(); */
B _tx_thread_schedule # Return to scheduler
/* } */
__tx_thread_fiq_idle_system_restore:
/* Just return back to the scheduler! */
ADD sp, sp, 24 # Recover FIQ stack space
MOV r3, SVC_MODE # Build SVC mode CPSR
MSR CPSR_c, r3 # Lockout interrupts
B _tx_thread_schedule # Return to scheduler
.type _tx_thread_fiq_context_restore,$function
.size _tx_thread_fiq_context_restore,.-_tx_thread_fiq_context_restore
/* } */

View File

@@ -0,0 +1,197 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_context_save Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function saves the context of an executing thread in the */
/* beginning of interrupt processing. The function also ensures that */
/* the system stack is used upon return to the calling ISR. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_context_save(VOID)
{ */
.globl _tx_thread_fiq_context_save
_tx_thread_fiq_context_save:
/* Upon entry to this routine, it is assumed that IRQ interrupts are locked
out, we are in IRQ mode, and all registers are intact. */
/* Check for a nested interrupt condition. */
/* if (_tx_thread_system_state++)
{ */
STMDB sp!, {r0-r3} # Save some working registers
LDR r3, =_tx_thread_system_state # Pickup address of system state var
LDR r2, [r3] # Pickup system state
CMP r2, 0 # Is this the first interrupt?
BEQ __tx_thread_fiq_not_nested_save # Yes, not a nested context save
/* Nested interrupt condition. */
ADD r2, r2, 1 # Increment the interrupt counter
STR r2, [r3] # Store it back in the variable
/* Save the rest of the scratch registers on the stack and return to the
calling ISR. */
MRS r0, SPSR # Pickup saved SPSR
SUB lr, lr, 4 # Adjust point of interrupt
STMDB sp!, {r0, r10, r12, lr} # Store other registers
/* Return to the ISR. */
MOV r10, 0 # Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
PUSH {lr} # Save ISR lr
BL _tx_execution_isr_enter # Call the ISR enter function
POP {lr} # Recover ISR lr
#endif
B __tx_fiq_processing_return # Continue FIQ processing
__tx_thread_fiq_not_nested_save:
/* } */
/* Otherwise, not nested, check to see if a thread was running. */
/* else if (_tx_thread_current_ptr)
{ */
ADD r2, r2, 1 # Increment the interrupt counter
STR r2, [r3] # Store it back in the variable
LDR r1, =_tx_thread_current_ptr # Pickup address of current thread ptr
LDR r0, [r1] # Pickup current thread pointer
CMP r0, 0 # Is it NULL?
BEQ __tx_thread_fiq_idle_system_save # If so, interrupt occurred in
/* # scheduling loop - nothing needs saving! */
/* Save minimal context of interrupted thread. */
MRS r2, SPSR # Pickup saved SPSR
SUB lr, lr, 4 # Adjust point of interrupt
STMDB sp!, {r2, lr} # Store other registers, Note that we don't
/* # need to save sl and ip since FIQ has
# copies of these registers. Nested
# interrupt processing does need to save
# these registers. */
/* Save the current stack pointer in the thread's control block. */
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; */
/* Switch to the system stack. */
/* sp = _tx_thread_system_stack_ptr; */
MOV r10, 0 # Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
PUSH {lr} # Save ISR lr
BL _tx_execution_isr_enter # Call the ISR enter function
POP {lr} # Recover ISR lr
#endif
B __tx_fiq_processing_return # Continue FIQ processing
/* }
else
{ */
__tx_thread_fiq_idle_system_save:
/* Interrupt occurred in the scheduling loop. */
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
PUSH {lr} # Save ISR lr
BL _tx_execution_isr_enter # Call the ISR enter function
POP {lr} # Recover ISR lr
#endif
/* Not much to do here, save the current SPSR and LR for possible
use in IRQ interrupted in idle system conditions, and return to
FIQ interrupt processing. */
MRS r0, SPSR # Pickup saved SPSR
SUB lr, lr, 4 # Adjust point of interrupt
STMDB sp!, {r0, lr} # Store other registers that will get used
/* # or stripped off the stack in context
# restore */
B __tx_fiq_processing_return # Continue FIQ processing
.type _tx_thread_fiq_context_save,$function
.size _tx_thread_fiq_context_save,.-_tx_thread_fiq_context_save
/* }
} */

View File

@@ -0,0 +1,109 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 # Disable IRQ and FIQ interrupts
#else
DISABLE_INTS = 0x80 # Disable IRQ interrupts
#endif
MODE_MASK = 0x1F # Mode mask
FIQ_MODE_BITS = 0x11 # FIQ mode bits
SVC_MODE_BITS = 0x13 # SVC mode value */
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_nesting_end Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called by the application from FIQ mode after */
/* _tx_thread_fiq_nesting_start has been called and switches the FIQ */
/* processing from system mode back to FIQ mode prior to the ISR */
/* calling _tx_thread_fiq_context_restore. Note that this function */
/* assumes the system stack pointer is in the same position after */
/* nesting start function was called. */
/* */
/* This function assumes that the system mode stack pointer was setup */
/* during low-level initialization (tx_initialize_low_level.arm). */
/* */
/* This function returns with FIQ interrupts disabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_nesting_end(VOID)
{ */
.globl _tx_thread_fiq_nesting_end
_tx_thread_fiq_nesting_end:
MOV r3,lr # Save ISR return address
MRS r0, CPSR # Pickup the CPSR
ORR r0, r0, DISABLE_INTS # Build disable interrupt value
MSR CPSR_c, r0 # Disable interrupts
LDR lr, [sp] # Pickup saved lr
ADD sp, sp, 4 # Adjust stack pointer
BIC r0, r0, MODE_MASK # Clear mode bits
ORR r0, r0, FIQ_MODE_BITS # Build IRQ mode CPSR
MSR CPSR_c, r0 # Re-enter IRQ mode
MOV pc, r3 # Return to ISR
.type _tx_thread_fiq_nesting_end,$function
.size _tx_thread_fiq_nesting_end,.-_tx_thread_fiq_nesting_end
/* } */

View File

@@ -0,0 +1,103 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
FIQ_DISABLE = 0x40 # FIQ disable bit
MODE_MASK = 0x1F # Mode mask
SYS_MODE_BITS = 0x1F # System mode bits
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_nesting_start Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called by the application from FIQ mode after */
/* _tx_thread_fiq_context_save has been called and switches the FIQ */
/* processing to the system mode so nested FIQ interrupt processing */
/* is possible (system mode has its own "lr" register). Note that */
/* this function assumes that the system mode stack pointer was setup */
/* during low-level initialization (tx_initialize_low_level.arm). */
/* */
/* This function returns with FIQ interrupts enabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_nesting_start(VOID)
{ */
.globl _tx_thread_fiq_nesting_start
_tx_thread_fiq_nesting_start:
MOV r3,lr # Save ISR return address
MRS r0, CPSR # Pickup the CPSR
BIC r0, r0, MODE_MASK # Clear the mode bits
ORR r0, r0, SYS_MODE_BITS # Build system mode CPSR
MSR CPSR_c, r0 # Enter system mode
STR lr, [sp, -4]! # Push the system mode lr on the system mode stack
BIC r0, r0, FIQ_DISABLE # Build enable FIQ CPSR
MSR CPSR_c, r0 # Enter system mode
MOV pc, r3 # Return to ISR
.type _tx_thread_fiq_nesting_start,$function
.size _tx_thread_fiq_nesting_start,.-_tx_thread_fiq_nesting_start
/* } */

View File

@@ -0,0 +1,101 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h" */
#ifdef TX_ENABLE_FIQ_SUPPORT
INT_MASK = 0xC0 # Interrupt bit mask
#else
INT_MASK = 0x80 # Interrupt bit mask
#endif
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for changing the interrupt lockout */
/* posture of the system. */
/* */
/* INPUT */
/* */
/* new_posture New interrupt lockout posture */
/* */
/* OUTPUT */
/* */
/* old_posture Old interrupt lockout posture */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_control(UINT new_posture)
{ */
.globl _tx_thread_interrupt_control
_tx_thread_interrupt_control:
/* Pickup current interrupt lockout posture. */
MRS r3, CPSR # Pickup current CPSR
BIC r1, r3, INT_MASK # Clear interrupt lockout bits
ORR r1, r1, r0 # Or-in new interrupt lockout bits
/* Apply the new interrupt posture. */
MSR CPSR_c, r1 # Setup new CPSR
AND r0, r3, INT_MASK # Return previous interrupt mask
RET # Return to caller
.type _tx_thread_interrupt_control,$function
.size _tx_thread_interrupt_control,.-_tx_thread_interrupt_control
/* } */

View File

@@ -0,0 +1,105 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h" */
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 # IRQ & FIQ interrupts disabled
#else
DISABLE_INTS = 0x80 # IRQ interrupts disabled
#endif
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for disabling interrupts */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* old_posture Old interrupt lockout posture */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_disable(void)
{ */
.globl _tx_thread_interrupt_disable
_tx_thread_interrupt_disable:
/* Pickup current interrupt lockout posture. */
MRS r0, CPSR # Pickup current CPSR
/* Mask interrupts. */
#ifdef TX_BEFORE_ARMV6
ORR r1, r0, DISABLE_INTS # Mask interrupts
MSR CPSR_c, r1 # Setup new CPSR
#else
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if # Disable IRQ and FIQ
#else
CPSID i # Disable IRQ
#endif
#endif
RET # Return previous CPSR value
.type _tx_thread_interrupt_disable,$function
.size _tx_thread_interrupt_disable,.-_tx_thread_interrupt_disable
/* } */

View File

@@ -0,0 +1,85 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h" */
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_restore Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for restoring interrupts to the state */
/* returned by a previous _tx_thread_interrupt_disable call. */
/* */
/* INPUT */
/* */
/* new_posture New interrupt lockout posture */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_interrupt_restore(UINT new_posture)
{ */
.globl _tx_thread_interrupt_restore
_tx_thread_interrupt_restore:
/* Apply the new interrupt posture. */
MSR CPSR_c, r0 # Setup new CPSR
RET
.type _tx_thread_interrupt_restore,$function
.size _tx_thread_interrupt_restore,.-_tx_thread_interrupt_restore
/* } */

View File

@@ -0,0 +1,109 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 # Disable IRQ and FIQ interrupts
#else
DISABLE_INTS = 0x80 # Disable IRQ interrupts
#endif
MODE_MASK = 0x1F # Mode mask
IRQ_MODE_BITS = 0x12 # IRQ mode bits
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_irq_nesting_end Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called by the application from IRQ mode after */
/* _tx_thread_irq_nesting_start has been called and switches the IRQ */
/* processing from system mode back to IRQ mode prior to the ISR */
/* calling _tx_thread_context_restore. Note that this function */
/* assumes the system stack pointer is in the same position after */
/* nesting start function was called. */
/* */
/* This function assumes that the system mode stack pointer was setup */
/* during low-level initialization (tx_initialize_low_level.arm). */
/* */
/* This function returns with IRQ interrupts disabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_irq_nesting_end(VOID)
{ */
.globl _tx_thread_irq_nesting_end
_tx_thread_irq_nesting_end:
MOV r3,lr # Save ISR return address
MRS r0, CPSR # Pickup the CPSR
ORR r0, r0, DISABLE_INTS # Build disable interrupt value
MSR CPSR_c, r0 # Disable interrupts
LDR lr, [sp] # Pickup saved lr
ADD sp, sp, 4 # Adjust stack pointer
BIC r0, r0, MODE_MASK # Clear mode bits
ORR r0, r0, IRQ_MODE_BITS # Build IRQ mode CPSR
MSR CPSR_c, r0 # Re-enter IRQ mode
MOV pc, r3 # Return to ISR
.type _tx_thread_irq_nesting_end,$function
.size _tx_thread_irq_nesting_end,.-_tx_thread_irq_nesting_end
/* } */

View File

@@ -0,0 +1,102 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
IRQ_DISABLE = 0x80 # IRQ disable bit
MODE_MASK = 0x1F # Mode mask
SYS_MODE_BITS = 0x1F # System mode bits
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_irq_nesting_start Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called by the application from IRQ mode after */
/* _tx_thread_context_save has been called and switches the IRQ */
/* processing to the system mode so nested IRQ interrupt processing */
/* is possible (system mode has its own "lr" register). Note that */
/* this function assumes that the system mode stack pointer was setup */
/* during low-level initialization (tx_initialize_low_level.arm). */
/* */
/* This function returns with IRQ interrupts enabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_irq_nesting_start(VOID)
{ */
.globl _tx_thread_irq_nesting_start
_tx_thread_irq_nesting_start:
MOV r3,lr # Save ISR return address
MRS r0, CPSR # Pickup the CPSR
BIC r0, r0, MODE_MASK # Clear the mode bits
ORR r0, r0, SYS_MODE_BITS # Build system mode CPSR
MSR CPSR_c, r0 # Enter system mode
STR lr, [sp, -4]! # Push the system mode lr on the system mode stack
BIC r0, r0, IRQ_DISABLE # Build enable IRQ CPSR
MSR CPSR_c, r0 # Enter system mode
MOV pc, r3 # Return to ISR
.type _tx_thread_irq_nesting_start,$function
.size _tx_thread_irq_nesting_start,.-_tx_thread_irq_nesting_start
/* } */

View File

@@ -0,0 +1,253 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
#ifdef TX_ENABLE_FIQ_SUPPORT
ENABLE_INTS = 0xC0 # IRQ & FIQ Interrupts enabled mask
#else
ENABLE_INTS = 0x80 # IRQ Interrupts enabled mask
#endif
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function waits for a thread control block pointer to appear in */
/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
/* in the variable, the corresponding thread is resumed. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_schedule(VOID)
{ */
.globl _tx_thread_schedule
_tx_thread_schedule:
/* Enable interrupts. */
#ifdef TX_BEFORE_ARMV6
MRS r2, CPSR # Pickup CPSR
BIC r0, r2, ENABLE_INTS # Clear the disable bit(s)
MSR CPSR_c, r0 # Enable interrupts
#else
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSIE if # Enable IRQ and FIQ interrupts
#else
CPSIE i # Enable IRQ interrupts
#endif
#endif
/* Wait for a thread to execute. */
/* do
{ */
LDR r1, =_tx_thread_execute_ptr # Address of thread execute ptr
__tx_thread_schedule_loop:
LDR r0, [r1] # Pickup next thread to execute
CMP r0, 0 # Is it NULL?
BEQ __tx_thread_schedule_loop # If so, keep looking for a thread
/* }
while(_tx_thread_execute_ptr == TX_NULL); */
/* Yes! We have a thread to execute. Lockout interrupts and
transfer control to it. */
#ifdef TX_BEFORE_ARMV6
MSR CPSR_c, r2 # Disable interrupts
#else
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if # Disable IRQ and FIQ interrupts
#else
CPSID i # Disable IRQ interrupts
#endif
#endif
/* Setup the current thread pointer. */
/* _tx_thread_current_ptr = _tx_thread_execute_ptr; */
#ifdef TX_ENABLE_EVENT_LOGGING
MOV v1, r0 # Save temp register in non-volatile register
BL _tx_el_thread_running # Call event logging routine
MOV r0, v1 # Restore temp register
#endif
LDR r1, =_tx_thread_current_ptr # Pickup address of current thread
STR r0, [r1] # Setup current thread pointer
/* Increment the run count for this thread. */
/* _tx_thread_current_ptr -> tx_thread_run_count++; */
LDR r2, [r0, 4] # Pickup run counter
LDR r3, [r0, 24] # Pickup time-slice for this thread
ADD r2, r2, 1 # Increment thread run-counter
STR r2, [r0, 4] # Store the new run counter
/* Setup time-slice, if present. */
/* _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; */
LDR r2, =_tx_timer_time_slice # Pickup address of time slice
/* # variable */
LDR sp, [r0, 8] # Switch stack pointers
STR r3, [r2] # Setup time-slice
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the thread entry function to indicate the thread is executing. */
MOV r5, r0 # Save r0
BL _tx_execution_thread_enter # Call the thread execution enter function
MOV r0, r5 # Restore r0
#endif
/* Switch to the thread's stack. */
/* sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr; */
/* Determine if an interrupt frame or a synchronous task suspension frame
is present. */
LDMIA sp!, {r4, r5} # Pickup the stack type and saved CPSR
CMP r4, 0 # Check for synchronous context switch
BEQ _tx_solicited_return
MSR SPSR_cxsf, r5 # Setup SPSR for return
#ifdef __VFP__
LDR r1, [r0, 144] # Pickup the VFP enabled flag
CMP r1, 0 # Is the VFP enabled?
BEQ _tx_skip_interrupt_vfp_restore # No, skip VFP interrupt restore
VLDMIA sp!, {D0-D15} # Recover D0-D15
VLDMIA sp!, {D16-D31} # Recover D16-D31
LDR r4, [sp], 4 # Pickup FPSCR
VMSR FPSCR, r4 # Restore FPSCR
_tx_skip_interrupt_vfp_restore:
#endif
LDMIA sp!, {r0-r12, lr, pc}^ # Return to point of thread interrupt
_tx_solicited_return:
#ifdef __VFP__
LDR r1, [r0, 144] # Pickup the VFP enabled flag
CMP r1, 0 # Is the VFP enabled?
BEQ _tx_skip_solicited_vfp_restore # No, skip VFP solicited restore
VLDMIA sp!, {D8-D15} # Recover D8-D15
VLDMIA sp!, {D16-D31} # Recover D16-D31
LDR r4, [sp], 4 # Pickup FPSCR
VMSR FPSCR, r4 # Restore FPSCR
_tx_skip_solicited_vfp_restore:
#endif
MSR CPSR_cxsf, r5 # Recover CPSR
LDMIA sp!, {r4-r11, lr} # Return to thread synchronously
RET # Return to caller (Thumb safe)
.type _tx_thread_schedule,$function
.size _tx_thread_schedule,.-_tx_thread_schedule
#ifdef __VFP__
.globl tx_thread_vfp_enable
tx_thread_vfp_enable:
MRS r2, CPSR # Pickup the CPSR
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSIE if # Enable IRQ and FIQ interrupts
#else
CPSIE i # Enable IRQ interrupts
#endif
LDR r0, =_tx_thread_current_ptr # Build current thread pointer address
LDR r1, [r0] # Pickup current thread pointer
CMP r1, 0 # Check for NULL thread pointer
BEQ __tx_no_thread_to_enable # If NULL, skip VFP enable
MOV r0, 1 # Build enable value
STR r0, [r1, 144] # Set the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD)
__tx_no_thread_to_enable:
MSR CPSR_cxsf, r2 # Recover CPSR
RET # Return to caller (Thumb safe)
.type tx_thread_vfp_enable,$function
.size tx_thread_vfp_enable,.-tx_thread_vfp_enable
.globl tx_thread_vfp_disable
tx_thread_vfp_disable:
MRS r2, CPSR # Pickup the CPSR
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSIE if # Enable IRQ and FIQ interrupts
#else
CPSIE i # Enable IRQ interrupts
#endif
LDR r0, =_tx_thread_current_ptr # Build current thread pointer address
LDR r1, [r0] # Pickup current thread pointer
CMP r1, 0 # Check for NULL thread pointer
BEQ __tx_no_thread_to_disable # If NULL, skip VFP disable
MOV r0, 0 # Build disable value
STR r0, [r1, 144] # Clear the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD)
__tx_no_thread_to_disable:
MSR CPSR_cxsf, r2 # Recover CPSR
RET # Return to caller (Thumb safe)
.type tx_thread_vfp_disable,$function
.size tx_thread_vfp_disable,.-tx_thread_vfp_disable
#endif
/* } */

View File

@@ -0,0 +1,161 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h" */
SVC_MODE = 0x13 # SVC mode
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSR_MASK = 0xDF # Mask initial CPSR, IRQ & FIQ ints enabled
#else
CPSR_MASK = 0x9F # Mask initial CPSR, IRQ ints enabled
#endif
THUMB_BIT = 0x20 # Thumb-bit
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds a stack frame on the supplied thread's stack. */
/* The stack frame results in a fake interrupt return to the supplied */
/* function pointer. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to thread control blk */
/* function_ptr Pointer to return function */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_thread_create Create thread service */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
{ */
.globl _tx_thread_stack_build
_tx_thread_stack_build:
/* Build a fake interrupt frame. The form of the fake interrupt stack
on the Cortex-A5 should look like the following after it is built:
Stack Top: 1 Interrupt stack frame type
CPSR Initial value for CPSR
r0 (a1) Initial value for r0
r1 (a2) Initial value for r1
r2 (a3) Initial value for r2
r3 (a4) Initial value for r3
r4 (v1) Initial value for r4
r5 (v2) Initial value for r5
r6 (v3) Initial value for r6
r7 (v4) Initial value for r7
r8 (v5) Initial value for r8
r9 (sb) Initial value for r9
r10 (sl) Initial value for r10
r11 (fp) Initial value for r11
r12 (ip) Initial value for r12
lr Initial value for lr
pc Initial value for pc
0 For stack backtracing
Stack Bottom: (higher memory address) */
LDR r2, [r0, 16] # Pickup end of stack area
BIC r2, r2, 7 # Ensure 8-byte alignment
SUB r2, r2, 76 # Allocate space for the stack frame
/* Actually build the stack frame. */
MOV r3, 1 # Build interrupt stack type
STR r3, [r2] # Store stack type
MOV r3, 0 # Build initial register value
STR r3, [r2, 8] # Store initial r0
STR r3, [r2, 12] # Store initial r1
STR r3, [r2, 16] # Store initial r2
STR r3, [r2, 20] # Store initial r3
STR r3, [r2, 24] # Store initial r4
STR r3, [r2, 28] # Store initial r5
STR r3, [r2, 32] # Store initial r6
STR r3, [r2, 36] # Store initial r7
STR r3, [r2, 40] # Store initial r8
STR r3, [r2, 44] # Store initial r9
LDR r3, [r0, 12] # Pickup stack starting address
STR r3, [r2, 48] # Store initial r10
MOV r3, 0 # Build initial register value
STR r3, [r2, 52] # Store initial r11
STR r3, [r2, 56] # Store initial r12
STR r3, [r2, 60] # Store initial lr
STR r1, [r2, 64] # Store initial pc
STR r3, [r2, 68] # 0 for back-trace
MRS r3, CPSR # Pickup CPSR
BIC r3, r3, CPSR_MASK # Mask mode bits of CPSR
ORR r3, r3, SVC_MODE # Build CPSR, SVC mode, interrupts enabled
BIC r3, r3, #THUMB_BIT # Clear Thumb-bit by default
AND r1, r1, #1 # Determine if the entry function is in Thumb mode
CMP r1, 1 # Is the Thumb-bit set?
ORREQ r3, r3, #THUMB_BIT # Yes, set the Thumb-bit
STR r3, [r2, 4] # Store initial CPSR
/* Setup stack pointer. */
/* thread_ptr -> tx_thread_stack_ptr = r2; */
STR r2, [r0, 8] # Save stack pointer in thread's
/* # control block */
RET # Return to caller
.type _tx_thread_stack_build,$function
.size _tx_thread_stack_build,.-_tx_thread_stack_build
/* } */

View File

@@ -0,0 +1,167 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 # IRQ & FIQ interrupts disabled
#else
DISABLE_INTS = 0x80 # IRQ interrupts disabled
#endif
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is target processor specific. It is used to transfer */
/* control from a thread back to the ThreadX system. Only a */
/* minimal context is saved since the compiler assumes temp registers */
/* are going to get slicked by a function call anyway. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_schedule Thread scheduling loop */
/* */
/* CALLED BY */
/* */
/* ThreadX components */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_system_return(VOID)
{ */
.globl _tx_thread_system_return
_tx_thread_system_return:
/* Save minimal context on the stack. */
MOV r0, 0 # Build a solicited stack type
MRS r1, CPSR # Pickup the CPSR
STMDB sp!, {r4-r11, lr} # Save minimal context
LDR r4, =_tx_thread_current_ptr # Pickup address of current ptr
LDR r5, [r4] # Pickup current thread pointer
#ifdef __VFP__
LDR r1, [r5, 144] # Pickup the VFP enabled flag
CMP r1, 0 # Is the VFP enabled?
BEQ _tx_skip_solicited_vfp_save # No, skip VFP solicited save
VMRS r1, FPSCR # Pickup the FPSCR
STR r1, [sp, -4]! # Save FPSCR
VSTMDB sp!, {D16-D31} # Save D16-D31
VSTMDB sp!, {D8-D15} # Save D8-D15
_tx_skip_solicited_vfp_save:
#endif
MOV r0, #0 # Build a solicited stack type
MRS r1, CPSR # Pickup the CPSR
STMDB sp!, {r0-r1} # Save type and CPSR
/* Lockout interrupts. */
#ifdef TX_BEFORE_ARMV6
ORR r2, r1, DISABLE_INTS # Build disable interrupt CPSR
MSR CPSR_c, r2 # Disable interrupts
#else
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if # Disable IRQ and FIQ interrupts
#else
CPSID i # Disable IRQ interrutps
#endif
#endif
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the thread exit function to indicate the thread is no longer executing. */
BL _tx_execution_thread_exit # Call the thread exit function
#endif
MOV r3, r4 # Pickup address of current ptr
MOV r0, r5 # Pickup current thread pointer
LDR r2, =_tx_timer_time_slice # Pickup address of time slice
LDR r1, [r2] # Pickup current time slice
/* Save current stack and switch to system stack. */
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
sp = _tx_thread_system_stack_ptr; */
STR sp, [r0, 8] # Save thread stack pointer
/* Determine if the time-slice is active. */
/* if (_tx_timer_time_slice)
{ */
MOV r4, 0 # Build clear value
CMP r1, 0 # Is a time-slice active?
BEQ __tx_thread_dont_save_ts # No, don't save the current time-slice
/* Save time-slice for the thread and clear the current time-slice. */
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
_tx_timer_time_slice = 0; */
STR r4, [r2, 0] # Clear time-slice
STR r1, [r0, 24] # Save current time-slice
/* } */
__tx_thread_dont_save_ts:
/* Clear the current thread pointer. */
/* _tx_thread_current_ptr = TX_NULL; */
STR r4, [r3] # Clear current thread pointer
B _tx_thread_schedule # Jump to scheduler!
.type _tx_thread_system_return,$function
.size _tx_thread_system_return,.-_tx_thread_system_return
/* } */

View File

@@ -0,0 +1,196 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h" */
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 # IRQ & FIQ interrupts disabled
#else
DISABLE_INTS = 0x80 # IRQ interrupts disabled
#endif
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_vectored_context_save Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function saves the context of an executing thread in the */
/* beginning of interrupt processing. The function also ensures that */
/* the system stack is used upon return to the calling ISR. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_vectored_context_save(VOID)
{ */
.globl _tx_thread_vectored_context_save
_tx_thread_vectored_context_save:
/* Upon entry to this routine, it is assumed that IRQ interrupts are locked
out, we are in IRQ mode, the minimal context is already saved, and the
lr register contains the return ISR address. */
/* Check for a nested interrupt condition. */
/* if (_tx_thread_system_state++)
{ */
#ifdef TX_ENABLE_FIQ_SUPPORT
#ifdef TX_BEFORE_ARMV6
MRS r0, CPSR # Pickup the CPSR
ORR r0, r0, DISABLE_INTS # Build disable interrupt CPSR
MSR CPSR_c, r0 # Disable interrupts
#else
CPSID if # Disable IRQ and FIQ interrupts
#endif
#endif
LDR r3, =_tx_thread_system_state # Pickup address of system state var
LDR r2, [r3] # Pickup system state
CMP r2, 0 # Is this the first interrupt?
BEQ __tx_thread_not_nested_save # Yes, not a nested context save
/* Nested interrupt condition. */
ADD r2, r2, 1 # Increment the interrupt counter
STR r2, [r3] # Store it back in the variable
/* Note: Minimal context of interrupted thread is already saved. */
/* Return to the ISR. */
MOV r10, 0 # Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
PUSH {lr} # Save ISR lr
BL _tx_execution_isr_enter # Call the ISR enter function
POP {lr} # Recover ISR lr
#endif
MOV pc, lr # Return to caller
__tx_thread_not_nested_save:
/* } */
/* Otherwise, not nested, check to see if a thread was running. */
/* else if (_tx_thread_current_ptr)
{ */
ADD r2, r2, 1 # Increment the interrupt counter
STR r2, [r3] # Store it back in the variable
LDR r1, =_tx_thread_current_ptr # Pickup address of current thread ptr
LDR r0, [r1] # Pickup current thread pointer
CMP r0, 0 # Is it NULL?
BEQ __tx_thread_idle_system_save # If so, interrupt occurred in
/* # scheduling loop - nothing needs saving! */
/* Note: Minimal context of interrupted thread is already saved. */
/* Save the current stack pointer in the thread's control block. */
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; */
/* Switch to the system stack. */
/* sp = _tx_thread_system_stack_ptr; */
MOV r10, 0 # Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
PUSH {lr} # Save ISR lr
BL _tx_execution_isr_enter # Call the ISR enter function
POP {lr} # Recover ISR lr
#endif
MOV pc, lr # Return to caller
/* }
else
{ */
__tx_thread_idle_system_save:
/* Interrupt occurred in the scheduling loop. */
/* Not much to do here, just adjust the stack pointer, and return to IRQ
processing. */
MOV r10, 0 # Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
PUSH {lr} # Save ISR lr
BL _tx_execution_isr_enter # Call the ISR enter function
POP {lr} # Recover ISR lr
#endif
ADD sp, sp, 32 # Recover saved registers
MOV pc, lr # Return to caller
.type _tx_thread_vectored_context_save,$function
.size _tx_thread_vectored_context_save,.-_tx_thread_vectored_context_save
/* }
} */

View File

@@ -0,0 +1,241 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Timer */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h"
#include "tx_timer.h"
#include "tx_thread.h" */
.text
.align 4
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt Cortex-A5/Green Hills */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the hardware timer interrupt. This */
/* processing includes incrementing the system clock and checking for */
/* time slice and/or timer expiration. If either is found, the */
/* interrupt context save/restore functions are called along with the */
/* expiration functions. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_timer_expiration_process Process timer expiration */
/* _tx_thread_time_slice Time slice interrupted thread */
/* */
/* CALLED BY */
/* */
/* interrupt vector */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_timer_interrupt(VOID)
{ */
.globl _tx_timer_interrupt
_tx_timer_interrupt:
/* Upon entry to this routine, it is assumed that context save has already
been called, and therefore the compiler scratch registers are available
for use. */
/* Increment the system clock. */
/* _tx_timer_system_clock++; */
LDR r1, =_tx_timer_system_clock # Pickup address of system clock
LDR r0, [r1] # Pickup system clock
ADD r0, r0, 1 # Increment system clock
STR r0, [r1] # Store new system clock
/* Test for time-slice expiration. */
/* if (_tx_timer_time_slice)
{ */
LDR r3, =_tx_timer_time_slice # Pickup address of time-slice
LDR r2, [r3] # Pickup time-slice
CMP r2, 0 # Is it non-active?
BEQ __tx_timer_no_time_slice # Yes, skip time-slice processing
/* Decrement the time_slice. */
/* _tx_timer_time_slice--; */
SUB r2, r2, 1 # Decrement the time-slice
STR r2, [r3] # Store new time-slice value
/* Check for expiration. */
/* if (__tx_timer_time_slice == 0) */
CMP r2, 0 # Has it expired?
BNE __tx_timer_no_time_slice # No, skip expiration processing
/* Set the time-slice expired flag. */
/* _tx_timer_expired_time_slice = TX_TRUE; */
LDR r3,=_tx_timer_expired_time_slice # Pickup address of expired flag
MOV r0, 1 # Build expired value
STR r0, [r3] # Set time-slice expiration flag
/* } */
__tx_timer_no_time_slice:
/* Test for timer expiration. */
/* if (*_tx_timer_current_ptr)
{ */
LDR r1, =_tx_timer_current_ptr # Pickup current timer pointer addr
LDR r0, [r1] # Pickup current timer
LDR r2, [r0] # Pickup timer list entry
CMP r2, 0 # Is there anything in the list?
BEQ __tx_timer_no_timer # No, just increment the timer
/* Set expiration flag. */
/* _tx_timer_expired = TX_TRUE; */
LDR r3, =_tx_timer_expired # Pickup expiration flag address
MOV r2, 1 # Build expired value
STR r2, [r3] # Set expired flag
B __tx_timer_done # Finished timer processing
/* }
else
{ */
__tx_timer_no_timer:
/* No timer expired, increment the timer pointer. */
/* _tx_timer_current_ptr++; */
ADD r0, r0, 4 # Move to next timer
/* Check for wrap-around. */
/* if (_tx_timer_current_ptr == _tx_timer_list_end) */
LDR r3, =_tx_timer_list_end # Pickup addr of timer list end
LDR r2, [r3] # Pickup list end
CMP r0, r2 # Are we at list end?
BNE __tx_timer_skip_wrap # No, skip wrap-around logic
/* Wrap to beginning of list. */
/* _tx_timer_current_ptr = _tx_timer_list_start; */
LDR r3, =_tx_timer_list_start # Pickup addr of timer list start
LDR r0, [r3] # Set current pointer to list start
__tx_timer_skip_wrap:
STR r0, [r1] # Store new current timer pointer
/* } */
__tx_timer_done:
/* See if anything has expired. */
/* if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
{ */
LDR r3, =_tx_timer_expired_time_slice # Pickup addr of expired flag
LDR r2, [r3] # Pickup time-slice expired flag
CMP r2, 0 # Did a time-slice expire?
BNE __tx_something_expired # If non-zero, time-slice expired
LDR r1, =_tx_timer_expired # Pickup addr of other expired flag
LDR r0, [r1] # Pickup timer expired flag
CMP r0, 0 # Did a timer expire?
BEQ __tx_timer_nothing_expired # No, nothing expired
__tx_something_expired:
STMDB sp!, {r0, lr} # Save the lr register on the stack
/* # and save r0 just to keep 8-byte alignment */
/* Did a timer expire? */
/* if (_tx_timer_expired)
{ */
LDR r1, =_tx_timer_expired # Pickup addr of expired flag
LDR r0, [r1] # Pickup timer expired flag
CMP r0, 0 # Check for timer expiration
BEQ __tx_timer_dont_activate # If not set, skip timer activation
/* Process the timer expiration. */
/* _tx_timer_expiration_process(); */
BL _tx_timer_expiration_process # Call the timer expiration handling routine
/* } */
__tx_timer_dont_activate:
/* Did time slice expire? */
/* if (_tx_timer_expired_time_slice)
{ */
LDR r3, =_tx_timer_expired_time_slice # Pickup addr of time-slice expired
LDR r2, [r3] # Pickup the actual flag
CMP r2, 0 # See if the flag is set
BEQ __tx_timer_not_ts_expiration # No, skip time-slice processing
/* Time slice interrupted thread. */
/* _tx_thread_time_slice(); */
BL _tx_thread_time_slice # Call time-slice processing
/* } */
__tx_timer_not_ts_expiration:
LDMIA sp!, {r0, lr} # Recover lr register (r0 is just there for
/* # the 8-byte stack alignment */
/* } */
__tx_timer_nothing_expired:
RET # Return to caller
.type _tx_timer_interrupt,$function
.size _tx_timer_interrupt,.-_tx_timer_interrupt
/* } */