Release 6.1.11
This commit is contained in:
@@ -2,5 +2,5 @@ arm-none-eabi-gcc -c -g -mcpu=cortex-a8 reset.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a8 crt0.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a8 tx_initialize_low_level.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a8 -I../../../../common/inc -I../inc sample_threadx.c
|
||||
arm-none-eabi-ld -A cortex-a8 -T sample_threadx.ld reset.o crt0.o tx_initialize_low_level.o sample_threadx.o tx.a libc.a libgcc.a -o sample_threadx.out -M > sample_threadx.map
|
||||
arm-none-eabi-gcc -g -mcpu=cortex-a8 -T sample_threadx.ld --specs=nosys.specs -o sample_threadx.out -Wl,-Map=sample_threadx.map tx_initialize_low_level.o sample_threadx.o tx.a
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ _mainCRTStartup:
|
||||
mov a2, #0 /* Second arg: fill value */
|
||||
mov fp, a2 /* Null frame pointer */
|
||||
mov r7, a2 /* Null frame pointer for Thumb */
|
||||
|
||||
ldr a1, .LC1 /* First arg: start of memory block */
|
||||
ldr a3, .LC2
|
||||
sub a3, a3, a1 /* Third arg: length of block */
|
||||
|
||||
|
||||
|
||||
ldr a1, .LC1 /* First arg: start of memory block */
|
||||
ldr a3, .LC2
|
||||
sub a3, a3, a1 /* Third arg: length of block */
|
||||
|
||||
|
||||
|
||||
bl memset
|
||||
mov r0, #0 /* no arguments */
|
||||
mov r1, #0 /* no argv either */
|
||||
@@ -48,15 +48,15 @@ _mainCRTStartup:
|
||||
/* bl init */
|
||||
mov r0, r4
|
||||
mov r1, r5
|
||||
#endif
|
||||
#endif
|
||||
bl main
|
||||
|
||||
bl exit /* Should not return. */
|
||||
|
||||
|
||||
/* For Thumb, constants must be after the code since only
|
||||
|
||||
/* For Thumb, constants must be after the code since only
|
||||
positive offsets are supported for PC relative addresses. */
|
||||
|
||||
|
||||
.align 0
|
||||
.LC0:
|
||||
.LC1:
|
||||
|
||||
@@ -1,35 +1,24 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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"
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.arm
|
||||
|
||||
@@ -41,36 +30,35 @@
|
||||
.global __tx_reserved_handler
|
||||
.global __tx_irq_handler
|
||||
.global __tx_fiq_handler
|
||||
@
|
||||
@
|
||||
@/* Define the vector area. This should be located or copied to 0. */
|
||||
@
|
||||
|
||||
/* Define the vector area. This should be located or copied to 0. */
|
||||
|
||||
.text
|
||||
.global __vectors
|
||||
__vectors:
|
||||
|
||||
LDR pc, STARTUP @ Reset goes to startup function
|
||||
LDR pc, UNDEFINED @ Undefined handler
|
||||
LDR pc, SWI @ Software interrupt handler
|
||||
LDR pc, PREFETCH @ Prefetch exception handler
|
||||
LDR pc, ABORT @ Abort exception handler
|
||||
LDR pc, RESERVED @ Reserved exception handler
|
||||
LDR pc, IRQ @ IRQ interrupt handler
|
||||
LDR pc, FIQ @ FIQ interrupt handler
|
||||
LDR pc, STARTUP // Reset goes to startup function
|
||||
LDR pc, UNDEFINED // Undefined handler
|
||||
LDR pc, SWI // Software interrupt handler
|
||||
LDR pc, PREFETCH // Prefetch exception handler
|
||||
LDR pc, ABORT // Abort exception handler
|
||||
LDR pc, RESERVED // Reserved exception handler
|
||||
LDR pc, IRQ // IRQ interrupt handler
|
||||
LDR pc, FIQ // FIQ interrupt handler
|
||||
|
||||
STARTUP:
|
||||
.word _start @ Reset goes to C startup function
|
||||
.word _start // Reset goes to C startup function
|
||||
UNDEFINED:
|
||||
.word __tx_undefined @ Undefined handler
|
||||
.word __tx_undefined // Undefined handler
|
||||
SWI:
|
||||
.word __tx_swi_interrupt @ Software interrupt handler
|
||||
.word __tx_swi_interrupt // Software interrupt handler
|
||||
PREFETCH:
|
||||
.word __tx_prefetch_handler @ Prefetch exception handler
|
||||
ABORT:
|
||||
.word __tx_abort_handler @ Abort exception handler
|
||||
RESERVED:
|
||||
.word __tx_reserved_handler @ Reserved exception handler
|
||||
IRQ:
|
||||
.word __tx_irq_handler @ IRQ interrupt handler
|
||||
.word __tx_prefetch_handler // Prefetch exception handler
|
||||
ABORT:
|
||||
.word __tx_abort_handler // Abort exception handler
|
||||
RESERVED:
|
||||
.word __tx_reserved_handler // Reserved exception handler
|
||||
IRQ:
|
||||
.word __tx_irq_handler // IRQ interrupt handler
|
||||
FIQ:
|
||||
.word __tx_fiq_handler @ FIQ interrupt handler
|
||||
.word __tx_fiq_handler // FIQ interrupt handler
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
|
||||
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
|
||||
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
|
||||
byte pool, and block pool. */
|
||||
|
||||
#include "tx_api.h"
|
||||
@@ -80,42 +80,42 @@ CHAR *pointer = TX_NULL;
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create the main thread. */
|
||||
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
|
||||
/* Allocate the stack for thread 1. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 1 and 2. These threads pass information through a ThreadX
|
||||
/* Create threads 1 and 2. These threads pass information through a ThreadX
|
||||
message queue. It is also interesting to note that these threads have a time
|
||||
slice. */
|
||||
tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 2. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 3. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
|
||||
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
|
||||
An interesting thing here is that both threads share the same instruction area. */
|
||||
tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 4. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 5. */
|
||||
@@ -123,23 +123,23 @@ CHAR *pointer = TX_NULL;
|
||||
|
||||
/* Create thread 5. This thread simply pends on an event flag which will be set
|
||||
by thread_0. */
|
||||
tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 6. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
|
||||
tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 7. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the message queue. */
|
||||
@@ -242,11 +242,11 @@ UINT status;
|
||||
/* Retrieve a message from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check completion status and make sure the message is what we
|
||||
/* Check completion status and make sure the message is what we
|
||||
expected. */
|
||||
if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received))
|
||||
break;
|
||||
|
||||
|
||||
/* Otherwise, all is okay. Increment the received message count. */
|
||||
thread_2_messages_received++;
|
||||
}
|
||||
@@ -305,7 +305,7 @@ ULONG actual_flags;
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
@@ -358,7 +358,7 @@ UINT status;
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
|
||||
@@ -1,47 +1,35 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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"
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.arm
|
||||
|
||||
SVC_MODE = 0xD3 @ Disable IRQ/FIQ SVC mode
|
||||
IRQ_MODE = 0xD2 @ Disable IRQ/FIQ IRQ mode
|
||||
FIQ_MODE = 0xD1 @ Disable IRQ/FIQ FIQ mode
|
||||
SYS_MODE = 0xDF @ Disable IRQ/FIQ SYS mode
|
||||
FIQ_STACK_SIZE = 512 @ FIQ stack size
|
||||
IRQ_STACK_SIZE = 1024 @ IRQ stack size
|
||||
SYS_STACK_SIZE = 1024 @ System stack size
|
||||
@
|
||||
@
|
||||
SVC_MODE = 0xD3 // Disable IRQ/FIQ SVC mode
|
||||
IRQ_MODE = 0xD2 // Disable IRQ/FIQ IRQ mode
|
||||
FIQ_MODE = 0xD1 // Disable IRQ/FIQ FIQ mode
|
||||
SYS_MODE = 0xDF // Disable IRQ/FIQ SYS mode
|
||||
FIQ_STACK_SIZE = 512 // FIQ stack size
|
||||
IRQ_STACK_SIZE = 1024 // IRQ stack size
|
||||
SYS_STACK_SIZE = 1024 // System stack size
|
||||
|
||||
.global _tx_thread_system_stack_ptr
|
||||
.global _tx_initialize_unused_memory
|
||||
.global _tx_thread_context_save
|
||||
@@ -51,297 +39,267 @@ SYS_STACK_SIZE = 1024 @ System stack size
|
||||
.global _sp
|
||||
.global _stack_bottom
|
||||
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_initialize_low_level for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
|
||||
/* Define the 16-bit Thumb mode veneer for _tx_initialize_low_level for
|
||||
applications calling this function from to 16-bit Thumb mode. */
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.global $_tx_initialize_low_level
|
||||
.type $_tx_initialize_low_level,function
|
||||
$_tx_initialize_low_level:
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
BX pc // Switch to 32-bit mode
|
||||
NOP //
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_initialize_low_level @ Call _tx_initialize_low_level function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
STMFD sp!, {lr} // Save return address
|
||||
BL _tx_initialize_low_level // Call _tx_initialize_low_level function
|
||||
LDMFD sp!, {lr} // Recover saved return address
|
||||
BX lr // Return to 16-bit caller
|
||||
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_initialize_low_level Cortex-A8/GNU */
|
||||
@/* 6.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 */
|
||||
@/* */
|
||||
@/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_initialize_low_level(VOID)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_initialize_low_level ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.global _tx_initialize_low_level
|
||||
.type _tx_initialize_low_level,function
|
||||
_tx_initialize_low_level:
|
||||
@
|
||||
@ /* We must be in SVC mode at this point! */
|
||||
@
|
||||
@ /* Setup various stack pointers. */
|
||||
@
|
||||
LDR r1, =_sp @ Get pointer to stack area
|
||||
|
||||
#ifdef TX_ENABLE_IRQ_NESTING
|
||||
@
|
||||
@ /* Setup the system mode stack for nested interrupt support */
|
||||
@
|
||||
LDR r2, =SYS_STACK_SIZE @ Pickup stack size
|
||||
MOV r3, #SYS_MODE @ Build SYS mode CPSR
|
||||
MSR CPSR_c, r3 @ Enter SYS mode
|
||||
SUB r1, r1, #1 @ Backup 1 byte
|
||||
BIC r1, r1, #7 @ Ensure 8-byte alignment
|
||||
MOV sp, r1 @ Setup SYS stack pointer
|
||||
SUB r1, r1, r2 @ Calculate start of next stack
|
||||
/* We must be in SVC mode at this point! */
|
||||
|
||||
/* Setup various stack pointers. */
|
||||
|
||||
LDR r1, =_sp // Get pointer to stack area
|
||||
|
||||
#ifdef TX_ENABLE_IRQ_NESTING
|
||||
|
||||
/* Setup the system mode stack for nested interrupt support */
|
||||
|
||||
LDR r2, =SYS_STACK_SIZE // Pickup stack size
|
||||
MOV r3, #SYS_MODE // Build SYS mode CPSR
|
||||
MSR CPSR_c, r3 // Enter SYS mode
|
||||
SUB r1, r1, #1 // Backup 1 byte
|
||||
BIC r1, r1, #7 // Ensure 8-byte alignment
|
||||
MOV sp, r1 // Setup SYS stack pointer
|
||||
SUB r1, r1, r2 // Calculate start of next stack
|
||||
#endif
|
||||
|
||||
LDR r2, =FIQ_STACK_SIZE @ Pickup stack size
|
||||
MOV r0, #FIQ_MODE @ Build FIQ mode CPSR
|
||||
MSR CPSR, r0 @ Enter FIQ mode
|
||||
SUB r1, r1, #1 @ Backup 1 byte
|
||||
BIC r1, r1, #7 @ Ensure 8-byte alignment
|
||||
MOV sp, r1 @ Setup FIQ stack pointer
|
||||
SUB r1, r1, r2 @ Calculate start of next stack
|
||||
LDR r2, =IRQ_STACK_SIZE @ Pickup IRQ stack size
|
||||
MOV r0, #IRQ_MODE @ Build IRQ mode CPSR
|
||||
MSR CPSR, r0 @ Enter IRQ mode
|
||||
SUB r1, r1, #1 @ Backup 1 byte
|
||||
BIC r1, r1, #7 @ Ensure 8-byte alignment
|
||||
MOV sp, r1 @ Setup IRQ stack pointer
|
||||
SUB r3, r1, r2 @ Calculate end of IRQ stack
|
||||
MOV r0, #SVC_MODE @ Build SVC mode CPSR
|
||||
MSR CPSR, r0 @ Enter SVC mode
|
||||
LDR r2, =_stack_bottom @ Pickup stack bottom
|
||||
CMP r3, r2 @ Compare the current stack end with the bottom
|
||||
_stack_error_loop:
|
||||
BLT _stack_error_loop @ If the IRQ stack exceeds the stack bottom, just sit here!
|
||||
@
|
||||
@ /* Save the system stack pointer. */
|
||||
@ _tx_thread_system_stack_ptr = (VOID_PTR) (sp);
|
||||
@
|
||||
LDR r2, =_tx_thread_system_stack_ptr @ Pickup stack pointer
|
||||
STR r1, [r2] @ Save the system stack
|
||||
@
|
||||
@ /* Save the first available memory address. */
|
||||
@ _tx_initialize_unused_memory = (VOID_PTR) _end;
|
||||
@
|
||||
LDR r1, =_end @ Get end of non-initialized RAM area
|
||||
LDR r2, =_tx_initialize_unused_memory @ Pickup unused memory ptr address
|
||||
ADD r1, r1, #8 @ Increment to next free word
|
||||
STR r1, [r2] @ Save first free memory address
|
||||
@
|
||||
@ /* Setup Timer for periodic interrupts. */
|
||||
@
|
||||
@ /* Done, return to caller. */
|
||||
@
|
||||
LDR r2, =FIQ_STACK_SIZE // Pickup stack size
|
||||
MOV r0, #FIQ_MODE // Build FIQ mode CPSR
|
||||
MSR CPSR, r0 // Enter FIQ mode
|
||||
SUB r1, r1, #1 // Backup 1 byte
|
||||
BIC r1, r1, #7 // Ensure 8-byte alignment
|
||||
MOV sp, r1 // Setup FIQ stack pointer
|
||||
SUB r1, r1, r2 // Calculate start of next stack
|
||||
LDR r2, =IRQ_STACK_SIZE // Pickup IRQ stack size
|
||||
MOV r0, #IRQ_MODE // Build IRQ mode CPSR
|
||||
MSR CPSR, r0 // Enter IRQ mode
|
||||
SUB r1, r1, #1 // Backup 1 byte
|
||||
BIC r1, r1, #7 // Ensure 8-byte alignment
|
||||
MOV sp, r1 // Setup IRQ stack pointer
|
||||
SUB r3, r1, r2 // Calculate end of IRQ stack
|
||||
MOV r0, #SVC_MODE // Build SVC mode CPSR
|
||||
MSR CPSR, r0 // Enter SVC mode
|
||||
LDR r2, =_stack_bottom // Pickup stack bottom
|
||||
CMP r3, r2 // Compare the current stack end with the bottom
|
||||
_stack_error_loop:
|
||||
BLT _stack_error_loop // If the IRQ stack exceeds the stack bottom, just sit here!
|
||||
|
||||
LDR r2, =_tx_thread_system_stack_ptr // Pickup stack pointer
|
||||
STR r1, [r2] // Save the system stack
|
||||
|
||||
LDR r1, =_end // Get end of non-initialized RAM area
|
||||
LDR r2, =_tx_initialize_unused_memory // Pickup unused memory ptr address
|
||||
ADD r1, r1, #8 // Increment to next free word
|
||||
STR r1, [r2] // Save first free memory address
|
||||
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
@}
|
||||
@
|
||||
@
|
||||
@/* Define shells for each of the interrupt vectors. */
|
||||
@
|
||||
|
||||
/* Define shells for each of the interrupt vectors. */
|
||||
|
||||
.global __tx_undefined
|
||||
__tx_undefined:
|
||||
B __tx_undefined @ Undefined handler
|
||||
@
|
||||
B __tx_undefined // Undefined handler
|
||||
|
||||
.global __tx_swi_interrupt
|
||||
__tx_swi_interrupt:
|
||||
B __tx_swi_interrupt @ Software interrupt handler
|
||||
@
|
||||
B __tx_swi_interrupt // Software interrupt handler
|
||||
|
||||
.global __tx_prefetch_handler
|
||||
__tx_prefetch_handler:
|
||||
B __tx_prefetch_handler @ Prefetch exception handler
|
||||
@
|
||||
B __tx_prefetch_handler // Prefetch exception handler
|
||||
|
||||
.global __tx_abort_handler
|
||||
__tx_abort_handler:
|
||||
B __tx_abort_handler @ Abort exception handler
|
||||
@
|
||||
B __tx_abort_handler // Abort exception handler
|
||||
|
||||
.global __tx_reserved_handler
|
||||
__tx_reserved_handler:
|
||||
B __tx_reserved_handler @ Reserved exception handler
|
||||
@
|
||||
B __tx_reserved_handler // Reserved exception handler
|
||||
|
||||
.global __tx_irq_handler
|
||||
.global __tx_irq_processing_return
|
||||
.global __tx_irq_processing_return
|
||||
__tx_irq_handler:
|
||||
@
|
||||
@ /* Jump to context save to save system context. */
|
||||
|
||||
/* Jump to context save to save system context. */
|
||||
B _tx_thread_context_save
|
||||
__tx_irq_processing_return:
|
||||
@
|
||||
@ /* 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. */
|
||||
//
|
||||
/* 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
|
||||
@
|
||||
@ /* For debug purpose, execute the timer interrupt processing here. In
|
||||
@ a real system, some kind of status indication would have to be checked
|
||||
@ before the timer interrupt handler could be called. */
|
||||
@
|
||||
BL _tx_timer_interrupt @ Timer interrupt handler
|
||||
@
|
||||
@
|
||||
@ /* 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. */
|
||||
|
||||
/* For debug purpose, execute the timer interrupt processing here. In
|
||||
a real system, some kind of status indication would have to be checked
|
||||
before the timer interrupt handler could be called. */
|
||||
|
||||
BL _tx_timer_interrupt // Timer interrupt handler
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* 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
|
||||
@__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
|
||||
@
|
||||
@
|
||||
|
||||
|
||||
/* This is an example of a vectored IRQ handler. */
|
||||
|
||||
|
||||
|
||||
/* Save initial context and call context save to prepare for
|
||||
vectored ISR execution. */
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* 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_FIQ_SUPPORT
|
||||
.global __tx_fiq_handler
|
||||
.global __tx_fiq_processing_return
|
||||
__tx_fiq_handler:
|
||||
@
|
||||
@ /* Jump to fiq context save to save system context. */
|
||||
|
||||
/* Jump to fiq context save to save system context. */
|
||||
B _tx_thread_fiq_context_save
|
||||
__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. */
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* Jump to fiq context restore to restore system context. */
|
||||
B _tx_thread_fiq_context_restore
|
||||
@
|
||||
@
|
||||
|
||||
|
||||
#else
|
||||
.global __tx_fiq_handler
|
||||
__tx_fiq_handler:
|
||||
B __tx_fiq_handler @ FIQ interrupt handler
|
||||
B __tx_fiq_handler // FIQ interrupt handler
|
||||
#endif
|
||||
@
|
||||
@
|
||||
|
||||
|
||||
BUILD_OPTIONS:
|
||||
.word _tx_build_options @ Reference to bring in
|
||||
.word _tx_build_options // Reference to bring in
|
||||
VERSION_ID:
|
||||
.word _tx_version_id @ Reference to bring in
|
||||
.word _tx_version_id // Reference to bring in
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Port Specific */
|
||||
@@ -21,36 +21,38 @@
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h Cortex-A8/GNU */
|
||||
/* 6.1.6 */
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file contains data type definitions that make the ThreadX */
|
||||
/* real-time kernel function identically on a variety of different */
|
||||
/* processor architectures. For example, the size or number of bits */
|
||||
/* in an "int" data type vary between microprocessor architectures and */
|
||||
/* even C compilers for the same microprocessor. ThreadX does not */
|
||||
/* directly use native C data types. Instead, ThreadX creates its */
|
||||
/* own special types that can be mapped to actual data types by this */
|
||||
/* file to guarantee consistency in the interface and functionality. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* */
|
||||
/* This file contains data type definitions that make the ThreadX */
|
||||
/* real-time kernel function identically on a variety of different */
|
||||
/* processor architectures. For example, the size or number of bits */
|
||||
/* in an "int" data type vary between microprocessor architectures and */
|
||||
/* even C compilers for the same microprocessor. ThreadX does not */
|
||||
/* directly use native C data types. Instead, ThreadX creates its */
|
||||
/* own special types that can be mapped to actual data types by this */
|
||||
/* file to guarantee consistency in the interface and functionality. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */
|
||||
/* macro definition, */
|
||||
/* resulting in version 6.1.6 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -63,7 +65,7 @@
|
||||
#ifdef TX_INCLUDE_USER_DEFINE_FILE
|
||||
|
||||
|
||||
/* Yes, include the user defines in tx_user.h. The defines in this file may
|
||||
/* Yes, include the user defines in tx_user.h. The defines in this file may
|
||||
alternately be defined on the command line. */
|
||||
|
||||
#include "tx_user.h"
|
||||
@@ -76,7 +78,7 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Define ThreadX basic types for this port. */
|
||||
/* Define ThreadX basic types for this port. */
|
||||
|
||||
#define VOID void
|
||||
typedef char CHAR;
|
||||
@@ -112,12 +114,12 @@ typedef unsigned short USHORT;
|
||||
#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
|
||||
#endif
|
||||
|
||||
#ifndef TX_TIMER_THREAD_PRIORITY
|
||||
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
|
||||
#ifndef TX_TIMER_THREAD_PRIORITY
|
||||
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define various constants for the ThreadX ARM port. */
|
||||
/* Define various constants for the ThreadX ARM port. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */
|
||||
@@ -127,8 +129,8 @@ typedef unsigned short USHORT;
|
||||
#define TX_INT_ENABLE 0x00 /* Enable IRQ interrupts */
|
||||
|
||||
|
||||
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
|
||||
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
|
||||
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
|
||||
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
|
||||
source constants would be:
|
||||
|
||||
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
|
||||
@@ -175,7 +177,7 @@ typedef unsigned short USHORT;
|
||||
#define TX_INLINE_INITIALIZATION
|
||||
|
||||
|
||||
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
|
||||
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
|
||||
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
|
||||
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
|
||||
define is negated, thereby forcing the stack fill which is necessary for the stack checking
|
||||
@@ -187,13 +189,13 @@ typedef unsigned short USHORT;
|
||||
|
||||
|
||||
/* Define the TX_THREAD control block extensions for this port. The main reason
|
||||
for the multiple macros is so that backward compatibility can be maintained with
|
||||
for the multiple macros is so that backward compatibility can be maintained with
|
||||
existing ThreadX kernel awareness modules. */
|
||||
|
||||
#define TX_THREAD_EXTENSION_0
|
||||
#define TX_THREAD_EXTENSION_1
|
||||
#define TX_THREAD_EXTENSION_0
|
||||
#define TX_THREAD_EXTENSION_1
|
||||
#define TX_THREAD_EXTENSION_2 ULONG tx_thread_vfp_enable;
|
||||
#define TX_THREAD_EXTENSION_3
|
||||
#define TX_THREAD_EXTENSION_3
|
||||
|
||||
|
||||
/* Define the port extensions of the remaining ThreadX objects. */
|
||||
@@ -207,11 +209,11 @@ typedef unsigned short USHORT;
|
||||
#define TX_TIMER_EXTENSION
|
||||
|
||||
|
||||
/* Define the user extension field of the thread control block. Nothing
|
||||
/* Define the user extension field of the thread control block. Nothing
|
||||
additional is needed for this port so it is defined as white space. */
|
||||
|
||||
#ifndef TX_THREAD_USER_EXTENSION
|
||||
#define TX_THREAD_USER_EXTENSION
|
||||
#define TX_THREAD_USER_EXTENSION
|
||||
#endif
|
||||
|
||||
|
||||
@@ -219,8 +221,8 @@ typedef unsigned short USHORT;
|
||||
tx_thread_shell_entry, and tx_thread_terminate. */
|
||||
|
||||
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
|
||||
|
||||
@@ -247,24 +249,24 @@ typedef unsigned short USHORT;
|
||||
#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
|
||||
|
||||
|
||||
/* Determine if the ARM architecture has the CLZ instruction. This is available on
|
||||
architectures v5 and above. If available, redefine the macro for calculating the
|
||||
/* Determine if the ARM architecture has the CLZ instruction. This is available on
|
||||
architectures v5 and above. If available, redefine the macro for calculating the
|
||||
lowest bit set. */
|
||||
|
||||
|
||||
#if __TARGET_ARCH_ARM > 4
|
||||
|
||||
#ifndef __thumb__
|
||||
|
||||
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \
|
||||
asm volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); \
|
||||
b = 31 - b;
|
||||
b = 31 - b;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define ThreadX interrupt lockout and restore macros for protection on
|
||||
access of critical kernel information. The restore interrupt macro must
|
||||
restore the interrupt posture of the running thread prior to the value
|
||||
/* Define ThreadX interrupt lockout and restore macros for protection on
|
||||
access of critical kernel information. The restore interrupt macro must
|
||||
restore the interrupt posture of the running thread prior to the value
|
||||
present prior to the disable macro. In most cases, the save area macro
|
||||
is used to define a local function save area for the disable and restore
|
||||
macros. */
|
||||
@@ -295,7 +297,7 @@ unsigned int _tx_thread_interrupt_restore(UINT old_posture);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define VFP extension for the Cortex-A8. Each is assumed to be called in the context of the executing
|
||||
/* Define VFP extension for the ARMv7-A. Each is assumed to be called in the context of the executing
|
||||
thread. */
|
||||
|
||||
void tx_thread_vfp_enable(void);
|
||||
@@ -315,8 +317,8 @@ void tx_thread_vfp_disable(void);
|
||||
/* Define the version ID of ThreadX. This may be utilized by the application. */
|
||||
|
||||
#ifdef TX_THREAD_INIT
|
||||
CHAR _tx_version_id[] =
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-A8/GNU Version 6.1.9 *";
|
||||
CHAR _tx_version_id[] =
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX ARMv7-A Version 6.1.11 *";
|
||||
#else
|
||||
extern CHAR _tx_version_id[];
|
||||
#endif
|
||||
|
||||
@@ -1,260 +1,222 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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"
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.arm
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
SVC_MODE = 0xD3 @ Disable IRQ/FIQ, SVC mode
|
||||
IRQ_MODE = 0xD2 @ Disable IRQ/FIQ, IRQ mode
|
||||
SVC_MODE = 0xD3 // Disable IRQ/FIQ, SVC mode
|
||||
IRQ_MODE = 0xD2 // Disable IRQ/FIQ, IRQ mode
|
||||
#else
|
||||
SVC_MODE = 0x93 @ Disable IRQ, SVC mode
|
||||
IRQ_MODE = 0x92 @ Disable IRQ, IRQ mode
|
||||
SVC_MODE = 0x93 // Disable IRQ, SVC mode
|
||||
IRQ_MODE = 0x92 // Disable IRQ, IRQ mode
|
||||
#endif
|
||||
@
|
||||
|
||||
.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
|
||||
.global _tx_execution_isr_exit
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_restore
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
|
||||
|
||||
|
||||
/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_restore
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_context_restore Cortex-A8/GNU */
|
||||
@/* 6.1.9 */
|
||||
@/* 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 */
|
||||
@/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
@/* execution profile support, */
|
||||
@/* resulting in version 6.1.9 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_context_restore(VOID)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_context_restore ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
/* execution profile support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.global _tx_thread_context_restore
|
||||
.type _tx_thread_context_restore,function
|
||||
_tx_thread_context_restore:
|
||||
@
|
||||
@ /* Lockout interrupts. */
|
||||
@
|
||||
|
||||
/* Lockout interrupts. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable IRQ and FIQ interrupts
|
||||
CPSID if // Disable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i @ Disable IRQ interrupts
|
||||
CPSID i // Disable IRQ interrupts
|
||||
#endif
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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 variable
|
||||
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 @ 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
|
||||
/* 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. */
|
||||
|
||||
LDR r3, =_tx_thread_system_state // Pickup address of system state variable
|
||||
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. */
|
||||
|
||||
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:
|
||||
|
||||
/* Recover the saved context and return to the point of interrupt. */
|
||||
|
||||
/* Pickup the saved stack pointer. */
|
||||
|
||||
/* 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
|
||||
|
||||
__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 // 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 TX_ENABLE_VFP_SUPPORT
|
||||
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
|
||||
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
|
||||
@
|
||||
@ /* 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
|
||||
@
|
||||
@ }
|
||||
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. */
|
||||
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
|
||||
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
|
||||
@ }
|
||||
@
|
||||
|
||||
/* Clear the current task pointer. */
|
||||
MOV r0, #0 // NULL value
|
||||
STR r0, [r1] // Clear current thread pointer
|
||||
|
||||
/* Return to the scheduler. */
|
||||
B _tx_thread_schedule // Return to scheduler
|
||||
|
||||
__tx_thread_idle_system_restore:
|
||||
@
|
||||
@ /* Just return back to the scheduler! */
|
||||
@
|
||||
MOV r0, #SVC_MODE @ Build SVC mode CPSR
|
||||
MSR CPSR_c, r0 @ Enter SVC mode
|
||||
B _tx_thread_schedule @ Return to scheduler
|
||||
@}
|
||||
|
||||
|
||||
|
||||
/* Just return back to the scheduler! */
|
||||
MOV r0, #SVC_MODE // Build SVC mode CPSR
|
||||
MSR CPSR_c, r0 // Enter SVC mode
|
||||
B _tx_thread_schedule // Return to scheduler
|
||||
|
||||
@@ -1,206 +1,172 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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"
|
||||
@
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_irq_processing_return
|
||||
.global _tx_execution_isr_enter
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_save
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.global __tx_irq_processing_return
|
||||
|
||||
|
||||
/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_save
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_context_save Cortex-A8/GNU */
|
||||
@/* 6.1.9 */
|
||||
@/* 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 */
|
||||
@/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
@/* execution profile support, */
|
||||
@/* resulting in version 6.1.9 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_context_save(VOID)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_context_save ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
/* execution profile support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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
|
||||
|
||||
/* 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. */
|
||||
|
||||
STMDB sp!, {r0-r3} // Save some working registers
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable FIQ interrupts
|
||||
CPSID if // Disable FIQ interrupts
|
||||
#endif
|
||||
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
|
||||
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
|
||||
LDR r3, =_tx_thread_system_state // Pickup address of system state variable
|
||||
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
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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
|
||||
|
||||
/* 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
|
||||
@
|
||||
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
|
||||
|
||||
/* Otherwise, not nested, check to see if a thread was running. */
|
||||
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
|
||||
|
||||
MOV r10, #0 // Clear stack limit
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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
|
||||
|
||||
/* 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
|
||||
@ {
|
||||
@
|
||||
B __tx_irq_processing_return // Continue IRQ processing
|
||||
|
||||
__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
|
||||
|
||||
/* 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
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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
|
||||
|
||||
/* 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
|
||||
@
|
||||
@ }
|
||||
@}
|
||||
|
||||
|
||||
|
||||
ADD sp, sp, #16 // Recover saved registers
|
||||
B __tx_irq_processing_return // Continue IRQ processing
|
||||
|
||||
@@ -1,43 +1,32 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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
|
||||
MODE_MASK = 0x1F @ Mode mask
|
||||
THUMB_MASK = 0x20 @ Thumb bit mask
|
||||
IRQ_MODE_BITS = 0x12 @ IRQ mode bits
|
||||
@
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
SVC_MODE = 0xD3 // SVC mode
|
||||
FIQ_MODE = 0xD1 // FIQ mode
|
||||
MODE_MASK = 0x1F // Mode mask
|
||||
THUMB_MASK = 0x20 // Thumb bit mask
|
||||
IRQ_MODE_BITS = 0x12 // IRQ mode bits
|
||||
|
||||
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_thread_system_stack_ptr
|
||||
@@ -46,218 +35,189 @@ IRQ_MODE_BITS = 0x12 @ IRQ mode bits
|
||||
.global _tx_thread_schedule
|
||||
.global _tx_thread_preempt_disable
|
||||
.global _tx_execution_isr_exit
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_restore
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
|
||||
|
||||
/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_restore
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_fiq_context_restore Cortex-A8/GNU */
|
||||
@/* 6.1.9 */
|
||||
@/* 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 */
|
||||
@/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
@/* execution profile support, */
|
||||
@/* resulting in version 6.1.9 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_fiq_context_restore(VOID)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_fiq_context_restore ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
/* execution profile support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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
|
||||
|
||||
/* Lockout interrupts. */
|
||||
|
||||
CPSID if // Disable IRQ and FIQ interrupts
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* Call the ISR exit function to indicate an ISR is complete. */
|
||||
@
|
||||
BL _tx_execution_isr_exit @ Call the ISR exit function
|
||||
|
||||
/* 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 variable
|
||||
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
|
||||
@
|
||||
@ }
|
||||
|
||||
/* Determine if interrupts are nested. */
|
||||
LDR r3, =_tx_thread_system_state // Pickup address of system state variable
|
||||
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
|
||||
|
||||
/* Determine if a thread was interrupted and no preemption is required. */
|
||||
|
||||
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 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
|
||||
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 @ Reenter 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
|
||||
/* Restore interrupted thread or ISR. */
|
||||
/* 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
|
||||
|
||||
__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 // Reenter 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 TX_ENABLE_VFP_SUPPORT
|
||||
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
|
||||
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 */
|
||||
@
|
||||
@ /* 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
|
||||
@
|
||||
@}
|
||||
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 */
|
||||
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
|
||||
|
||||
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. */
|
||||
|
||||
MOV r0, #0 // NULL value
|
||||
STR r0, [r1] // Clear current thread pointer
|
||||
|
||||
/* Return to the scheduler. */
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -1,207 +1,178 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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"
|
||||
@
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
.global __tx_fiq_processing_return
|
||||
.global _tx_execution_isr_enter
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_save
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
|
||||
|
||||
/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_save
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_fiq_context_save Cortex-A8/GNU */
|
||||
@/* 6.1.9 */
|
||||
@/* 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 */
|
||||
@/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
@/* execution profile support, */
|
||||
@/* resulting in version 6.1.9 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@ VOID _tx_thread_fiq_context_save(VOID)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_fiq_context_save ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
/* execution profile support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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 variable
|
||||
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
|
||||
|
||||
/* 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. */
|
||||
|
||||
STMDB sp!, {r0-r3} // Save some working registers
|
||||
LDR r3, =_tx_thread_system_state // Pickup address of system state variable
|
||||
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
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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
|
||||
|
||||
/* 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
|
||||
@
|
||||
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
|
||||
|
||||
/* Otherwise, not nested, check to see if a thread was running. */
|
||||
|
||||
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.
|
||||
|
||||
MOV r10, #0 // Clear stack limit
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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
|
||||
|
||||
/* 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
|
||||
@ {
|
||||
@
|
||||
B __tx_fiq_processing_return // Continue FIQ processing
|
||||
|
||||
__tx_thread_fiq_idle_system_save:
|
||||
@
|
||||
@ /* Interrupt occurred in the scheduling loop. */
|
||||
@
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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
|
||||
@
|
||||
@ }
|
||||
@}
|
||||
|
||||
/* Interrupt occurred in the scheduling loop. */
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -1,116 +1,104 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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"
|
||||
@
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
|
||||
DISABLE_INTS = 0xC0 // Disable IRQ/FIQ interrupts
|
||||
#else
|
||||
DISABLE_INTS = 0x80 @ Disable IRQ interrupts
|
||||
DISABLE_INTS = 0x80 // Disable IRQ interrupts
|
||||
#endif
|
||||
MODE_MASK = 0x1F @ Mode mask
|
||||
FIQ_MODE_BITS = 0x11 @ FIQ mode bits
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_end
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
MODE_MASK = 0x1F // Mode mask
|
||||
FIQ_MODE_BITS = 0x11 // FIQ mode bits
|
||||
|
||||
|
||||
/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_end
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_fiq_nesting_end Cortex-A8/GNU */
|
||||
@/* 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.s). */
|
||||
@/* */
|
||||
@/* 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)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_fiq_nesting_end ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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
|
||||
MRS r0, CPSR @ Pickup the CPSR
|
||||
ORR r0, r0, #DISABLE_INTS @ Build disable interrupt value
|
||||
MSR CPSR_c, r0 @ Disable interrupts
|
||||
LDMIA sp!, {r1, lr} @ Pickup saved lr (and r1 throw-away for
|
||||
@ 8-byte alignment logic)
|
||||
BIC r0, r0, #MODE_MASK @ Clear mode bits
|
||||
ORR r0, r0, #FIQ_MODE_BITS @ Build IRQ mode CPSR
|
||||
MSR CPSR_c, r0 @ Reenter IRQ mode
|
||||
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
|
||||
LDMIA sp!, {r1, lr} // Pickup saved lr (and r1 throw-away for
|
||||
// 8-byte alignment logic)
|
||||
BIC r0, r0, #MODE_MASK // Clear mode bits
|
||||
ORR r0, r0, #FIQ_MODE_BITS // Build IRQ mode CPSR
|
||||
MSR CPSR_c, r0 // Reenter IRQ mode
|
||||
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 @ Return to caller
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 @ Return to caller
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
|
||||
@@ -1,108 +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"
|
||||
@
|
||||
@
|
||||
FIQ_DISABLE = 0x40 @ FIQ disable bit
|
||||
MODE_MASK = 0x1F @ Mode mask
|
||||
SYS_MODE_BITS = 0x1F @ System mode bits
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_start
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
FIQ_DISABLE = 0x40 // FIQ disable bit
|
||||
MODE_MASK = 0x1F // Mode mask
|
||||
SYS_MODE_BITS = 0x1F // System mode bits
|
||||
|
||||
|
||||
/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_start
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_fiq_nesting_start Cortex-A8/GNU */
|
||||
@/* 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.s). */
|
||||
@/* */
|
||||
@/* 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)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_fiq_nesting_start ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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
|
||||
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
|
||||
STMDB sp!, {r1, lr} @ Push the system mode lr on the system mode stack
|
||||
@ and push r1 just to keep 8-byte alignment
|
||||
BIC r0, r0, #FIQ_DISABLE @ Build enable FIQ CPSR
|
||||
MSR CPSR_c, r0 @ Enter system mode
|
||||
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
|
||||
STMDB sp!, {r1, lr} // Push the system mode lr on the system mode stack
|
||||
// and push r1 just to keep 8-byte alignment
|
||||
BIC r0, r0, #FIQ_DISABLE // Build enable FIQ CPSR
|
||||
MSR CPSR_c, r0 // Enter system mode
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 @ Return to caller
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 @ Return to caller
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
|
||||
@@ -1,115 +1,104 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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" */
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
INT_MASK = 0x03F
|
||||
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_control for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
|
||||
/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_control for
|
||||
applications calling this function from to 16-bit Thumb mode. */
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_interrupt_control
|
||||
$_tx_thread_interrupt_control:
|
||||
.thumb
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
BX pc // Switch to 32-bit mode
|
||||
NOP //
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_interrupt_control @ Call _tx_thread_interrupt_control function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
STMFD sp!, {lr} // Save return address
|
||||
BL _tx_thread_interrupt_control // Call _tx_thread_interrupt_control function
|
||||
LDMFD sp!, {lr} // Recover saved return address
|
||||
BX lr // Return to 16-bit caller
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_interrupt_control Cortex-A8/GNU */
|
||||
@/* 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)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_interrupt_control ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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
|
||||
MOV r2, #INT_MASK @ Build interrupt mask
|
||||
AND r1, r3, r2 @ 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
|
||||
BIC r0, r3, r2 @ Return previous interrupt mask
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
/* Pickup current interrupt lockout posture. */
|
||||
|
||||
MRS r3, CPSR // Pickup current CPSR
|
||||
MOV r2, #INT_MASK // Build interrupt mask
|
||||
AND r1, r3, r2 // 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
|
||||
BIC r0, r3, r2 // Return previous interrupt mask
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
|
||||
@@ -1,113 +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"
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_disable for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 the 16-bit Thumb mode veneer for _tx_thread_interrupt_disable for
|
||||
applications calling this function from to 16-bit Thumb mode. */
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_interrupt_disable
|
||||
$_tx_thread_interrupt_disable:
|
||||
.thumb
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
BX pc // Switch to 32-bit mode
|
||||
NOP //
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_interrupt_disable @ Call _tx_thread_interrupt_disable function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
STMFD sp!, {lr} // Save return address
|
||||
BL _tx_thread_interrupt_disable // Call _tx_thread_interrupt_disable function
|
||||
LDMFD sp!, {lr} // Recover saved return address
|
||||
BX lr // Return to 16-bit caller
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_interrupt_disable Cortex-A8/GNU */
|
||||
@/* 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)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_interrupt_disable ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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. */
|
||||
@
|
||||
|
||||
/* Pickup current interrupt lockout posture. */
|
||||
|
||||
MRS r0, CPSR // Pickup current CPSR
|
||||
|
||||
/* Mask interrupts. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable IRQ and FIQ
|
||||
CPSID if // Disable IRQ and FIQ
|
||||
#else
|
||||
CPSID i @ Disable IRQ
|
||||
CPSID i // Disable IRQ
|
||||
#endif
|
||||
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
|
||||
|
||||
@@ -1,104 +1,93 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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 the 16-bit Thumb mode veneer for _tx_thread_interrupt_restore for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 the 16-bit Thumb mode veneer for _tx_thread_interrupt_restore for
|
||||
applications calling this function from to 16-bit Thumb mode. */
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_interrupt_restore
|
||||
$_tx_thread_interrupt_restore:
|
||||
.thumb
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
BX pc // Switch to 32-bit mode
|
||||
NOP //
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_interrupt_restore @ Call _tx_thread_interrupt_restore function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
STMFD sp!, {lr} // Save return address
|
||||
BL _tx_thread_interrupt_restore // Call _tx_thread_interrupt_restore function
|
||||
LDMFD sp!, {lr} // Recover saved return address
|
||||
BX lr // Return to 16-bit caller
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_interrupt_restore Cortex-A8/GNU */
|
||||
@/* 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 */
|
||||
@/* */
|
||||
@/* old_posture Old 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 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@UINT _tx_thread_interrupt_restore(UINT old_posture)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_interrupt_restore ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
/* Apply the new interrupt posture. */
|
||||
|
||||
MSR CPSR_c, r0 // Setup new CPSR
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
|
||||
@@ -1,115 +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"
|
||||
@
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
|
||||
DISABLE_INTS = 0xC0 // Disable IRQ/FIQ interrupts
|
||||
#else
|
||||
DISABLE_INTS = 0x80 @ Disable IRQ interrupts
|
||||
DISABLE_INTS = 0x80 // Disable IRQ interrupts
|
||||
#endif
|
||||
MODE_MASK = 0x1F @ Mode mask
|
||||
IRQ_MODE_BITS = 0x12 @ IRQ mode bits
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_end
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
MODE_MASK = 0x1F // Mode mask
|
||||
IRQ_MODE_BITS = 0x12 // IRQ mode bits
|
||||
|
||||
|
||||
/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_end
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_irq_nesting_end Cortex-A8/GNU */
|
||||
@/* 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.s). */
|
||||
@/* */
|
||||
@/* 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)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_irq_nesting_end ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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
|
||||
MRS r0, CPSR @ Pickup the CPSR
|
||||
ORR r0, r0, #DISABLE_INTS @ Build disable interrupt value
|
||||
MSR CPSR_c, r0 @ Disable interrupts
|
||||
LDMIA sp!, {r1, lr} @ Pickup saved lr (and r1 throw-away for
|
||||
@ 8-byte alignment logic)
|
||||
BIC r0, r0, #MODE_MASK @ Clear mode bits
|
||||
ORR r0, r0, #IRQ_MODE_BITS @ Build IRQ mode CPSR
|
||||
MSR CPSR_c, r0 @ Reenter IRQ mode
|
||||
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
|
||||
LDMIA sp!, {r1, lr} // Pickup saved lr (and r1 throw-away for
|
||||
// 8-byte alignment logic)
|
||||
BIC r0, r0, #MODE_MASK // Clear mode bits
|
||||
ORR r0, r0, #IRQ_MODE_BITS // Build IRQ mode CPSR
|
||||
MSR CPSR_c, r0 // Reenter IRQ mode
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 @ Return to caller
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 @ Return to caller
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
|
||||
@@ -1,108 +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"
|
||||
@
|
||||
@
|
||||
IRQ_DISABLE = 0x80 @ IRQ disable bit
|
||||
MODE_MASK = 0x1F @ Mode mask
|
||||
SYS_MODE_BITS = 0x1F @ System mode bits
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_start
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
IRQ_DISABLE = 0x80 // IRQ disable bit
|
||||
MODE_MASK = 0x1F // Mode mask
|
||||
SYS_MODE_BITS = 0x1F // System mode bits
|
||||
|
||||
|
||||
/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_start
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_irq_nesting_start Cortex-A8/GNU */
|
||||
@/* 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.s). */
|
||||
@/* */
|
||||
@/* 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)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_irq_nesting_start ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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
|
||||
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
|
||||
STMDB sp!, {r1, lr} @ Push the system mode lr on the system mode stack
|
||||
@ and push r1 just to keep 8-byte alignment
|
||||
BIC r0, r0, #IRQ_DISABLE @ Build enable IRQ CPSR
|
||||
MSR CPSR_c, r0 @ Enter system mode
|
||||
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
|
||||
STMDB sp!, {r1, lr} // Push the system mode lr on the system mode stack
|
||||
// and push r1 just to keep 8-byte alignment
|
||||
BIC r0, r0, #IRQ_DISABLE // Build enable IRQ CPSR
|
||||
MSR CPSR_c, r0 // Enter system mode
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 @ Return to caller
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 @ Return to caller
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
|
||||
@@ -1,258 +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"
|
||||
@
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.global _tx_thread_execute_ptr
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_execution_thread_enter
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_schedule for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
|
||||
|
||||
/* Define the 16-bit Thumb mode veneer for _tx_thread_schedule for
|
||||
applications calling this function from to 16-bit Thumb mode. */
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_schedule
|
||||
.type $_tx_thread_schedule,function
|
||||
$_tx_thread_schedule:
|
||||
.thumb
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
BX pc // Switch to 32-bit mode
|
||||
NOP //
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_schedule @ Call _tx_thread_schedule function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
STMFD sp!, {lr} // Save return address
|
||||
BL _tx_thread_schedule // Call _tx_thread_schedule function
|
||||
LDMFD sp!, {lr} // Recover saved return address
|
||||
BX lr // Return to 16-bit caller
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_schedule Cortex-A8/GNU */
|
||||
@/* 6.1.9 */
|
||||
@/* 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 */
|
||||
@/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
@/* execution profile support, */
|
||||
@/* resulting in version 6.1.9 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_schedule(VOID)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_schedule ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
/* execution profile support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.global _tx_thread_schedule
|
||||
.type _tx_thread_schedule,function
|
||||
_tx_thread_schedule:
|
||||
@
|
||||
@ /* Enable interrupts. */
|
||||
@
|
||||
|
||||
/* Enable interrupts. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSIE if @ Enable IRQ and FIQ interrupts
|
||||
CPSIE if // Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSIE i @ Enable IRQ interrupts
|
||||
CPSIE i // Enable IRQ interrupts
|
||||
#endif
|
||||
@
|
||||
@ /* Wait for a thread to execute. */
|
||||
@ do
|
||||
@ {
|
||||
LDR r1, =_tx_thread_execute_ptr @ Address of thread execute ptr
|
||||
@
|
||||
|
||||
/* Wait for a thread to execute. */
|
||||
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. */
|
||||
@
|
||||
|
||||
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
|
||||
/* 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
|
||||
CPSID if // Disable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i @ Disable IRQ interrupts
|
||||
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] @ 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
|
||||
@
|
||||
@ /* Switch to the thread's stack. */
|
||||
@ sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
|
||||
@
|
||||
|
||||
/* Setup the current thread pointer. */
|
||||
|
||||
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. */
|
||||
|
||||
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. */
|
||||
|
||||
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
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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
|
||||
|
||||
/* 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
|
||||
@
|
||||
@ /* 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
|
||||
|
||||
/* 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
|
||||
MSR SPSR_cxsf, r5 // Setup SPSR for return
|
||||
#ifdef TX_ENABLE_VFP_SUPPORT
|
||||
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
|
||||
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
|
||||
LDMIA sp!, {r0-r12, lr, pc}^ // Return to point of thread interrupt
|
||||
|
||||
_tx_solicited_return:
|
||||
|
||||
#ifdef TX_ENABLE_VFP_SUPPORT
|
||||
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
|
||||
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
|
||||
MSR CPSR_cxsf, r5 // Recover CPSR
|
||||
LDMIA sp!, {r4-r11, lr} // Return to thread synchronously
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
@
|
||||
@}
|
||||
@
|
||||
|
||||
#ifdef TX_ENABLE_VFP_SUPPORT
|
||||
|
||||
.global tx_thread_vfp_enable
|
||||
.type tx_thread_vfp_enable,function
|
||||
tx_thread_vfp_enable:
|
||||
MRS r2, CPSR @ Pickup the CPSR
|
||||
MRS r2, CPSR // Pickup the CPSR
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Enable IRQ and FIQ interrupts
|
||||
CPSID if // Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i @ Enable IRQ interrupts
|
||||
CPSID 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)
|
||||
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
|
||||
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
|
||||
MRS r2, CPSR // Pickup the CPSR
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Enable IRQ and FIQ interrupts
|
||||
CPSID if // Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i @ Enable IRQ interrupts
|
||||
CPSID 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)
|
||||
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
|
||||
MSR CPSR_cxsf, r2 // Recover CPSR
|
||||
BX LR // Return to caller
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,178 +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"
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
.arm
|
||||
|
||||
SVC_MODE = 0x13 @ SVC mode
|
||||
SVC_MODE = 0x13 // SVC mode
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSR_MASK = 0xDF @ Mask initial CPSR, IRQ & FIQ interrupts enabled
|
||||
CPSR_MASK = 0xDF // Mask initial CPSR, IRQ & FIQ interrupts enabled
|
||||
#else
|
||||
CPSR_MASK = 0x9F @ Mask initial CPSR, IRQ interrupts enabled
|
||||
CPSR_MASK = 0x9F // Mask initial CPSR, IRQ interrupts enabled
|
||||
#endif
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_stack_build for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
|
||||
|
||||
/* Define the 16-bit Thumb mode veneer for _tx_thread_stack_build for
|
||||
applications calling this function from to 16-bit Thumb mode. */
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.global $_tx_thread_stack_build
|
||||
.type $_tx_thread_stack_build,function
|
||||
$_tx_thread_stack_build:
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
BX pc // Switch to 32-bit mode
|
||||
NOP //
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_stack_build @ Call _tx_thread_stack_build function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
STMFD sp!, {lr} // Save return address
|
||||
BL _tx_thread_stack_build // Call _tx_thread_stack_build function
|
||||
LDMFD sp!, {lr} // Recover saved return address
|
||||
BX lr // Return to 16-bit caller
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_stack_build Cortex-A8/GNU */
|
||||
@/* 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))
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_stack_build ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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-A8 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)
|
||||
LDR r3,=_tx_thread_schedule @ Pickup address of _tx_thread_schedule for GDB backtrace
|
||||
STR r3, [r2, #60] @ Store initial r14 (lr)
|
||||
MOV r3, #0 @ Build initial register value
|
||||
STR r3, [r2, #52] @ Store initial r11
|
||||
STR r3, [r2, #56] @ Store initial r12
|
||||
STR r1, [r2, #64] @ Store initial pc
|
||||
STR r3, [r2, #68] @ 0 for back-trace
|
||||
MRS r1, CPSR @ Pickup CPSR
|
||||
BIC r1, r1, #CPSR_MASK @ Mask mode bits of CPSR
|
||||
ORR r3, r1, #SVC_MODE @ Build CPSR, SVC mode, interrupts enabled
|
||||
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
|
||||
|
||||
|
||||
/* Build a fake interrupt frame. The form of the fake interrupt stack
|
||||
on the ARMv7-A 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
|
||||
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)
|
||||
LDR r3,=_tx_thread_schedule // Pickup address of _tx_thread_schedule for GDB backtrace
|
||||
STR r3, [r2, #60] // Store initial r14 (lr)
|
||||
MOV r3, #0 // Build initial register value
|
||||
STR r3, [r2, #52] // Store initial r11
|
||||
STR r3, [r2, #56] // Store initial r12
|
||||
STR r1, [r2, #64] // Store initial pc
|
||||
STR r3, [r2, #68] // 0 for back-trace
|
||||
MRS r1, CPSR // Pickup CPSR
|
||||
BIC r1, r1, #CPSR_MASK // Mask mode bits of CPSR
|
||||
ORR r3, r1, #SVC_MODE // Build CPSR, SVC mode, interrupts enabled
|
||||
STR r3, [r2, #4] // Store initial CPSR
|
||||
|
||||
/* Setup stack pointer. */
|
||||
|
||||
STR r2, [r0, #8] // Save stack pointer in thread's
|
||||
// control block
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
|
||||
|
||||
@@ -1,183 +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"
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.arm
|
||||
@
|
||||
@
|
||||
|
||||
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_thread_schedule
|
||||
.global _tx_execution_thread_exit
|
||||
@
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_system_return for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
|
||||
|
||||
|
||||
/* Define the 16-bit Thumb mode veneer for _tx_thread_system_return for
|
||||
applications calling this function from to 16-bit Thumb mode. */
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_system_return
|
||||
.type $_tx_thread_system_return,function
|
||||
$_tx_thread_system_return:
|
||||
.thumb
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
BX pc // Switch to 32-bit mode
|
||||
NOP //
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_system_return @ Call _tx_thread_system_return function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
STMFD sp!, {lr} // Save return address
|
||||
BL _tx_thread_system_return // Call _tx_thread_system_return function
|
||||
LDMFD sp!, {lr} // Recover saved return address
|
||||
BX lr // Return to 16-bit caller
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_system_return Cortex-A8/GNU */
|
||||
@/* 6.1.9 */
|
||||
@/* 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 */
|
||||
@/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
@/* execution profile support, */
|
||||
@/* resulting in version 6.1.9 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_system_return(VOID)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_system_return ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
/* execution profile support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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 r4, =_tx_thread_current_ptr @ Pickup address of current ptr
|
||||
LDR r5, [r4] @ Pickup current thread pointer
|
||||
|
||||
/* Save minimal context on the stack. */
|
||||
|
||||
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 TX_ENABLE_VFP_SUPPORT
|
||||
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
|
||||
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_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i @ Disable IRQ interrupts
|
||||
#endif
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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 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] @ 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!
|
||||
@
|
||||
@}
|
||||
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
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
|
||||
/* 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. */
|
||||
|
||||
STR sp, [r0, #8] // Save thread stack pointer
|
||||
|
||||
/* Determine if the time-slice is active. */
|
||||
|
||||
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 time-slice for the thread and clear the current time-slice. */
|
||||
|
||||
STR r4, [r2] // Clear time-slice
|
||||
STR r1, [r0, #24] // Save current time-slice
|
||||
|
||||
__tx_thread_dont_save_ts:
|
||||
|
||||
/* Clear the current thread pointer. */
|
||||
|
||||
STR r4, [r3] // Clear current thread pointer
|
||||
B _tx_thread_schedule // Jump to scheduler!
|
||||
|
||||
@@ -1,193 +1,165 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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"
|
||||
@
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_execution_isr_enter
|
||||
@
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_vectored_context_save
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
|
||||
|
||||
|
||||
/* No 16-bit Thumb mode veneer code is needed for _tx_thread_vectored_context_save
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_vectored_context_save Cortex-A8/GNU */
|
||||
@/* 6.1.9 */
|
||||
@/* 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 */
|
||||
@/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
@/* execution profile support, */
|
||||
@/* resulting in version 6.1.9 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_vectored_context_save(VOID)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_vectored_context_save ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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 */
|
||||
/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
/* execution profile support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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++)
|
||||
@ {
|
||||
@
|
||||
|
||||
/* 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. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable IRQ and FIQ interrupts
|
||||
CPSID if // Disable IRQ and FIQ interrupts
|
||||
#endif
|
||||
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
|
||||
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
|
||||
LDR r3, =_tx_thread_system_state // Pickup address of system state variable
|
||||
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
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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
|
||||
|
||||
/* 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
|
||||
@
|
||||
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, #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
|
||||
|
||||
/* Otherwise, not nested, check to see if a thread was running. */
|
||||
|
||||
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. */
|
||||
|
||||
MOV r10, #0 // Clear stack limit
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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
|
||||
|
||||
/* 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
|
||||
@ {
|
||||
@
|
||||
MOV pc, lr // Return to caller
|
||||
|
||||
__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
|
||||
|
||||
/* 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
|
||||
|
||||
#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE))
|
||||
@
|
||||
@ /* 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
|
||||
|
||||
/* 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
|
||||
@
|
||||
@ }
|
||||
@}
|
||||
|
||||
ADD sp, sp, #32 // Recover saved registers
|
||||
MOV pc, lr // Return to caller
|
||||
|
||||
@@ -1,40 +1,30 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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"
|
||||
@
|
||||
@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.arm
|
||||
|
||||
@
|
||||
@/* Define Assembly language external references... */
|
||||
@
|
||||
|
||||
/* Define Assembly language external references... */
|
||||
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_timer_system_clock
|
||||
.global _tx_timer_current_ptr
|
||||
@@ -43,237 +33,199 @@
|
||||
.global _tx_timer_expired_time_slice
|
||||
.global _tx_timer_expired
|
||||
.global _tx_thread_time_slice
|
||||
@
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_timer_interrupt for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
|
||||
|
||||
|
||||
/* Define the 16-bit Thumb mode veneer for _tx_timer_interrupt for
|
||||
applications calling this function from to 16-bit Thumb mode. */
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.global $_tx_timer_interrupt
|
||||
.type $_tx_timer_interrupt,function
|
||||
$_tx_timer_interrupt:
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
BX pc // Switch to 32-bit mode
|
||||
NOP //
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_timer_interrupt @ Call _tx_timer_interrupt function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
STMFD sp!, {lr} // Save return address
|
||||
BL _tx_timer_interrupt // Call _tx_timer_interrupt function
|
||||
LDMFD sp!, {lr} // Recover saved return address
|
||||
BX lr // Return to 16-bit caller
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_timer_interrupt Cortex-A8/GNU */
|
||||
@/* 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_thread_time_slice Time slice interrupted thread */
|
||||
@/* _tx_timer_expiration_process Timer expiration processing */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* interrupt vector */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_timer_interrupt(VOID)
|
||||
@{
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_timer_interrupt ARMv7-A */
|
||||
/* 6.1.11 */
|
||||
/* 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_thread_time_slice Time slice interrupted thread */
|
||||
/* _tx_timer_expiration_process Timer expiration processing */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* interrupt vector */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 04-25-2022 Zhen Kong Updated comments, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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] @ 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 address
|
||||
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 wraparound. */
|
||||
@ if (_tx_timer_current_ptr == _tx_timer_list_end)
|
||||
@
|
||||
LDR r3, =_tx_timer_list_end @ Pickup address 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 wraparound logic
|
||||
@
|
||||
@ /* Wrap to beginning of list. */
|
||||
@ _tx_timer_current_ptr = _tx_timer_list_start;
|
||||
@
|
||||
LDR r3, =_tx_timer_list_start @ Pickup address 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 address 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 address 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 address 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 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 address 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:
|
||||
@
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
#endif
|
||||
@
|
||||
@}
|
||||
|
||||
/* 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. */
|
||||
|
||||
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. */
|
||||
|
||||
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. */
|
||||
|
||||
SUB r2, r2, #1 // Decrement the time-slice
|
||||
STR r2, [r3] // Store new time-slice value
|
||||
|
||||
/* Check for expiration. */
|
||||
|
||||
CMP r2, #0 // Has it expired?
|
||||
BNE __tx_timer_no_time_slice // No, skip expiration processing
|
||||
|
||||
/* Set the time-slice expired flag. */
|
||||
|
||||
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. */
|
||||
|
||||
LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer address
|
||||
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. */
|
||||
|
||||
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
|
||||
|
||||
__tx_timer_no_timer:
|
||||
|
||||
/* No timer expired, increment the timer pointer. */
|
||||
ADD r0, r0, #4 // Move to next timer
|
||||
|
||||
/* Check for wraparound. */
|
||||
|
||||
LDR r3, =_tx_timer_list_end // Pickup address 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 wraparound logic
|
||||
|
||||
/* Wrap to beginning of list. */
|
||||
|
||||
LDR r3, =_tx_timer_list_start // Pickup address 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. */
|
||||
|
||||
LDR r3, =_tx_timer_expired_time_slice // Pickup address 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 address 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? */
|
||||
|
||||
LDR r1, =_tx_timer_expired // Pickup address 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 timer expiration. */
|
||||
BL _tx_timer_expiration_process // Call the timer expiration handling routine
|
||||
|
||||
__tx_timer_dont_activate:
|
||||
|
||||
/* Did time slice expire? */
|
||||
|
||||
LDR r3, =_tx_timer_expired_time_slice // Pickup address 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. */
|
||||
|
||||
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:
|
||||
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user