mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2025-11-16 04:24:48 +00:00
Compare commits
8 Commits
v6.1.10_re
...
v6.1.12_re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c3c08f108 | ||
|
|
54cda6ee9e | ||
|
|
83b57acde9 | ||
|
|
e11c166a40 | ||
|
|
408f9fa1b7 | ||
|
|
cef9cb22a5 | ||
|
|
f851772ce0 | ||
|
|
cd4e736a44 |
@@ -31,8 +31,17 @@ endif()
|
||||
# Pick up the common stuff
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common)
|
||||
|
||||
|
||||
|
||||
# Define the FreeRTOS adaptation layer
|
||||
add_library(freertos-threadx EXCLUDE_FROM_ALL)
|
||||
target_include_directories(freertos-threadx
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}/utility/rtos_compatibility_layers/FreeRTOS
|
||||
)
|
||||
target_sources(freertos-threadx
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}/utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c
|
||||
)
|
||||
target_link_libraries(freertos-threadx PUBLIC threadx)
|
||||
|
||||
# If the user provided an override, copy it to the custom directory
|
||||
if (NOT TX_USER_FILE)
|
||||
|
||||
16
README.md
16
README.md
@@ -87,11 +87,11 @@ Azure RTOS provides OEMs with components to secure communication and to create c
|
||||
|
||||
# Adaptation layer for ThreadX
|
||||
|
||||
Azure RTOS ThreadX is an advanced real-time operating system (RTOS) designed specifically for deeply embedded applications. To help ease application migration to Auzre RTOS, ThreadX provides [adaption layers](https://github.com/azure-rtos/threadx/tree/master/utility/rtos_compatibility_layers) for various legacy RTOS APIs (FreeRTOS, POSIX, OSEK, etc.).
|
||||
Azure RTOS ThreadX is an advanced real-time operating system (RTOS) designed specifically for deeply embedded applications. To help ease application migration to Azure RTOS, ThreadX provides [adaption layers](https://github.com/azure-rtos/threadx/tree/master/utility/rtos_compatibility_layers) for various legacy RTOS APIs (FreeRTOS, POSIX, OSEK, etc.).
|
||||
|
||||
# Licensing
|
||||
|
||||
License terms for using Azure RTOS are defined in the LICENSE.txt file of this repo. Please refer to this file for all definitive licensing information. No additional license fees are required for deploying Azure RTOS on hardware defined in the LICENSED-HARDWARE.txt file. If you are using hardware not defined in the LICENSED-HARDWARE.txt file or have licensing questions in general, please contact Microsoft directly at https://azure-rtos.ms-iot-contact.com/
|
||||
License terms for using Azure RTOS are defined in the LICENSE.txt file of this repo. Please refer to this file for all definitive licensing information. No additional license fees are required for deploying Azure RTOS on hardware defined in the LICENSED-HARDWARE.txt file. If you are using hardware not defined in the LICENSED-HARDWARE.txt file or have licensing questions in general, please contact Microsoft directly at https://aka.ms/azrtos-license.
|
||||
|
||||
# Contribution, feedback, issues, and professional support
|
||||
|
||||
@@ -104,12 +104,14 @@ Professional support plans (https://azure.microsoft.com/en-us/support/options/)
|
||||
# Additional Resources
|
||||
|
||||
The following are references to additional Azure RTOS and Azure IoT in general:
|
||||
| | |
|
||||
| Content | Link |
|
||||
|---|---|
|
||||
| TraceX Installer | https://aka.ms/azrtos-tracex-installer |
|
||||
| Azure RTOS Documentation and Guides: | https://docs.microsoft.com/azure/rtos |
|
||||
| Azure RTOS Website: | https://azure.microsoft.com/services/rtos/ |
|
||||
| Azure RTOS Sales Questions: | https://azure-rtos.ms-iot-contact.com/ |
|
||||
| For technical questions check out Microsoft Q/A for Azure IoT: | https://aka.ms/QnA/azure-rtos |
|
||||
| Internet of Things Show for latest announcements and online training: | https://aka.ms/iotshow |
|
||||
| IoT Tech Community: | https://aka.ms/community/azure-rtos |
|
||||
| Azure RTOS Sales Questions: | https://aka.ms/azrtos-license |
|
||||
| Azure RTOS Product Support Policy | https://aka.ms/azrtos/lts |
|
||||
| Azure RTOS Functional Safety Artifacts | https://aka.ms/azrtos/tuv |
|
||||
| For technical questions check out Microsoft Q/A for Azure IoT | https://aka.ms/QnA/azure-rtos |
|
||||
| Internet of Things Show for latest announcements and online training | https://aka.ms/iotshow |
|
||||
| IoT Tech Community | https://aka.ms/community/azure-rtos |
|
||||
|
||||
@@ -202,6 +202,7 @@ target_sources(${PROJECT_NAME}
|
||||
|
||||
# Add the Common/inc directory to the project include list
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
SYSTEM
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}/inc
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/* APPLICATION INTERFACE DEFINITION RELEASE */
|
||||
/* */
|
||||
/* tx_api.h PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* 6.1.12 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -82,6 +82,13 @@
|
||||
/* add unused parameter macro, */
|
||||
/* update patch number, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* 04-25-2022 Wenhui Xie Modified comment(s), */
|
||||
/* optimized the definition of */
|
||||
/* TX_TIMER_TICKS_PER_SECOND, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* 07-29-2022 Scott Larson Modified comment(s), */
|
||||
/* update patch number, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -118,7 +125,7 @@ extern "C" {
|
||||
#define AZURE_RTOS_THREADX
|
||||
#define THREADX_MAJOR_VERSION 6
|
||||
#define THREADX_MINOR_VERSION 1
|
||||
#define THREADX_PATCH_VERSION 10
|
||||
#define THREADX_PATCH_VERSION 12
|
||||
|
||||
/* Define the following symbol for backward compatibility */
|
||||
#define EL_PRODUCT_THREADX
|
||||
@@ -221,7 +228,7 @@ extern "C" {
|
||||
as a compilation option. */
|
||||
|
||||
#ifndef TX_TIMER_TICKS_PER_SECOND
|
||||
#define TX_TIMER_TICKS_PER_SECOND ((ULONG) 100)
|
||||
#define TX_TIMER_TICKS_PER_SECOND (100UL)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_user.h PORTABLE C */
|
||||
/* 6.1.9 */
|
||||
/* 6.1.11 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
@@ -58,6 +58,10 @@
|
||||
/* user-configurable symbol */
|
||||
/* TX_TIMER_TICKS_PER_SECOND */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* 04-25-2022 Wenhui Xie Modified comment(s), */
|
||||
/* optimized the definition of */
|
||||
/* TX_TIMER_TICKS_PER_SECOND, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -116,7 +120,7 @@
|
||||
Note: the actual hardware timer value may need to be changed (usually in tx_initialize_low_level). */
|
||||
|
||||
/*
|
||||
#define TX_TIMER_TICKS_PER_SECOND ((ULONG) 100)
|
||||
#define TX_TIMER_TICKS_PER_SECOND (100UL)
|
||||
*/
|
||||
|
||||
/* Determine if there is a FileX pointer in the thread control block.
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_get PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* 6.1.11 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -73,9 +73,12 @@
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* resulting in version 6.1 */
|
||||
/* 04-25-2022 Scott Larson Modified comment(s), */
|
||||
/* handle 0 flags case, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags,
|
||||
@@ -276,11 +279,12 @@ UINT interrupted_set_request;
|
||||
if (wait_option != TX_NO_WAIT)
|
||||
{
|
||||
|
||||
/* Determine if the preempt disable flag is non-zero. */
|
||||
if (_tx_thread_preempt_disable != ((UINT) 0))
|
||||
/* Determine if the preempt disable flag is non-zero OR the requested events is 0. */
|
||||
if ((_tx_thread_preempt_disable != ((UINT) 0)) || (requested_flags == (UINT) 0))
|
||||
{
|
||||
|
||||
/* Suspension is not allowed if the preempt disable flag is non-zero at this point, return error completion. */
|
||||
/* Suspension is not allowed if the preempt disable flag is non-zero at this point,
|
||||
or if requested_flags is 0, return error completion. */
|
||||
status = TX_NO_EVENTS;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_set PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* 6.1.11 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -72,9 +72,13 @@
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* resulting in version 6.1 */
|
||||
/* 04-25-2022 William E. Lamie Modified comment(s), and */
|
||||
/* added corrected preemption */
|
||||
/* check logic, resulting in */
|
||||
/* version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_set(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG flags_to_set, UINT set_option)
|
||||
@@ -264,9 +268,6 @@ VOID (*events_set_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *notify_
|
||||
/* Yes, resume the thread and apply any event flag
|
||||
clearing. */
|
||||
|
||||
/* Set the preempt check flag. */
|
||||
preempt_check = TX_TRUE;
|
||||
|
||||
/* Return the actual event flags that satisfied the request. */
|
||||
suspend_info_ptr = TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_additional_suspend_info);
|
||||
*suspend_info_ptr = current_event_flags;
|
||||
@@ -336,6 +337,11 @@ VOID (*events_set_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *notify_
|
||||
/* Disable preemption while we process the suspended list. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Since we have temporarily disabled preemption globally, set the preempt
|
||||
check flag to check for any preemption condition - including from
|
||||
unrelated ISR processing. */
|
||||
preempt_check = TX_TRUE;
|
||||
|
||||
/* Loop to examine all of the suspended threads. */
|
||||
do
|
||||
{
|
||||
@@ -419,9 +425,6 @@ VOID (*events_set_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *notify_
|
||||
|
||||
/* Yes, this request can be handled now. */
|
||||
|
||||
/* Set the preempt check flag. */
|
||||
preempt_check = TX_TRUE;
|
||||
|
||||
/* Determine if the thread is still suspended on the event flag group. If not, a wait
|
||||
abort must have been done from an ISR. */
|
||||
if (thread_ptr -> tx_thread_state == TX_EVENT_FLAG)
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h"
|
||||
|
||||
#if defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)
|
||||
extern VOID _tx_execution_initialize(VOID);
|
||||
#endif
|
||||
|
||||
/* Define any port-specific scheduling data structures. */
|
||||
|
||||
@@ -46,7 +49,7 @@ TX_SAFETY_CRITICAL_EXCEPTION_HANDLER
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_initialize_kernel_enter PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* 6.1.11 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -84,9 +87,12 @@ TX_SAFETY_CRITICAL_EXCEPTION_HANDLER
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* resulting in version 6.1 */
|
||||
/* 04-25-2022 Scott Larson Modified comment(s), */
|
||||
/* added EPK initialization, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_initialize_kernel_enter(VOID)
|
||||
@@ -138,6 +144,11 @@ VOID _tx_initialize_kernel_enter(VOID)
|
||||
/* Call any port specific pre-scheduler processing. */
|
||||
TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION
|
||||
|
||||
#if defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)
|
||||
/* Initialize Execution Profile Kit. */
|
||||
_tx_execution_initialize();
|
||||
#endif
|
||||
|
||||
/* Enter the scheduling loop to start executing threads! */
|
||||
_tx_thread_schedule();
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_trace_object_register PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* 6.1.12 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -69,9 +69,12 @@
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* resulting in version 6.1 */
|
||||
/* 07-29-2022 Scott Larson Modified comment(s), */
|
||||
/* check for null name, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_trace_object_register(UCHAR object_type, VOID *object_ptr, CHAR *object_name, ULONG parameter_1, ULONG parameter_2)
|
||||
@@ -223,6 +226,12 @@ TX_TRACE_OBJECT_ENTRY *entry_ptr;
|
||||
work_ptr = TX_CHAR_TO_UCHAR_POINTER_CONVERT(object_name);
|
||||
work_ptr = TX_UCHAR_POINTER_ADD(work_ptr, i);
|
||||
|
||||
/* Determine if object_name (work_ptr) is null. */
|
||||
if (work_ptr == TX_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Copy a character of the name. */
|
||||
entry_ptr -> tx_trace_object_entry_name[i] = (UCHAR) *work_ptr;
|
||||
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Define the file handles. */
|
||||
|
||||
FILE *source_file;
|
||||
FILE *array_file;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
int alpha;
|
||||
int alpha1;
|
||||
int alpha2;
|
||||
int alpha3;
|
||||
unsigned long address;
|
||||
unsigned long column;
|
||||
|
||||
|
||||
/* Determine if the proper number of files are provided. */
|
||||
if (argc != 3)
|
||||
{
|
||||
|
||||
/* Print an error message out and wait for user key hit. */
|
||||
printf("module_binary_to_c_array.exe - Copyright (c) Microsoft Corporation v5.8\n");
|
||||
printf("**** Error: invalid input parameter for module_binary_to_c_array.exe **** \n");
|
||||
printf(" Command Line Should be:\n\n");
|
||||
printf(" > module_binary_to_c_array source_binary_file c_array_file <cr> \n\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Attempt to open the source file for reading. */
|
||||
source_file = fopen(argv[1], "rb");
|
||||
|
||||
/* Determine if the source file was opened properly. */
|
||||
if (source_file == NULL)
|
||||
{
|
||||
|
||||
/* Print an error message out and wait for user key hit. */
|
||||
printf("**** Error: open failed on binary source file **** \n");
|
||||
printf(" File: %s ", argv[1]);
|
||||
return(2);
|
||||
}
|
||||
|
||||
/* Determine if the binary file is a valid ThreadX module. */
|
||||
alpha = fgetc(source_file);
|
||||
alpha1 = fgetc(source_file);
|
||||
alpha2 = fgetc(source_file);
|
||||
alpha3 = fgetc(source_file);
|
||||
|
||||
if ((alpha != 0x4D && alpha != 0x55) || (alpha1 != 0x4F && alpha1 != 0x44) || (alpha2 != 0x44 && alpha2 != 0x4F) || (alpha3 != 0x55 && alpha3 != 0x4D))
|
||||
{
|
||||
|
||||
/* Print an error message out and wait for user key hit. */
|
||||
printf("**** Error: invalid format of binary input file **** \n");
|
||||
printf(" File: %s ", argv[1]);
|
||||
return(3);
|
||||
}
|
||||
|
||||
/* Attempt to open the dump file for writing. */
|
||||
array_file = fopen(argv[2], "w");
|
||||
|
||||
/* Determine if the dump file was opened properly. */
|
||||
if (array_file == NULL)
|
||||
{
|
||||
|
||||
/* Print an error message out and wait for user key hit. */
|
||||
printf("**** Error: open failed on C array file **** \n");
|
||||
printf(" File: %s ", argv[2]);
|
||||
return(4);
|
||||
}
|
||||
|
||||
fprintf(array_file, "/**************************** Module-Binary-to-C-array Utility **********************************/\n");
|
||||
fprintf(array_file, "/* */\n");
|
||||
fprintf(array_file, "/* Copyright (c) Microsoft Corporation Version 5.4, build date: 03-01-2018 */\n");
|
||||
fprintf(array_file, "/* */\n");
|
||||
fprintf(array_file, "/************************************************************************************************/\n\n");
|
||||
fprintf(array_file, "/* \n");
|
||||
fprintf(array_file, " Input Binary file: %30s\n", argv[1]);
|
||||
fprintf(array_file, " Output C Array file: %30s\n", argv[2]);
|
||||
fprintf(array_file, "*/\n\n");
|
||||
|
||||
/* Now print out the sections in a C array. */
|
||||
fprintf(array_file, "unsigned char module_code[] = {\n\n");
|
||||
fprintf(array_file, "/* Address Contents */\n\n");
|
||||
|
||||
/* Seek to the beginning of the source file. */
|
||||
fseek(source_file, 0, SEEK_SET);
|
||||
|
||||
/* Initialize the variables. */
|
||||
address = 0;
|
||||
column = 0;
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
/* Get character from the input file. */
|
||||
alpha = fgetc(source_file);
|
||||
|
||||
/* Have we reached EOF? */
|
||||
if (alpha == EOF)
|
||||
break;
|
||||
|
||||
/* Print out character with a leading comma, except on the first character. */
|
||||
if (column == 0)
|
||||
{
|
||||
if (address != 0)
|
||||
fprintf(array_file, ",\n");
|
||||
fprintf(array_file, "/* 0x%08X */ 0x%02X", address, (unsigned int) alpha);
|
||||
}
|
||||
else
|
||||
fprintf(array_file, ", 0x%02X", (unsigned int) alpha);
|
||||
|
||||
/* Move column forward. */
|
||||
column++;
|
||||
|
||||
/* Are we at the end of the column? */
|
||||
if (column >= 16)
|
||||
{
|
||||
|
||||
column = 0;
|
||||
}
|
||||
|
||||
/* Move address forward. */
|
||||
address++;
|
||||
} while (alpha != EOF);
|
||||
|
||||
/* Finally, finish the C array containing the module code. */
|
||||
fprintf(array_file, "};\n\n");
|
||||
|
||||
/* Close files. */
|
||||
fclose(source_file);
|
||||
fclose(array_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
332
common_modules/module_manager/utilities/module_to_binary.c
Normal file
332
common_modules/module_manager/utilities/module_to_binary.c
Normal file
@@ -0,0 +1,332 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Define the file handles. */
|
||||
|
||||
FILE *source_file;
|
||||
FILE *binary_file;
|
||||
|
||||
|
||||
#define ELF_ID_STRING_SIZE 16
|
||||
#define ELF_ARM_MACHINE_TYPE 40
|
||||
#define ELF_EXECUTABLE 2
|
||||
|
||||
|
||||
typedef struct ELF_HEADER_STRUCT
|
||||
{
|
||||
unsigned char elf_header_id_string[ELF_ID_STRING_SIZE];
|
||||
unsigned short elf_header_file_type;
|
||||
unsigned short elf_header_machinge_type;
|
||||
unsigned long elf_header_version;
|
||||
unsigned long elf_header_entry_address;
|
||||
unsigned long elf_header_program_header_offset;
|
||||
unsigned long elf_header_section_header_offset;
|
||||
unsigned long elf_header_processor_flags;
|
||||
unsigned short elf_header_size;
|
||||
unsigned short elf_header_program_header_size;
|
||||
unsigned short elf_header_program_header_entries;
|
||||
unsigned short elf_header_section_header_size;
|
||||
unsigned short elf_header_section_header_entries;
|
||||
unsigned short elf_header_section_string_index;
|
||||
} ELF_HEADER;
|
||||
|
||||
|
||||
typedef struct ELF_PROGRAM_HEADER_STRUCT
|
||||
{
|
||||
unsigned long elf_program_header_type;
|
||||
unsigned long elf_program_header_offset;
|
||||
unsigned long elf_program_header_virtual_address;
|
||||
unsigned long elf_program_header_physical_address;
|
||||
unsigned long elf_program_header_file_size;
|
||||
unsigned long elf_program_header_memory_size;
|
||||
unsigned long elf_program_header_flags;
|
||||
unsigned long elf_program_header_alignment;
|
||||
} ELF_PROGRAM_HEADER;
|
||||
|
||||
|
||||
typedef struct ELF_SECTION_HEADER_STRUCT
|
||||
{
|
||||
unsigned long elf_section_header_name;
|
||||
unsigned long elf_section_header_type;
|
||||
unsigned long elf_section_header_flags;
|
||||
unsigned long elf_section_header_address;
|
||||
unsigned long elf_section_header_offset;
|
||||
unsigned long elf_section_header_size;
|
||||
unsigned long elf_section_header_link;
|
||||
unsigned long elf_section_header_info;
|
||||
unsigned long elf_section_header_alignment;
|
||||
unsigned long elf_section_header_entry_size;
|
||||
} ELF_SECTION_HEADER;
|
||||
|
||||
|
||||
typedef struct ELF_SYMBOL_TABLE_ENTRY_STRUCT
|
||||
{
|
||||
unsigned long elf_symbol_table_entry_name;
|
||||
unsigned long elf_symbol_table_entry_address;
|
||||
unsigned long elf_symbol_table_entry_size;
|
||||
unsigned char elf_symbol_table_entry_info;
|
||||
unsigned char elf_symbol_table_entry_other;
|
||||
unsigned short elf_symbol_table_entry_shndx;
|
||||
|
||||
} ELF_SYMBOL_TABLE_ENTRY;
|
||||
|
||||
|
||||
typedef struct CODE_SECTION_ENTRY_STRUCT
|
||||
{
|
||||
unsigned long code_section_index;
|
||||
unsigned long code_section_address;
|
||||
unsigned long code_section_size;
|
||||
} CODE_SECTION_ENTRY;
|
||||
|
||||
|
||||
/* Define global variables. */
|
||||
|
||||
ELF_HEADER header;
|
||||
ELF_PROGRAM_HEADER *program_header;
|
||||
ELF_SECTION_HEADER *section_header;
|
||||
unsigned char *section_string_table;
|
||||
unsigned char *main_string_table;
|
||||
unsigned long total_symbols;
|
||||
ELF_SYMBOL_TABLE_ENTRY *symbol_table;
|
||||
unsigned long total_functions;
|
||||
ELF_SYMBOL_TABLE_ENTRY *function_table;
|
||||
CODE_SECTION_ENTRY *code_section_array;
|
||||
|
||||
|
||||
/* Define helper functions. */
|
||||
|
||||
int elf_object_read(unsigned long offset, void *object_address, int object_size)
|
||||
{
|
||||
|
||||
int i;
|
||||
int alpha;
|
||||
unsigned char *buffer;
|
||||
|
||||
/* Setup the buffer pointer. */
|
||||
buffer = (unsigned char *) object_address;
|
||||
|
||||
/* Seek to the proper position in the file. */
|
||||
fseek(source_file, offset, SEEK_SET);
|
||||
|
||||
/* Read the ELF object. */
|
||||
for (i = 0; i < object_size; i++)
|
||||
{
|
||||
alpha = fgetc(source_file);
|
||||
|
||||
if (alpha == EOF)
|
||||
return(1);
|
||||
|
||||
buffer[i] = (unsigned char) alpha;
|
||||
}
|
||||
|
||||
/* Return success. */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
unsigned long i, j;
|
||||
unsigned long current_total;
|
||||
unsigned long address;
|
||||
unsigned long size;
|
||||
unsigned char *code_buffer;
|
||||
unsigned long code_section_index;
|
||||
CODE_SECTION_ENTRY code_section_temp;
|
||||
unsigned char zero_value;
|
||||
|
||||
|
||||
/* Determine if the proper number of files are provided. */
|
||||
if (argc != 3)
|
||||
{
|
||||
|
||||
/* Print an error message out and wait for user key hit. */
|
||||
printf("module_to_binary.exe - Copyright (c) Microsoft Corporation v5.8\n");
|
||||
printf("**** Error: invalid input parameter for module_to_binary.exe **** \n");
|
||||
printf(" Command Line Should be:\n\n");
|
||||
printf(" > module_to_binary source_elf_file c_binary_file <cr> \n\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Attempt to open the source file for reading. */
|
||||
source_file = fopen(argv[1], "rb");
|
||||
|
||||
/* Determine if the source file was opened properly. */
|
||||
if (source_file == NULL)
|
||||
{
|
||||
|
||||
/* Print an error message out. */
|
||||
printf("**** Error: open failed on source elf file **** \n");
|
||||
printf(" File: %s ", argv[1]);
|
||||
return(2);
|
||||
}
|
||||
|
||||
/* Attempt to open the binary file for writing. */
|
||||
binary_file = fopen(argv[2], "wb");
|
||||
|
||||
/* Determine if the binary file was opened properly. */
|
||||
if (binary_file == NULL)
|
||||
{
|
||||
|
||||
/* Print an error message out and wait for user key hit. */
|
||||
printf("**** Error: open failed on binary output file **** \n");
|
||||
printf(" File: %s ", argv[2]);
|
||||
return(3);
|
||||
}
|
||||
|
||||
/* Read the ELF header. */
|
||||
elf_object_read(0, &header, sizeof(header));
|
||||
|
||||
/* Allocate memory for the program header(s). */
|
||||
program_header = malloc(sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries);
|
||||
|
||||
/* Read the program header(s). */
|
||||
elf_object_read(header.elf_header_program_header_offset, program_header, (sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries));
|
||||
|
||||
/* Allocate memory for the section header(s). */
|
||||
section_header = malloc(sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries);
|
||||
|
||||
/* Read the section header(s). */
|
||||
elf_object_read(header.elf_header_section_header_offset, section_header, (sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries));
|
||||
|
||||
|
||||
/* Alocate memory for the section string table. */
|
||||
section_string_table = malloc(section_header[header.elf_header_section_string_index].elf_section_header_size);
|
||||
|
||||
/* Read the section string table. */
|
||||
elf_object_read(section_header[header.elf_header_section_string_index].elf_section_header_offset, section_string_table, section_header[header.elf_header_section_string_index].elf_section_header_size);
|
||||
|
||||
/* Allocate memory for the code section array. */
|
||||
code_section_array = malloc(sizeof(CODE_SECTION_ENTRY)*header.elf_header_section_header_entries);
|
||||
code_section_index = 0;
|
||||
|
||||
/* Print out the section header(s). */
|
||||
for (i = 0; i < header.elf_header_section_header_entries; i++)
|
||||
{
|
||||
|
||||
/* Determine if this section is a code section and there is a size. */
|
||||
if ((section_header[i].elf_section_header_type == 1) && (section_header[i].elf_section_header_size))
|
||||
{
|
||||
|
||||
/* Check for an-instruction area. */
|
||||
if ((section_header[i].elf_section_header_flags & 0x4) || (section_header[i].elf_section_header_flags & 0x2))
|
||||
{
|
||||
|
||||
/* Determine if this new section overlaps with an existing section. */
|
||||
for (j = 0; j < code_section_index; j++)
|
||||
{
|
||||
/* Is there an overlap? */
|
||||
if ((section_header[i].elf_section_header_address >= code_section_array[j].code_section_address) &&
|
||||
((section_header[i].elf_section_header_address+section_header[i].elf_section_header_size + section_header[i].elf_section_header_offset) < (code_section_array[j].code_section_address+code_section_array[j].code_section_size)))
|
||||
{
|
||||
/* New section is within a current section, just disregard it. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if we have an overlap. */
|
||||
if (j == code_section_index)
|
||||
{
|
||||
|
||||
/* Yes, we have a code section... save it! */
|
||||
code_section_array[code_section_index].code_section_index = i;
|
||||
code_section_array[code_section_index].code_section_address = section_header[i].elf_section_header_address;
|
||||
code_section_array[code_section_index].code_section_size = section_header[i].elf_section_header_size;
|
||||
|
||||
/* Move to next code section. */
|
||||
code_section_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for no code sections. */
|
||||
if (code_section_index == 0)
|
||||
{
|
||||
|
||||
/* Close files. */
|
||||
fclose(source_file);
|
||||
fclose(binary_file);
|
||||
|
||||
return(4);
|
||||
}
|
||||
|
||||
/* One or more code sections have been found... let's put them in the correct order by address. */
|
||||
i = 0;
|
||||
while (i+1 < code_section_index)
|
||||
{
|
||||
|
||||
/* Make the "ith" entry the lowest address. */
|
||||
j = i + 1;
|
||||
do
|
||||
{
|
||||
/* Is there a new lowest address? */
|
||||
if (code_section_array[j].code_section_address < code_section_array[i].code_section_address)
|
||||
{
|
||||
/* Yes, swap them! */
|
||||
code_section_temp = code_section_array[i];
|
||||
code_section_array[i] = code_section_array[j];
|
||||
code_section_array[j] = code_section_temp;
|
||||
}
|
||||
|
||||
/* Move the inner index. */
|
||||
j++;
|
||||
} while (j < code_section_index);
|
||||
|
||||
/* Move top index. */
|
||||
i++;
|
||||
}
|
||||
|
||||
address = code_section_array[0].code_section_address;
|
||||
zero_value = 0;
|
||||
for (i = 0; i < code_section_index; i++)
|
||||
{
|
||||
|
||||
/* Determine if there is any fill characters between sections. */
|
||||
while (address < code_section_array[i].code_section_address)
|
||||
{
|
||||
|
||||
/* Write a zero value. */
|
||||
fwrite(&zero_value, 1, 1, binary_file);
|
||||
|
||||
/* Move address forward. */
|
||||
address++;
|
||||
}
|
||||
|
||||
/* Now allocate memory for the code section. */
|
||||
code_buffer = malloc(code_section_array[i].code_section_size);
|
||||
|
||||
/* Read in the code area. */
|
||||
j = code_section_array[i].code_section_index;
|
||||
elf_object_read(section_header[j].elf_section_header_offset, code_buffer, code_section_array[i].code_section_size);
|
||||
|
||||
/* Write out the contents of this program area. */
|
||||
size = code_section_array[i].code_section_size;
|
||||
|
||||
j = 0;
|
||||
while (size)
|
||||
{
|
||||
|
||||
/* Print out a byte. */
|
||||
fwrite(&code_buffer[j], 1, 1, binary_file);
|
||||
|
||||
/* Move address forward. */
|
||||
address++;
|
||||
|
||||
/* Decrement size. */
|
||||
size--;
|
||||
|
||||
/* Move index into buffer. */
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close files. */
|
||||
fclose(source_file);
|
||||
fclose(binary_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
392
common_modules/module_manager/utilities/module_to_c_array.c
Normal file
392
common_modules/module_manager/utilities/module_to_c_array.c
Normal file
@@ -0,0 +1,392 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Define the file handles. */
|
||||
|
||||
FILE *source_file;
|
||||
FILE *array_file;
|
||||
|
||||
|
||||
#define ELF_ID_STRING_SIZE 16
|
||||
#define ELF_ARM_MACHINE_TYPE 40
|
||||
#define ELF_EXECUTABLE 2
|
||||
|
||||
|
||||
typedef struct ELF_HEADER_STRUCT
|
||||
{
|
||||
unsigned char elf_header_id_string[ELF_ID_STRING_SIZE];
|
||||
unsigned short elf_header_file_type;
|
||||
unsigned short elf_header_machinge_type;
|
||||
unsigned long elf_header_version;
|
||||
unsigned long elf_header_entry_address;
|
||||
unsigned long elf_header_program_header_offset;
|
||||
unsigned long elf_header_section_header_offset;
|
||||
unsigned long elf_header_processor_flags;
|
||||
unsigned short elf_header_size;
|
||||
unsigned short elf_header_program_header_size;
|
||||
unsigned short elf_header_program_header_entries;
|
||||
unsigned short elf_header_section_header_size;
|
||||
unsigned short elf_header_section_header_entries;
|
||||
unsigned short elf_header_section_string_index;
|
||||
} ELF_HEADER;
|
||||
|
||||
|
||||
typedef struct ELF_PROGRAM_HEADER_STRUCT
|
||||
{
|
||||
unsigned long elf_program_header_type;
|
||||
unsigned long elf_program_header_offset;
|
||||
unsigned long elf_program_header_virtual_address;
|
||||
unsigned long elf_program_header_physical_address;
|
||||
unsigned long elf_program_header_file_size;
|
||||
unsigned long elf_program_header_memory_size;
|
||||
unsigned long elf_program_header_flags;
|
||||
unsigned long elf_program_header_alignment;
|
||||
} ELF_PROGRAM_HEADER;
|
||||
|
||||
|
||||
typedef struct ELF_SECTION_HEADER_STRUCT
|
||||
{
|
||||
unsigned long elf_section_header_name;
|
||||
unsigned long elf_section_header_type;
|
||||
unsigned long elf_section_header_flags;
|
||||
unsigned long elf_section_header_address;
|
||||
unsigned long elf_section_header_offset;
|
||||
unsigned long elf_section_header_size;
|
||||
unsigned long elf_section_header_link;
|
||||
unsigned long elf_section_header_info;
|
||||
unsigned long elf_section_header_alignment;
|
||||
unsigned long elf_section_header_entry_size;
|
||||
} ELF_SECTION_HEADER;
|
||||
|
||||
|
||||
typedef struct ELF_SYMBOL_TABLE_ENTRY_STRUCT
|
||||
{
|
||||
unsigned long elf_symbol_table_entry_name;
|
||||
unsigned long elf_symbol_table_entry_address;
|
||||
unsigned long elf_symbol_table_entry_size;
|
||||
unsigned char elf_symbol_table_entry_info;
|
||||
unsigned char elf_symbol_table_entry_other;
|
||||
unsigned short elf_symbol_table_entry_shndx;
|
||||
|
||||
} ELF_SYMBOL_TABLE_ENTRY;
|
||||
|
||||
|
||||
typedef struct CODE_SECTION_ENTRY_STRUCT
|
||||
{
|
||||
unsigned long code_section_index;
|
||||
unsigned long code_section_address;
|
||||
unsigned long code_section_size;
|
||||
} CODE_SECTION_ENTRY;
|
||||
|
||||
|
||||
/* Define global variables. */
|
||||
|
||||
ELF_HEADER header;
|
||||
ELF_PROGRAM_HEADER *program_header;
|
||||
ELF_SECTION_HEADER *section_header;
|
||||
unsigned char *section_string_table;
|
||||
unsigned char *main_string_table;
|
||||
unsigned long total_symbols;
|
||||
ELF_SYMBOL_TABLE_ENTRY *symbol_table;
|
||||
unsigned long total_functions;
|
||||
ELF_SYMBOL_TABLE_ENTRY *function_table;
|
||||
CODE_SECTION_ENTRY *code_section_array;
|
||||
|
||||
|
||||
/* Define helper functions. */
|
||||
|
||||
int elf_object_read(unsigned long offset, void *object_address, int object_size)
|
||||
{
|
||||
|
||||
int i;
|
||||
int alpha;
|
||||
unsigned char *buffer;
|
||||
|
||||
/* Setup the buffer pointer. */
|
||||
buffer = (unsigned char *) object_address;
|
||||
|
||||
/* Seek to the proper position in the file. */
|
||||
fseek(source_file, offset, SEEK_SET);
|
||||
|
||||
/* Read the ELF object. */
|
||||
for (i = 0; i < object_size; i++)
|
||||
{
|
||||
alpha = fgetc(source_file);
|
||||
|
||||
if (alpha == EOF)
|
||||
return(1);
|
||||
|
||||
buffer[i] = (unsigned char) alpha;
|
||||
}
|
||||
|
||||
/* Return success. */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
unsigned long i, j, k;
|
||||
unsigned long current_total;
|
||||
unsigned long address;
|
||||
unsigned long size;
|
||||
unsigned long column;
|
||||
unsigned char *code_buffer;
|
||||
unsigned long code_section_index;
|
||||
CODE_SECTION_ENTRY code_section_temp;
|
||||
|
||||
|
||||
/* Determine if the proper number of files are provided. */
|
||||
if (argc != 3)
|
||||
{
|
||||
|
||||
/* Print an error message out and wait for user key hit. */
|
||||
printf("module_to_c_array.exe - Copyright (c) Microsoft Corporation v5.8\n");
|
||||
printf("**** Error: invalid input parameter for module_to_c_array.exe **** \n");
|
||||
printf(" Command Line Should be:\n\n");
|
||||
printf(" > module_to_c_array source_elf_file c_array_file <cr> \n\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Attempt to open the source file for reading. */
|
||||
source_file = fopen(argv[1], "rb");
|
||||
|
||||
/* Determine if the source file was opened properly. */
|
||||
if (source_file == NULL)
|
||||
{
|
||||
|
||||
/* Print an error message out and wait for user key hit. */
|
||||
printf("**** Error: open failed on source elf file **** \n");
|
||||
printf(" File: %s ", argv[1]);
|
||||
return(2);
|
||||
}
|
||||
|
||||
/* Attempt to open the dump file for writing. */
|
||||
array_file = fopen(argv[2], "w");
|
||||
|
||||
/* Determine if the dump file was opened properly. */
|
||||
if (array_file == NULL)
|
||||
{
|
||||
|
||||
/* Print an error message out and wait for user key hit. */
|
||||
printf("**** Error: open failed on C array file **** \n");
|
||||
printf(" File: %s ", argv[2]);
|
||||
return(3);
|
||||
}
|
||||
|
||||
/* Read the ELF header. */
|
||||
elf_object_read(0, &header, sizeof(header));
|
||||
|
||||
fprintf(array_file, "/**************************** Module-to-C-array Utility *****************************************/\n");
|
||||
fprintf(array_file, "/* */\n");
|
||||
fprintf(array_file, "/* Copyright (c) Microsoft Corporation Version 5.8, build date: 03-01-2018 */\n");
|
||||
fprintf(array_file, "/* */\n");
|
||||
fprintf(array_file, "/************************************************************************************************/\n\n");
|
||||
fprintf(array_file, "/* \n");
|
||||
fprintf(array_file, " Input ELF file: %30s\n", argv[1]);
|
||||
fprintf(array_file, " Output C Array file: %30s\n", argv[2]);
|
||||
fprintf(array_file, "*/\n\n");
|
||||
|
||||
/* Allocate memory for the program header(s). */
|
||||
program_header = malloc(sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries);
|
||||
|
||||
/* Read the program header(s). */
|
||||
elf_object_read(header.elf_header_program_header_offset, program_header, (sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries));
|
||||
|
||||
/* Allocate memory for the section header(s). */
|
||||
section_header = malloc(sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries);
|
||||
|
||||
/* Read the section header(s). */
|
||||
elf_object_read(header.elf_header_section_header_offset, section_header, (sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries));
|
||||
|
||||
|
||||
/* Alocate memory for the section string table. */
|
||||
section_string_table = malloc(section_header[header.elf_header_section_string_index].elf_section_header_size);
|
||||
|
||||
/* Read the section string table. */
|
||||
elf_object_read(section_header[header.elf_header_section_string_index].elf_section_header_offset, section_string_table, section_header[header.elf_header_section_string_index].elf_section_header_size);
|
||||
|
||||
/* Allocate memory for the code section array. */
|
||||
code_section_array = malloc(sizeof(CODE_SECTION_ENTRY)*header.elf_header_section_header_entries);
|
||||
code_section_index = 0;
|
||||
|
||||
/* Print out the section header(s). */
|
||||
for (i = 0; i < header.elf_header_section_header_entries; i++)
|
||||
{
|
||||
|
||||
/* Determine if this section is a code section and there is a size. */
|
||||
if ((section_header[i].elf_section_header_type == 1) && (section_header[i].elf_section_header_size))
|
||||
{
|
||||
|
||||
/* Check for an-instruction area. */
|
||||
if ((section_header[i].elf_section_header_flags & 0x4) || (section_header[i].elf_section_header_flags & 0x2))
|
||||
{
|
||||
/* Determine if this new section overlaps with an existing section. */
|
||||
for (j = 0; j < code_section_index; j++)
|
||||
{
|
||||
/* Is there an overlap? */
|
||||
if ((section_header[i].elf_section_header_address >= code_section_array[j].code_section_address) &&
|
||||
((section_header[i].elf_section_header_address+section_header[i].elf_section_header_size + section_header[i].elf_section_header_offset) < (code_section_array[j].code_section_address+code_section_array[j].code_section_size)))
|
||||
{
|
||||
/* New section is within a current section, just disregard it. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if we have an overlap. */
|
||||
if (j == code_section_index)
|
||||
{
|
||||
|
||||
/* Yes, we have a code section... save it! */
|
||||
code_section_array[code_section_index].code_section_index = i;
|
||||
code_section_array[code_section_index].code_section_address = section_header[i].elf_section_header_address;
|
||||
code_section_array[code_section_index].code_section_size = section_header[i].elf_section_header_size;
|
||||
|
||||
/* Move to next code section. */
|
||||
code_section_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for no code sections. */
|
||||
if (code_section_index == 0)
|
||||
{
|
||||
|
||||
/* Print an error message out. */
|
||||
printf("**** Error: No code sections found! **** \n");
|
||||
|
||||
fprintf(array_file, "unsigned char module_code[] = {0x00};\n\n");
|
||||
|
||||
/* Close files. */
|
||||
fclose(source_file);
|
||||
fclose(array_file);
|
||||
|
||||
return(4);
|
||||
}
|
||||
|
||||
/* One or more code sections have been found... let's put them in the correct order by address. */
|
||||
i = 0;
|
||||
while (i+1 < code_section_index)
|
||||
{
|
||||
|
||||
/* Make the "ith" entry the lowest address. */
|
||||
j = i + 1;
|
||||
do
|
||||
{
|
||||
/* Is there a new lowest address? */
|
||||
if (code_section_array[j].code_section_address < code_section_array[i].code_section_address)
|
||||
{
|
||||
/* Yes, swap them! */
|
||||
code_section_temp = code_section_array[i];
|
||||
code_section_array[i] = code_section_array[j];
|
||||
code_section_array[j] = code_section_temp;
|
||||
}
|
||||
|
||||
/* Move the inner index. */
|
||||
j++;
|
||||
} while (j < code_section_index);
|
||||
|
||||
/* Move top index. */
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Now print out the sections in a C array. */
|
||||
fprintf(array_file, "unsigned char module_code[] = {\n\n");
|
||||
fprintf(array_file, "/* Address Contents */\n\n");
|
||||
|
||||
address = code_section_array[0].code_section_address;
|
||||
column = 0;
|
||||
|
||||
for (i = 0; i < code_section_index; i++)
|
||||
{
|
||||
|
||||
/* Determine if there is any fill characters between sections. */
|
||||
while (address < code_section_array[i].code_section_address)
|
||||
{
|
||||
|
||||
/* Print out a character with a leading comma, except on the first character. */
|
||||
if (column == 0)
|
||||
fprintf(array_file, "/* 0x%08X */ 0x00", address);
|
||||
else
|
||||
fprintf(array_file, ", 0x00");
|
||||
|
||||
/* Move column forward. */
|
||||
column++;
|
||||
|
||||
/* Are we at the end of the column? */
|
||||
if (column >= 16)
|
||||
{
|
||||
fprintf(array_file, ",\n");
|
||||
column = 0;
|
||||
}
|
||||
|
||||
/* Move address forward. */
|
||||
address++;
|
||||
}
|
||||
|
||||
/* Now allocate memory for the code section. */
|
||||
code_buffer = malloc(code_section_array[i].code_section_size);
|
||||
|
||||
/* Read in the code area. */
|
||||
j = code_section_array[i].code_section_index;
|
||||
elf_object_read(section_header[j].elf_section_header_offset, code_buffer, code_section_array[i].code_section_size);
|
||||
|
||||
/* Write out the contents of this program area. */
|
||||
size = code_section_array[i].code_section_size;
|
||||
|
||||
j = 0;
|
||||
k = 0;
|
||||
while (size)
|
||||
{
|
||||
|
||||
/* Print out a character with a leading comma, except on the first character. */
|
||||
if (column == 0)
|
||||
fprintf(array_file, "/* 0x%08X */ 0x%02X", address, (unsigned int) code_buffer[j]);
|
||||
else
|
||||
fprintf(array_file, ", 0x%02X", (unsigned int) code_buffer[j]);
|
||||
|
||||
/* Move column forward. */
|
||||
column++;
|
||||
|
||||
/* Are we at the end of the column? */
|
||||
if (column >= 16)
|
||||
{
|
||||
|
||||
/* Is this the last byte of the image? */
|
||||
if ((size != 1) || (i+1 != code_section_index))
|
||||
{
|
||||
if (k == 0)
|
||||
{
|
||||
k = code_section_array[i].code_section_index;
|
||||
fprintf(array_file, ", /* SECTION: %s */\n", §ion_string_table[section_header[k].elf_section_header_name]);
|
||||
}
|
||||
else
|
||||
fprintf(array_file, ",\n");
|
||||
}
|
||||
column = 0;
|
||||
}
|
||||
|
||||
/* Move address forward. */
|
||||
address++;
|
||||
|
||||
/* Decrement size. */
|
||||
size--;
|
||||
|
||||
/* Move index into buffer. */
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, finish the C array containing the module code. */
|
||||
fprintf(array_file, "};\n\n");
|
||||
|
||||
/* Close files. */
|
||||
fclose(source_file);
|
||||
fclose(array_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
/* APPLICATION INTERFACE DEFINITION RELEASE */
|
||||
/* */
|
||||
/* tx_api.h PORTABLE SMP */
|
||||
/* 6.1.10 */
|
||||
/* 6.1.12 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -71,6 +71,13 @@
|
||||
/* add unused parameter macro, */
|
||||
/* update patch number, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* 04-25-2022 Wenhui Xie Modified comment(s), */
|
||||
/* optimized the definition of */
|
||||
/* TX_TIMER_TICKS_PER_SECOND, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* 07-29-2022 Scott Larson Modified comment(s), */
|
||||
/* update patch number, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -123,7 +130,7 @@ extern "C" {
|
||||
#define AZURE_RTOS_THREADX
|
||||
#define THREADX_MAJOR_VERSION 6
|
||||
#define THREADX_MINOR_VERSION 1
|
||||
#define THREADX_PATCH_VERSION 10
|
||||
#define THREADX_PATCH_VERSION 12
|
||||
|
||||
/* Define the following symbol for backward compatibility */
|
||||
#define EL_PRODUCT_THREADX
|
||||
@@ -226,7 +233,7 @@ extern "C" {
|
||||
as a compilation option. */
|
||||
|
||||
#ifndef TX_TIMER_TICKS_PER_SECOND
|
||||
#define TX_TIMER_TICKS_PER_SECOND ((ULONG) 100)
|
||||
#define TX_TIMER_TICKS_PER_SECOND (100UL)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_user.h PORTABLE C */
|
||||
/* 6.1.9 */
|
||||
/* 6.1.11 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
@@ -58,6 +58,10 @@
|
||||
/* user-configurable symbol */
|
||||
/* TX_TIMER_TICKS_PER_SECOND */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* 04-25-2022 Wenhui Xie Modified comment(s), */
|
||||
/* optimized the definition of */
|
||||
/* TX_TIMER_TICKS_PER_SECOND, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -116,7 +120,7 @@
|
||||
Note: the actual hardware timer value may need to be changed (usually in tx_initialize_low_level). */
|
||||
|
||||
/*
|
||||
#define TX_TIMER_TICKS_PER_SECOND ((ULONG) 100)
|
||||
#define TX_TIMER_TICKS_PER_SECOND (100UL)
|
||||
*/
|
||||
|
||||
/* Determine if there is a FileX pointer in the thread control block.
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_get PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* 6.1.11 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -73,9 +73,12 @@
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* resulting in version 6.1 */
|
||||
/* 04-25-2022 Scott Larson Modified comment(s), */
|
||||
/* handle 0 flags case, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags,
|
||||
@@ -276,11 +279,12 @@ UINT interrupted_set_request;
|
||||
if (wait_option != TX_NO_WAIT)
|
||||
{
|
||||
|
||||
/* Determine if the preempt disable flag is non-zero. */
|
||||
if (_tx_thread_preempt_disable != ((UINT) 0))
|
||||
/* Determine if the preempt disable flag is non-zero OR the requested events is 0. */
|
||||
if ((_tx_thread_preempt_disable != ((UINT) 0)) || (requested_flags == (UINT) 0))
|
||||
{
|
||||
|
||||
/* Suspension is not allowed if the preempt disable flag is non-zero at this point, return error completion. */
|
||||
/* Suspension is not allowed if the preempt disable flag is non-zero at this point,
|
||||
or if requested_flags is 0, return error completion. */
|
||||
status = TX_NO_EVENTS;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_set PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* 6.1.11 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -72,9 +72,13 @@
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* resulting in version 6.1 */
|
||||
/* 04-25-2022 William E. Lamie Modified comment(s), and */
|
||||
/* added corrected preemption */
|
||||
/* check logic, resulting in */
|
||||
/* version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_set(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG flags_to_set, UINT set_option)
|
||||
@@ -264,9 +268,6 @@ VOID (*events_set_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *notify_
|
||||
/* Yes, resume the thread and apply any event flag
|
||||
clearing. */
|
||||
|
||||
/* Set the preempt check flag. */
|
||||
preempt_check = TX_TRUE;
|
||||
|
||||
/* Return the actual event flags that satisfied the request. */
|
||||
suspend_info_ptr = TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_additional_suspend_info);
|
||||
*suspend_info_ptr = current_event_flags;
|
||||
@@ -336,6 +337,11 @@ VOID (*events_set_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *notify_
|
||||
/* Disable preemption while we process the suspended list. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Since we have temporarily disabled preemption globally, set the preempt
|
||||
check flag to check for any preemption condition - including from
|
||||
unrelated ISR processing. */
|
||||
preempt_check = TX_TRUE;
|
||||
|
||||
/* Loop to examine all of the suspended threads. */
|
||||
do
|
||||
{
|
||||
@@ -419,9 +425,6 @@ VOID (*events_set_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *notify_
|
||||
|
||||
/* Yes, this request can be handled now. */
|
||||
|
||||
/* Set the preempt check flag. */
|
||||
preempt_check = TX_TRUE;
|
||||
|
||||
/* Determine if the thread is still suspended on the event flag group. If not, a wait
|
||||
abort must have been done from an ISR. */
|
||||
if (thread_ptr -> tx_thread_state == TX_EVENT_FLAG)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_system_suspend PORTABLE SMP */
|
||||
/* 6.1 */
|
||||
/* 6.1.11 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -87,7 +87,10 @@
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 04-25-2022 Scott Larson Modified comments and fixed */
|
||||
/* loop to find next thread, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_thread_system_suspend(TX_THREAD *thread_ptr)
|
||||
@@ -667,9 +670,18 @@ UINT processing_complete;
|
||||
/* Calculate the possible complex path. */
|
||||
complex_path_possible = possible_cores & available_cores;
|
||||
|
||||
/* Check if we need to loop to find the next highest priority thread. */
|
||||
if (next_priority == TX_MAX_PRIORITIES)
|
||||
{
|
||||
loop_finished = TX_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
loop_finished = TX_FALSE;
|
||||
}
|
||||
|
||||
/* Loop to find the next highest priority ready thread that is allowed to run on this core. */
|
||||
loop_finished = TX_FALSE;
|
||||
do
|
||||
while (loop_finished == TX_FALSE)
|
||||
{
|
||||
|
||||
/* Determine if there is a thread to examine. */
|
||||
@@ -814,7 +826,7 @@ UINT processing_complete;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (loop_finished == TX_FALSE);
|
||||
}
|
||||
|
||||
#ifdef TX_THREAD_SMP_INTER_CORE_INTERRUPT
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_trace_object_register PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* 6.1.12 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -69,9 +69,12 @@
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
||||
/* resulting in version 6.1 */
|
||||
/* 07-29-2022 Scott Larson Modified comment(s), */
|
||||
/* check for null name, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_trace_object_register(UCHAR object_type, VOID *object_ptr, CHAR *object_name, ULONG parameter_1, ULONG parameter_2)
|
||||
@@ -223,6 +226,12 @@ TX_TRACE_OBJECT_ENTRY *entry_ptr;
|
||||
work_ptr = TX_CHAR_TO_UCHAR_POINTER_CONVERT(object_name);
|
||||
work_ptr = TX_UCHAR_POINTER_ADD(work_ptr, i);
|
||||
|
||||
/* Determine if object_name (work_ptr) is null. */
|
||||
if (work_ptr == TX_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Copy a character of the name. */
|
||||
entry_ptr -> tx_trace_object_entry_name[i] = (UCHAR) *work_ptr;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h C667x/TI */
|
||||
/* 6.1.6 */
|
||||
/* 6.1.11 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
@@ -51,6 +51,10 @@
|
||||
/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */
|
||||
/* macro definition, */
|
||||
/* resulting in version 6.1.6 */
|
||||
/* 04-25-2022 Wenhui Xie Modified comment(s), */
|
||||
/* optimized the definition of */
|
||||
/* TX_TIMER_TICKS_PER_SECOND, */
|
||||
/* resulting in version 6.1.11 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -125,7 +129,7 @@ typedef unsigned short USHORT;
|
||||
|
||||
|
||||
#ifndef TX_TIMER_TICKS_PER_SECOND
|
||||
#define TX_TIMER_TICKS_PER_SECOND ((ULONG) 100)
|
||||
#define TX_TIMER_TICKS_PER_SECOND (100UL)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
369
ports/cortex_a12/ac6/example_build/sample_threadx.c
Normal file
369
ports/cortex_a12/ac6/example_build/sample_threadx.c
Normal file
@@ -0,0 +1,369 @@
|
||||
/* 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,
|
||||
byte pool, and block pool. */
|
||||
|
||||
#include "tx_api.h"
|
||||
|
||||
#define DEMO_STACK_SIZE 1024
|
||||
#define DEMO_BYTE_POOL_SIZE 9120
|
||||
#define DEMO_BLOCK_POOL_SIZE 100
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
TX_THREAD thread_0;
|
||||
TX_THREAD thread_1;
|
||||
TX_THREAD thread_2;
|
||||
TX_THREAD thread_3;
|
||||
TX_THREAD thread_4;
|
||||
TX_THREAD thread_5;
|
||||
TX_THREAD thread_6;
|
||||
TX_THREAD thread_7;
|
||||
TX_QUEUE queue_0;
|
||||
TX_SEMAPHORE semaphore_0;
|
||||
TX_MUTEX mutex_0;
|
||||
TX_EVENT_FLAGS_GROUP event_flags_0;
|
||||
TX_BYTE_POOL byte_pool_0;
|
||||
TX_BLOCK_POOL block_pool_0;
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
ULONG thread_0_counter;
|
||||
ULONG thread_1_counter;
|
||||
ULONG thread_1_messages_sent;
|
||||
ULONG thread_2_counter;
|
||||
ULONG thread_2_messages_received;
|
||||
ULONG thread_3_counter;
|
||||
ULONG thread_4_counter;
|
||||
ULONG thread_5_counter;
|
||||
ULONG thread_6_counter;
|
||||
ULONG thread_7_counter;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input);
|
||||
void thread_1_entry(ULONG thread_input);
|
||||
void thread_2_entry(ULONG thread_input);
|
||||
void thread_3_and_4_entry(ULONG thread_input);
|
||||
void thread_5_entry(ULONG thread_input);
|
||||
void thread_6_and_7_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Define main entry point. */
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
/* Enter the ThreadX kernel. */
|
||||
tx_kernel_enter();
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
void tx_application_define(void *first_unused_memory)
|
||||
{
|
||||
|
||||
CHAR *pointer = TX_NULL;
|
||||
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE);
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
/* Allocate the stack for thread 0. */
|
||||
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,
|
||||
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
|
||||
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,
|
||||
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,
|
||||
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.
|
||||
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,
|
||||
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,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 5. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* 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,
|
||||
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,
|
||||
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,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the message queue. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
|
||||
|
||||
/* Create the message queue shared by threads 1 and 2. */
|
||||
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
|
||||
|
||||
/* Create the semaphore used by threads 3 and 4. */
|
||||
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Create the event flags group used by threads 1 and 5. */
|
||||
tx_event_flags_create(&event_flags_0, "event flags 0");
|
||||
|
||||
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
|
||||
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Allocate the memory for a small block pool. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create a block memory pool to allocate a message buffer from. */
|
||||
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
|
||||
|
||||
/* Allocate a block and release the block memory. */
|
||||
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
|
||||
|
||||
/* Release the block back to the pool. */
|
||||
tx_block_release(pointer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sits in while-forever-sleep loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Sleep for 10 ticks. */
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Set event flag 0 to wakeup thread 5. */
|
||||
status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sends messages to a queue shared by thread 2. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Send message to queue 0. */
|
||||
status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check completion status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the message sent. */
|
||||
thread_1_messages_sent++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG received_message;
|
||||
UINT status;
|
||||
|
||||
/* This thread retrieves messages placed on the queue by thread 1. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* 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
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_3_and_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 3 and thread 4. As the loop
|
||||
below shows, these function compete for ownership of semaphore_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 3)
|
||||
thread_3_counter++;
|
||||
else
|
||||
thread_4_counter++;
|
||||
|
||||
/* Get the semaphore with suspension. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the semaphore. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the semaphore. */
|
||||
status = tx_semaphore_put(&semaphore_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_flags;
|
||||
|
||||
|
||||
/* This thread simply waits for an event in a forever loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_flags != 0x1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_6_and_7_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 6 and thread 7. As the loop
|
||||
below shows, these function compete for ownership of mutex_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 6)
|
||||
thread_6_counter++;
|
||||
else
|
||||
thread_7_counter++;
|
||||
|
||||
/* Get the mutex with suspension. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Get the mutex again with suspension. This shows
|
||||
that an owning thread may retrieve the mutex it
|
||||
owns multiple times. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the mutex. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the mutex. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
176
ports/cortex_a12/ac6/example_build/sample_threadx/.cproject
Normal file
176
ports/cortex_a12/ac6/example_build/sample_threadx/.cproject
Normal file
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.exe.debug.base.469946340">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.debug.base.469946340" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.exe.debug.base.469946340" name="Debug" parent="com.arm.eclipse.build.config.v6.exe.debug.base">
|
||||
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.exe.debug.base.469946340." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6.573134568" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.84862199" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" value="Cortex-A12.NoFPU" valueType="string"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.floatabi.57442314" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.inst.560764723" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.debug.level.480956369" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<targetPlatform id="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6.573134568.953059653" name=""/>
|
||||
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/sample_threadx}/Debug" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.2091893653" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="8" superClass="com.arm.toolchain.v6.builder"/>
|
||||
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.480843237" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.target.665260895" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.2102538095" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-a7" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.fpu.633771589" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.1961565341" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.c.compiler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.inst.904338235" name="Instruction set" superClass="com.arm.tool.c.compiler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.compiler.v6.base.option.incpath.1101243778" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/inc_generic}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/inc_port}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.1919910001" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1889095542" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.1580367129" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.1827702550" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.1929311259" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.target.748329430" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" useByScannerDiscovery="false" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.cpu.289232043" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-a7" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.fpu.2069861530" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.floatabi.1140611893" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.assembler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.inst.1944846971" name="Instruction set" superClass="com.arm.tool.assembler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.options.debug.level.1266868530" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" value="com.arm.tool.assembler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.2014598915" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.1841579990" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.linker.option.entry.1438082076" name="Image entry point (--entry)" superClass="com.arm.tool.c.linker.option.entry" useByScannerDiscovery="false" value="Vectors" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.linker.option.scatter.295049975" name="Scatter file (--scatter)" superClass="com.arm.tool.c.linker.option.scatter" useByScannerDiscovery="false" value="../sample_threadx.scat" valueType="string"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.linker.libs.1672250850" name="User library files" superClass="com.arm.tool.c.linker.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/Debug/tx.a}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="com.arm.tool.c.linker.option.imagemap.1579816297" name="Generate image map (--map)" superClass="com.arm.tool.c.linker.option.imagemap" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
|
||||
<option id="com.arm.tool.c.linker.option.redirectoutput.1433429713" name="Redirect diagnostics output to file (--list)" superClass="com.arm.tool.c.linker.option.redirectoutput" useByScannerDiscovery="false" value="sample_threadx.map" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.linker.v6.option.suppress.829979840" name="Suppress (--diag_suppress)" superClass="com.arm.tool.linker.v6.option.suppress" useByScannerDiscovery="false" value="L6306W" valueType="string"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.305140315" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="timer_interrupts.c|MP_GIC.S|reset.S|crt0.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
|
||||
|
||||
<externalSettings containerId="tx;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="sample_threadx.com.arm.eclipse.build.project.v6.exe.1093829338" name="Executable"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="com.arm.projectSettings" version="6.0.0"/>
|
||||
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
|
||||
<configuration configurationName="Debug">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/sample_threadx"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration configurationName="Release">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/sample_threadx"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
|
||||
</cproject>
|
||||
27
ports/cortex_a12/ac6/example_build/sample_threadx/.project
Normal file
27
ports/cortex_a12/ac6/example_build/sample_threadx/.project
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>sample_threadx</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>tx</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,369 @@
|
||||
/* 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,
|
||||
byte pool, and block pool. */
|
||||
|
||||
#include "tx_api.h"
|
||||
|
||||
#define DEMO_STACK_SIZE 1024
|
||||
#define DEMO_BYTE_POOL_SIZE 9120
|
||||
#define DEMO_BLOCK_POOL_SIZE 100
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
TX_THREAD thread_0;
|
||||
TX_THREAD thread_1;
|
||||
TX_THREAD thread_2;
|
||||
TX_THREAD thread_3;
|
||||
TX_THREAD thread_4;
|
||||
TX_THREAD thread_5;
|
||||
TX_THREAD thread_6;
|
||||
TX_THREAD thread_7;
|
||||
TX_QUEUE queue_0;
|
||||
TX_SEMAPHORE semaphore_0;
|
||||
TX_MUTEX mutex_0;
|
||||
TX_EVENT_FLAGS_GROUP event_flags_0;
|
||||
TX_BYTE_POOL byte_pool_0;
|
||||
TX_BLOCK_POOL block_pool_0;
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
ULONG thread_0_counter;
|
||||
ULONG thread_1_counter;
|
||||
ULONG thread_1_messages_sent;
|
||||
ULONG thread_2_counter;
|
||||
ULONG thread_2_messages_received;
|
||||
ULONG thread_3_counter;
|
||||
ULONG thread_4_counter;
|
||||
ULONG thread_5_counter;
|
||||
ULONG thread_6_counter;
|
||||
ULONG thread_7_counter;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input);
|
||||
void thread_1_entry(ULONG thread_input);
|
||||
void thread_2_entry(ULONG thread_input);
|
||||
void thread_3_and_4_entry(ULONG thread_input);
|
||||
void thread_5_entry(ULONG thread_input);
|
||||
void thread_6_and_7_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Define main entry point. */
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
/* Enter the ThreadX kernel. */
|
||||
tx_kernel_enter();
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
void tx_application_define(void *first_unused_memory)
|
||||
{
|
||||
|
||||
CHAR *pointer = TX_NULL;
|
||||
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE);
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
/* Allocate the stack for thread 0. */
|
||||
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,
|
||||
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
|
||||
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,
|
||||
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,
|
||||
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.
|
||||
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,
|
||||
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,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 5. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* 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,
|
||||
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,
|
||||
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,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the message queue. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
|
||||
|
||||
/* Create the message queue shared by threads 1 and 2. */
|
||||
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
|
||||
|
||||
/* Create the semaphore used by threads 3 and 4. */
|
||||
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Create the event flags group used by threads 1 and 5. */
|
||||
tx_event_flags_create(&event_flags_0, "event flags 0");
|
||||
|
||||
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
|
||||
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Allocate the memory for a small block pool. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create a block memory pool to allocate a message buffer from. */
|
||||
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
|
||||
|
||||
/* Allocate a block and release the block memory. */
|
||||
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
|
||||
|
||||
/* Release the block back to the pool. */
|
||||
tx_block_release(pointer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sits in while-forever-sleep loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Sleep for 10 ticks. */
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Set event flag 0 to wakeup thread 5. */
|
||||
status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sends messages to a queue shared by thread 2. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Send message to queue 0. */
|
||||
status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check completion status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the message sent. */
|
||||
thread_1_messages_sent++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG received_message;
|
||||
UINT status;
|
||||
|
||||
/* This thread retrieves messages placed on the queue by thread 1. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* 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
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_3_and_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 3 and thread 4. As the loop
|
||||
below shows, these function compete for ownership of semaphore_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 3)
|
||||
thread_3_counter++;
|
||||
else
|
||||
thread_4_counter++;
|
||||
|
||||
/* Get the semaphore with suspension. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the semaphore. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the semaphore. */
|
||||
status = tx_semaphore_put(&semaphore_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_flags;
|
||||
|
||||
|
||||
/* This thread simply waits for an event in a forever loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_flags != 0x1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_6_and_7_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 6 and thread 7. As the loop
|
||||
below shows, these function compete for ownership of mutex_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 6)
|
||||
thread_6_counter++;
|
||||
else
|
||||
thread_7_counter++;
|
||||
|
||||
/* Get the mutex with suspension. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Get the mutex again with suspension. This shows
|
||||
that an owning thread may retrieve the mutex it
|
||||
owns multiple times. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the mutex. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the mutex. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.arm.debugger.launcher2">
|
||||
<mapAttribute key="AverageDurationTracker">
|
||||
<mapEntry key="*Fetching Data Model" value="2711474"/>
|
||||
<mapEntry key="*list global low level symbols" value="27705253"/>
|
||||
<mapEntry key="*loading values from target" value="9455698"/>
|
||||
<mapEntry key="*updating expressions" value="49184293"/>
|
||||
<mapEntry key="*updating registers" value="67114301"/>
|
||||
<mapEntry key="AddEventObserver" value="4941002"/>
|
||||
<mapEntry key="ClearEngineCaches" value="1706400"/>
|
||||
<mapEntry key="Evaluate" value="2082850"/>
|
||||
<mapEntry key="SourceToAddress" value="768400"/>
|
||||
<mapEntry key="break" value="19995639"/>
|
||||
<mapEntry key="compute execution mode" value="818086"/>
|
||||
<mapEntry key="continue" value="16091521"/>
|
||||
<mapEntry key="disassemble" value="84357009"/>
|
||||
<mapEntry key="get capabilities" value="242101"/>
|
||||
<mapEntry key="get execution addresss" value="637787"/>
|
||||
<mapEntry key="get source lines" value="866330"/>
|
||||
<mapEntry key="initialize command help" value="82932286"/>
|
||||
<mapEntry key="interrupt" value="11925285"/>
|
||||
<mapEntry key="list breakpoint options" value="242832"/>
|
||||
<mapEntry key="list breakpoints" value="757587"/>
|
||||
<mapEntry key="list instruction sets" value="2216552"/>
|
||||
<mapEntry key="list signals" value="4642679"/>
|
||||
<mapEntry key="list watchpoint options" value="4504028"/>
|
||||
<mapEntry key="list watchpoints" value="959949"/>
|
||||
<mapEntry key="loadfile" value="176206178"/>
|
||||
<mapEntry key="next" value="25130219"/>
|
||||
<mapEntry key="nexti" value="24711500"/>
|
||||
<mapEntry key="remove" value="1513600"/>
|
||||
<mapEntry key="set $pc" value="12244700"/>
|
||||
<mapEntry key="set CWD" value="7171160"/>
|
||||
<mapEntry key="set breakpoint properties" value="9403852"/>
|
||||
<mapEntry key="set debug-from" value="1618455"/>
|
||||
<mapEntry key="start" value="184031679"/>
|
||||
<mapEntry key="step" value="31817500"/>
|
||||
<mapEntry key="synchronizing trace ranges" value="39600"/>
|
||||
<mapEntry key="toggleBreakpoint" value="7412657"/>
|
||||
<mapEntry key="waitForTargetToStop" value="28230483"/>
|
||||
</mapAttribute>
|
||||
<intAttribute key="DEBUG_TAB..RESOURCES.COUNT" value="0"/>
|
||||
<intAttribute key="FILES.CONNECT_TO_GDB_SERVER.RESOURCES.COUNT" value="0"/>
|
||||
<intAttribute key="FILES.DEBUG_EXISTING_ANDROID.RESOURCES.COUNT" value="0"/>
|
||||
<listAttribute key="FILES.DEBUG_RESIDENT_ANDROID"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.0.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.COUNT" value="1"/>
|
||||
<listAttribute key="FILES.DEBUG_RESIDENT_APP"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.TYPE" value="APPLICATION_ON_TARGET"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.COUNT" value="2"/>
|
||||
<listAttribute key="FILES.DOWNLOAD_AND_DEBUG"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.TYPE" value="TARGET_DOWNLOAD_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.COUNT" value="3"/>
|
||||
<listAttribute key="FILES.DOWNLOAD_DEBUG"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.TYPE" value="TARGET_DOWNLOAD_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.COUNT" value="3"/>
|
||||
<intAttribute key="FILES.DOWNLOAD_DEBUG_ANDROID.RESOURCES.COUNT" value="0"/>
|
||||
<listAttribute key="FILES.ICE_DEBUG">
|
||||
<listEntry value="ON_DEMAND_LOAD"/>
|
||||
<listEntry value="ALSO_LOAD_SYMBOLS"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.VALUE" value="${workspace_loc:/sample_threadx/Debug/sample_threadx.axf}"/>
|
||||
<intAttribute key="FILES.ICE_DEBUG.RESOURCES.COUNT" value="1"/>
|
||||
<listAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE">
|
||||
<listEntry value="ON_DEMAND_LOAD"/>
|
||||
<listEntry value="ALSO_LOAD_SYMBOLS"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.VALUE" value=""/>
|
||||
<intAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.COUNT" value="1"/>
|
||||
<listAttribute key="FILES.ICE_DEBUG_WITH_TRACE">
|
||||
<listEntry value="ON_DEMAND_LOAD"/>
|
||||
<listEntry value="ALSO_LOAD_SYMBOLS"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.VALUE" value=""/>
|
||||
<intAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.COUNT" value="1"/>
|
||||
<stringAttribute key="FILES.SELECTED_DEBUG_OPEATION" value="ICE_DEBUG"/>
|
||||
<stringAttribute key="HOST_WORKING_DIR" value="${workspace_loc}"/>
|
||||
<booleanAttribute key="HOST_WORKING_DIR_USE_DEFAULT" value="true"/>
|
||||
<booleanAttribute key="InstructionStepping" value="true"/>
|
||||
<booleanAttribute key="KEY_COMMANDS_AFTER_CONNECT" value="false"/>
|
||||
<stringAttribute key="KEY_COMMANDS_AFTER_CONNECT_TEXT" value=""/>
|
||||
<booleanAttribute key="KEY_COMMANDS_AS_CONNECT" value="false"/>
|
||||
<booleanAttribute key="RSE_USE_HOSTNAME" value="true"/>
|
||||
<stringAttribute key="TCP_DISABLE_EXTENDED_MODE" value="true"/>
|
||||
<booleanAttribute key="TCP_KILL_ON_EXIT" value="false"/>
|
||||
<listAttribute key="TREE_NODE_PROPERTIES:debugger.view.ExpressionsView">
|
||||
<listEntry value="NODE CACHE VERSION 1"/>
|
||||
<listEntry value="EXPRESSION_GROUP:Expressions:VALUE:_tx_timer_list"/>
|
||||
<listEntry value="1"/>
|
||||
<listEntry value="element formatter"/>
|
||||
<listEntry value="Hexadecimal"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="VFS_ENABLED" value="true"/>
|
||||
<stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/>
|
||||
<stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/>
|
||||
<stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" hostFile="C:\Users\nisohack\Documents\work\x-ware_libs\threadx_github\ports\cortex_a7\ac6\example_build\sample_threadx\tx_initialize_low_level.S" line="215"/> 		<location index="0" enabled="true" version="2" address="S:0x80000314" debugFile="C:/Users/nisohack/Documents/work/x-ware_libs/threadx_github/ports/cortex_a7/ac6/example_build/sample_threadx/tx_initialize_low_level.S" hostFile="C:\Users\nisohack\Documents\work\x-ware_libs\threadx_github\ports\cortex_a7\ac6\example_build\sample_threadx\tx_initialize_low_level.S" line="238"/> 	</breakpoint> </breakpoints> "/>
|
||||
<listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses">
|
||||
<listEntry value="<Next Instruction>"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
|
||||
<listEntry value="100"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="config_db_activity_name" value="Debug Cortex-A12"/>
|
||||
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option dtsl_config_script model_params config_file setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
|
||||
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
|
||||
<stringAttribute key="config_db_platform_name" value="Arm FVP (Installed with Arm DS) - VE_Cortex_A12x1"/>
|
||||
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
|
||||
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
|
||||
<stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp_installedwitharmds_/ve_cortex_a12x1"/>
|
||||
<stringAttribute key="config_file" value="CDB://cadi_config.xml"/>
|
||||
<booleanAttribute key="connectOnly" value="false"/>
|
||||
<listAttribute key="debugger.view.DisassemblyView:current">
|
||||
<listEntry value="<Next Instruction>"/>
|
||||
<listEntry value="100"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="debugger.view.ExpressionsView">
|
||||
<listEntry value="thread_0_counter"/>
|
||||
<listEntry value="thread_1_counter"/>
|
||||
<listEntry value="thread_2_counter"/>
|
||||
<listEntry value="thread_3_counter"/>
|
||||
<listEntry value="thread_4_counter"/>
|
||||
<listEntry value="thread_5_counter"/>
|
||||
<listEntry value="thread_6_counter"/>
|
||||
<listEntry value="thread_7_counter"/>
|
||||
</listAttribute>
|
||||
<mapAttribute key="debugger.view.ExpressionsView.ExpressionsData">
|
||||
<mapEntry key="0" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="1" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="2" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="3" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="4" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="5" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="6" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="7" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
</mapAttribute>
|
||||
<stringAttribute key="debugger.view.ExpressionsView:DebugOutlineColumnState" value="OutlineConfig1	8	0	true	false	172	-1	true	1	false	true	90	-1	true	2	true	true	108	-1	true	3	true	true	57	-1	true	4	true	true	50	-1	true	5	true	true	37	-1	true	6	true	true	90	-1	true	7	true	true	53	-1	true"/>
|
||||
<stringAttribute key="debugger.view.NewRegisterView:DebugOutlineColumnState" value="OutlineConfig1	8	0	true	true	78	-1	true	1	false	true	90	-1	true	2	true	true	117	-1	true	3	false	true	41	-1	true	4	false	true	50	-1	true	5	true	true	37	-1	true	6	false	true	62	-1	true	7	true	true	53	-1	true"/>
|
||||
<stringAttribute key="debugger.view.NewRegisterView:_selectedRegisterSet" value="All registers"/>
|
||||
<mapAttribute key="debugger.view.NewRegisterView_registerSets"/>
|
||||
<listAttribute key="debugger.view.TraceView:TRACE_EXPORT_FILTERS"/>
|
||||
<booleanAttribute key="debugger.view.expression.DrawAsHex" value="false"/>
|
||||
<booleanAttribute key="debugger.view.register.DrawAsHex" value="false"/>
|
||||
<stringAttribute key="dtsl_config" value="DtslScript"/>
|
||||
<stringAttribute key="dtsl_config_script" value="CDB://dtsl_config_script.py"/>
|
||||
<stringAttribute key="dtsl_options_file" value="default"/>
|
||||
<stringAttribute key="dtsl_tracecapture_option" value="options.traceBuffer.traceCaptureDevice"/>
|
||||
<stringAttribute key="launch_configuration_version" value="5.29.3"/>
|
||||
<booleanAttribute key="linuxOS" value="false"/>
|
||||
<stringAttribute key="model_params" value=""/>
|
||||
<booleanAttribute key="runAfterConnect" value="false"/>
|
||||
<listAttribute key="setup">
|
||||
<listEntry value="CDB://Scripts/rtsm_launcher.py"/>
|
||||
<listEntry value=""FVP_VE_Cortex-A12x1""/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="stopAtExpression" value="main"/>
|
||||
<stringAttribute key="watchpoints" value="<?xml version="1.0" encoding="UTF-8"?> <watchpoints> </watchpoints> "/>
|
||||
</launchConfiguration>
|
||||
@@ -0,0 +1,44 @@
|
||||
;*******************************************************
|
||||
; Copyright (c) 2011-2016 Arm Limited (or its affiliates). All rights reserved.
|
||||
; Use, modification and redistribution of this file is subject to your possession of a
|
||||
; valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
; and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
;*******************************************************
|
||||
|
||||
; Scatter-file for ARMv7-A bare-metal example on Versatile Express
|
||||
|
||||
; This scatter-file places application code, data, stack and heap at suitable addresses in the memory map.
|
||||
|
||||
|
||||
SDRAM 0x80000000 0x20000000
|
||||
{
|
||||
VECTORS +0
|
||||
{
|
||||
* (VECTORS, +FIRST) ; Vector table and other (assembler) startup code
|
||||
* (InRoot$$Sections) ; All (library) code that must be in a root region
|
||||
}
|
||||
|
||||
RO_CODE +0
|
||||
{ * (+RO-CODE) } ; Application RO code (.text)
|
||||
|
||||
RO_DATA +0
|
||||
{ * (+RO-DATA) } ; Application RO data (.constdata)
|
||||
|
||||
RW_DATA +0
|
||||
{ * (+RW) } ; Application RW data (.data)
|
||||
|
||||
ZI_DATA +0
|
||||
{ * (+ZI) } ; Application ZI data (.bss)
|
||||
|
||||
ARM_LIB_HEAP 0x80040000 EMPTY 0x00040000 ; Application heap
|
||||
{ }
|
||||
|
||||
ARM_LIB_STACK 0x80090000 EMPTY 0x00010000 ; Application (SVC mode) stack
|
||||
{ }
|
||||
|
||||
; IRQ_STACK 0x800A0000 EMPTY -0x00010000 ; IRQ mode stack
|
||||
; { }
|
||||
|
||||
TTB 0x80100000 EMPTY 0x4000 ; Level-1 Translation Table for MMU
|
||||
{ }
|
||||
}
|
||||
397
ports/cortex_a12/ac6/example_build/sample_threadx/startup.S
Normal file
397
ports/cortex_a12/ac6/example_build/sample_threadx/startup.S
Normal file
@@ -0,0 +1,397 @@
|
||||
//----------------------------------------------------------------
|
||||
// ARMv7-A Embedded example - Startup Code
|
||||
//
|
||||
// Copyright (c) 2005-2018 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// Standard definitions of mode bits and interrupt (I & F) flags in PSRs
|
||||
|
||||
#define Mode_USR 0x10
|
||||
#define Mode_FIQ 0x11
|
||||
#define Mode_IRQ 0x12
|
||||
#define Mode_SVC 0x13
|
||||
#define Mode_ABT 0x17
|
||||
#define Mode_UND 0x1B
|
||||
#define Mode_SYS 0x1F
|
||||
|
||||
#define I_Bit 0x80 // When I bit is set, IRQ is disabled
|
||||
#define F_Bit 0x40 // When F bit is set, FIQ is disabled
|
||||
|
||||
|
||||
.section VECTORS, "ax"
|
||||
.align 3
|
||||
.cfi_sections .debug_frame // put stack frame info into .debug_frame instead of .eh_frame
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Entry point for the Reset handler
|
||||
//----------------------------------------------------------------
|
||||
|
||||
.global Vectors
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Exception Vector Table
|
||||
//----------------------------------------------------------------
|
||||
// Note: LDR PC instructions are used here, though branch (B) instructions
|
||||
// could also be used, unless the exception handlers are >32MB away.
|
||||
|
||||
Vectors:
|
||||
LDR PC, Reset_Addr
|
||||
LDR PC, Undefined_Addr
|
||||
LDR PC, SVC_Addr
|
||||
LDR PC, Prefetch_Addr
|
||||
LDR PC, Abort_Addr
|
||||
LDR PC, Hypervisor_Addr
|
||||
LDR PC, IRQ_Addr
|
||||
LDR PC, FIQ_Addr
|
||||
|
||||
|
||||
.balign 4
|
||||
Reset_Addr:
|
||||
.word Reset_Handler
|
||||
Undefined_Addr:
|
||||
.word __tx_undefined
|
||||
SVC_Addr:
|
||||
.word __tx_swi_interrupt
|
||||
Prefetch_Addr:
|
||||
.word __tx_prefetch_handler
|
||||
Abort_Addr:
|
||||
.word __tx_abort_handler
|
||||
Hypervisor_Addr:
|
||||
.word __tx_reserved_handler
|
||||
IRQ_Addr:
|
||||
.word __tx_irq_handler
|
||||
FIQ_Addr:
|
||||
.word __tx_fiq_handler
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Exception Handlers
|
||||
//----------------------------------------------------------------
|
||||
|
||||
Undefined_Handler:
|
||||
B Undefined_Handler
|
||||
SVC_Handler:
|
||||
B SVC_Handler
|
||||
Prefetch_Handler:
|
||||
B Prefetch_Handler
|
||||
Abort_Handler:
|
||||
B Abort_Handler
|
||||
Hypervisor_Handler:
|
||||
B Hypervisor_Handler
|
||||
IRQ_Handler:
|
||||
B IRQ_Handler
|
||||
FIQ_Handler:
|
||||
B FIQ_Handler
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Reset Handler
|
||||
//----------------------------------------------------------------
|
||||
Reset_Handler:
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Disable caches and MMU in case they were left enabled from an earlier run
|
||||
// This does not need to be done from a cold reset
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
BIC r0, r0, #(0x1 << 12) // Clear I bit 12 to disable I Cache
|
||||
BIC r0, r0, #(0x1 << 2) // Clear C bit 2 to disable D Cache
|
||||
BIC r0, r0, #0x1 // Clear M bit 0 to disable MMU
|
||||
BIC r0, r0, #(0x1 << 11) // Clear Z bit 11 to disable branch prediction
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
|
||||
// The MMU is enabled later, before calling main(). Caches are enabled inside main(),
|
||||
// after the MMU has been enabled and scatterloading has been performed.
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// ACTLR.SMP bit must be set before the caches and MMU are enabled,
|
||||
// or any cache and TLB maintenance operations are performed, even for single-core
|
||||
//----------------------------------------------------------------
|
||||
MRC p15, 0, r0, c1, c0, 1 // Read ACTLR
|
||||
ORR r0, r0, #(1 << 6) // Set ACTLR.SMP bit
|
||||
MCR p15, 0, r0, c1, c0, 1 // Write ACTLR
|
||||
ISB
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Invalidate Data and Instruction TLBs and branch predictor
|
||||
// This does not need to be done from a cold reset
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MOV r0,#0
|
||||
MCR p15, 0, r0, c8, c7, 0 // I-TLB and D-TLB invalidation
|
||||
MCR p15, 0, r0, c7, c5, 6 // BPIALL - Invalidate entire branch predictor array
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Initialize Supervisor Mode Stack
|
||||
// Note stack must be 8 byte aligned.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
LDR SP, =Image$$ARM_LIB_STACK$$ZI$$Limit
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Disable loop-buffer to fix errata on A15 r0p0
|
||||
//----------------------------------------------------------------
|
||||
MRC p15, 0, r0, c0, c0, 0 // Read main ID register MIDR
|
||||
MOV r1, r0, lsr #4 // Extract Primary Part Number
|
||||
LDR r2, =0xFFF
|
||||
AND r1, r1, r2
|
||||
LDR r2, =0xC0F
|
||||
CMP r1, r2 // Is this an A15?
|
||||
BNE notA15r0p0 // Jump if not A15
|
||||
AND r5, r0, #0x00f00000 // Variant
|
||||
AND r6, r0, #0x0000000f // Revision
|
||||
ORRS r6, r6, r5 // Combine variant and revision
|
||||
BNE notA15r0p0 // Jump if not r0p0
|
||||
MRC p15, 0, r0, c1, c0, 1 // Read Aux Ctrl Reg
|
||||
ORR r0, r0, #(1 << 1) // Set bit 1 to Disable Loop Buffer
|
||||
MCR p15, 0, r0, c1, c0, 1 // Write Aux Ctrl Reg
|
||||
ISB
|
||||
notA15r0p0:
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Set Vector Base Address Register (VBAR) to point to this application's vector table
|
||||
//----------------------------------------------------------------
|
||||
|
||||
LDR r0, =Vectors
|
||||
MCR p15, 0, r0, c12, c0, 0
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Cache Invalidation code for ARMv7-A
|
||||
// The caches, MMU and BTB do not need post-reset invalidation on Cortex-A7,
|
||||
// but forcing a cache invalidation makes the code more portable to other CPUs (e.g. Cortex-A9)
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// Invalidate L1 Instruction Cache
|
||||
|
||||
MRC p15, 1, r0, c0, c0, 1 // Read Cache Level ID Register (CLIDR)
|
||||
TST r0, #0x3 // Harvard Cache?
|
||||
MOV r0, #0 // SBZ
|
||||
MCRNE p15, 0, r0, c7, c5, 0 // ICIALLU - Invalidate instruction cache and flush branch target cache
|
||||
|
||||
// Invalidate Data/Unified Caches
|
||||
|
||||
MRC p15, 1, r0, c0, c0, 1 // Read CLIDR
|
||||
ANDS r3, r0, #0x07000000 // Extract coherency level
|
||||
MOV r3, r3, LSR #23 // Total cache levels << 1
|
||||
BEQ Finished // If 0, no need to clean
|
||||
|
||||
MOV r10, #0 // R10 holds current cache level << 1
|
||||
Loop1:
|
||||
ADD r2, r10, r10, LSR #1 // R2 holds cache "Set" position
|
||||
MOV r1, r0, LSR r2 // Bottom 3 bits are the Cache-type for this level
|
||||
AND r1, r1, #7 // Isolate those lower 3 bits
|
||||
CMP r1, #2
|
||||
BLT Skip // No cache or only instruction cache at this level
|
||||
|
||||
MCR p15, 2, r10, c0, c0, 0 // Write the Cache Size selection register
|
||||
ISB // ISB to sync the change to the CacheSizeID reg
|
||||
MRC p15, 1, r1, c0, c0, 0 // Reads current Cache Size ID register
|
||||
AND r2, r1, #7 // Extract the line length field
|
||||
ADD r2, r2, #4 // Add 4 for the line length offset (log2 16 bytes)
|
||||
LDR r4, =0x3FF
|
||||
ANDS r4, r4, r1, LSR #3 // R4 is the max number on the way size (right aligned)
|
||||
CLZ r5, r4 // R5 is the bit position of the way size increment
|
||||
LDR r7, =0x7FFF
|
||||
ANDS r7, r7, r1, LSR #13 // R7 is the max number of the index size (right aligned)
|
||||
|
||||
Loop2:
|
||||
MOV r9, r4 // R9 working copy of the max way size (right aligned)
|
||||
|
||||
Loop3:
|
||||
ORR r11, r10, r9, LSL r5 // Factor in the Way number and cache number into R11
|
||||
ORR r11, r11, r7, LSL r2 // Factor in the Set number
|
||||
MCR p15, 0, r11, c7, c6, 2 // Invalidate by Set/Way
|
||||
SUBS r9, r9, #1 // Decrement the Way number
|
||||
BGE Loop3
|
||||
SUBS r7, r7, #1 // Decrement the Set number
|
||||
BGE Loop2
|
||||
Skip:
|
||||
ADD r10, r10, #2 // Increment the cache number
|
||||
CMP r3, r10
|
||||
BGT Loop1
|
||||
|
||||
Finished:
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// MMU Configuration
|
||||
// Set translation table base
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// Two translation tables are supported, TTBR0 and TTBR1
|
||||
// Configure translation table base (TTB) control register cp15,c2
|
||||
// to a value of all zeros, indicates we are using TTB register 0.
|
||||
|
||||
MOV r0,#0x0
|
||||
MCR p15, 0, r0, c2, c0, 2
|
||||
|
||||
// write the address of our page table base to TTB register 0
|
||||
LDR r0,=Image$$TTB$$ZI$$Base
|
||||
|
||||
MOV r1, #0x08 // RGN=b01 (outer cacheable write-back cached, write allocate)
|
||||
// S=0 (translation table walk to non-shared memory)
|
||||
ORR r1,r1,#0x40 // IRGN=b01 (inner cacheability for the translation table walk is Write-back Write-allocate)
|
||||
|
||||
ORR r0,r0,r1
|
||||
|
||||
MCR p15, 0, r0, c2, c0, 0
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// PAGE TABLE generation
|
||||
|
||||
// Generate the page tables
|
||||
// Build a flat translation table for the whole address space.
|
||||
// ie: Create 4096 1MB sections from 0x000xxxxx to 0xFFFxxxxx
|
||||
|
||||
|
||||
// 31 20 19 18 17 16 15 14 12 11 10 9 8 5 4 3 2 1 0
|
||||
// |section base address| 0 0 |nG| S |AP2| TEX | AP | P | Domain | XN | C B | 1 0|
|
||||
//
|
||||
// Bits[31:20] - Top 12 bits of VA is pointer into table
|
||||
// nG[17]=0 - Non global, enables matching against ASID in the TLB when set.
|
||||
// S[16]=0 - Indicates normal memory is shared when set.
|
||||
// AP2[15]=0
|
||||
// AP[11:10]=11 - Configure for full read/write access in all modes
|
||||
// TEX[14:12]=000
|
||||
// CB[3:2]= 00 - Set attributes to Strongly-ordered memory.
|
||||
// (except for the code segment descriptor, see below)
|
||||
// IMPP[9]=0 - Ignored
|
||||
// Domain[5:8]=1111 - Set all pages to use domain 15
|
||||
// XN[4]=1 - Execute never on Strongly-ordered memory
|
||||
// Bits[1:0]=10 - Indicate entry is a 1MB section
|
||||
//----------------------------------------------------------------
|
||||
LDR r0,=Image$$TTB$$ZI$$Base
|
||||
LDR r1,=0xfff // loop counter
|
||||
LDR r2,=0b00000000000000000000110111100010
|
||||
|
||||
// r0 contains the address of the translation table base
|
||||
// r1 is loop counter
|
||||
// r2 is level1 descriptor (bits 19:0)
|
||||
|
||||
// use loop counter to create 4096 individual table entries.
|
||||
// this writes from address 'Image$$TTB$$ZI$$Base' +
|
||||
// offset 0x3FFC down to offset 0x0 in word steps (4 bytes)
|
||||
|
||||
init_ttb_1:
|
||||
ORR r3, r2, r1, LSL#20 // R3 now contains full level1 descriptor to write
|
||||
ORR r3, r3, #0b0000000010000 // Set XN bit
|
||||
STR r3, [r0, r1, LSL#2] // Str table entry at TTB base + loopcount*4
|
||||
SUBS r1, r1, #1 // Decrement loop counter
|
||||
BPL init_ttb_1
|
||||
|
||||
// In this example, the 1MB section based at '__code_start' is setup specially as cacheable (write back mode).
|
||||
// TEX[14:12]=001 and CB[3:2]= 11, Outer and inner write back, write allocate normal memory.
|
||||
LDR r1,=Image$$VECTORS$$Base // Base physical address of code segment
|
||||
LSR r1, #20 // Shift right to align to 1MB boundaries
|
||||
ORR r3, r2, r1, LSL#20 // Setup the initial level1 descriptor again
|
||||
ORR r3, r3, #0b0000000001100 // Set CB bits
|
||||
ORR r3, r3, #0b1000000000000 // Set TEX bit 12
|
||||
STR r3, [r0, r1, LSL#2] // str table entry
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Setup domain control register - Enable all domains to client mode
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MRC p15, 0, r0, c3, c0, 0 // Read Domain Access Control Register
|
||||
LDR r0, =0x55555555 // Initialize every domain entry to b01 (client)
|
||||
MCR p15, 0, r0, c3, c0, 0 // Write Domain Access Control Register
|
||||
|
||||
#if defined(__ARM_NEON) || defined(__ARM_FP)
|
||||
//----------------------------------------------------------------
|
||||
// Enable access to NEON/VFP by enabling access to Coprocessors 10 and 11.
|
||||
// Enables Full Access i.e. in both privileged and non privileged modes
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 2 // Read Coprocessor Access Control Register (CPACR)
|
||||
ORR r0, r0, #(0xF << 20) // Enable access to CP 10 & 11
|
||||
MCR p15, 0, r0, c1, c0, 2 // Write Coprocessor Access Control Register (CPACR)
|
||||
ISB
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Switch on the VFP and NEON hardware
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MOV r0, #0x40000000
|
||||
VMSR FPEXC, r0 // Write FPEXC register, EN bit set
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Enable MMU and branch to __main
|
||||
// Leaving the caches disabled until after scatter loading.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
LDR r12,=__main
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
BIC r0, r0, #(0x1 << 12) // Clear I bit 12 to disable I Cache
|
||||
BIC r0, r0, #(0x1 << 2) // Clear C bit 2 to disable D Cache
|
||||
BIC r0, r0, #0x2 // Clear A bit 1 to disable strict alignment fault checking
|
||||
ORR r0, r0, #0x1 // Set M bit 0 to enable MMU before scatter loading
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
|
||||
// Now the MMU is enabled, virtual to physical address translations will occur. This will affect the next
|
||||
// instruction fetch.
|
||||
//
|
||||
// The two instructions currently in the pipeline will have been fetched before the MMU was enabled.
|
||||
// The branch to __main is safe because the Virtual Address (VA) is the same as the Physical Address (PA)
|
||||
// (flat mapping) of this code that enables the MMU and performs the branch
|
||||
|
||||
BX r12 // Branch to __main C library entry point
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Enable caches and branch prediction
|
||||
// This code must be run from a privileged mode
|
||||
//----------------------------------------------------------------
|
||||
|
||||
.section ENABLECACHES,"ax"
|
||||
.align 3
|
||||
|
||||
.global enable_caches
|
||||
.type enable_caches, "function"
|
||||
.cfi_startproc
|
||||
enable_caches:
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Enable caches and branch prediction
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
ORR r0, r0, #(0x1 << 12) // Set I bit 12 to enable I Cache
|
||||
ORR r0, r0, #(0x1 << 2) // Set C bit 2 to enable D Cache
|
||||
ORR r0, r0, #(0x1 << 11) // Set Z bit 11 to enable branch prediction
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 1 // Read Auxiliary Control Register
|
||||
ORR r0, #2 // L2EN bit, enable L2 cache
|
||||
ORR r0, r0, #(0x1 << 2) // Set DP bit 2 to enable L1 Dside prefetch
|
||||
MCR p15, 0, r0, c1, c0, 1 // Write Auxiliary Control Register
|
||||
ISB
|
||||
|
||||
BX lr
|
||||
.cfi_endproc
|
||||
|
||||
.global disable_caches
|
||||
.type disable_caches, "function"
|
||||
disable_caches:
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
BIC r0, r0, #(0x1 << 12) // Clear I bit 12 to disable I Cache
|
||||
BIC r0, r0, #(0x1 << 2) // Clear C bit 2 to disable D Cache
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
|
||||
BX lr
|
||||
|
||||
|
||||
@@ -0,0 +1,299 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
|
||||
.global _tx_thread_system_stack_ptr
|
||||
.global _tx_initialize_unused_memory
|
||||
.global _tx_thread_context_save
|
||||
.global _tx_thread_context_restore
|
||||
.global _tx_timer_interrupt
|
||||
|
||||
|
||||
|
||||
/* 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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, =Image$$ARM_LIB_STACK$$ZI$$Limit // 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, =Image$$ARM_LIB_STACK$$Base // 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, =Image$$ZI_DATA$$ZI$$Limit // 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
|
||||
#else
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
|
||||
/* Define shells for each of the interrupt vectors. */
|
||||
|
||||
.global __tx_undefined
|
||||
__tx_undefined:
|
||||
B __tx_undefined // Undefined handler
|
||||
|
||||
.global __tx_swi_interrupt
|
||||
__tx_swi_interrupt:
|
||||
B __tx_swi_interrupt // Software interrupt handler
|
||||
|
||||
.global __tx_prefetch_handler
|
||||
__tx_prefetch_handler:
|
||||
B __tx_prefetch_handler // Prefetch exception handler
|
||||
|
||||
.global __tx_abort_handler
|
||||
__tx_abort_handler:
|
||||
B __tx_abort_handler // Abort exception handler
|
||||
|
||||
.global __tx_reserved_handler
|
||||
__tx_reserved_handler:
|
||||
B __tx_reserved_handler // Reserved exception handler
|
||||
|
||||
.global __tx_irq_processing_return
|
||||
.type __tx_irq_processing_return,function
|
||||
.global __tx_irq_handler
|
||||
__tx_irq_handler:
|
||||
|
||||
/* 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. */
|
||||
#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. */
|
||||
#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. */
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* Jump to context restore to restore system context. */
|
||||
|
||||
#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. */
|
||||
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. */
|
||||
#ifdef TX_ENABLE_FIQ_NESTING
|
||||
BL _tx_thread_fiq_nesting_start
|
||||
#endif
|
||||
|
||||
/* Application FIQ handlers can be called here! */
|
||||
|
||||
/* If interrupt nesting was started earlier, the end of interrupt nesting
|
||||
service must be called before returning to _tx_thread_fiq_context_restore. */
|
||||
#ifdef TX_ENABLE_FIQ_NESTING
|
||||
BL _tx_thread_fiq_nesting_end
|
||||
#endif
|
||||
|
||||
/* Jump to fiq context restore to restore system context. */
|
||||
B _tx_thread_fiq_context_restore
|
||||
|
||||
|
||||
#else
|
||||
.global __tx_fiq_handler
|
||||
__tx_fiq_handler:
|
||||
B __tx_fiq_handler // FIQ interrupt handler
|
||||
#endif
|
||||
|
||||
|
||||
BUILD_OPTIONS:
|
||||
.word _tx_build_options // Reference to bring in
|
||||
VERSION_ID:
|
||||
.word _tx_version_id // Reference to bring in
|
||||
|
||||
|
||||
146
ports/cortex_a12/ac6/example_build/tx/.cproject
Normal file
146
ports/cortex_a12/ac6/example_build/tx/.cproject
Normal file
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.lib.debug.base.934844632">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.debug.base.934844632" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.lib.debug.base.934844632" name="Debug" parent="com.arm.eclipse.build.config.v6.lib.debug.base">
|
||||
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.lib.debug.base.934844632." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1304206628" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.934944269" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" value="Cortex-A12.NoFPU" valueType="string"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.floatabi.363048496" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.inst.1780343986" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.debug.level.1864778484" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<targetPlatform id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1304206628.377253723" name=""/>
|
||||
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/tx}/Debug" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.15498832" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="8" superClass="com.arm.toolchain.v6.builder"/>
|
||||
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.1220788691" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.target.2070983899" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.1346103117" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-a7" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.fpu.90247954" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.1142506275" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.c.compiler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.inst.977911686" name="Instruction set" superClass="com.arm.tool.c.compiler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.compiler.v6.base.option.incpath.1425313179" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc_generic}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc_port}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.1440291498" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1880232756" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.514805588" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.115990951" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.962352112" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.target.1068198178" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" useByScannerDiscovery="false" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.cpu.452335018" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-a7" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.fpu.1016536584" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.floatabi.930478556" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.assembler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.inst.896699076" name="Instruction set" superClass="com.arm.tool.assembler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.options.debug.level.1163443645" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" value="com.arm.tool.assembler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.1702147376" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.149261228" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.1983404149" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="tx.com.arm.eclipse.build.project.v6.lib.1435017208" name="Static Library"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="com.arm.projectSettings" version="6.0.0"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
|
||||
<configuration configurationName="Debug">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/tx"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration configurationName="Release">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/tx"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
</cproject>
|
||||
48
ports/cortex_a12/ac6/example_build/tx/.project
Normal file
48
ports/cortex_a12/ac6/example_build/tx/.project
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>tx</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>inc_generic</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common/inc</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>inc_port</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/inc</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_generic</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common/src</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_port</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/src</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
||||
331
ports/cortex_a12/ac6/inc/tx_port.h
Normal file
331
ports/cortex_a12/ac6/inc/tx_port.h
Normal file
@@ -0,0 +1,331 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/** Port Specific */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h ARMv7-A */
|
||||
/* 6.1.12 */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* 07-29-2022 Scott Larson Updated comments, removed */
|
||||
/* unneeded temp variable, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_PORT_H
|
||||
#define TX_PORT_H
|
||||
|
||||
|
||||
/* Determine if the optional ThreadX user define file should be used. */
|
||||
|
||||
#ifdef TX_INCLUDE_USER_DEFINE_FILE
|
||||
|
||||
|
||||
/* 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"
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler library include files. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Define ThreadX basic types for this port. */
|
||||
|
||||
#define VOID void
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
|
||||
|
||||
/* Define the priority levels for ThreadX. Legal values range
|
||||
from 32 to 1024 and MUST be evenly divisible by 32. */
|
||||
|
||||
#ifndef TX_MAX_PRIORITIES
|
||||
#define TX_MAX_PRIORITIES 32
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
|
||||
thread creation is less than this value, the thread create call will return an error. */
|
||||
|
||||
#ifndef TX_MINIMUM_STACK
|
||||
#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the system timer thread's default stack size and priority. These are only applicable
|
||||
if TX_TIMER_PROCESS_IN_ISR is not defined. */
|
||||
|
||||
#ifndef TX_TIMER_THREAD_STACK_SIZE
|
||||
#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 */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define various constants for the ThreadX ARM port. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */
|
||||
#else
|
||||
#define TX_INT_DISABLE 0x80 /* Disable IRQ interrupts */
|
||||
#endif
|
||||
#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
|
||||
source constants would be:
|
||||
|
||||
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
|
||||
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TX_TRACE_TIME_SOURCE
|
||||
#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
|
||||
#endif
|
||||
#ifndef TX_TRACE_TIME_MASK
|
||||
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the port specific options for the _tx_build_options variable. This variable indicates
|
||||
how the ThreadX library was built. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_FIQ_ENABLED 1
|
||||
#else
|
||||
#define TX_FIQ_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_IRQ_NESTING
|
||||
#define TX_IRQ_NESTING_ENABLED 2
|
||||
#else
|
||||
#define TX_IRQ_NESTING_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_NESTING
|
||||
#define TX_FIQ_NESTING_ENABLED 4
|
||||
#else
|
||||
#define TX_FIQ_NESTING_ENABLED 0
|
||||
#endif
|
||||
|
||||
#define TX_PORT_SPECIFIC_BUILD_OPTIONS TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED
|
||||
|
||||
|
||||
/* Define the in-line initialization constant so that modules with in-line
|
||||
initialization capabilities can prevent their initialization from being
|
||||
a function call. */
|
||||
|
||||
#define TX_INLINE_INITIALIZATION
|
||||
|
||||
|
||||
/* 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
|
||||
logic. */
|
||||
|
||||
#ifdef TX_ENABLE_STACK_CHECKING
|
||||
#undef TX_DISABLE_STACK_FILLING
|
||||
#endif
|
||||
|
||||
|
||||
/* 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
|
||||
existing ThreadX kernel awareness modules. */
|
||||
|
||||
#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 the port extensions of the remaining ThreadX objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_EXTENSION
|
||||
#define TX_BYTE_POOL_EXTENSION
|
||||
#define TX_EVENT_FLAGS_GROUP_EXTENSION
|
||||
#define TX_MUTEX_EXTENSION
|
||||
#define TX_QUEUE_EXTENSION
|
||||
#define TX_SEMAPHORE_EXTENSION
|
||||
#define TX_TIMER_EXTENSION
|
||||
|
||||
|
||||
/* 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
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
|
||||
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_COMPLETED_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
|
||||
|
||||
|
||||
/* Define the ThreadX object creation extensions for the remaining objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
|
||||
#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
|
||||
#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
|
||||
#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
|
||||
#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
|
||||
|
||||
|
||||
/* Define the ThreadX object deletion extensions for the remaining objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
|
||||
#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
|
||||
#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
|
||||
#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
|
||||
#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
|
||||
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;
|
||||
#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
|
||||
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. */
|
||||
|
||||
#ifdef __thumb__
|
||||
|
||||
unsigned int _tx_thread_interrupt_disable(void);
|
||||
unsigned int _tx_thread_interrupt_restore(UINT old_posture);
|
||||
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
|
||||
|
||||
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
|
||||
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
|
||||
|
||||
#else
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_DISABLE asm volatile (" MRS %0,CPSR; CPSID if ": "=r" (interrupt_save) );
|
||||
#else
|
||||
#define TX_DISABLE asm volatile (" MRS %0,CPSR; CPSID i ": "=r" (interrupt_save) );
|
||||
#endif
|
||||
|
||||
#define TX_RESTORE asm volatile (" MSR CPSR_c,%0 "::"r" (interrupt_save) );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* 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);
|
||||
void tx_thread_vfp_disable(void);
|
||||
|
||||
|
||||
/* Define the interrupt lockout macros for each ThreadX object. */
|
||||
|
||||
#define TX_BLOCK_POOL_DISABLE TX_DISABLE
|
||||
#define TX_BYTE_POOL_DISABLE TX_DISABLE
|
||||
#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
|
||||
#define TX_MUTEX_DISABLE TX_DISABLE
|
||||
#define TX_QUEUE_DISABLE TX_DISABLE
|
||||
#define TX_SEMAPHORE_DISABLE TX_DISABLE
|
||||
|
||||
|
||||
/* 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 ARMv7-A Version 6.1.11 *";
|
||||
#else
|
||||
extern CHAR _tx_version_id[];
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
222
ports/cortex_a12/ac6/src/tx_thread_context_restore.S
Normal file
222
ports/cortex_a12/ac6/src/tx_thread_context_restore.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.arm
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
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
|
||||
#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
|
||||
|
||||
|
||||
|
||||
/* 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 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. */
|
||||
|
||||
#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 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
|
||||
|
||||
_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. */
|
||||
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. */
|
||||
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
|
||||
172
ports/cortex_a12/ac6/src/tx_thread_context_save.S
Normal file
172
ports/cortex_a12/ac6/src/tx_thread_context_save.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
.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 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. */
|
||||
|
||||
STMDB sp!, {r0-r3} // Save some working registers
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if // Disable FIQ interrupts
|
||||
#endif
|
||||
LDR r3, =_tx_thread_system_state // Pickup address of system state 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
|
||||
#endif
|
||||
|
||||
B __tx_irq_processing_return // Continue IRQ processing
|
||||
|
||||
__tx_thread_not_nested_save:
|
||||
|
||||
/* Otherwise, not nested, check to see if a thread was running. */
|
||||
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
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
#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
|
||||
|
||||
ADD sp, sp, #16 // Recover saved registers
|
||||
B __tx_irq_processing_return // Continue IRQ processing
|
||||
223
ports/cortex_a12/ac6/src/tx_thread_fiq_context_restore.S
Normal file
223
ports/cortex_a12/ac6/src/tx_thread_fiq_context_restore.S
Normal file
@@ -0,0 +1,223 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
.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_fiq_context_restore
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
|
||||
#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. */
|
||||
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. */
|
||||
|
||||
LDR r1, [sp] // Pickup the saved SPSR
|
||||
MOV r2, #MODE_MASK // Build mask to isolate the interrupted mode
|
||||
AND r1, r1, r2 // Isolate mode bits
|
||||
CMP r1, #IRQ_MODE_BITS // Was an interrupt taken in IRQ mode before we
|
||||
// got to context save? */
|
||||
BEQ __tx_thread_fiq_no_preempt_restore // Yes, just go back to point of interrupt
|
||||
|
||||
|
||||
LDR r1, =_tx_thread_current_ptr // Pickup address of current thread ptr
|
||||
LDR r0, [r1] // Pickup actual current thread pointer
|
||||
CMP r0, #0 // Is it NULL?
|
||||
BEQ __tx_thread_fiq_idle_system_restore // Yes, idle system was interrupted
|
||||
|
||||
LDR r3, =_tx_thread_preempt_disable // Pickup preempt disable address
|
||||
LDR r2, [r3] // Pickup actual preempt disable flag
|
||||
CMP r2, #0 // Is it set?
|
||||
BNE __tx_thread_fiq_no_preempt_restore // Yes, don't preempt this thread
|
||||
LDR r3, =_tx_thread_execute_ptr // Pickup address of execute thread ptr
|
||||
LDR r2, [r3] // Pickup actual execute thread pointer
|
||||
CMP r0, r2 // Is the same thread highest priority?
|
||||
BNE __tx_thread_fiq_preempt_restore // No, preemption needs to happen
|
||||
|
||||
|
||||
__tx_thread_fiq_no_preempt_restore:
|
||||
|
||||
/* Restore interrupted thread or ISR. */
|
||||
/* 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
|
||||
_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 */
|
||||
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
|
||||
|
||||
178
ports/cortex_a12/ac6/src/tx_thread_fiq_context_save.S
Normal file
178
ports/cortex_a12/ac6/src/tx_thread_fiq_context_save.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
|
||||
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
|
||||
#endif
|
||||
|
||||
B __tx_fiq_processing_return // Continue FIQ processing
|
||||
//
|
||||
__tx_thread_fiq_not_nested_save:
|
||||
|
||||
/* Otherwise, not nested, check to see if a thread was running. */
|
||||
|
||||
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
|
||||
#endif
|
||||
|
||||
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
|
||||
104
ports/cortex_a12/ac6/src/tx_thread_fiq_nesting_end.S
Normal file
104
ports/cortex_a12/ac6/src/tx_thread_fiq_nesting_end.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS = 0xC0 // Disable IRQ/FIQ interrupts
|
||||
#else
|
||||
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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
96
ports/cortex_a12/ac6/src/tx_thread_fiq_nesting_start.S
Normal file
96
ports/cortex_a12/ac6/src/tx_thread_fiq_nesting_start.S
Normal file
@@ -0,0 +1,96 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
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 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
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
104
ports/cortex_a12/ac6/src/tx_thread_interrupt_control.S
Normal file
104
ports/cortex_a12/ac6/src/tx_thread_interrupt_control.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
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. */
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_interrupt_control
|
||||
$_tx_thread_interrupt_control:
|
||||
.thumb
|
||||
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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
101
ports/cortex_a12/ac6/src/tx_thread_interrupt_disable.S
Normal file
101
ports/cortex_a12/ac6/src/tx_thread_interrupt_disable.S
Normal file
@@ -0,0 +1,101 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* Define 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if // Disable IRQ and FIQ
|
||||
#else
|
||||
CPSID i // Disable IRQ
|
||||
#endif
|
||||
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
93
ports/cortex_a12/ac6/src/tx_thread_interrupt_restore.S
Normal file
93
ports/cortex_a12/ac6/src/tx_thread_interrupt_restore.S
Normal file
@@ -0,0 +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 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
103
ports/cortex_a12/ac6/src/tx_thread_irq_nesting_end.S
Normal file
103
ports/cortex_a12/ac6/src/tx_thread_irq_nesting_end.S
Normal file
@@ -0,0 +1,103 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS = 0xC0 // Disable IRQ/FIQ interrupts
|
||||
#else
|
||||
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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
96
ports/cortex_a12/ac6/src/tx_thread_irq_nesting_start.S
Normal file
96
ports/cortex_a12/ac6/src/tx_thread_irq_nesting_start.S
Normal file
@@ -0,0 +1,96 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
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 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
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
230
ports/cortex_a12/ac6/src/tx_thread_schedule.S
Normal file
230
ports/cortex_a12/ac6/src/tx_thread_schedule.S
Normal file
@@ -0,0 +1,230 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.global _tx_thread_execute_ptr
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_timer_time_slice
|
||||
|
||||
|
||||
/* 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSIE if // Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSIE i // Enable IRQ interrupts
|
||||
#endif
|
||||
|
||||
/* Wait for a thread to execute. */
|
||||
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
|
||||
/* Yes! We have a thread to execute. Lockout interrupts and
|
||||
transfer control to it. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if // Disable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i // Disable IRQ interrupts
|
||||
#endif
|
||||
|
||||
/* Setup the current thread pointer. */
|
||||
|
||||
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
|
||||
#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
|
||||
BEQ _tx_solicited_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
|
||||
_tx_skip_interrupt_vfp_restore:
|
||||
#endif
|
||||
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
|
||||
_tx_skip_solicited_vfp_restore:
|
||||
#endif
|
||||
MSR CPSR_cxsf, r5 // Recover CPSR
|
||||
LDMIA sp!, {r4-r11, lr} // Return to thread synchronously
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
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
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if // Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
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)
|
||||
__tx_no_thread_to_enable:
|
||||
MSR CPSR_cxsf, r2 // Recover CPSR
|
||||
BX LR // Return to caller
|
||||
|
||||
.global tx_thread_vfp_disable
|
||||
.type tx_thread_vfp_disable,function
|
||||
tx_thread_vfp_disable:
|
||||
MRS r2, CPSR // Pickup the CPSR
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if // Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
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)
|
||||
__tx_no_thread_to_disable:
|
||||
MSR CPSR_cxsf, r2 // Recover CPSR
|
||||
BX LR // Return to caller
|
||||
|
||||
#endif
|
||||
164
ports/cortex_a12/ac6/src/tx_thread_stack_build.S
Normal file
164
ports/cortex_a12/ac6/src/tx_thread_stack_build.S
Normal file
@@ -0,0 +1,164 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
.arm
|
||||
|
||||
SVC_MODE = 0x13 // SVC mode
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSR_MASK = 0xDF // Mask initial CPSR, IRQ & FIQ interrupts enabled
|
||||
#else
|
||||
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. */
|
||||
|
||||
.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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 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
|
||||
#else
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
162
ports/cortex_a12/ac6/src/tx_thread_system_return.S
Normal file
162
ports/cortex_a12/ac6/src/tx_thread_system_return.S
Normal file
@@ -0,0 +1,162 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.arm
|
||||
|
||||
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_thread_schedule
|
||||
|
||||
|
||||
|
||||
/* 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
|
||||
#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
|
||||
_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. */
|
||||
|
||||
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!
|
||||
165
ports/cortex_a12/ac6/src/tx_thread_vectored_context_save.S
Normal file
165
ports/cortex_a12/ac6/src/tx_thread_vectored_context_save.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
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
|
||||
|
||||
#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
|
||||
|
||||
MOV pc, lr // Return to caller
|
||||
|
||||
__tx_thread_not_nested_save:
|
||||
|
||||
/* 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
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
#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
|
||||
|
||||
ADD sp, sp, #32 // Recover saved registers
|
||||
MOV pc, lr // Return to caller
|
||||
231
ports/cortex_a12/ac6/src/tx_timer_interrupt.S
Normal file
231
ports/cortex_a12/ac6/src/tx_timer_interrupt.S
Normal file
@@ -0,0 +1,231 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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... */
|
||||
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_timer_system_clock
|
||||
.global _tx_timer_current_ptr
|
||||
.global _tx_timer_list_start
|
||||
.global _tx_timer_list_end
|
||||
.global _tx_timer_expired_time_slice
|
||||
.global _tx_timer_expired
|
||||
.global _tx_thread_time_slice
|
||||
|
||||
|
||||
|
||||
/* 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
|
||||
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
|
||||
238
ports/cortex_a12/gnu/example_build/build_threadx.bat
Normal file
238
ports/cortex_a12/gnu/example_build/build_threadx.bat
Normal file
@@ -0,0 +1,238 @@
|
||||
del tx.a
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 tx_initialize_low_level.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_stack_build.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_schedule.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_system_return.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_context_save.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_context_restore.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_interrupt_control.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_timer_interrupt.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_interrupt_disable.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_interrupt_restore.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_fiq_context_save.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_fiq_nesting_start.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_irq_nesting_start.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_irq_nesting_end.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_fiq_nesting_end.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_fiq_context_restore.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 ../src/tx_thread_vectored_context_save.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_block_allocate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_cleanup.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_initialize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_system_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_prioritize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_block_release.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_allocate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_cleanup.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_initialize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_system_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_prioritize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_search.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_release.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_cleanup.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_initialize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_system_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set_notify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_high_level.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_enter.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_setup.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_cleanup.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_initialize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_system_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_prioritize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_priority_change.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_put.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_cleanup.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_flush.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_front_send.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_initialize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_system_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_prioritize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_receive.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send_notify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_ceiling_put.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_cleanup.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_initialize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_system_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_prioritize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put_notify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_entry_exit_notify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_identify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_initialize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_system_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_preemption_change.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_priority_change.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_relinquish.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_reset.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_resume.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_shell_entry.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_sleep.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_analyze.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_handler.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_notify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_suspend.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_preempt_check.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_resume.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_suspend.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_terminate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice_change.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_timeout.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_wait_abort.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_time_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_time_set.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_activate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_change.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_deactivate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_expiration_process.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_initialize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_system_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_activate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_deactivate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_thread_entry.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_enable.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_disable.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_initialize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_interrupt_control.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_enter_insert.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_exit_insert.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_register.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_unregister.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_user_event_insert.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_buffer_full_notify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_filter.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_unfilter.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_block_allocate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_prioritize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_block_release.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_allocate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_prioritize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_release.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set_notify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_prioritize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_put.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_flush.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_front_send.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_prioritize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_receive.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send_notify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_ceiling_put.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_prioritize.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put_notify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_entry_exit_notify.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_info_get.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_preemption_change.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_priority_change.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_relinquish.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_reset.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_resume.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_suspend.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_terminate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_time_slice_change.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_wait_abort.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_activate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_change.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_create.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_deactivate.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_delete.c
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_info_get.c
|
||||
arm-none-eabi-ar -r tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o
|
||||
arm-none-eabi-ar -r tx.a tx_thread_interrupt_disable.o tx_thread_interrupt_restore.o tx_thread_fiq_context_save.o tx_thread_fiq_nesting_start.o tx_thread_irq_nesting_start.o tx_thread_irq_nesting_end.o
|
||||
arm-none-eabi-ar -r tx.a tx_thread_fiq_nesting_end.o tx_thread_fiq_context_restore.o tx_thread_vectored_context_save.o tx_initialize_low_level.o
|
||||
arm-none-eabi-ar -r tx.a tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o
|
||||
arm-none-eabi-ar -r tx.a tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o
|
||||
arm-none-eabi-ar -r tx.a tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o
|
||||
arm-none-eabi-ar -r tx.a tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o
|
||||
arm-none-eabi-ar -r tx.a tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o
|
||||
arm-none-eabi-ar -r tx.a tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o tx_event_flags_performance_system_info_get.o
|
||||
arm-none-eabi-ar -r tx.a tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o
|
||||
arm-none-eabi-ar -r tx.a tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o
|
||||
arm-none-eabi-ar -r tx.a tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o
|
||||
arm-none-eabi-ar -r tx.a tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o
|
||||
arm-none-eabi-ar -r tx.a tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o
|
||||
arm-none-eabi-ar -r tx.a tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o
|
||||
arm-none-eabi-ar -r tx.a tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o tx_semaphore_put_notify.o
|
||||
arm-none-eabi-ar -r tx.a tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o
|
||||
arm-none-eabi-ar -r tx.a tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o
|
||||
arm-none-eabi-ar -r tx.a tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o
|
||||
arm-none-eabi-ar -r tx.a tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o
|
||||
arm-none-eabi-ar -r tx.a tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o
|
||||
arm-none-eabi-ar -r tx.a tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o
|
||||
arm-none-eabi-ar -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o
|
||||
arm-none-eabi-ar -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o
|
||||
arm-none-eabi-ar -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o
|
||||
arm-none-eabi-ar -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o
|
||||
arm-none-eabi-ar -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o
|
||||
arm-none-eabi-ar -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o
|
||||
arm-none-eabi-ar -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o
|
||||
arm-none-eabi-ar -r tx.a txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o
|
||||
arm-none-eabi-ar -r tx.a txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o txe_queue_prioritize.o
|
||||
arm-none-eabi-ar -r tx.a txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o
|
||||
arm-none-eabi-ar -r tx.a txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o
|
||||
arm-none-eabi-ar -r tx.a txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o
|
||||
arm-none-eabi-ar -r tx.a txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o
|
||||
arm-none-eabi-ar -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o
|
||||
@@ -0,0 +1,6 @@
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 reset.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 crt0.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 tx_initialize_low_level.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a12 -I../../../../common/inc -I../inc sample_threadx.c
|
||||
arm-none-eabi-gcc -g -mcpu=cortex-a12 -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
|
||||
|
||||
90
ports/cortex_a12/gnu/example_build/crt0.S
Normal file
90
ports/cortex_a12/gnu/example_build/crt0.S
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
/* .text is used instead of .section .text so it works with arm-aout too. */
|
||||
.text
|
||||
.code 32
|
||||
.align 0
|
||||
|
||||
.global _mainCRTStartup
|
||||
.global _start
|
||||
.global start
|
||||
start:
|
||||
_start:
|
||||
_mainCRTStartup:
|
||||
|
||||
/* Start by setting up a stack */
|
||||
/* Set up the stack pointer to a fixed value */
|
||||
ldr r3, .LC0
|
||||
mov sp, r3
|
||||
/* Setup a default stack-limit in case the code has been
|
||||
compiled with "-mapcs-stack-check". Hard-wiring this value
|
||||
is not ideal, since there is currently no support for
|
||||
checking that the heap and stack have not collided, or that
|
||||
this default 64k is enough for the program being executed.
|
||||
However, it ensures that this simple crt0 world will not
|
||||
immediately cause an overflow event: */
|
||||
sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
|
||||
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 */
|
||||
|
||||
|
||||
|
||||
bl memset
|
||||
mov r0, #0 /* no arguments */
|
||||
mov r1, #0 /* no argv either */
|
||||
#ifdef __USES_INITFINI__
|
||||
/* Some arm/elf targets use the .init and .fini sections
|
||||
to create constructors and destructors, and for these
|
||||
targets we need to call the _init function and arrange
|
||||
for _fini to be called at program exit. */
|
||||
mov r4, r0
|
||||
mov r5, r1
|
||||
/* ldr r0, .Lfini */
|
||||
bl atexit
|
||||
/* bl init */
|
||||
mov r0, r4
|
||||
mov r1, r5
|
||||
#endif
|
||||
bl main
|
||||
|
||||
bl exit /* Should not return. */
|
||||
|
||||
|
||||
/* For Thumb, constants must be after the code since only
|
||||
positive offsets are supported for PC relative addresses. */
|
||||
|
||||
.align 0
|
||||
.LC0:
|
||||
.LC1:
|
||||
.word __bss_start__
|
||||
.LC2:
|
||||
.word __bss_end__
|
||||
/*
|
||||
#ifdef __USES_INITFINI__
|
||||
.Lfini:
|
||||
.word _fini
|
||||
#endif */
|
||||
/* Return ... */
|
||||
#ifdef __APCS_26__
|
||||
movs pc, lr
|
||||
#else
|
||||
#ifdef __THUMB_INTERWORK
|
||||
bx lr
|
||||
#else
|
||||
mov pc, lr
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Workspace for Angel calls. */
|
||||
.data
|
||||
/* Data returned by monitor SWI. */
|
||||
.global __stack_base__
|
||||
HeapBase: .word 0
|
||||
HeapLimit: .word 0
|
||||
__stack_base__: .word 0
|
||||
StackLimit: .word 0
|
||||
64
ports/cortex_a12/gnu/example_build/reset.S
Normal file
64
ports/cortex_a12/gnu/example_build/reset.S
Normal file
@@ -0,0 +1,64 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
|
||||
.global _start
|
||||
.global __tx_undefined
|
||||
.global __tx_swi_interrupt
|
||||
.global __tx_prefetch_handler
|
||||
.global __tx_abort_handler
|
||||
.global __tx_reserved_handler
|
||||
.global __tx_irq_handler
|
||||
.global __tx_fiq_handler
|
||||
|
||||
/* 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
|
||||
|
||||
STARTUP:
|
||||
.word _start // Reset goes to C startup function
|
||||
UNDEFINED:
|
||||
.word __tx_undefined // Undefined handler
|
||||
SWI:
|
||||
.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
|
||||
FIQ:
|
||||
.word __tx_fiq_handler // FIQ interrupt handler
|
||||
369
ports/cortex_a12/gnu/example_build/sample_threadx.c
Normal file
369
ports/cortex_a12/gnu/example_build/sample_threadx.c
Normal file
@@ -0,0 +1,369 @@
|
||||
/* 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,
|
||||
byte pool, and block pool. */
|
||||
|
||||
#include "tx_api.h"
|
||||
|
||||
#define DEMO_STACK_SIZE 1024
|
||||
#define DEMO_BYTE_POOL_SIZE 9120
|
||||
#define DEMO_BLOCK_POOL_SIZE 100
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
TX_THREAD thread_0;
|
||||
TX_THREAD thread_1;
|
||||
TX_THREAD thread_2;
|
||||
TX_THREAD thread_3;
|
||||
TX_THREAD thread_4;
|
||||
TX_THREAD thread_5;
|
||||
TX_THREAD thread_6;
|
||||
TX_THREAD thread_7;
|
||||
TX_QUEUE queue_0;
|
||||
TX_SEMAPHORE semaphore_0;
|
||||
TX_MUTEX mutex_0;
|
||||
TX_EVENT_FLAGS_GROUP event_flags_0;
|
||||
TX_BYTE_POOL byte_pool_0;
|
||||
TX_BLOCK_POOL block_pool_0;
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
ULONG thread_0_counter;
|
||||
ULONG thread_1_counter;
|
||||
ULONG thread_1_messages_sent;
|
||||
ULONG thread_2_counter;
|
||||
ULONG thread_2_messages_received;
|
||||
ULONG thread_3_counter;
|
||||
ULONG thread_4_counter;
|
||||
ULONG thread_5_counter;
|
||||
ULONG thread_6_counter;
|
||||
ULONG thread_7_counter;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input);
|
||||
void thread_1_entry(ULONG thread_input);
|
||||
void thread_2_entry(ULONG thread_input);
|
||||
void thread_3_and_4_entry(ULONG thread_input);
|
||||
void thread_5_entry(ULONG thread_input);
|
||||
void thread_6_and_7_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Define main entry point. */
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
/* Enter the ThreadX kernel. */
|
||||
tx_kernel_enter();
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
void tx_application_define(void *first_unused_memory)
|
||||
{
|
||||
|
||||
CHAR *pointer = TX_NULL;
|
||||
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE);
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
/* Allocate the stack for thread 0. */
|
||||
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,
|
||||
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
|
||||
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,
|
||||
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,
|
||||
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.
|
||||
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,
|
||||
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,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 5. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* 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,
|
||||
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,
|
||||
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,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the message queue. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
|
||||
|
||||
/* Create the message queue shared by threads 1 and 2. */
|
||||
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
|
||||
|
||||
/* Create the semaphore used by threads 3 and 4. */
|
||||
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Create the event flags group used by threads 1 and 5. */
|
||||
tx_event_flags_create(&event_flags_0, "event flags 0");
|
||||
|
||||
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
|
||||
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Allocate the memory for a small block pool. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create a block memory pool to allocate a message buffer from. */
|
||||
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
|
||||
|
||||
/* Allocate a block and release the block memory. */
|
||||
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
|
||||
|
||||
/* Release the block back to the pool. */
|
||||
tx_block_release(pointer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sits in while-forever-sleep loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Sleep for 10 ticks. */
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Set event flag 0 to wakeup thread 5. */
|
||||
status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sends messages to a queue shared by thread 2. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Send message to queue 0. */
|
||||
status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check completion status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the message sent. */
|
||||
thread_1_messages_sent++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG received_message;
|
||||
UINT status;
|
||||
|
||||
/* This thread retrieves messages placed on the queue by thread 1. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* 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
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_3_and_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 3 and thread 4. As the loop
|
||||
below shows, these function compete for ownership of semaphore_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 3)
|
||||
thread_3_counter++;
|
||||
else
|
||||
thread_4_counter++;
|
||||
|
||||
/* Get the semaphore with suspension. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the semaphore. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the semaphore. */
|
||||
status = tx_semaphore_put(&semaphore_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_flags;
|
||||
|
||||
|
||||
/* This thread simply waits for an event in a forever loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_flags != 0x1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_6_and_7_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 6 and thread 7. As the loop
|
||||
below shows, these function compete for ownership of mutex_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 6)
|
||||
thread_6_counter++;
|
||||
else
|
||||
thread_7_counter++;
|
||||
|
||||
/* Get the mutex with suspension. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Get the mutex again with suspension. This shows
|
||||
that an owning thread may retrieve the mutex it
|
||||
owns multiple times. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the mutex. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the mutex. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
239
ports/cortex_a12/gnu/example_build/sample_threadx.ld
Normal file
239
ports/cortex_a12/gnu/example_build/sample_threadx.ld
Normal file
@@ -0,0 +1,239 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
|
||||
"elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
/* ENTRY(_start) */
|
||||
/* Do we need any of these for elf?
|
||||
__DYNAMIC = 0; */
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
.vectors : {reset.o(.text) }
|
||||
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = 0x00001000;
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rel.init : { *(.rel.init) }
|
||||
.rela.init : { *(.rela.init) }
|
||||
.rel.text :
|
||||
{
|
||||
*(.rel.text)
|
||||
*(.rel.text.*)
|
||||
*(.rel.gnu.linkonce.t*)
|
||||
}
|
||||
.rela.text :
|
||||
{
|
||||
*(.rela.text)
|
||||
*(.rela.text.*)
|
||||
*(.rela.gnu.linkonce.t*)
|
||||
}
|
||||
.rel.fini : { *(.rel.fini) }
|
||||
.rela.fini : { *(.rela.fini) }
|
||||
.rel.rodata :
|
||||
{
|
||||
*(.rel.rodata)
|
||||
*(.rel.rodata.*)
|
||||
*(.rel.gnu.linkonce.r*)
|
||||
}
|
||||
.rela.rodata :
|
||||
{
|
||||
*(.rela.rodata)
|
||||
*(.rela.rodata.*)
|
||||
*(.rela.gnu.linkonce.r*)
|
||||
}
|
||||
.rel.data :
|
||||
{
|
||||
*(.rel.data)
|
||||
*(.rel.data.*)
|
||||
*(.rel.gnu.linkonce.d*)
|
||||
}
|
||||
.rela.data :
|
||||
{
|
||||
*(.rela.data)
|
||||
*(.rela.data.*)
|
||||
*(.rela.gnu.linkonce.d*)
|
||||
}
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.sdata :
|
||||
{
|
||||
*(.rel.sdata)
|
||||
*(.rel.sdata.*)
|
||||
*(.rel.gnu.linkonce.s*)
|
||||
}
|
||||
.rela.sdata :
|
||||
{
|
||||
*(.rela.sdata)
|
||||
*(.rela.sdata.*)
|
||||
*(.rela.gnu.linkonce.s*)
|
||||
}
|
||||
.rel.sbss : { *(.rel.sbss) }
|
||||
.rela.sbss : { *(.rela.sbss) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.plt : { *(.plt) }
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.stub)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t*)
|
||||
*(.glue_7t) *(.glue_7)
|
||||
} =0
|
||||
.init :
|
||||
{
|
||||
KEEP (*(.init))
|
||||
} =0
|
||||
_etext = .;
|
||||
PROVIDE (etext = .);
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
} =0
|
||||
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = ALIGN(256) + (. & (256 - 1));
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
SORT(CONSTRUCTORS)
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
.eh_frame : { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : { *(.gcc_except_table) }
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
from the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.got : { *(.got.plt) *(.got) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
/* We want the small data sections together, so single-instruction offsets
|
||||
can access them all, and initialized data all before uninitialized, so
|
||||
we can shorten the on-disk segment size. */
|
||||
.sdata :
|
||||
{
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
.sbss :
|
||||
{
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.scommon)
|
||||
}
|
||||
.bss :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections. */
|
||||
. = ALIGN(32 / 8);
|
||||
}
|
||||
. = ALIGN(32 / 8);
|
||||
|
||||
_bss_end__ = . ; __bss_end__ = . ;
|
||||
PROVIDE (end = .);
|
||||
|
||||
.stack :
|
||||
{
|
||||
|
||||
_stack_bottom = ABSOLUTE(.) ;
|
||||
|
||||
/* Allocate room for stack. This must be big enough for the IRQ, FIQ, and
|
||||
SYS stack if nested interrupts are enabled. */
|
||||
. = ALIGN(8) ;
|
||||
. += 4096 ;
|
||||
_sp = . - 16 ;
|
||||
_stack_top = ABSOLUTE(.) ;
|
||||
}
|
||||
|
||||
_end = .; __end__ = . ;
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
|
||||
/* These must appear regardless of . */
|
||||
}
|
||||
305
ports/cortex_a12/gnu/example_build/tx_initialize_low_level.S
Normal file
305
ports/cortex_a12/gnu/example_build/tx_initialize_low_level.S
Normal file
@@ -0,0 +1,305 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
|
||||
.global _tx_thread_system_stack_ptr
|
||||
.global _tx_initialize_unused_memory
|
||||
.global _tx_thread_context_save
|
||||
.global _tx_thread_context_restore
|
||||
.global _tx_timer_interrupt
|
||||
.global _end
|
||||
.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. */
|
||||
|
||||
.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 //
|
||||
.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
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
#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!
|
||||
|
||||
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
|
||||
#else
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
|
||||
/* Define shells for each of the interrupt vectors. */
|
||||
|
||||
.global __tx_undefined
|
||||
__tx_undefined:
|
||||
B __tx_undefined // Undefined handler
|
||||
|
||||
.global __tx_swi_interrupt
|
||||
__tx_swi_interrupt:
|
||||
B __tx_swi_interrupt // Software interrupt handler
|
||||
|
||||
.global __tx_prefetch_handler
|
||||
__tx_prefetch_handler:
|
||||
B __tx_prefetch_handler // Prefetch exception handler
|
||||
|
||||
.global __tx_abort_handler
|
||||
__tx_abort_handler:
|
||||
B __tx_abort_handler // Abort exception handler
|
||||
|
||||
.global __tx_reserved_handler
|
||||
__tx_reserved_handler:
|
||||
B __tx_reserved_handler // Reserved exception handler
|
||||
|
||||
.global __tx_irq_handler
|
||||
.global __tx_irq_processing_return
|
||||
__tx_irq_handler:
|
||||
|
||||
/* 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. */
|
||||
#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. */
|
||||
#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. */
|
||||
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. */
|
||||
#ifdef TX_ENABLE_FIQ_NESTING
|
||||
BL _tx_thread_fiq_nesting_start
|
||||
#endif
|
||||
|
||||
/* Application FIQ handlers can be called here! */
|
||||
|
||||
/* If interrupt nesting was started earlier, the end of interrupt nesting
|
||||
service must be called before returning to _tx_thread_fiq_context_restore. */
|
||||
#ifdef TX_ENABLE_FIQ_NESTING
|
||||
BL _tx_thread_fiq_nesting_end
|
||||
#endif
|
||||
|
||||
/* Jump to fiq context restore to restore system context. */
|
||||
B _tx_thread_fiq_context_restore
|
||||
|
||||
|
||||
#else
|
||||
.global __tx_fiq_handler
|
||||
__tx_fiq_handler:
|
||||
B __tx_fiq_handler // FIQ interrupt handler
|
||||
#endif
|
||||
|
||||
|
||||
BUILD_OPTIONS:
|
||||
.word _tx_build_options // Reference to bring in
|
||||
VERSION_ID:
|
||||
.word _tx_version_id // Reference to bring in
|
||||
|
||||
|
||||
|
||||
331
ports/cortex_a12/gnu/inc/tx_port.h
Normal file
331
ports/cortex_a12/gnu/inc/tx_port.h
Normal file
@@ -0,0 +1,331 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/** Port Specific */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h ARMv7-A */
|
||||
/* 6.1.12 */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* 07-29-2022 Scott Larson Updated comments, removed */
|
||||
/* unneeded temp variable, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_PORT_H
|
||||
#define TX_PORT_H
|
||||
|
||||
|
||||
/* Determine if the optional ThreadX user define file should be used. */
|
||||
|
||||
#ifdef TX_INCLUDE_USER_DEFINE_FILE
|
||||
|
||||
|
||||
/* 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"
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler library include files. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Define ThreadX basic types for this port. */
|
||||
|
||||
#define VOID void
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
|
||||
|
||||
/* Define the priority levels for ThreadX. Legal values range
|
||||
from 32 to 1024 and MUST be evenly divisible by 32. */
|
||||
|
||||
#ifndef TX_MAX_PRIORITIES
|
||||
#define TX_MAX_PRIORITIES 32
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
|
||||
thread creation is less than this value, the thread create call will return an error. */
|
||||
|
||||
#ifndef TX_MINIMUM_STACK
|
||||
#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the system timer thread's default stack size and priority. These are only applicable
|
||||
if TX_TIMER_PROCESS_IN_ISR is not defined. */
|
||||
|
||||
#ifndef TX_TIMER_THREAD_STACK_SIZE
|
||||
#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 */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define various constants for the ThreadX ARM port. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */
|
||||
#else
|
||||
#define TX_INT_DISABLE 0x80 /* Disable IRQ interrupts */
|
||||
#endif
|
||||
#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
|
||||
source constants would be:
|
||||
|
||||
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
|
||||
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TX_TRACE_TIME_SOURCE
|
||||
#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
|
||||
#endif
|
||||
#ifndef TX_TRACE_TIME_MASK
|
||||
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the port specific options for the _tx_build_options variable. This variable indicates
|
||||
how the ThreadX library was built. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_FIQ_ENABLED 1
|
||||
#else
|
||||
#define TX_FIQ_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_IRQ_NESTING
|
||||
#define TX_IRQ_NESTING_ENABLED 2
|
||||
#else
|
||||
#define TX_IRQ_NESTING_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_NESTING
|
||||
#define TX_FIQ_NESTING_ENABLED 4
|
||||
#else
|
||||
#define TX_FIQ_NESTING_ENABLED 0
|
||||
#endif
|
||||
|
||||
#define TX_PORT_SPECIFIC_BUILD_OPTIONS TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED
|
||||
|
||||
|
||||
/* Define the in-line initialization constant so that modules with in-line
|
||||
initialization capabilities can prevent their initialization from being
|
||||
a function call. */
|
||||
|
||||
#define TX_INLINE_INITIALIZATION
|
||||
|
||||
|
||||
/* 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
|
||||
logic. */
|
||||
|
||||
#ifdef TX_ENABLE_STACK_CHECKING
|
||||
#undef TX_DISABLE_STACK_FILLING
|
||||
#endif
|
||||
|
||||
|
||||
/* 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
|
||||
existing ThreadX kernel awareness modules. */
|
||||
|
||||
#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 the port extensions of the remaining ThreadX objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_EXTENSION
|
||||
#define TX_BYTE_POOL_EXTENSION
|
||||
#define TX_EVENT_FLAGS_GROUP_EXTENSION
|
||||
#define TX_MUTEX_EXTENSION
|
||||
#define TX_QUEUE_EXTENSION
|
||||
#define TX_SEMAPHORE_EXTENSION
|
||||
#define TX_TIMER_EXTENSION
|
||||
|
||||
|
||||
/* 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
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
|
||||
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_COMPLETED_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
|
||||
|
||||
|
||||
/* Define the ThreadX object creation extensions for the remaining objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
|
||||
#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
|
||||
#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
|
||||
#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
|
||||
#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
|
||||
|
||||
|
||||
/* Define the ThreadX object deletion extensions for the remaining objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
|
||||
#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
|
||||
#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
|
||||
#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
|
||||
#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
|
||||
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;
|
||||
#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
|
||||
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. */
|
||||
|
||||
#ifdef __thumb__
|
||||
|
||||
unsigned int _tx_thread_interrupt_disable(void);
|
||||
unsigned int _tx_thread_interrupt_restore(UINT old_posture);
|
||||
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
|
||||
|
||||
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
|
||||
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
|
||||
|
||||
#else
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_DISABLE asm volatile (" MRS %0,CPSR; CPSID if ": "=r" (interrupt_save) );
|
||||
#else
|
||||
#define TX_DISABLE asm volatile (" MRS %0,CPSR; CPSID i ": "=r" (interrupt_save) );
|
||||
#endif
|
||||
|
||||
#define TX_RESTORE asm volatile (" MSR CPSR_c,%0 "::"r" (interrupt_save) );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* 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);
|
||||
void tx_thread_vfp_disable(void);
|
||||
|
||||
|
||||
/* Define the interrupt lockout macros for each ThreadX object. */
|
||||
|
||||
#define TX_BLOCK_POOL_DISABLE TX_DISABLE
|
||||
#define TX_BYTE_POOL_DISABLE TX_DISABLE
|
||||
#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
|
||||
#define TX_MUTEX_DISABLE TX_DISABLE
|
||||
#define TX_QUEUE_DISABLE TX_DISABLE
|
||||
#define TX_SEMAPHORE_DISABLE TX_DISABLE
|
||||
|
||||
|
||||
/* 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 ARMv7-A Version 6.1.11 *";
|
||||
#else
|
||||
extern CHAR _tx_version_id[];
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
222
ports/cortex_a12/gnu/src/tx_thread_context_restore.S
Normal file
222
ports/cortex_a12/gnu/src/tx_thread_context_restore.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.arm
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
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
|
||||
#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
|
||||
|
||||
|
||||
|
||||
/* 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 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. */
|
||||
|
||||
#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 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
|
||||
|
||||
_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. */
|
||||
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. */
|
||||
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
|
||||
172
ports/cortex_a12/gnu/src/tx_thread_context_save.S
Normal file
172
ports/cortex_a12/gnu/src/tx_thread_context_save.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
.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 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. */
|
||||
|
||||
STMDB sp!, {r0-r3} // Save some working registers
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if // Disable FIQ interrupts
|
||||
#endif
|
||||
LDR r3, =_tx_thread_system_state // Pickup address of system state 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
|
||||
#endif
|
||||
|
||||
B __tx_irq_processing_return // Continue IRQ processing
|
||||
|
||||
__tx_thread_not_nested_save:
|
||||
|
||||
/* Otherwise, not nested, check to see if a thread was running. */
|
||||
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
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
#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
|
||||
|
||||
ADD sp, sp, #16 // Recover saved registers
|
||||
B __tx_irq_processing_return // Continue IRQ processing
|
||||
223
ports/cortex_a12/gnu/src/tx_thread_fiq_context_restore.S
Normal file
223
ports/cortex_a12/gnu/src/tx_thread_fiq_context_restore.S
Normal file
@@ -0,0 +1,223 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
.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_fiq_context_restore
|
||||
since it will never be called 16-bit mode. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
|
||||
#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. */
|
||||
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. */
|
||||
|
||||
LDR r1, [sp] // Pickup the saved SPSR
|
||||
MOV r2, #MODE_MASK // Build mask to isolate the interrupted mode
|
||||
AND r1, r1, r2 // Isolate mode bits
|
||||
CMP r1, #IRQ_MODE_BITS // Was an interrupt taken in IRQ mode before we
|
||||
// got to context save? */
|
||||
BEQ __tx_thread_fiq_no_preempt_restore // Yes, just go back to point of interrupt
|
||||
|
||||
|
||||
LDR r1, =_tx_thread_current_ptr // Pickup address of current thread ptr
|
||||
LDR r0, [r1] // Pickup actual current thread pointer
|
||||
CMP r0, #0 // Is it NULL?
|
||||
BEQ __tx_thread_fiq_idle_system_restore // Yes, idle system was interrupted
|
||||
|
||||
LDR r3, =_tx_thread_preempt_disable // Pickup preempt disable address
|
||||
LDR r2, [r3] // Pickup actual preempt disable flag
|
||||
CMP r2, #0 // Is it set?
|
||||
BNE __tx_thread_fiq_no_preempt_restore // Yes, don't preempt this thread
|
||||
LDR r3, =_tx_thread_execute_ptr // Pickup address of execute thread ptr
|
||||
LDR r2, [r3] // Pickup actual execute thread pointer
|
||||
CMP r0, r2 // Is the same thread highest priority?
|
||||
BNE __tx_thread_fiq_preempt_restore // No, preemption needs to happen
|
||||
|
||||
|
||||
__tx_thread_fiq_no_preempt_restore:
|
||||
|
||||
/* Restore interrupted thread or ISR. */
|
||||
/* 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
|
||||
_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 */
|
||||
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
|
||||
|
||||
178
ports/cortex_a12/gnu/src/tx_thread_fiq_context_save.S
Normal file
178
ports/cortex_a12/gnu/src/tx_thread_fiq_context_save.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
|
||||
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
|
||||
#endif
|
||||
|
||||
B __tx_fiq_processing_return // Continue FIQ processing
|
||||
//
|
||||
__tx_thread_fiq_not_nested_save:
|
||||
|
||||
/* Otherwise, not nested, check to see if a thread was running. */
|
||||
|
||||
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
|
||||
#endif
|
||||
|
||||
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
|
||||
104
ports/cortex_a12/gnu/src/tx_thread_fiq_nesting_end.S
Normal file
104
ports/cortex_a12/gnu/src/tx_thread_fiq_nesting_end.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS = 0xC0 // Disable IRQ/FIQ interrupts
|
||||
#else
|
||||
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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
96
ports/cortex_a12/gnu/src/tx_thread_fiq_nesting_start.S
Normal file
96
ports/cortex_a12/gnu/src/tx_thread_fiq_nesting_start.S
Normal file
@@ -0,0 +1,96 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
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 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
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
104
ports/cortex_a12/gnu/src/tx_thread_interrupt_control.S
Normal file
104
ports/cortex_a12/gnu/src/tx_thread_interrupt_control.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
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. */
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_interrupt_control
|
||||
$_tx_thread_interrupt_control:
|
||||
.thumb
|
||||
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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
101
ports/cortex_a12/gnu/src/tx_thread_interrupt_disable.S
Normal file
101
ports/cortex_a12/gnu/src/tx_thread_interrupt_disable.S
Normal file
@@ -0,0 +1,101 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* Define 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if // Disable IRQ and FIQ
|
||||
#else
|
||||
CPSID i // Disable IRQ
|
||||
#endif
|
||||
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
93
ports/cortex_a12/gnu/src/tx_thread_interrupt_restore.S
Normal file
93
ports/cortex_a12/gnu/src/tx_thread_interrupt_restore.S
Normal file
@@ -0,0 +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 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
103
ports/cortex_a12/gnu/src/tx_thread_irq_nesting_end.S
Normal file
103
ports/cortex_a12/gnu/src/tx_thread_irq_nesting_end.S
Normal file
@@ -0,0 +1,103 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS = 0xC0 // Disable IRQ/FIQ interrupts
|
||||
#else
|
||||
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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
96
ports/cortex_a12/gnu/src/tx_thread_irq_nesting_start.S
Normal file
96
ports/cortex_a12/gnu/src/tx_thread_irq_nesting_start.S
Normal file
@@ -0,0 +1,96 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
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 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
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 // Return to caller
|
||||
#else
|
||||
MOV pc, r3 // Return to caller
|
||||
#endif
|
||||
230
ports/cortex_a12/gnu/src/tx_thread_schedule.S
Normal file
230
ports/cortex_a12/gnu/src/tx_thread_schedule.S
Normal file
@@ -0,0 +1,230 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.global _tx_thread_execute_ptr
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_timer_time_slice
|
||||
|
||||
|
||||
/* 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSIE if // Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSIE i // Enable IRQ interrupts
|
||||
#endif
|
||||
|
||||
/* Wait for a thread to execute. */
|
||||
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
|
||||
/* Yes! We have a thread to execute. Lockout interrupts and
|
||||
transfer control to it. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if // Disable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i // Disable IRQ interrupts
|
||||
#endif
|
||||
|
||||
/* Setup the current thread pointer. */
|
||||
|
||||
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
|
||||
#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
|
||||
BEQ _tx_solicited_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
|
||||
_tx_skip_interrupt_vfp_restore:
|
||||
#endif
|
||||
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
|
||||
_tx_skip_solicited_vfp_restore:
|
||||
#endif
|
||||
MSR CPSR_cxsf, r5 // Recover CPSR
|
||||
LDMIA sp!, {r4-r11, lr} // Return to thread synchronously
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr // Return to caller
|
||||
#else
|
||||
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
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if // Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
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)
|
||||
__tx_no_thread_to_enable:
|
||||
MSR CPSR_cxsf, r2 // Recover CPSR
|
||||
BX LR // Return to caller
|
||||
|
||||
.global tx_thread_vfp_disable
|
||||
.type tx_thread_vfp_disable,function
|
||||
tx_thread_vfp_disable:
|
||||
MRS r2, CPSR // Pickup the CPSR
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if // Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
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)
|
||||
__tx_no_thread_to_disable:
|
||||
MSR CPSR_cxsf, r2 // Recover CPSR
|
||||
BX LR // Return to caller
|
||||
|
||||
#endif
|
||||
164
ports/cortex_a12/gnu/src/tx_thread_stack_build.S
Normal file
164
ports/cortex_a12/gnu/src/tx_thread_stack_build.S
Normal file
@@ -0,0 +1,164 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
.arm
|
||||
|
||||
SVC_MODE = 0x13 // SVC mode
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSR_MASK = 0xDF // Mask initial CPSR, IRQ & FIQ interrupts enabled
|
||||
#else
|
||||
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. */
|
||||
|
||||
.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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 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
|
||||
#else
|
||||
MOV pc, lr // Return to caller
|
||||
#endif
|
||||
162
ports/cortex_a12/gnu/src/tx_thread_system_return.S
Normal file
162
ports/cortex_a12/gnu/src/tx_thread_system_return.S
Normal file
@@ -0,0 +1,162 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.arm
|
||||
|
||||
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_thread_schedule
|
||||
|
||||
|
||||
|
||||
/* 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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
|
||||
|
||||
#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
|
||||
_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. */
|
||||
|
||||
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!
|
||||
165
ports/cortex_a12/gnu/src/tx_thread_vectored_context_save.S
Normal file
165
ports/cortex_a12/gnu/src/tx_thread_vectored_context_save.S
Normal file
@@ -0,0 +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 */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
.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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
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
|
||||
|
||||
#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
|
||||
|
||||
MOV pc, lr // Return to caller
|
||||
|
||||
__tx_thread_not_nested_save:
|
||||
|
||||
/* 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
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
#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
|
||||
|
||||
ADD sp, sp, #32 // Recover saved registers
|
||||
MOV pc, lr // Return to caller
|
||||
231
ports/cortex_a12/gnu/src/tx_timer_interrupt.S
Normal file
231
ports/cortex_a12/gnu/src/tx_timer_interrupt.S
Normal file
@@ -0,0 +1,231 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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... */
|
||||
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_timer_system_clock
|
||||
.global _tx_timer_current_ptr
|
||||
.global _tx_timer_list_start
|
||||
.global _tx_timer_list_end
|
||||
.global _tx_timer_expired_time_slice
|
||||
.global _tx_timer_expired
|
||||
.global _tx_thread_time_slice
|
||||
|
||||
|
||||
|
||||
/* 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 //
|
||||
.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
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
|
||||
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
|
||||
369
ports/cortex_a15/ac6/example_build/sample_threadx.c
Normal file
369
ports/cortex_a15/ac6/example_build/sample_threadx.c
Normal file
@@ -0,0 +1,369 @@
|
||||
/* 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,
|
||||
byte pool, and block pool. */
|
||||
|
||||
#include "tx_api.h"
|
||||
|
||||
#define DEMO_STACK_SIZE 1024
|
||||
#define DEMO_BYTE_POOL_SIZE 9120
|
||||
#define DEMO_BLOCK_POOL_SIZE 100
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
TX_THREAD thread_0;
|
||||
TX_THREAD thread_1;
|
||||
TX_THREAD thread_2;
|
||||
TX_THREAD thread_3;
|
||||
TX_THREAD thread_4;
|
||||
TX_THREAD thread_5;
|
||||
TX_THREAD thread_6;
|
||||
TX_THREAD thread_7;
|
||||
TX_QUEUE queue_0;
|
||||
TX_SEMAPHORE semaphore_0;
|
||||
TX_MUTEX mutex_0;
|
||||
TX_EVENT_FLAGS_GROUP event_flags_0;
|
||||
TX_BYTE_POOL byte_pool_0;
|
||||
TX_BLOCK_POOL block_pool_0;
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
ULONG thread_0_counter;
|
||||
ULONG thread_1_counter;
|
||||
ULONG thread_1_messages_sent;
|
||||
ULONG thread_2_counter;
|
||||
ULONG thread_2_messages_received;
|
||||
ULONG thread_3_counter;
|
||||
ULONG thread_4_counter;
|
||||
ULONG thread_5_counter;
|
||||
ULONG thread_6_counter;
|
||||
ULONG thread_7_counter;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input);
|
||||
void thread_1_entry(ULONG thread_input);
|
||||
void thread_2_entry(ULONG thread_input);
|
||||
void thread_3_and_4_entry(ULONG thread_input);
|
||||
void thread_5_entry(ULONG thread_input);
|
||||
void thread_6_and_7_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Define main entry point. */
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
/* Enter the ThreadX kernel. */
|
||||
tx_kernel_enter();
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
void tx_application_define(void *first_unused_memory)
|
||||
{
|
||||
|
||||
CHAR *pointer = TX_NULL;
|
||||
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE);
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
/* Allocate the stack for thread 0. */
|
||||
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,
|
||||
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
|
||||
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,
|
||||
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,
|
||||
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.
|
||||
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,
|
||||
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,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 5. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* 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,
|
||||
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,
|
||||
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,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the message queue. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
|
||||
|
||||
/* Create the message queue shared by threads 1 and 2. */
|
||||
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
|
||||
|
||||
/* Create the semaphore used by threads 3 and 4. */
|
||||
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Create the event flags group used by threads 1 and 5. */
|
||||
tx_event_flags_create(&event_flags_0, "event flags 0");
|
||||
|
||||
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
|
||||
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Allocate the memory for a small block pool. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create a block memory pool to allocate a message buffer from. */
|
||||
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
|
||||
|
||||
/* Allocate a block and release the block memory. */
|
||||
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
|
||||
|
||||
/* Release the block back to the pool. */
|
||||
tx_block_release(pointer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sits in while-forever-sleep loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Sleep for 10 ticks. */
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Set event flag 0 to wakeup thread 5. */
|
||||
status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sends messages to a queue shared by thread 2. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Send message to queue 0. */
|
||||
status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check completion status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the message sent. */
|
||||
thread_1_messages_sent++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG received_message;
|
||||
UINT status;
|
||||
|
||||
/* This thread retrieves messages placed on the queue by thread 1. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* 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
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_3_and_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 3 and thread 4. As the loop
|
||||
below shows, these function compete for ownership of semaphore_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 3)
|
||||
thread_3_counter++;
|
||||
else
|
||||
thread_4_counter++;
|
||||
|
||||
/* Get the semaphore with suspension. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the semaphore. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the semaphore. */
|
||||
status = tx_semaphore_put(&semaphore_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_flags;
|
||||
|
||||
|
||||
/* This thread simply waits for an event in a forever loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_flags != 0x1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_6_and_7_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 6 and thread 7. As the loop
|
||||
below shows, these function compete for ownership of mutex_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 6)
|
||||
thread_6_counter++;
|
||||
else
|
||||
thread_7_counter++;
|
||||
|
||||
/* Get the mutex with suspension. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Get the mutex again with suspension. This shows
|
||||
that an owning thread may retrieve the mutex it
|
||||
owns multiple times. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the mutex. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the mutex. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.exe.debug.base.var.arm_compiler_6-6.866723656">
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.exe.debug.base.469946340">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.debug.base.var.arm_compiler_6-6.866723656" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.debug.base.469946340" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
@@ -23,41 +23,37 @@
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.exe.debug.base.var.arm_compiler_6-6.866723656" name="Debug" parent="com.arm.eclipse.build.config.v6.exe.debug.base.var.arm_compiler_6-6">
|
||||
<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.exe.debug.base.469946340" name="Debug" parent="com.arm.eclipse.build.config.v6.exe.debug.base">
|
||||
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.exe.debug.base.var.arm_compiler_6-6.866723656." name="/" resourcePath="">
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.exe.debug.base.469946340." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6.1485601055" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6">
|
||||
<toolChain id="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6.573134568" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6">
|
||||
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.toolchain.v6.base.options.debug.level.936878797" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.84862199" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" value="Cortex-A15.NoFPU" valueType="string"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.1017835173" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-A15.VFPv4.Neon" valueType="string"/>
|
||||
<option id="com.arm.toolchain.v6.base.options.floatabi.57442314" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.floatabi.694551773" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.floatabi.hard" valueType="enumerated"/>
|
||||
<option id="com.arm.toolchain.v6.base.options.inst.560764723" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.inst.1653037675" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
<option id="com.arm.toolchain.v6.base.options.debug.level.480956369" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<targetPlatform id="com.arm.eclipse.build.config.v6.exe.debug.base.var.arm_compiler_6-6.866723656..365717981" name=""/>
|
||||
<targetPlatform id="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6.573134568.953059653" name=""/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/sample_threadx}/Debug" id="com.arm.toolchain.v6.builder.1035556537" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.arm.toolchain.v6.builder"/>
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/sample_threadx}/Debug" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.2091893653" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="8" superClass="com.arm.toolchain.v6.builder"/>
|
||||
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.884748322" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.480843237" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.61859374" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.target.665260895" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.86306431" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.2102538095" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-a7" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.926604944" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-a15" valueType="string"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.fpu.633771589" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.target.407494234" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="arm-arm-none-eabi" valueType="string"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.1961565341" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.c.compiler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.fpu.594176683" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="neon-vfpv4" valueType="string"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.inst.904338235" name="Instruction set" superClass="com.arm.tool.c.compiler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.913406133" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.c.compiler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.hard" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.inst.672759252" name="Instruction set" superClass="com.arm.tool.c.compiler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.compiler.v6.base.option.incpath.1501449994" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.compiler.v6.base.option.incpath.1101243778" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/inc_generic}""/>
|
||||
|
||||
@@ -65,61 +61,67 @@
|
||||
|
||||
</option>
|
||||
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1748030661" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.1919910001" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1889095542" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.709303949" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.1580367129" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.182665037" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1891093264" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.1827702550" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.1999076495" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.1929311259" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.std" id="com.arm.tool.assembler.v6.base.options.debug.level.1774425889" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.target.748329430" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" useByScannerDiscovery="false" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.cpu.706318352" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-a15" valueType="string"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.cpu.289232043" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-a7" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.target.1902308428" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" useByScannerDiscovery="false" value="arm-arm-none-eabi" valueType="string"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.fpu.2069861530" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.fpu.484483495" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="neon-vfpv4" valueType="string"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.floatabi.1140611893" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.assembler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.floatabi.1670352062" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.assembler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.hard" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.inst.1944846971" name="Instruction set" superClass="com.arm.tool.assembler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.inst.1289893037" name="Instruction set" superClass="com.arm.tool.assembler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.options.debug.level.1266868530" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" value="com.arm.tool.assembler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.440386505" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.2014598915" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.2143357221" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6">
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.1841579990" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.linker.option.scatter.1973860669" name="Scatter file (--scatter)" superClass="com.arm.tool.c.linker.option.scatter" useByScannerDiscovery="false" value="../sample_threadx.scat" valueType="string"/>
|
||||
<option id="com.arm.tool.c.linker.option.entry.1438082076" name="Image entry point (--entry)" superClass="com.arm.tool.c.linker.option.entry" useByScannerDiscovery="false" value="Vectors" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.linker.option.entry.250351843" name="Image entry point (--entry)" superClass="com.arm.tool.c.linker.option.entry" useByScannerDiscovery="false" value="Vectors" valueType="string"/>
|
||||
<option id="com.arm.tool.c.linker.option.scatter.295049975" name="Scatter file (--scatter)" superClass="com.arm.tool.c.linker.option.scatter" useByScannerDiscovery="false" value="../sample_threadx.scat" valueType="string"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.linker.libs.1333093957" name="User library files" superClass="com.arm.tool.c.linker.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.linker.libs.1672250850" name="User library files" superClass="com.arm.tool.c.linker.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/Debug/tx.a}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="com.arm.tool.c.linker.option.imagemap.354818852" name="Generate image map (--map)" superClass="com.arm.tool.c.linker.option.imagemap" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.arm.tool.c.linker.option.imagemap.1579816297" name="Generate image map (--map)" superClass="com.arm.tool.c.linker.option.imagemap" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
|
||||
<option id="com.arm.tool.c.linker.option.redirectoutput.1892388300" name="Redirect diagnostics output to file (--list)" superClass="com.arm.tool.c.linker.option.redirectoutput" useByScannerDiscovery="false" value="sample_threadx.map" valueType="string"/>
|
||||
<option id="com.arm.tool.c.linker.option.redirectoutput.1433429713" name="Redirect diagnostics output to file (--list)" superClass="com.arm.tool.c.linker.option.redirectoutput" useByScannerDiscovery="false" value="sample_threadx.map" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.linker.v6.option.suppress.1089906829" name="Suppress (--diag_suppress)" superClass="com.arm.tool.linker.v6.option.suppress" useByScannerDiscovery="false" value="L6306W" valueType="string"/>
|
||||
<option id="com.arm.tool.linker.v6.option.suppress.829979840" name="Suppress (--diag_suppress)" superClass="com.arm.tool.linker.v6.option.suppress" useByScannerDiscovery="false" value="L6306W" valueType="string"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.2076014102" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.305140315" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="timer_interrupts.c|MP_GIC.S|reset.S|crt0.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
@@ -137,7 +139,7 @@
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="sample_threadx.com.arm.eclipse.build.project.v6.exe.base.var.arm_compiler_6-6.458858052" name="Executable" projectType="com.arm.eclipse.build.project.v6.exe.base.var.arm_compiler_6-6"/>
|
||||
<project id="sample_threadx.com.arm.eclipse.build.project.v6.exe.1093829338" name="Executable"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
@@ -168,5 +170,7 @@
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
|
||||
</cproject>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.arm.debug.ds.nature</nature>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.arm.debugger.launcher2">
|
||||
<mapAttribute key="AverageDurationTracker">
|
||||
<mapEntry key="*Fetching Data Model" value="2711474"/>
|
||||
<mapEntry key="*list global low level symbols" value="27705253"/>
|
||||
<mapEntry key="*loading values from target" value="9455698"/>
|
||||
<mapEntry key="*updating expressions" value="49184293"/>
|
||||
<mapEntry key="*updating registers" value="67114301"/>
|
||||
<mapEntry key="AddEventObserver" value="4941002"/>
|
||||
<mapEntry key="ClearEngineCaches" value="1706400"/>
|
||||
<mapEntry key="Evaluate" value="2082850"/>
|
||||
<mapEntry key="SourceToAddress" value="768400"/>
|
||||
<mapEntry key="break" value="19995639"/>
|
||||
<mapEntry key="compute execution mode" value="818086"/>
|
||||
<mapEntry key="continue" value="16091521"/>
|
||||
<mapEntry key="disassemble" value="84357009"/>
|
||||
<mapEntry key="get capabilities" value="242101"/>
|
||||
<mapEntry key="get execution addresss" value="637787"/>
|
||||
<mapEntry key="get source lines" value="866330"/>
|
||||
<mapEntry key="initialize command help" value="82932286"/>
|
||||
<mapEntry key="interrupt" value="11925285"/>
|
||||
<mapEntry key="list breakpoint options" value="242832"/>
|
||||
<mapEntry key="list breakpoints" value="757587"/>
|
||||
<mapEntry key="list instruction sets" value="2216552"/>
|
||||
<mapEntry key="list signals" value="4642679"/>
|
||||
<mapEntry key="list watchpoint options" value="4504028"/>
|
||||
<mapEntry key="list watchpoints" value="959949"/>
|
||||
<mapEntry key="loadfile" value="176206178"/>
|
||||
<mapEntry key="next" value="25130219"/>
|
||||
<mapEntry key="nexti" value="24711500"/>
|
||||
<mapEntry key="remove" value="1513600"/>
|
||||
<mapEntry key="set $pc" value="12244700"/>
|
||||
<mapEntry key="set CWD" value="7171160"/>
|
||||
<mapEntry key="set breakpoint properties" value="9403852"/>
|
||||
<mapEntry key="set debug-from" value="1618455"/>
|
||||
<mapEntry key="start" value="184031679"/>
|
||||
<mapEntry key="step" value="31817500"/>
|
||||
<mapEntry key="synchronizing trace ranges" value="39600"/>
|
||||
<mapEntry key="toggleBreakpoint" value="7412657"/>
|
||||
<mapEntry key="waitForTargetToStop" value="28230483"/>
|
||||
</mapAttribute>
|
||||
<intAttribute key="DEBUG_TAB..RESOURCES.COUNT" value="0"/>
|
||||
<intAttribute key="FILES.CONNECT_TO_GDB_SERVER.RESOURCES.COUNT" value="0"/>
|
||||
<intAttribute key="FILES.DEBUG_EXISTING_ANDROID.RESOURCES.COUNT" value="0"/>
|
||||
<listAttribute key="FILES.DEBUG_RESIDENT_ANDROID"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.0.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.COUNT" value="1"/>
|
||||
<listAttribute key="FILES.DEBUG_RESIDENT_APP"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.TYPE" value="APPLICATION_ON_TARGET"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.COUNT" value="2"/>
|
||||
<listAttribute key="FILES.DOWNLOAD_AND_DEBUG"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.TYPE" value="TARGET_DOWNLOAD_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.COUNT" value="3"/>
|
||||
<listAttribute key="FILES.DOWNLOAD_DEBUG"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.TYPE" value="TARGET_DOWNLOAD_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.COUNT" value="3"/>
|
||||
<intAttribute key="FILES.DOWNLOAD_DEBUG_ANDROID.RESOURCES.COUNT" value="0"/>
|
||||
<listAttribute key="FILES.ICE_DEBUG">
|
||||
<listEntry value="ON_DEMAND_LOAD"/>
|
||||
<listEntry value="ALSO_LOAD_SYMBOLS"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.VALUE" value="${workspace_loc:/sample_threadx/Debug/sample_threadx.axf}"/>
|
||||
<intAttribute key="FILES.ICE_DEBUG.RESOURCES.COUNT" value="1"/>
|
||||
<listAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE">
|
||||
<listEntry value="ON_DEMAND_LOAD"/>
|
||||
<listEntry value="ALSO_LOAD_SYMBOLS"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.VALUE" value=""/>
|
||||
<intAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.COUNT" value="1"/>
|
||||
<listAttribute key="FILES.ICE_DEBUG_WITH_TRACE">
|
||||
<listEntry value="ON_DEMAND_LOAD"/>
|
||||
<listEntry value="ALSO_LOAD_SYMBOLS"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.VALUE" value=""/>
|
||||
<intAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.COUNT" value="1"/>
|
||||
<stringAttribute key="FILES.SELECTED_DEBUG_OPEATION" value="ICE_DEBUG"/>
|
||||
<stringAttribute key="HOST_WORKING_DIR" value="${workspace_loc}"/>
|
||||
<booleanAttribute key="HOST_WORKING_DIR_USE_DEFAULT" value="true"/>
|
||||
<booleanAttribute key="InstructionStepping" value="true"/>
|
||||
<booleanAttribute key="KEY_COMMANDS_AFTER_CONNECT" value="false"/>
|
||||
<stringAttribute key="KEY_COMMANDS_AFTER_CONNECT_TEXT" value=""/>
|
||||
<booleanAttribute key="KEY_COMMANDS_AS_CONNECT" value="false"/>
|
||||
<booleanAttribute key="RSE_USE_HOSTNAME" value="true"/>
|
||||
<stringAttribute key="TCP_DISABLE_EXTENDED_MODE" value="true"/>
|
||||
<booleanAttribute key="TCP_KILL_ON_EXIT" value="false"/>
|
||||
<listAttribute key="TREE_NODE_PROPERTIES:debugger.view.ExpressionsView">
|
||||
<listEntry value="NODE CACHE VERSION 1"/>
|
||||
<listEntry value="EXPRESSION_GROUP:Expressions:VALUE:_tx_timer_list"/>
|
||||
<listEntry value="1"/>
|
||||
<listEntry value="element formatter"/>
|
||||
<listEntry value="Hexadecimal"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="VFS_ENABLED" value="true"/>
|
||||
<stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/>
|
||||
<stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/>
|
||||
<stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" hostFile="C:\Users\nisohack\Documents\work\x-ware_libs\threadx_github\ports\cortex_a7\ac6\example_build\sample_threadx\tx_initialize_low_level.S" line="215"/> 		<location index="0" enabled="true" version="2" address="S:0x80000314" debugFile="C:/Users/nisohack/Documents/work/x-ware_libs/threadx_github/ports/cortex_a7/ac6/example_build/sample_threadx/tx_initialize_low_level.S" hostFile="C:\Users\nisohack\Documents\work\x-ware_libs\threadx_github\ports\cortex_a7\ac6\example_build\sample_threadx\tx_initialize_low_level.S" line="238"/> 	</breakpoint> </breakpoints> "/>
|
||||
<listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses">
|
||||
<listEntry value="<Next Instruction>"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
|
||||
<listEntry value="100"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="config_db_activity_name" value="Debug Cortex-A15"/>
|
||||
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option dtsl_config_script model_params config_file setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
|
||||
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
|
||||
<stringAttribute key="config_db_platform_name" value="Arm FVP (Installed with Arm DS) - VE_Cortex_A15x1"/>
|
||||
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
|
||||
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
|
||||
<stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp_installedwitharmds_/ve_cortex_a15x1"/>
|
||||
<stringAttribute key="config_file" value="CDB://cadi_config.xml"/>
|
||||
<booleanAttribute key="connectOnly" value="false"/>
|
||||
<listAttribute key="debugger.view.DisassemblyView:current">
|
||||
<listEntry value="<Next Instruction>"/>
|
||||
<listEntry value="100"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="debugger.view.ExpressionsView">
|
||||
<listEntry value="thread_0_counter"/>
|
||||
<listEntry value="thread_1_counter"/>
|
||||
<listEntry value="thread_2_counter"/>
|
||||
<listEntry value="thread_3_counter"/>
|
||||
<listEntry value="thread_4_counter"/>
|
||||
<listEntry value="thread_5_counter"/>
|
||||
<listEntry value="thread_6_counter"/>
|
||||
<listEntry value="thread_7_counter"/>
|
||||
</listAttribute>
|
||||
<mapAttribute key="debugger.view.ExpressionsView.ExpressionsData">
|
||||
<mapEntry key="0" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="1" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="2" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="3" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="4" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="5" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="6" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="7" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
</mapAttribute>
|
||||
<stringAttribute key="debugger.view.ExpressionsView:DebugOutlineColumnState" value="OutlineConfig1	8	0	true	false	172	-1	true	1	false	true	90	-1	true	2	true	true	108	-1	true	3	true	true	57	-1	true	4	true	true	50	-1	true	5	true	true	37	-1	true	6	true	true	90	-1	true	7	true	true	53	-1	true"/>
|
||||
<stringAttribute key="debugger.view.NewRegisterView:DebugOutlineColumnState" value="OutlineConfig1	8	0	true	true	78	-1	true	1	false	true	90	-1	true	2	true	true	117	-1	true	3	false	true	41	-1	true	4	false	true	50	-1	true	5	true	true	37	-1	true	6	false	true	62	-1	true	7	true	true	53	-1	true"/>
|
||||
<stringAttribute key="debugger.view.NewRegisterView:_selectedRegisterSet" value="All registers"/>
|
||||
<mapAttribute key="debugger.view.NewRegisterView_registerSets"/>
|
||||
<listAttribute key="debugger.view.TraceView:TRACE_EXPORT_FILTERS"/>
|
||||
<booleanAttribute key="debugger.view.expression.DrawAsHex" value="false"/>
|
||||
<booleanAttribute key="debugger.view.register.DrawAsHex" value="false"/>
|
||||
<stringAttribute key="dtsl_config" value="DtslScript"/>
|
||||
<stringAttribute key="dtsl_config_script" value="CDB://dtsl_config_script.py"/>
|
||||
<stringAttribute key="dtsl_options_file" value="default"/>
|
||||
<stringAttribute key="dtsl_tracecapture_option" value="options.traceBuffer.traceCaptureDevice"/>
|
||||
<stringAttribute key="launch_configuration_version" value="5.29.3"/>
|
||||
<booleanAttribute key="linuxOS" value="false"/>
|
||||
<stringAttribute key="model_params" value=""/>
|
||||
<booleanAttribute key="runAfterConnect" value="false"/>
|
||||
<listAttribute key="setup">
|
||||
<listEntry value="CDB://Scripts/rtsm_launcher.py"/>
|
||||
<listEntry value=""FVP_VE_Cortex-A15x1""/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="stopAtExpression" value="main"/>
|
||||
<stringAttribute key="watchpoints" value="<?xml version="1.0" encoding="UTF-8"?> <watchpoints> </watchpoints> "/>
|
||||
</launchConfiguration>
|
||||
@@ -1,47 +1,44 @@
|
||||
;**************************************************
|
||||
; Copyright (c) 2011 Arm Limited (or its affiliates). All rights reserved.
|
||||
;*******************************************************
|
||||
; Copyright (c) 2011-2016 Arm Limited (or its affiliates). All rights reserved.
|
||||
; Use, modification and redistribution of this file is subject to your possession of a
|
||||
; valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
; and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
;**************************************************
|
||||
;*******************************************************
|
||||
|
||||
; Scatter-file for bare-metal example on Versatile Express
|
||||
; Scatter-file for ARMv7-A bare-metal example on Versatile Express
|
||||
|
||||
; This scatter-file places application code, data, stack and heap at suitable addresses in the Versatile Express Cortex-A15 Core memory map.
|
||||
|
||||
; Versatile Express Cortex-A15 Core has SDRAM at 0x80000000, which this scatter-file uses.
|
||||
; This scatter-file places application code, data, stack and heap at suitable addresses in the memory map.
|
||||
|
||||
|
||||
SDRAM 0x80000000
|
||||
SDRAM 0x80000000 0x20000000
|
||||
{
|
||||
VECTORS +0
|
||||
{
|
||||
* (VECTORS, +FIRST) ; Vector table and other (assembler) startup code
|
||||
* (InRoot$$Sections) ; All (library) code that must be in a root region
|
||||
}
|
||||
|
||||
RO_CODE +0
|
||||
{ * (+RO-CODE) } ; Application RO code (.text)
|
||||
|
||||
RO_DATA +0
|
||||
{ * (+RO-DATA) } ; Application RO data (.constdata)
|
||||
RO_CODE +0
|
||||
{ * (+RO-CODE) } ; Application RO code (.text)
|
||||
|
||||
RW_DATA +0
|
||||
{ * (+RW) } ; Application RW data (.data)
|
||||
RO_DATA +0
|
||||
{ * (+RO-DATA) } ; Application RO data (.constdata)
|
||||
|
||||
ZI_DATA +0
|
||||
{ * (+ZI) } ; Application ZI data (.bss)
|
||||
RW_DATA +0
|
||||
{ * (+RW) } ; Application RW data (.data)
|
||||
|
||||
ARM_LIB_HEAP 0x80040000 EMPTY 0x00040000 ; Application heap
|
||||
{ }
|
||||
ZI_DATA +0
|
||||
{ * (+ZI) } ; Application ZI data (.bss)
|
||||
|
||||
ARM_LIB_STACK 0x80090000 EMPTY -0x00010000 ; Application (SVC mode) stack
|
||||
{ }
|
||||
ARM_LIB_HEAP 0x80040000 EMPTY 0x00040000 ; Application heap
|
||||
{ }
|
||||
|
||||
;IRQ_STACK 0x800A0000 EMPTY -0x00010000 ; IRQ mode stack
|
||||
;{ }
|
||||
ARM_LIB_STACK 0x80090000 EMPTY 0x00010000 ; Application (SVC mode) stack
|
||||
{ }
|
||||
|
||||
TTB 0x80100000 EMPTY 0x4000 ; Level-1 Translation Table for MMU
|
||||
{ }
|
||||
; IRQ_STACK 0x800A0000 EMPTY -0x00010000 ; IRQ mode stack
|
||||
; { }
|
||||
|
||||
TTB 0x80100000 EMPTY 0x4000 ; Level-1 Translation Table for MMU
|
||||
{ }
|
||||
}
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
//----------------------------------------------------------------
|
||||
// Cortex-A15 Embedded example - Startup Code
|
||||
// ARMv7-A Embedded example - Startup Code
|
||||
//
|
||||
// Copyright (c) 2005-2018 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
|
||||
// Standard definitions of mode bits and interrupt (I & F) flags in PSRs
|
||||
|
||||
#define Mode_USR 0x10
|
||||
#define Mode_FIQ 0x11
|
||||
#define Mode_IRQ 0x12
|
||||
#define Mode_SVC 0x13
|
||||
#define Mode_ABT 0x17
|
||||
#define Mode_UND 0x1B
|
||||
#define Mode_SYS 0x1F
|
||||
#define Mode_USR 0x10
|
||||
#define Mode_FIQ 0x11
|
||||
#define Mode_IRQ 0x12
|
||||
#define Mode_SVC 0x13
|
||||
#define Mode_ABT 0x17
|
||||
#define Mode_UND 0x1B
|
||||
#define Mode_SYS 0x1F
|
||||
|
||||
#define I_Bit 0x80 // When I bit is set, IRQ is disabled
|
||||
#define F_Bit 0x40 // When F bit is set, FIQ is disabled
|
||||
#define I_Bit 0x80 // When I bit is set, IRQ is disabled
|
||||
#define F_Bit 0x40 // When F bit is set, FIQ is disabled
|
||||
|
||||
|
||||
.section VECTORS, "ax"
|
||||
.align 3
|
||||
.cfi_sections .debug_frame // put stack frame info into .debug_frame instead of .eh_frame
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Entry point for the Reset handler
|
||||
//----------------------------------------------------------------
|
||||
@@ -48,29 +48,23 @@ Vectors:
|
||||
LDR PC, IRQ_Addr
|
||||
LDR PC, FIQ_Addr
|
||||
|
||||
|
||||
.balign 4
|
||||
Reset_Addr:
|
||||
.word Reset_Handler
|
||||
Undefined_Addr:
|
||||
//.word Undefined_Handler
|
||||
.word __tx_undefined
|
||||
SVC_Addr:
|
||||
//.word SVC_Handler
|
||||
.word __tx_swi_interrupt
|
||||
Prefetch_Addr:
|
||||
//.word Prefetch_Handler
|
||||
.word __tx_prefetch_handler
|
||||
Abort_Addr:
|
||||
//.word Abort_Handler
|
||||
.word __tx_abort_handler
|
||||
Hypervisor_Addr:
|
||||
//.word Hypervisor_Handler
|
||||
.word __tx_reserved_handler
|
||||
IRQ_Addr:
|
||||
//.word IRQ_Handler
|
||||
.word __tx_irq_handler
|
||||
FIQ_Addr:
|
||||
//.word FIQ_Handler
|
||||
.word __tx_fiq_handler
|
||||
|
||||
|
||||
@@ -100,26 +94,24 @@ FIQ_Handler:
|
||||
Reset_Handler:
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Disable caches, MMU and branch prediction in case they were left enabled from an earlier run
|
||||
// Disable caches and MMU in case they were left enabled from an earlier run
|
||||
// This does not need to be done from a cold reset
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
BIC r0, r0, #(0x1 << 12) // Clear I bit 12 to disable I Cache
|
||||
BIC r0, r0, #(0x1 << 2) // Clear C bit 2 to disable D Cache
|
||||
BIC r0, r0, #0x1 // Clear M bit 0 to disable MMU
|
||||
BIC r0, r0, #(0x1 << 11) // Clear Z bit 11 to disable branch prediction
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
BIC r0, r0, #(0x1 << 12) // Clear I bit 12 to disable I Cache
|
||||
BIC r0, r0, #(0x1 << 2) // Clear C bit 2 to disable D Cache
|
||||
BIC r0, r0, #0x1 // Clear M bit 0 to disable MMU
|
||||
BIC r0, r0, #(0x1 << 11) // Clear Z bit 11 to disable branch prediction
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
|
||||
// The MMU is enabled later, before calling main(). Caches and branch prediction are enabled inside main(),
|
||||
// The MMU is enabled later, before calling main(). Caches are enabled inside main(),
|
||||
// after the MMU has been enabled and scatterloading has been performed.
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// ACTLR.SMP bit must be set before the caches and MMU are enabled,
|
||||
// or any cache and TLB maintenance operations are performed, even for "AMP" CPUs.
|
||||
// In the Cortex-A15 processor, the L1 data cache and L2 cache are always coherent,
|
||||
// for shared or non-shared data, regardless of the value of the SMP bit.
|
||||
// ACTLR.SMP bit must be set before the caches and MMU are enabled,
|
||||
// or any cache and TLB maintenance operations are performed, even for single-core
|
||||
//----------------------------------------------------------------
|
||||
MRC p15, 0, r0, c1, c0, 1 // Read ACTLR
|
||||
ORR r0, r0, #(1 << 6) // Set ACTLR.SMP bit
|
||||
@@ -127,7 +119,7 @@ Reset_Handler:
|
||||
ISB
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Invalidate Data and Instruction TLBs and branch predictor in case they were left enabled from an earlier run
|
||||
// Invalidate Data and Instruction TLBs and branch predictor
|
||||
// This does not need to be done from a cold reset
|
||||
//----------------------------------------------------------------
|
||||
|
||||
@@ -170,8 +162,8 @@ notA15r0p0:
|
||||
MCR p15, 0, r0, c12, c0, 0
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Cache Invalidation code for Cortex-A15
|
||||
// NOTE: Neither Caches, nor MMU, nor BTB need post-reset invalidation on Cortex-A15,
|
||||
// Cache Invalidation code for ARMv7-A
|
||||
// The caches, MMU and BTB do not need post-reset invalidation on Cortex-A7,
|
||||
// but forcing a cache invalidation makes the code more portable to other CPUs (e.g. Cortex-A9)
|
||||
//----------------------------------------------------------------
|
||||
|
||||
@@ -190,7 +182,8 @@ notA15r0p0:
|
||||
BEQ Finished // If 0, no need to clean
|
||||
|
||||
MOV r10, #0 // R10 holds current cache level << 1
|
||||
Loop1: ADD r2, r10, r10, LSR #1 // R2 holds cache "Set" position
|
||||
Loop1:
|
||||
ADD r2, r10, r10, LSR #1 // R2 holds cache "Set" position
|
||||
MOV r1, r0, LSR r2 // Bottom 3 bits are the Cache-type for this level
|
||||
AND r1, r1, #7 // Isolate those lower 3 bits
|
||||
CMP r1, #2
|
||||
@@ -207,16 +200,19 @@ Loop1: ADD r2, r10, r10, LSR #1 // R2 holds cache "Set" position
|
||||
LDR r7, =0x7FFF
|
||||
ANDS r7, r7, r1, LSR #13 // R7 is the max number of the index size (right aligned)
|
||||
|
||||
Loop2: MOV r9, r4 // R9 working copy of the max way size (right aligned)
|
||||
Loop2:
|
||||
MOV r9, r4 // R9 working copy of the max way size (right aligned)
|
||||
|
||||
Loop3: ORR r11, r10, r9, LSL r5 // Factor in the Way number and cache number into R11
|
||||
Loop3:
|
||||
ORR r11, r10, r9, LSL r5 // Factor in the Way number and cache number into R11
|
||||
ORR r11, r11, r7, LSL r2 // Factor in the Set number
|
||||
MCR p15, 0, r11, c7, c6, 2 // Invalidate by Set/Way
|
||||
SUBS r9, r9, #1 // Decrement the Way number
|
||||
BGE Loop3
|
||||
SUBS r7, r7, #1 // Decrement the Set number
|
||||
BGE Loop2
|
||||
Skip: ADD r10, r10, #2 // Increment the cache number
|
||||
Skip:
|
||||
ADD r10, r10, #2 // Increment the cache number
|
||||
CMP r3, r10
|
||||
BGT Loop1
|
||||
|
||||
@@ -237,11 +233,13 @@ Finished:
|
||||
|
||||
// write the address of our page table base to TTB register 0
|
||||
LDR r0,=Image$$TTB$$ZI$$Base
|
||||
|
||||
MOV r1, #0x08 // RGN=b01 (outer cacheable write-back cached, write allocate)
|
||||
// S=0 (translation table walk to non-shared memory)
|
||||
ORR r1,r1,#0x40 // IRGN=b01 (inner cacheability for the translation table walk is Write-back Write-allocate)
|
||||
|
||||
ORR r0,r0,r1
|
||||
|
||||
MCR p15, 0, r0, c2, c0, 0
|
||||
|
||||
|
||||
@@ -259,7 +257,7 @@ Finished:
|
||||
// Bits[31:20] - Top 12 bits of VA is pointer into table
|
||||
// nG[17]=0 - Non global, enables matching against ASID in the TLB when set.
|
||||
// S[16]=0 - Indicates normal memory is shared when set.
|
||||
// AP2[15]=0
|
||||
// AP2[15]=0
|
||||
// AP[11:10]=11 - Configure for full read/write access in all modes
|
||||
// TEX[14:12]=000
|
||||
// CB[3:2]= 00 - Set attributes to Strongly-ordered memory.
|
||||
@@ -269,32 +267,32 @@ Finished:
|
||||
// XN[4]=1 - Execute never on Strongly-ordered memory
|
||||
// Bits[1:0]=10 - Indicate entry is a 1MB section
|
||||
//----------------------------------------------------------------
|
||||
LDR r0, =Image$$TTB$$ZI$$Base
|
||||
LDR r0,=Image$$TTB$$ZI$$Base
|
||||
LDR r1,=0xfff // loop counter
|
||||
LDR r2,=3554
|
||||
LDR r2,=0b00000000000000000000110111100010
|
||||
|
||||
// r0 contains the address of the translation table base
|
||||
// r1 is loop counter
|
||||
// r2 is level1 descriptor (bits 19:0)
|
||||
|
||||
// use loop counter to create 4096 individual table entries.
|
||||
// this writes from address 'Image$$TTB$$ZI$$Base' +
|
||||
// this writes from address 'Image$$TTB$$ZI$$Base' +
|
||||
// offset 0x3FFC down to offset 0x0 in word steps (4 bytes)
|
||||
|
||||
init_ttb_1:
|
||||
ORR r3, r2, r1, LSL#20 // R3 now contains full level1 descriptor to write
|
||||
ORR r3, r3, #16 // Set XN bit
|
||||
ORR r3, r3, #0b0000000010000 // Set XN bit
|
||||
STR r3, [r0, r1, LSL#2] // Str table entry at TTB base + loopcount*4
|
||||
SUBS r1, r1, #1 // Decrement loop counter
|
||||
BPL init_ttb_1
|
||||
|
||||
// In this example, the 1MB section based at 'Image$$VECTORS$$Base' is setup specially as cacheable (write back mode).
|
||||
// In this example, the 1MB section based at '__code_start' is setup specially as cacheable (write back mode).
|
||||
// TEX[14:12]=001 and CB[3:2]= 11, Outer and inner write back, write allocate normal memory.
|
||||
LDR r1, =Image$$VECTORS$$Base // Base physical address of code segment
|
||||
LDR r1,=Image$$VECTORS$$Base // Base physical address of code segment
|
||||
LSR r1, #20 // Shift right to align to 1MB boundaries
|
||||
ORR r3, r2, r1, LSL#20 // Setup the initial level1 descriptor again
|
||||
ORR r3, r3, #12 // Set CB bits
|
||||
ORR r3, r3, #4096 // Set TEX bit 12
|
||||
ORR r3, r3, #0b0000000001100 // Set CB bits
|
||||
ORR r3, r3, #0b1000000000000 // Set TEX bit 12
|
||||
STR r3, [r0, r1, LSL#2] // str table entry
|
||||
|
||||
//----------------------------------------------------------------
|
||||
@@ -306,7 +304,6 @@ init_ttb_1:
|
||||
MCR p15, 0, r0, c3, c0, 0 // Write Domain Access Control Register
|
||||
|
||||
#if defined(__ARM_NEON) || defined(__ARM_FP)
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Enable access to NEON/VFP by enabling access to Coprocessors 10 and 11.
|
||||
// Enables Full Access i.e. in both privileged and non privileged modes
|
||||
@@ -325,15 +322,14 @@ init_ttb_1:
|
||||
VMSR FPEXC, r0 // Write FPEXC register, EN bit set
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Enable MMU and branch to __main
|
||||
// Leaving the caches disabled until after scatter loading.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
LDR r12,=__main // Save this in register for possible long jump
|
||||
LDR r12,=__main
|
||||
|
||||
#if 0
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
BIC r0, r0, #(0x1 << 12) // Clear I bit 12 to disable I Cache
|
||||
BIC r0, r0, #(0x1 << 2) // Clear C bit 2 to disable D Cache
|
||||
@@ -341,7 +337,6 @@ init_ttb_1:
|
||||
ORR r0, r0, #0x1 // Set M bit 0 to enable MMU before scatter loading
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
#endif
|
||||
|
||||
// Now the MMU is enabled, virtual to physical address translations will occur. This will affect the next
|
||||
// instruction fetch.
|
||||
@@ -350,7 +345,7 @@ init_ttb_1:
|
||||
// The branch to __main is safe because the Virtual Address (VA) is the same as the Physical Address (PA)
|
||||
// (flat mapping) of this code that enables the MMU and performs the branch
|
||||
|
||||
BX r12 // Branch to __main C library entry point
|
||||
BX r12 // Branch to __main C library entry point
|
||||
|
||||
|
||||
|
||||
@@ -378,7 +373,25 @@ enable_caches:
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
|
||||
BX lr
|
||||
MRC p15, 0, r0, c1, c0, 1 // Read Auxiliary Control Register
|
||||
ORR r0, #2 // L2EN bit, enable L2 cache
|
||||
ORR r0, r0, #(0x1 << 2) // Set DP bit 2 to enable L1 Dside prefetch
|
||||
MCR p15, 0, r0, c1, c0, 1 // Write Auxiliary Control Register
|
||||
ISB
|
||||
|
||||
BX lr
|
||||
.cfi_endproc
|
||||
|
||||
.global disable_caches
|
||||
.type disable_caches, "function"
|
||||
disable_caches:
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
BIC r0, r0, #(0x1 << 12) // Clear I bit 12 to disable I Cache
|
||||
BIC r0, r0, #(0x1 << 2) // Clear C bit 2 to disable D Cache
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
|
||||
BX lr
|
||||
|
||||
|
||||
|
||||
@@ -1,345 +1,299 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* 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
|
||||
.global _tx_thread_context_restore
|
||||
.global _tx_timer_interrupt
|
||||
|
||||
@
|
||||
@
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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, =Image$$ARM_LIB_STACK$$ZI$$Limit @ 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, =Image$$ARM_LIB_STACK$$ZI$$Limit // 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, =Image$$ARM_LIB_STACK$$Base @ 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, =Image$$ZI_DATA$$ZI$$Limit @ 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, =Image$$ARM_LIB_STACK$$Base // 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, =Image$$ZI_DATA$$ZI$$Limit // 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
|
||||
@
|
||||
.global __tx_irq_processing_return
|
||||
B __tx_reserved_handler // Reserved exception handler
|
||||
|
||||
.global __tx_irq_processing_return
|
||||
.type __tx_irq_processing_return,function
|
||||
.global __tx_irq_handler
|
||||
.global __tx_irq_handler
|
||||
__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. */
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* Jump to context restore to restore system context. */
|
||||
|
||||
#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
|
||||
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.lib.debug.base.115793157">
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.lib.debug.base.934844632">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.debug.base.115793157" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.debug.base.934844632" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
@@ -23,37 +23,37 @@
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.lib.debug.base.115793157" name="Debug" parent="com.arm.eclipse.build.config.v6.lib.debug.base">
|
||||
<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.lib.debug.base.934844632" name="Debug" parent="com.arm.eclipse.build.config.v6.lib.debug.base">
|
||||
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.lib.debug.base.115793157." name="/" resourcePath="">
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.lib.debug.base.934844632." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1542210244" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6">
|
||||
<toolChain id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1304206628" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.1043361309" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-A15.NoFPU" valueType="string"/>
|
||||
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.934944269" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" value="Cortex-A15.NoFPU" valueType="string"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.floatabi.159331044" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
<option id="com.arm.toolchain.v6.base.options.floatabi.363048496" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.inst.1207111466" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
<option id="com.arm.toolchain.v6.base.options.inst.1780343986" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.debug.level.1676142430" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" useByScannerDiscovery="false" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
<option id="com.arm.toolchain.v6.base.options.debug.level.1864778484" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<targetPlatform id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1542210244.686945374" name=""/>
|
||||
<targetPlatform id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1304206628.377253723" name=""/>
|
||||
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/tx}/Debug" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.37587106" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="8" superClass="com.arm.toolchain.v6.builder"/>
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/tx}/Debug" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.15498832" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="8" superClass="com.arm.toolchain.v6.builder"/>
|
||||
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.471110708" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.1220788691" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.target.671970" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="arm-arm-none-eabi" valueType="string"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.target.2070983899" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.453165343" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-a15" valueType="string"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.1346103117" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-a7" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.fpu.1695873808" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.fpu.90247954" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.1877405688" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.c.compiler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.1142506275" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.c.compiler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.inst.1105089347" name="Instruction set" superClass="com.arm.tool.c.compiler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.inst.977911686" name="Instruction set" superClass="com.arm.tool.c.compiler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.compiler.v6.base.option.incpath.528439459" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.compiler.v6.base.option.incpath.1425313179" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc_generic}""/>
|
||||
|
||||
@@ -61,39 +61,39 @@
|
||||
|
||||
</option>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.843334238" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.1440291498" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1337235665" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1880232756" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.2017310235" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.514805588" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.587943874" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.115990951" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.1548968340" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.962352112" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.target.307531555" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" useByScannerDiscovery="false" value="arm-arm-none-eabi" valueType="string"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.target.1068198178" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" useByScannerDiscovery="false" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.cpu.318635999" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-a15" valueType="string"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.cpu.452335018" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-a7" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.fpu.603753703" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.fpu.1016536584" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.floatabi.1482685231" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.assembler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.floatabi.930478556" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.assembler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.inst.2025279024" name="Instruction set" superClass="com.arm.tool.assembler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.inst.896699076" name="Instruction set" superClass="com.arm.tool.assembler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.options.debug.level.361295991" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" value="com.arm.tool.assembler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.options.debug.level.1163443645" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" value="com.arm.tool.assembler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.303789605" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.1702147376" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.1281582449" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6"/>
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.149261228" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.1707598424" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.1983404149" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="tx.com.arm.eclipse.build.project.v6.lib.1408735755" name="Static Library"/>
|
||||
<project id="tx.com.arm.eclipse.build.project.v6.lib.1435017208" name="Static Library"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
@@ -123,6 +123,10 @@
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="com.arm.projectSettings" version="6.0.0"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
|
||||
<configuration configurationName="Debug">
|
||||
@@ -138,9 +142,5 @@
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="com.arm.projectSettings" version="6.0.0"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
</cproject>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Port Specific */
|
||||
@@ -21,36 +21,41 @@
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h Cortex-A15/AC6 */
|
||||
/* 6.1.6 */
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h ARMv7-A */
|
||||
/* 6.1.12 */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* 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 */
|
||||
/* 07-29-2022 Scott Larson Updated comments, removed */
|
||||
/* unneeded temp variable, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -63,7 +68,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 +81,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 +117,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 +132,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 +180,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 +192,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 +212,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 +224,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 +252,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. */
|
||||
@@ -282,7 +287,7 @@ unsigned int _tx_thread_interrupt_restore(UINT old_posture);
|
||||
|
||||
#else
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save, tx_temp;
|
||||
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_DISABLE asm volatile (" MRS %0,CPSR; CPSID if ": "=r" (interrupt_save) );
|
||||
@@ -295,7 +300,7 @@ unsigned int _tx_thread_interrupt_restore(UINT old_posture);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define VFP extension for the Cortex-A15. 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 +320,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-A15/AC6 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,259 +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
|
||||
@
|
||||
@
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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,205 +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
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_save
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
|
||||
|
||||
/* 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-A15/AC6 */
|
||||
@/* 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
|
||||
@@ -45,218 +34,190 @@ IRQ_MODE_BITS = 0x12 @ IRQ mode bits
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_thread_schedule
|
||||
.global _tx_thread_preempt_disable
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_restore
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_fiq_context_restore Cortex-A15/AC6 */
|
||||
@/* 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,206 +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
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_save
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_fiq_context_save Cortex-A15/AC6 */
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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,257 +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
|
||||
@
|
||||
@
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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-A15 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,182 +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
|
||||
@
|
||||
@
|
||||
@
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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,192 +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
|
||||
@
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_vectored_context_save
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.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. */
|
||||
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_vectored_context_save Cortex-A15/AC6 */
|
||||
@/* 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-A15/AC6 */
|
||||
@/* 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
|
||||
|
||||
@@ -2,5 +2,5 @@ arm-none-eabi-gcc -c -g -mcpu=cortex-a15 reset.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a15 crt0.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a15 tx_initialize_low_level.S
|
||||
arm-none-eabi-gcc -c -g -mcpu=cortex-a15 -I../../../../common/inc -I../inc sample_threadx.c
|
||||
arm-none-eabi-ld -A cortex-a15 -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-a15 -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);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user