From 455aba3676cefd984bc3b1b46df5c3b47610a345 Mon Sep 17 00:00:00 2001 From: Yilin Sun Date: Sun, 11 Feb 2024 21:03:38 +0800 Subject: [PATCH] Initial ThreadX support. Signed-off-by: Yilin Sun --- .gitmodules | 3 + CMakeLists.txt | 9 +- SDK | 1 + include/app_init.h | 9 ++ include/tx_user.h | 319 +++++++++++++++++++++++++++++++++++++++++++++ lib/threadx | 1 + src/app_init.c | 16 +++ src/main.c | 44 ++++++- 8 files changed, 396 insertions(+), 6 deletions(-) create mode 160000 SDK create mode 100644 include/app_init.h create mode 100644 include/tx_user.h create mode 160000 lib/threadx create mode 100644 src/app_init.c diff --git a/.gitmodules b/.gitmodules index e169242..bfa4e73 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "SDK"] path = SDK url = https://git.minori.work/Embedded_SDK/MCUXpresso_MCXA153.git +[submodule "lib/threadx"] + path = lib/threadx + url = https://github.com/eclipse-threadx/threadx.git diff --git a/CMakeLists.txt b/CMakeLists.txt index b19bbac..beb61c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) -project(mcxa153_template) +project(mcxa153_threadx) enable_language(CXX) enable_language(ASM) @@ -59,6 +59,7 @@ set(TARGET_SOURCES "board/clock_config.c" "board/peripherals.c" "board/pin_mux.c" + "src/app_init.c" "src/main.c" ) @@ -84,6 +85,7 @@ set(TARGET_C_INCLUDES # Shared libraries linked with application set(TARGET_LIBS + "threadx" "c" "m" "nosys" @@ -111,6 +113,11 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-common -fno-builtin -f set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") +set(THREADX_ARCH "cortex_m33" CACHE STRING "") +set(THREADX_TOOLCHAIN "gnu" CACHE STRING "") +set(TX_USER_FILE "${CMAKE_CURRENT_SOURCE_DIR}/include/tx_user.h" CACHE STRING "") +add_subdirectory(lib/threadx) + # Shared sources, includes and definitions add_compile_definitions(${TARGET_C_DEFINES}) include_directories(${TARGET_C_INCLUDES}) diff --git a/SDK b/SDK new file mode 160000 index 0000000..35e6783 --- /dev/null +++ b/SDK @@ -0,0 +1 @@ +Subproject commit 35e678394aa4065fadbecb3eeba701552d955ced diff --git a/include/app_init.h b/include/app_init.h new file mode 100644 index 0000000..96a2968 --- /dev/null +++ b/include/app_init.h @@ -0,0 +1,9 @@ +#ifndef APP_INIT_H +#define APP_INIT_H + +#include "tx_api.h" + +extern TX_THREAD app_init_thread_id; +void app_init_thread(ULONG thread_input); + +#endif // APP_INIT_H \ No newline at end of file diff --git a/include/tx_user.h b/include/tx_user.h new file mode 100644 index 0000000..e1daa63 --- /dev/null +++ b/include/tx_user.h @@ -0,0 +1,319 @@ +/**************************************************************************/ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** User Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_user.h PORTABLE C */ +/* 6.3.0 */ +/* */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains user defines for configuring ThreadX in specific */ +/* ways. This file will have an effect only if the application and */ +/* ThreadX library are built with TX_INCLUDE_USER_DEFINE_FILE defined. */ +/* Note that all the defines in this file may also be made on the */ +/* command line when building ThreadX library and application objects. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 William E. Lamie Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* 03-02-2021 Scott Larson Modified comment(s), */ +/* added option to remove */ +/* FileX pointer, */ +/* resulting in version 6.1.5 */ +/* 06-02-2021 Scott Larson Added options for multiple */ +/* block pool search & delay, */ +/* resulting in version 6.1.7 */ +/* 10-15-2021 Yuxin Zhou Modified comment(s), added */ +/* 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 */ +/* 10-31-2023 Xiuwen Cai Modified comment(s), */ +/* added option for random */ +/* number stack filling, */ +/* resulting in version 6.3.0 */ +/* */ +/**************************************************************************/ + +#ifndef TX_USER_H +#define TX_USER_H + + +/* Define various build options for the ThreadX port. The application should either make changes + here by commenting or un-commenting the conditional compilation defined OR supply the defines + though the compiler's equivalent of the -D option. + + For maximum speed, the following should be defined: + + TX_MAX_PRIORITIES 32 + TX_DISABLE_PREEMPTION_THRESHOLD + TX_DISABLE_REDUNDANT_CLEARING + TX_DISABLE_NOTIFY_CALLBACKS + TX_NOT_INTERRUPTABLE + TX_TIMER_PROCESS_IN_ISR + TX_REACTIVATE_INLINE + TX_DISABLE_STACK_FILLING + TX_INLINE_THREAD_RESUME_SUSPEND + + For minimum size, the following should be defined: + + TX_MAX_PRIORITIES 32 + TX_DISABLE_PREEMPTION_THRESHOLD + TX_DISABLE_REDUNDANT_CLEARING + TX_DISABLE_NOTIFY_CALLBACKS + TX_NO_FILEX_POINTER + TX_NOT_INTERRUPTABLE + TX_TIMER_PROCESS_IN_ISR + + Of course, many of these defines reduce functionality and/or change the behavior of the + system in ways that may not be worth the trade-off. For example, the TX_TIMER_PROCESS_IN_ISR + results in faster and smaller code, however, it increases the amount of processing in the ISR. + In addition, some services that are available in timers are not available from ISRs and will + therefore return an error if this option is used. This may or may not be desirable for a + given application. */ + + +/* Override various options with default values already assigned in tx_port.h. Please also refer + to tx_port.h for descriptions on each of these options. */ + +/* +#define TX_MAX_PRIORITIES 32 +#define TX_MINIMUM_STACK ???? +#define TX_THREAD_USER_EXTENSION ???? +#define TX_TIMER_THREAD_STACK_SIZE ???? +#define TX_TIMER_THREAD_PRIORITY ???? +*/ + +/* Define the common timer tick reference for use by other middleware components. The default + value is 10ms (i.e. 100 ticks, defined in tx_api.h), but may be replaced by a port-specific + version in tx_port.h or here. + Note: the actual hardware timer value may need to be changed (usually in tx_initialize_low_level). */ + + +#define TX_TIMER_TICKS_PER_SECOND (1000UL) + + +/* Determine if there is a FileX pointer in the thread control block. + By default, the pointer is there for legacy/backwards compatibility. + The pointer must also be there for applications using FileX. + Define this to save space in the thread control block. +*/ + +/* +#define TX_NO_FILEX_POINTER +*/ + +/* Determine if timer expirations (application timers, timeouts, and tx_thread_sleep calls + should be processed within the a system timer thread or directly in the timer ISR. + By default, the timer thread is used. When the following is defined, the timer expiration + processing is done directly from the timer ISR, thereby eliminating the timer thread control + block, stack, and context switching to activate it. */ + +/* +#define TX_TIMER_PROCESS_IN_ISR +*/ + +/* Determine if in-line timer reactivation should be used within the timer expiration processing. + By default, this is disabled and a function call is used. When the following is defined, + reactivating is performed in-line resulting in faster timer processing but slightly larger + code size. */ + +/* +#define TX_REACTIVATE_INLINE +*/ + +/* Determine is stack filling is enabled. By default, ThreadX stack filling is enabled, + which places an 0xEF pattern in each byte of each thread's stack. This is used by + debuggers with ThreadX-awareness and by the ThreadX run-time stack checking feature. */ + +/* +#define TX_DISABLE_STACK_FILLING +*/ + +/* 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. */ + +/* +#define TX_ENABLE_STACK_CHECKING +*/ + +/* Determine if random number is used for stack filling. By default, ThreadX uses a fixed + pattern for stack filling. When the following is defined, ThreadX uses a random number + for stack filling. This is effective only when TX_ENABLE_STACK_CHECKING is defined. */ + +/* +#define TX_ENABLE_RANDOM_NUMBER_STACK_FILLING +*/ + +/* Determine if preemption-threshold should be disabled. By default, preemption-threshold is + enabled. If the application does not use preemption-threshold, it may be disabled to reduce + code size and improve performance. */ + +/* +#define TX_DISABLE_PREEMPTION_THRESHOLD +*/ + +/* Determine if global ThreadX variables should be cleared. If the compiler startup code clears + the .bss section prior to ThreadX running, the define can be used to eliminate unnecessary + clearing of ThreadX global variables. */ + +/* +#define TX_DISABLE_REDUNDANT_CLEARING +*/ + +/* Determine if no timer processing is required. This option will help eliminate the timer + processing when not needed. The user will also have to comment out the call to + tx_timer_interrupt, which is typically made from assembly language in + tx_initialize_low_level. Note: if TX_NO_TIMER is used, the define TX_TIMER_PROCESS_IN_ISR + must also be used and tx_timer_initialize must be removed from ThreadX library. */ + +/* +#define TX_NO_TIMER +#ifndef TX_TIMER_PROCESS_IN_ISR +#define TX_TIMER_PROCESS_IN_ISR +#endif +*/ + +/* Determine if the notify callback option should be disabled. By default, notify callbacks are + enabled. If the application does not use notify callbacks, they may be disabled to reduce + code size and improve performance. */ + +/* +#define TX_DISABLE_NOTIFY_CALLBACKS +*/ + + +/* Determine if the tx_thread_resume and tx_thread_suspend services should have their internal + code in-line. This results in a larger image, but improves the performance of the thread + resume and suspend services. */ + +/* +#define TX_INLINE_THREAD_RESUME_SUSPEND +*/ + + +/* Determine if the internal ThreadX code is non-interruptable. This results in smaller code + size and less processing overhead, but increases the interrupt lockout time. */ + +/* +#define TX_NOT_INTERRUPTABLE +*/ + + +/* Determine if the trace event logging code should be enabled. This causes slight increases in + code size and overhead, but provides the ability to generate system trace information which + is available for viewing in TraceX. */ + +/* +#define TX_ENABLE_EVENT_TRACE +*/ + + +/* Determine if block pool performance gathering is required by the application. When the following is + defined, ThreadX gathers various block pool performance information. */ + +/* +#define TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if byte pool performance gathering is required by the application. When the following is + defined, ThreadX gathers various byte pool performance information. */ + +/* +#define TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if event flags performance gathering is required by the application. When the following is + defined, ThreadX gathers various event flags performance information. */ + +/* +#define TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if mutex performance gathering is required by the application. When the following is + defined, ThreadX gathers various mutex performance information. */ + +/* +#define TX_MUTEX_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if queue performance gathering is required by the application. When the following is + defined, ThreadX gathers various queue performance information. */ + +/* +#define TX_QUEUE_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if semaphore performance gathering is required by the application. When the following is + defined, ThreadX gathers various semaphore performance information. */ + +/* +#define TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if thread performance gathering is required by the application. When the following is + defined, ThreadX gathers various thread performance information. */ + +/* +#define TX_THREAD_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if timer performance gathering is required by the application. When the following is + defined, ThreadX gathers various timer performance information. */ + +/* +#define TX_TIMER_ENABLE_PERFORMANCE_INFO +*/ + +/* Override options for byte pool searches of multiple blocks. */ + +/* +#define TX_BYTE_POOL_MULTIPLE_BLOCK_SEARCH 20 +*/ + +/* Override options for byte pool search delay to avoid thrashing. */ + +/* +#define TX_BYTE_POOL_DELAY_VALUE 3 +*/ + +#define TX_SINGLE_MODE_NON_SECURE (1) + +#endif diff --git a/lib/threadx b/lib/threadx new file mode 160000 index 0000000..35fba3c --- /dev/null +++ b/lib/threadx @@ -0,0 +1 @@ +Subproject commit 35fba3cfb266c629eadc3e533edf4d902041b05a diff --git a/src/app_init.c b/src/app_init.c new file mode 100644 index 0000000..0a6308f --- /dev/null +++ b/src/app_init.c @@ -0,0 +1,16 @@ +/* Board */ +#include "pin_mux.h" + +/* SDK drivers */ +#include "fsl_gpio.h" + +/* App */ +#include "app_init.h" + +TX_THREAD app_init_thread_id; +void app_init_thread(ULONG thread_input) { + for (;;) { + GPIO_PortToggle(BOARD_INITLEDPINS_LED_R_GPIO, BOARD_INITLEDPINS_LED_R_PIN_MASK); + tx_thread_sleep(1000); + } +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index e3bb43d..14cbfc4 100644 --- a/src/main.c +++ b/src/main.c @@ -1,11 +1,46 @@ -#include - /* Board */ #include "board.h" #include "clock_config.h" #include "peripherals.h" #include "pin_mux.h" +/* ThreadX */ +#include "tx_api.h" + +/* App */ +#include "app_init.h" + +extern void *__HeapLimit; +extern void *_tx_initialize_unused_memory; + +extern void _tx_timer_interrupt(void); + +void tx_application_define(void *first_unused_memory) { + tx_thread_create(&app_init_thread_id, "INIT", app_init_thread, 0, first_unused_memory, 1024, 3, 3, TX_NO_TIME_SLICE, + TX_AUTO_START); +} + +void _tx_initialize_low_level(void) { + const uint32_t primask = DisableGlobalIRQ(); + + _tx_initialize_unused_memory = (void *)&__HeapLimit; + + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + + SysTick_Config(CLOCK_GetCoreSysClkFreq() / TX_TIMER_TICKS_PER_SECOND); + + NVIC_SetPriority(SVCall_IRQn, 7); + NVIC_SetPriority(PendSV_IRQn, 7); + + NVIC_SetPriority(SysTick_IRQn, 6); + + EnableGlobalIRQ(primask); +} + +void SysTick_Handler(void) { + _tx_timer_interrupt(); +} + int main(void) { BOARD_InitBootPins(); BOARD_InitBootClocks(); @@ -13,10 +48,9 @@ int main(void) { BOARD_InitDebugConsole(); - printf("Hello world.\r\n"); + tx_kernel_enter(); for (;;) { - GPIO_PortToggle(BOARD_INITLEDPINS_LED_R_GPIO,BOARD_INITLEDPINS_LED_R_GPIO_PIN_MASK); - SDK_DelayAtLeastUs(500 * 1000, CLOCK_GetCoreSysClkFreq()); + __WFI(); } }