updated to 6.0.1 and added additional processors/toolchains

This commit is contained in:
tameraw
2020-07-16 14:32:40 -07:00
parent f8e91d4762
commit 2c35570dc9
1285 changed files with 550383 additions and 50 deletions

View File

@@ -0,0 +1,326 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Initialize */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
#define GICI_BASE 0xAE000000
#define ICCIAR_OFFSET 0x0000000C
#define ICCEOIR_OFFSET 0x00000010
.global _tx_thread_system_stack_ptr
.global _tx_initialize_unused_memory
.global _tx_thread_context_save
.global _tx_thread_context_restore
#ifdef TX_ENABLE_FIQ_SUPPORT
.global _tx_thread_fiq_context_save
.global _tx_thread_fiq_context_restore
#endif
#ifdef TX_ENABLE_IRQ_NESTING
.global _tx_thread_irq_nesting_start
.global _tx_thread_irq_nesting_end
#endif
#ifdef TX_ENABLE_FIQ_NESTING
.global _tx_thread_fiq_nesting_start
.global _tx_thread_fiq_nesting_end
#endif
.global _tx_timer_interrupt
.global __main
.global _tx_version_id
.global _tx_build_options
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_initialize_low_level Cortex-R4/AC6 */
/* 6.0.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for any low-level processor */
/* initialization, including setting up interrupt vectors, setting */
/* up a periodic timer interrupt source, saving the system stack */
/* pointer for use in ISR processing later, and finding the first */
/* available RAM memory address for tx_application_define. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_initialize_low_level(VOID)
{ */
.global _tx_initialize_low_level
.type _tx_initialize_low_level, "function"
_tx_initialize_low_level:
/* Save the system stack pointer. */
/* _tx_thread_system_stack_ptr = (VOID_PTR) (sp); */
LDR r0, =Image$$SVC_STACK$$ZI$$Limit
LDR r1, =_tx_thread_system_stack_ptr // Pickup address of system stack ptr
STR r0, [r1] // Pickup system stack
/* Save the first available memory address. */
/* _tx_initialize_unused_memory = (VOID_PTR) Image$$ZI$$Limit + HEAP + [SYS_STACK] + FIQ_STACK + IRQ_STACK; */
LDR r0, =Image$$DATA$$ZI$$Limit
LDR r2, =_tx_initialize_unused_memory // Pickup unused memory ptr address
STR r0, [r2, #0] // Save first free memory address
/* Return to caller. */
BX lr // Return to caller
/* } */
/* Define shells for each of the interrupt vectors. */
.global __tx_undefined
.type __tx_undefined, "function"
__tx_undefined:
B __tx_undefined // Undefined handler
.global __tx_swi_interrupt
.type __tx_swi_interrupt, "function"
__tx_swi_interrupt:
B __tx_swi_interrupt // Software interrupt handler
.global __tx_prefetch_handler
.type __tx_prefetch_handler, "function"
__tx_prefetch_handler:
B __tx_prefetch_handler // Prefetch exception handler
.global __tx_abort_handler
.type __tx_abort_handler, "function"
__tx_abort_handler:
B __tx_abort_handler // Abort exception handler
.global __tx_reserved_handler
.type __tx_reserved_handler, "function"
__tx_reserved_handler:
B __tx_reserved_handler // Reserved exception handler
.global __tx_irq_handler
.type __tx_irq_handler, "function"
.global __tx_irq_processing_return
.type __tx_irq_processing_return, "function"
__tx_irq_handler:
/* Jump to context save to save system context. */
B _tx_thread_context_save
__tx_irq_processing_return:
/* Acknowledge the interrupt. */
LDR r1, =GICI_BASE // Load the base of the GIC
LDR r0, [r1, #ICCIAR_OFFSET] // Read ICCIAR (GIC CPU Interface register)
DSB // Ensure that interrupt acknowledge completes before re-enabling interrupts
PUSH {r0, r1} // Save the IRQ ID and the GIC base address on the stack
/* Clear the timer interrupt. */
LDR r0, =0xB0110000 // Load the base address of the timer
MOV r1, #1 // Setup value to write to the interrupt clear register - can be anything.
STR r1, [r0, #0x0C] // Clear the interrupt. 0x0C is the offset to the interrupt clear register.
/* At this point execution is still in the IRQ mode. The CPSR, point of
interrupt, and all C scratch registers are available for use. In
addition, IRQ interrupts may be re-enabled - with certain restrictions -
if nested IRQ interrupts are desired. Interrupts may be re-enabled over
small code sequences where lr is saved before enabling interrupts and
restored after interrupts are again disabled. */
BL _tx_timer_interrupt // Timer interrupt handler
_tx_not_timer_interrupt:
/* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
from IRQ mode with interrupts disabled. This routine switches to the
system mode and returns with IRQ interrupts enabled. */
/* NOTE: It is very important to ensure all IRQ interrupts are cleared
prior to enabling nested IRQ interrupts. */
#ifdef TX_ENABLE_IRQ_NESTING
BL _tx_thread_irq_nesting_start
#endif
/* Application IRQ handlers can be called here! */
/* If interrupt nesting was started earlier, the end of interrupt nesting
service must be called before returning to _tx_thread_context_restore.
This routine returns in processing in IRQ mode with interrupts disabled. */
#ifdef TX_ENABLE_IRQ_NESTING
BL _tx_thread_irq_nesting_end
#endif
POP {r0, r1} // Restore the IRQ ID and GIC base address
STR r0, [r1, #ICCEOIR_OFFSET] // Write the IRQ ID to the End Of Interrupt register to clear the active bit
/* Jump to context restore to restore system context. */
B _tx_thread_context_restore
/* This is an example of a vectored IRQ handler. */
.global __tx_example_vectored_irq_handler
.type __tx_example_vectored_irq_handler, "function"
__tx_example_vectored_irq_handler:
/* Save initial context and call context save to prepare for
vectored ISR execution. */
/*
STMDB sp!, {r0-r3} // Save some scratch registers
MRS r0, SPSR // Pickup saved SPSR
SUB lr, lr, #4 // Adjust point of interrupt
STMDB sp!, {r0, r10, r12, lr} // Store other scratch registers
BL _tx_thread_vectored_context_save // Vectored context save
*/
/* At this point execution is still in the IRQ mode. The CPSR, point of
interrupt, and all C scratch registers are available for use. In
addition, IRQ interrupts may be re-enabled - with certain restrictions -
if nested IRQ interrupts are desired. Interrupts may be re-enabled over
small code sequences where lr is saved before enabling interrupts and
restored after interrupts are again disabled. */
/* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
from IRQ mode with interrupts disabled. This routine switches to the
system mode and returns with IRQ interrupts enabled. */
/* NOTE: It is very important to ensure all IRQ interrupts are cleared
prior to enabling nested IRQ interrupts. */
/*
#ifdef TX_ENABLE_IRQ_NESTING
BL _tx_thread_irq_nesting_start
#endif
*/
/* Application IRQ handlers can be called here! */
/* If interrupt nesting was started earlier, the end of interrupt nesting
service must be called before returning to _tx_thread_context_restore.
This routine returns in processing in IRQ mode with interrupts disabled. */
/*
#ifdef TX_ENABLE_IRQ_NESTING
BL _tx_thread_irq_nesting_end
#endif
*/
/* Jump to context restore to restore system context. */
/*
B _tx_thread_context_restore
*/
#ifdef TX_ENABLE_FIQ_SUPPORT
.global __tx_fiq_handler
.type __tx_fiq_handler, "function"
__tx_fiq_handler:
/* Jump to fiq context save to save system context. */
B _tx_thread_fiq_context_save
.global __tx_fiq_processing_return
.type __tx_fiq_processing_return, "function"
__tx_fiq_processing_return:
/* At this point execution is still in the FIQ mode. The CPSR, point of
interrupt, and all C scratch registers are available for use. */
/* Interrupt nesting is allowed after calling _tx_thread_fiq_nesting_start
from FIQ mode with interrupts disabled. This routine switches to the
system mode and returns with FIQ interrupts enabled. */
/* NOTE: It is very important to ensure all FIQ interrupts are cleared
prior to enabling nested FIQ interrupts. */
#ifdef TX_ENABLE_FIQ_NESTING
BL _tx_thread_fiq_nesting_start
#endif
/* Application FIQ handlers can be called here! */
/* If interrupt nesting was started earlier, the end of interrupt nesting
service must be called before returning to _tx_thread_fiq_context_restore. */
#ifdef TX_ENABLE_FIQ_NESTING
BL _tx_thread_fiq_nesting_end
#endif
/* Jump to fiq context restore to restore system context. */
B _tx_thread_fiq_context_restore
#else
.global __tx_fiq_handler
.type __tx_fiq_handler, "function"
__tx_fiq_handler:
B __tx_fiq_handler // FIQ interrupt handler
#endif
/* Reference build options and version ID to ensure they come in. */
LDR r2, =_tx_build_options // Pickup build options variable address
LDR r0, [r2, #0] // Pickup build options content
LDR r2, =_tx_version_id // Pickup version ID variable address
LDR r0, [r2, #0] // Pickup version ID content

View File

@@ -0,0 +1,252 @@
/**************************************************************************/
/* */
/* 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"
*/
#define IRQ_MODE 0x12 // IRQ mode
#define SVC_MODE 0x13 // SVC mode
.global _tx_thread_system_state
.global _tx_thread_current_ptr
.global _tx_thread_execute_ptr
.global _tx_timer_time_slice
.global _tx_thread_schedule
.global _tx_thread_preempt_disable
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_exit
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_restore(VOID)
{ */
.global _tx_thread_context_restore
.type _tx_thread_context_restore, "function"
_tx_thread_context_restore:
/* Lockout interrupts. */
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable IRQ 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, #0] // Pickup system state
SUB r2, r2, #1 // Decrement the counter
STR r2, [r3, #0] // 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
SUBS pc, lr, #0 // 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, #0] // 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, #0] // 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, #0] // 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
SUBS pc, lr, #0 // 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)
CPS #SVC_MODE // Switch to SVC mode to save context on thread stack
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
CPS #IRQ_MODE // Switch back to IRQ mode
LDMIA sp!, {r0-r3} // Recover r0-r3
CPS #SVC_MODE // Switch to SVC mode to save remaining context on thread stack
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, #0] // Pickup current thread pointer
#ifdef __ARM_FP
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!, {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
/* 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, #0] // 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, #0] // 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, #0] // 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! */
CPS #SVC_MODE // Switch to SVC mode
B _tx_thread_schedule // Return to scheduler
/* } */

View File

@@ -0,0 +1,202 @@
/**************************************************************************/
/* */
/* 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" */
.global _tx_thread_system_state
.global _tx_thread_current_ptr
.global __tx_irq_processing_return
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_enter
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_save(VOID)
{ */
.global _tx_thread_context_save
.type _tx_thread_context_save, "function"
_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
CPSID if // Disable FIQ interrupts
#endif
LDR r3, =_tx_thread_system_state // Pickup address of system state var
LDR r2, [r3, #0] // 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, #0] // 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, #0] // Store it back in the variable
LDR r1, =_tx_thread_current_ptr // Pickup address of current thread ptr
LDR r0, [r1, #0] // 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
/* } */
/* } */

View File

@@ -0,0 +1,260 @@
/**************************************************************************/
/* */
/* 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" */
#define FIQ_MODE 0x11 // FIQ mode
#define SVC_MODE 0x13 // SVC mode
#define MODE_MASK 0x1F // Mode mask
#define IRQ_MODE_BITS 0x12 // IRQ mode bits
.global _tx_thread_system_state
.global _tx_thread_current_ptr
.global _tx_thread_system_stack_ptr
.global _tx_thread_execute_ptr
.global _tx_timer_time_slice
.global _tx_thread_schedule
.global _tx_thread_preempt_disable
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_exit
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_context_restore Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_context_restore(VOID) */
/* { */
.global _tx_thread_fiq_context_restore
.type _tx_thread_fiq_context_restore, "function"
_tx_thread_fiq_context_restore:
/* Lockout interrupts. */
CPSID if // Disable IRQ and FIQ interrupts
#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
SUBS pc, lr, #0 // 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 and POI
MSR SPSR_cxsf, r0 // Put SPSR back
LDMIA sp!, {r0-r3} // Recover r0-r3
SUBS pc, lr, #0 // 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)
CPS #SVC_MODE // Switch to SVC mode to save context on thread stack
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
CPS #FIQ_MODE // Switch back to FIQ mode
LDMIA sp!, {r0-r3} // Recover r0-r3
CPS #SVC_MODE // Switch to SVC mode to save remaining context on thread stack
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 __ARM_FP
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 FIQ save
VMRS r2, FPSCR // Pickup the FPSCR
STR r2, [sp, #-4]! // Save FPSCR
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
/* 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
CPS #SVC_MODE // Switch to SVC mode
B _tx_thread_schedule // Return to scheduler
/* } */

View File

@@ -0,0 +1,209 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/**************************************************************************/
/**************************************************************************/
#ifdef TX_ENABLE_FIQ_SUPPORT
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/* #include "tx_api.h" */
/* #include "tx_thread.h" */
.global _tx_thread_system_state
.global _tx_thread_current_ptr
.global __tx_fiq_processing_return
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_enter
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_context_save Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_context_save(VOID) */
/* { */
.global _tx_thread_fiq_context_save
.type _tx_thread_fiq_context_save, "function"
_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
/* } */
/* } */
#endif

View File

@@ -0,0 +1,108 @@
/**************************************************************************/
/* */
/* 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" */
#define FIQ_MODE 0x11 // FIQ Mode bits
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_nesting_end Cortex-R4/AC6 */
/* 6.0.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.s). */
/* */
/* This function returns with FIQ interrupts disabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_nesting_end(VOID) */
/* { */
.global _tx_thread_fiq_nesting_end
.type _tx_thread_fiq_nesting_end, "function"
_tx_thread_fiq_nesting_end:
MOV r3, lr // Save ISR return address
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable IRQ interrupts
#endif
LDMIA sp!, {r1, lr} // Pickup saved lr (and r1 throw-away for
// 8-byte alignment logic)
CPS #FIQ_MODE // Switch back to FIQ mode
BX r3 // Return to caller
/* } */

View File

@@ -0,0 +1,96 @@
/**************************************************************************/
/* */
/* 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" */
#define SYS_MODE 0x12 // System mode
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fiq_nesting_start Cortex-R4/AC6 */
/* 6.0.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.s). */
/* */
/* This function returns with FIQ interrupts enabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_fiq_nesting_start(VOID) */
/* { */
.global _tx_thread_fiq_nesting_start
.type _tx_thread_fiq_nesting_start, "function"
_tx_thread_fiq_nesting_start:
MOV r3, lr // Save ISR return address
CPS #SYS_MODE // Switch to system mode
STMDB sp!, {r1, lr} // Push the system mode lr on the system mode stack
// and push r1 just to keep 8-byte alignment
CPSIE f // Enable FIQ interrupts
BX r3 // Return to caller
/* } */

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" */
#ifdef TX_ENABLE_FIQ_SUPPORT
#define INT_MASK 0xC0 // Interrupt bit mask
#else
#define INT_MASK 0x80 // Interrupt bit mask
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_control(UINT new_posture) */
/* { */
.global _tx_thread_interrupt_control
.type _tx_thread_interrupt_control, "function"
_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
BX lr // Return to caller
/* } */

View File

@@ -0,0 +1,96 @@
/**************************************************************************/
/* */
/* 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_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_disable(void) */
/* { */
.global _tx_thread_interrupt_disable
.type _tx_thread_interrupt_disable, "function"
_tx_thread_interrupt_disable:
/* Pickup current interrupt lockout posture. */
MRS r0, CPSR // Pickup current CPSR
/* Mask interrupts. */
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ
#else
CPSID i // Disable IRQ
#endif
BX lr // Return to caller
/* } */

View File

@@ -0,0 +1,90 @@
/**************************************************************************/
/* */
/* 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_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_restore Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* old_posture Old interrupt lockout posture */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_restore(UINT old_posture) */
/* { */
.global _tx_thread_interrupt_restore
.type _tx_thread_interrupt_restore, "function"
_tx_thread_interrupt_restore:
/* Apply the new interrupt posture. */
MSR CPSR_c, r0 // Setup new CPSR
BX lr // Return to caller
/* } */

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" */
#define IRQ_MODE 0x12 // IRQ Mode bits
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_irq_nesting_end Cortex-R4/AC6 */
/* 6.0.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.s). */
/* */
/* This function returns with IRQ interrupts disabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_irq_nesting_end(VOID) */
/* { */
.global _tx_thread_irq_nesting_end
.type _tx_thread_irq_nesting_end, "function"
_tx_thread_irq_nesting_end:
MOV r3, lr // Save ISR return address
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable IRQ interrupts
#endif
LDMIA sp!, {r1, lr} // Pickup saved lr (and r1 throw-away for
// 8-byte alignment logic)
CPS #IRQ_MODE // Switch back to IRQ mode
BX r3 // Return to caller
/* } */

View File

@@ -0,0 +1,96 @@
/**************************************************************************/
/* */
/* 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" */
#define SYS_MODE 0x1F // System mode bits
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_irq_nesting_start Cortex-R4/AC6 */
/* 6.0.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.s). */
/* */
/* This function returns with IRQ interrupts enabled. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ISRs */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_irq_nesting_start(VOID) */
/* { */
.global _tx_thread_irq_nesting_start
.type _tx_thread_irq_nesting_start, "function"
_tx_thread_irq_nesting_start:
MOV r3, lr // Save ISR return address
CPS #SYS_MODE // Switch to System Mode
STMDB sp!, {r1, lr} // Push the system mode lr on the system mode stack
// and push r1 just to keep 8-byte alignment
CPSIE i // Enable IRQ interrupts
BX r3 // Return to caller
/* } */

View File

@@ -0,0 +1,230 @@
/**************************************************************************/
/* */
/* 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" */
.global _tx_thread_execute_ptr
.global _tx_thread_current_ptr
.global _tx_timer_time_slice
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_thread_enter
#endif
.arm
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_schedule(VOID) */
/* { */
.global _tx_thread_schedule
.type _tx_thread_schedule, "function"
_tx_thread_schedule:
/* Enable interrupts. */
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSIE if // Enable IRQ and FIQ interrupts
#else
CPSIE i // Enable IRQ interrupts
#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, #0] // 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_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable IRQ interrupts
#endif
/* Setup the current thread pointer. */
/* _tx_thread_current_ptr = _tx_thread_execute_ptr; */
LDR r1, =_tx_thread_current_ptr // Pickup address of current thread
STR r0, [r1, #0] // 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, #0] // 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 __ARM_FP
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
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 __ARM_FP
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
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
BX lr // Return to caller
/* } */
#ifdef __ARM_FP
.global tx_thread_vfp_enable
.type tx_thread_vfp_enable, "function"
tx_thread_vfp_enable:
MRS r2, CPSR // Pickup the CPSR
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable 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
BX LR // Return to caller
.global tx_thread_vfp_disable
.type tx_thread_vfp_disable, "function"
tx_thread_vfp_disable:
MRS r2, CPSR // Pickup the CPSR
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable 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
BX LR // Return to caller
#endif

View File

@@ -0,0 +1,164 @@
/**************************************************************************/
/* */
/* 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" */
#define SVC_MODE 0x13 // SVC mode
#ifdef TX_ENABLE_FIQ_SUPPORT
#define CPSR_MASK 0xDF // Mask initial CPSR, IRQ & FIQ ints enabled
#else
#define CPSR_MASK 0x9F // Mask initial CPSR, IRQ ints enabled
#endif
#define THUMB_BIT 0x20 // Thumb-bit
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) */
/* { */
.global _tx_thread_stack_build
.type _tx_thread_stack_build, "function"
_tx_thread_stack_build:
/* Build a fake interrupt frame. The form of the fake interrupt stack
on the Cortex-R4 should look like the following after it is built:
Stack Top: 1 Interrupt stack frame type
CPSR Initial value for CPSR
a1 (r0) Initial value for a1
a2 (r1) Initial value for a2
a3 (r2) Initial value for a3
a4 (r3) Initial value for a4
v1 (r4) Initial value for v1
v2 (r5) Initial value for v2
v3 (r6) Initial value for v3
v4 (r7) Initial value for v4
v5 (r8) Initial value for v5
sb (r9) Initial value for sb
sl (r10) Initial value for sl
fp (r11) Initial value for fp
ip (r12) Initial value for ip
lr (r14) Initial value for lr
pc (r15) 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, #0] // 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 (sl)
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
TST r1, 1 // Test if Thumb bit is set in entry function address
ITE NE
ORRNE r3, r3, #THUMB_BIT // Yes, set the Thumb bit
BICEQ r3, r3, #THUMB_BIT // No, clear 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
BX lr // Return to caller
/* } */

View File

@@ -0,0 +1,162 @@
/**************************************************************************/
/* */
/* 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" */
.global _tx_thread_current_ptr
.global _tx_timer_time_slice
.global _tx_thread_schedule
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_thread_exit
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_system_return(VOID) */
/* { */
.global _tx_thread_system_return
.type _tx_thread_system_return, "function"
_tx_thread_system_return:
/* Save minimal context on the stack. */
STMDB sp!, {r4-r11, lr} // Save minimal context
LDR r5, =_tx_thread_current_ptr // Pickup address of current ptr
LDR r6, [r5, #0] // Pickup current thread pointer
#ifdef __ARM_FP
LDR r0, [r6, #144] // Pickup the VFP enabled flag
CMP r0, #0 // Is the VFP enabled?
BEQ _tx_skip_solicited_vfp_save // No, skip VFP solicited save
VMRS r4, FPSCR // Pickup the FPSCR
STR r4, [sp, #-4]! // Save FPSCR
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_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#else
CPSID i // Disable IRQ interrupts
#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
LDR r2, =_tx_timer_time_slice // Pickup address of time slice
LDR r1, [r2, #0] // 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, [r6, #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 time-slice
/* Save the current remaining 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, [r6, #24] // Store current time-slice
/* } */
__tx_thread_dont_save_ts:
/* Clear the current thread pointer. */
/* _tx_thread_current_ptr = TX_NULL; */
STR r4, [r5, #0] // Clear current thread pointer
B _tx_thread_schedule // Jump to scheduler!
/* } */

View File

@@ -0,0 +1,193 @@
/**************************************************************************/
/* */
/* 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" */
.global _tx_thread_system_state
.global _tx_thread_current_ptr
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_enter
#endif
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_vectored_context_save Cortex-R4/AC6 */
/* 6.0.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 */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_vectored_context_save(VOID) */
/* { */
.global _tx_thread_vectored_context_save
.type _tx_thread_vectored_context_save, "function"
_tx_thread_vectored_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++) */
/* { */
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if // Disable IRQ and FIQ interrupts
#endif
LDR r3, =_tx_thread_system_state // Pickup address of system state var
LDR r2, [r3, #0] // 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, #0] // 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
BX 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, #0] // Store it back in the variable
LDR r1, =_tx_thread_current_ptr // Pickup address of current thread ptr
LDR r0, [r1, #0] // 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
BX 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
BX lr // Return to caller
/* } */
/* } */

View File

@@ -0,0 +1,257 @@
/**************************************************************************/
/* */
/* 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" */
/* Define Assembly language external references... */
.global _tx_timer_time_slice
.global _tx_timer_system_clock
.global _tx_timer_current_ptr
.global _tx_timer_list_start
.global _tx_timer_list_end
.global _tx_timer_expired_time_slice
.global _tx_timer_expired
.global _tx_thread_time_slice
.global _tx_timer_expiration_process
#ifdef TX_THUMB_MODE
.thumb
#else
.arm
#endif
.text
.eabi_attribute Tag_ABI_align_preserved, 1
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt Cortex-R4/AC6 */
/* 6.0.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 Timer expiration processing */
/* _tx_thread_time_slice Time slice interrupted thread */
/* */
/* CALLED BY */
/* */
/* interrupt vector */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
/* VOID _tx_timer_interrupt(VOID) */
/* { */
.global _tx_timer_interrupt
.type _tx_timer_interrupt, "function"
_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, #0] // Pickup system clock
ADD r0, r0, #1 // Increment system clock
STR r0, [r1, #0] // 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, #0] // 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, #0] // 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, #0] // 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, #0] // Pickup current timer
LDR r2, [r0, #0] // 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, #0] // 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, #0] // 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, #0] // Set current pointer to list start
__tx_timer_skip_wrap:
STR r0, [r1, #0] // 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, #0] // 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, #0] // 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, #0] // Pickup timer expired flag
CMP r0, #0 // Check for timer expiration
BEQ __tx_timer_dont_activate // If not set, skip timer activation
/* Process 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, #0] // 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:
BX lr // Return to caller
/* } */