前言
- 先让threadx在板子上跑起来再说;
- 使用的芯片stm32f407zgt6
- 开发环境使用的是clion+cubemx
- 编译使用的是arm-none-gcc
实现效果
- 定时打印输出
- 添加threadx的cpu扩展工具,打印threadx任务相关信息
测试代码
相关宏定义
#define TX_CONV_STACK_SIZE(size) ((((UINT) size)+((sizeof(ULONG)) - ((UINT) 1)))/sizeof(ULONG))
main入口函数
/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-4-4 shchl first version
*/
#include "includes.h"
int main() {
/*系统初始化*/
System_Init();
/*外设初始化*/
bsp_Init();
/*进入threadx 内核*/
tx_kernel_enter();
while (1) {
printf("app run\r\n");
HAL_Delay(1000);
}
return 0;
}
threadx 切入点函数(这里使用了tx里面的一个宏定义去初始化通信变量)
/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-4-4 shchl first version
*
*
* tx_kernel_enter() 执行逻辑(关键)
* TX_PORT_SPECIFIC_PRE_INITIALIZATION----可扩展
* _tx_initialize_low_level() --- 设备层(寄存器)初始化
* _tx_initialize_high_level() --- tx os 内部相关初始化
* TX_INITIALIZE_KERNEL_ENTER_EXTENSION----可扩展
* tx_application_define(_tx_initialize_unused_memory);
* TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION ---可扩展
*
*/
#include "includes.h"
//#define USE_THREADX_BYTE_POOL
//#define USE_FILEX_BYTE_POOL
//#define USE_FILEX_BYTE_POOL
/*
*******************************************************************************************************
* 外部引入变量
*******************************************************************************************************
*/
/*
*******************************************************************************************************
* 变量
*******************************************************************************************************
*/
TX_MUTEX AppPrintfSemp; /* 用于printf互斥 */
/*
*********************************************************************************************************
* 静态全局变量
*********************************************************************************************************
*/
#ifdef USE_THREADX_BYTE_POOL
/* USER CODE BEGIN TX_Pool_Buffer */
/* USER CODE END TX_Pool_Buffer */
static UCHAR tx_byte_pool_buffer[TX_APP_MEM_POOL_SIZE];
static TX_BYTE_POOL tx_app_byte_pool;
#endif
#ifdef USE_FILEX_BYTE_POOL
/* USER CODE BEGIN FX_Pool_Buffer */
/* USER CODE END FX_Pool_Buffer */
static UCHAR fx_byte_pool_buffer[FX_APP_MEM_POOL_SIZE];
static TX_BYTE_POOL fx_app_byte_pool;
#endif
#ifdef USE_FILEX_BYTE_POOL
/* USER CODE BEGIN NX_Pool_Buffer */
/* USER CODE END NX_Pool_Buffer */
static UCHAR nx_byte_pool_buffer[NX_APP_MEM_POOL_SIZE];
static TX_BYTE_POOL nx_app_byte_pool;
#endif
/*
*********************************************************************************************************
* 函数声明
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 外部函数
*********************************************************************************************************
*/
/**
* @brief 此函数 被宏定义 TX_INITIALIZE_KERNEL_ENTER_EXTENSION 引用
*/
void tx_initialize_kernel_enter_extension() {
/* 创建互斥信号量 */
tx_mutex_create(&AppPrintfSemp, "AppPrintfSemp", TX_NO_INHERIT);
}
/**
* @brief 应用组件定义初始化
* @param first_unused_memory : Pointer to the first unused memory
* @retval None
*/
VOID tx_application_define(VOID *first_unused_memory) {
(void *) first_unused_memory;
VOID *memory_ptr;
#ifdef USE_THREADX_BYTE_POOL
if (tx_byte_pool_create(&tx_app_byte_pool, "Tx App memory pool", tx_byte_pool_buffer, TX_APP_MEM_POOL_SIZE) !=
TX_SUCCESS) {
/* USER CODE BEGIN TX_Byte_Pool_Error */
/* USER CODE END TX_Byte_Pool_Error */
} else {
/* USER CODE BEGIN TX_Byte_Pool_Success */
/* USER CODE END TX_Byte_Pool_Success */
memory_ptr = (VOID *) &tx_app_byte_pool;
if (App_ThreadX_Init(memory_ptr) != TX_SUCCESS) {
/* USER CODE BEGIN App_ThreadX_Init_Error */
/* USER CODE END App_ThreadX_Init_Error */
}
/* USER CODE BEGIN App_ThreadX_Init_Success */
/* USER CODE END App_ThreadX_Init_Success */
}
#else
if (App_ThreadX_Init(TX_NULL) != TX_SUCCESS) {
/* USER CODE BEGIN App_ThreadX_Init_Error */
/* USER CODE END App_ThreadX_Init_Error */
}
#endif
#ifdef USE_FILEX_BYTE_POOL
if (tx_byte_pool_create(&fx_app_byte_pool, "Fx App memory pool", fx_byte_pool_buffer, FX_APP_MEM_POOL_SIZE) !=
TX_SUCCESS) {
/* USER CODE BEGIN FX_Byte_Pool_Error */
/* USER CODE END FX_Byte_Pool_Error */
} else {
/* USER CODE BEGIN FX_Byte_Pool_Success */
/* USER CODE END FX_Byte_Pool_Success */
memory_ptr = (VOID *) &fx_app_byte_pool;
if (MX_FileX_Init(memory_ptr) != FX_SUCCESS) {
/* USER CODE BEGIN MX_FileX_Init_Error */
/* USER CODE END MX_FileX_Init_Error */
}
/* USER CODE BEGIN MX_FileX_Init_Success */
/* USER CODE END MX_FileX_Init_Success */
}
#else
// if (MX_FileX_Init(TX_NULL) != FX_SUCCESS) {
// /* USER CODE BEGIN MX_FileX_Init_Error */
//
// /* USER CODE END MX_FileX_Init_Error */
// }
#endif
#ifdef USE_FILEX_BYTE_POOL
if (tx_byte_pool_create(&nx_app_byte_pool, "Nx App memory pool", nx_byte_pool_buffer, NX_APP_MEM_POOL_SIZE) !=
TX_SUCCESS) {
/* USER CODE BEGIN NX_Byte_Pool_Error */
/* USER CODE END NX_Byte_Pool_Error */
} else {
/* USER CODE BEGIN TX_Byte_Pool_Success */
/* USER CODE END TX_Byte_Pool_Success */
memory_ptr = (VOID *) &nx_app_byte_pool;
if (MX_NetXDuo_Init(memory_ptr) != NX_SUCCESS) {
/* USER CODE BEGIN MX_NetXDuo_Init_Error */
/* USER CODE END MX_NetXDuo_Init_Error */
}
}
#else
// if (MX_NetXDuo_Init(TX_NULL) != NX_SUCCESS) {
// /* USER CODE BEGIN MX_NetXDuo_Init_Error */
//
// /* USER CODE END MX_NetXDuo_Init_Error */
// }
#endif
}
/*
*********************************************************************************************************
* 内部函数
*********************************************************************************************************
*/
threadx里面的日志打印封装(简单加入互斥量)
/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-4-4 shchl first version
*/
#include "includes.h"
/*
*******************************************************************************************************
* 外部引入变量
*******************************************************************************************************
*/
extern TX_MUTEX AppPrintfSemp; /* 用于printf互斥 */
/*
*******************************************************************************************************
* 变量
*******************************************************************************************************
*/
/*
*********************************************************************************************************
* 静态全局变量
*********************************************************************************************************
*/
static char buf_str[TX_LOG_BUF_SZ] = {0}; /* 特别注意,如果printf的变量较多,注意此局部变量的大小是否够用 */
/*
*********************************************************************************************************
* 函数声明
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 外部函数
*********************************************************************************************************
*/
void tx_log(const char *fmt, ...) {
va_list v_args;
va_start(v_args, fmt);
int len = vsnprintf((char *) &buf_str[0],
(size_t) sizeof(buf_str),
(char const *) fmt,
v_args);
va_end(v_args);
/* 互斥操作 */
tx_mutex_get(&AppPrintfSemp, TX_WAIT_FOREVER);
if (len > TX_LOG_BUF_SZ - 1) {
len = TX_LOG_BUF_SZ - 1;
}
buf_str[len] = '\0';
printf("%s", buf_str);
tx_mutex_put(&AppPrintfSemp);
}
void tx_log_no_mutex(const char *fmt, ...) {
va_list v_args;
va_start(v_args, fmt);
(void) vsnprintf((char *) &buf_str[0],
(size_t) sizeof(buf_str),
(char const *) fmt,
v_args);
va_end(v_args);
/* 互斥操作 */
printf("%s", buf_str);
}
应用函数源文件
/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-4-4 shchl first version
*
*
* tx_kernel_enter() 执行逻辑(关键)
* TX_PORT_SPECIFIC_PRE_INITIALIZATION----可扩展
* _tx_initialize_low_level() --- 设备层(寄存器)初始化
* _tx_initialize_high_level() --- tx os 内部相关初始化
* TX_INITIALIZE_KERNEL_ENTER_EXTENSION----可扩展
* tx_application_define(_tx_initialize_unused_memory);
* TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION ---可扩展
*
*/
#include "includes.h"
/*
*******************************************************************************************************
* 外部引入变量
*******************************************************************************************************
*/
/*
*******************************************************************************************************
* 变量
*******************************************************************************************************
*/
/*
*********************************************************************************************************
* 静态全局变量
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 函数声明
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 外部函数
*********************************************************************************************************
*/
/**
* @brief Application ThreadX Initialization.
* @param memory_ptr: 内存指针 (如果是静态分配的话,内存地址指针是为NULL)
* @note 开启动态分配内存,在汇编文件【tx_initialize_low_level.s】中开启宏定义 USE_DYNAMIC_MEMORY_ALLOCATION
* @retval int
*/
UINT App_ThreadX_Init(VOID *memory_ptr) {
UINT ret = TX_SUCCESS;
TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL *) memory_ptr;
(void) byte_pool;
/**************创建启动任务*********************/
/*线程创建模板*/
#define APP_THREAD_STACK_SIZE 4096
#define APP_THREAD_PRIORITY 10
VOID _app_printf_entity(ULONG timer_thread_input);
static ULONG _app_thread_stack_area[TX_CONV_STACK_SIZE(APP_THREAD_STACK_SIZE)];
static TX_THREAD _app_print_thread;
ULONG *stack_start = _app_thread_stack_area;
ULONG stack_size = APP_THREAD_STACK_SIZE;
ULONG priority = APP_THREAD_PRIORITY;
tx_thread_create(&_app_print_thread, /* 任务控制块地址 */
"App Task Start", /* 任务名 */
_app_printf_entity, /* 启动任务函数地址 */
0, /* 传递给任务的参数 */
stack_start, /* 堆栈基地址 */
stack_size, /* 堆栈空间大小 */
priority, /* 任务优先级*/
priority, /* 任务抢占阀值 */
TX_NO_TIME_SLICE, /* 不开启时间片 */
TX_AUTO_START); /* 创建后立即启动 */
return ret;
}
/*
*********************************************************************************************************
* 内部函数
*********************************************************************************************************
*/
VOID _app_printf_entity(ULONG timer_thread_input) {
while (TX_LOOP_FOREVER) {
/*函数打印进行封装,加入互斥量*/
tx_log("hello threadx,current thread name:%s\r\n", tx_thread_identify()->tx_thread_name);
tx_thread_sleep(1000);
}
}
测试结果
加入threadx扩展工具代码(用于cpu利用率)
- 自己实现参考安富莱论坛
CMakeLists中添加对应的工具代码文件
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
cmake_minimum_required(VERSION 3.27)
# specify cross-compilers and tools
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_AR arm-none-eabi-ar)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_OBJDUMP arm-none-eabi-objdump)
set(SIZE arm-none-eabi-size)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
# project settings
project(app_threadx C CXX ASM)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)
SET(CMAKE_C_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "c debug compiler flags")
SET(CMAKE_CXX_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "cxx debug compiler flags")
SET(CMAKE_ASM_FLAGS_DEBUG "-g -ggdb3" CACHE INTERNAL "asm debug compiler flags")
add_compile_definitions(ARM_MATH_CM4;ARM_MATH_MATRIX_CHECK;ARM_MATH_ROUNDING)
add_compile_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
add_link_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
add_compile_options(-mcpu=cortex-m4 -mthumb -mthumb-interwork)
add_compile_options(-ffunction-sections -fdata-sections -fno-common -fmessage-length=0)
add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-x$<SEMICOLON>assembler-with-cpp>)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
message(STATUS "Maximum optimization for speed")
add_compile_options(-Ofast)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
message(STATUS "Maximum optimization for speed, debug info included")
add_compile_options(-Ofast -g)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
message(STATUS "Maximum optimization for size")
add_compile_options(-Os)
else ()
message(STATUS "Minimal optimization, debug info included")
add_compile_options(-Og -g)
endif ()
add_definitions(-DDEBUG -DUSE_HAL_DRIVER -DSTM32F407xx)
set(COMMON_DRIVER_DIR ${CMAKE_CURRENT_LIST_DIR}/../Drivers)
list(APPEND HAL_INC ${COMMON_DRIVER_DIR}/STM32F4xx_HAL_Driver/Inc)
list(APPEND HAL_INC ${COMMON_DRIVER_DIR}/CMSIS/Include)
list(APPEND HAL_INC ${COMMON_DRIVER_DIR}/CMSIS/Device/ST/STM32F4xx/Include)
list(APPEND HAL_SRC ${COMMON_DRIVER_DIR}/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal*.c)
list(APPEND HAL_SRC ${COMMON_DRIVER_DIR}/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c)
file(GLOB_RECURSE HAL_SRC ${HAL_SRC})
#[[------------------------------------------------硬件驱动库-------------------------------------------]]
list(APPEND BSP_DRIVER_INC ${COMMON_DRIVER_DIR}/Bsp/)
list(APPEND BSP_DRIVER_DRC ${COMMON_DRIVER_DIR}/Bsp/*.c)
file(GLOB_RECURSE BSP_DRIVER_DRC ${BSP_DRIVER_DRC})
#[[------------------------------------------------THREAD X-------------------------------------------]]
add_definitions(-DTX_ENABLE_FPU_SUPPORT -DTX_ENABLE_STACK_CHECKING -DTX_INCLUDE_USER_DEFINE_FILE)
set(THREAD_X_DIR ${CMAKE_CURRENT_LIST_DIR}/../Component/threadx)
list(APPEND THREAD_X_INC ${THREAD_X_DIR}/common/inc)
list(APPEND THREAD_X_SRC ${THREAD_X_DIR}/common/src/*.c)
list(APPEND THREAD_X_INC ${CMAKE_CURRENT_LIST_DIR}/Middleware/threadx/inc)
list(APPEND THREAD_X_SRC ${CMAKE_CURRENT_LIST_DIR}/Middleware/threadx/src/*.*)
#[[------------------------------------------------THREAD X utility-------------------------------------------]]
add_definitions(-DTX_EXECUTION_PROFILE_ENABLE)
list(APPEND THREAD_X_UTILITY_INC ${THREAD_X_DIR}/utility/execution_profile_kit)
list(APPEND THREAD_X_UTILITY_SRC ${THREAD_X_DIR}/utility/execution_profile_kit/tx_execution_profile.c)
list(APPEND THREAD_X_INC ${THREAD_X_UTILITY_INC})
list(APPEND THREAD_X_SRC ${THREAD_X_UTILITY_SRC})
file(GLOB_RECURSE THREAD_X_SRC ${THREAD_X_SRC})
#[[-------------------------------------------------------------------------------------------]]
set(APP_INC
${CMAKE_CURRENT_LIST_DIR}/Core/Inc
)
file(GLOB_RECURSE APP_SRC
${CMAKE_CURRENT_LIST_DIR}/Core/Startup/startup_stm32f407zgtx.s
${CMAKE_CURRENT_LIST_DIR}/Core/Src/*.c
)
set(LINKER_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/Core/Startup/STM32F407ZGTX_FLASH.ld)
#[[-------------------------------------------------------------------------------------------]]
include_directories(${BSP_DRIVER_INC})
list(APPEND SOURCES ${BSP_DRIVER_DRC})
include_directories(${THREAD_X_INC})
list(APPEND SOURCES ${THREAD_X_SRC})
include_directories(${APP_INC})
list(APPEND SOURCES ${APP_SRC})
include_directories(${HAL_INC})
list(APPEND SOURCES ${HAL_SRC})
# lib
# math lib
link_libraries(m)
link_libraries(c)
add_link_options(-Wl,-gc-sections,--print-memory-usage,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map)
add_link_options(-mcpu=cortex-m4 -mthumb -mthumb-interwork)
add_link_options(-T ${LINKER_SCRIPT})
add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})
set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
COMMENT "Building ${HEX_FILE}
Building ${BIN_FILE}")
应用函数源文件(修改)
/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-4-4 shchl first version
*
*
* tx_kernel_enter() 执行逻辑(关键)
* TX_PORT_SPECIFIC_PRE_INITIALIZATION----可扩展
* _tx_initialize_low_level() --- 设备层(寄存器)初始化
* _tx_initialize_high_level() --- tx os 内部相关初始化
* TX_INITIALIZE_KERNEL_ENTER_EXTENSION----可扩展
* tx_application_define(_tx_initialize_unused_memory);
* TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION ---可扩展
*
*/
#include "includes.h"
/*
*******************************************************************************************************
* 外部引入变量
*******************************************************************************************************
*/
/*
*******************************************************************************************************
* 变量
*******************************************************************************************************
*/
/*
*********************************************************************************************************
* 静态全局变量
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 函数声明
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 外部函数
*********************************************************************************************************
*/
/**
* @brief Application ThreadX Initialization.
* @param memory_ptr: 内存指针 (如果是静态分配的话,内存地址指针是为NULL)
* @note 开启动态分配内存,在汇编文件【tx_initialize_low_level.s】中开启宏定义 USE_DYNAMIC_MEMORY_ALLOCATION
* @retval int
*/
UINT App_ThreadX_Init(VOID *memory_ptr) {
UINT ret = TX_SUCCESS;
TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL *) memory_ptr;
(void) byte_pool;
/**************创建启动任务*********************/
void tx_task_cpu_stat_create();
void tx_task_serial_monitor_create();
tx_task_cpu_stat_create();
tx_task_serial_monitor_create();
return ret;
}
/*
*********************************************************************************************************
* 内部函数
*********************************************************************************************************
*/
cpu状态检测线程
/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-4-4 shchl first version
*/
#include "includes.h"
/*
*******************************************************************************************************
* 任务相关宏定义
*******************************************************************************************************
*/
#define APP_TASK_CPU_STAT_PRIO 30
#define APP_TASK_CPU_STAT_STK_SIZE 1024
/*
*******************************************************************************************************
* 外部引入变量
*******************************************************************************************************
*/
extern EXECUTION_TIME _tx_execution_idle_time_total;
extern EXECUTION_TIME _tx_execution_thread_time_total;
extern EXECUTION_TIME _tx_execution_isr_time_total;
/*
*******************************************************************************************************
* 变量
*******************************************************************************************************
*/
__IO double OSCPUUsage; /* CPU百分比 */
/*
*********************************************************************************************************
* 静态全局变量
*********************************************************************************************************
*/
static TX_THREAD cpu_stat_task_thread;
static ULONG cpu_stat_task_stk[APP_TASK_CPU_STAT_STK_SIZE / sizeof(ULONG)];
/*
*********************************************************************************************************
* 函数声明
*********************************************************************************************************
*/
static VOID task_cpu_stat_entry(ULONG input);
/*
*********************************************************************************************************
* 外部函数
*********************************************************************************************************
*/
/**
* @brief cpu 状态任务
* @param first_thread 第一个启动的任务线程首地址
*/
void tx_task_cpu_stat_create() {
tx_thread_create(&cpu_stat_task_thread, /* 任务控制块地址 */
"app_cpu_stat", /* 任务名 */
task_cpu_stat_entry, /* 启动任务函数地址 */
0, /* 传递给任务的参数 */
&cpu_stat_task_stk[0], /* 堆栈基地址 */
APP_TASK_CPU_STAT_STK_SIZE, /* 堆栈空间大小 */
APP_TASK_CPU_STAT_PRIO, /* 任务优先级*/
APP_TASK_CPU_STAT_PRIO, /* 任务抢占阀值 */
TX_NO_TIME_SLICE, /* 不开启时间片 */
TX_AUTO_START); /* 创建后立即启动 */
}
/*
*********************************************************************************************************
* 函 数 名: app_task_info_out
* 功能说明: 将ThreadX任务信息通过串口打印出来
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void app_task_info_out(void) {
TX_THREAD *p_tcb = _tx_thread_identify(); /* 定义一个任务控制块指针,并指向当前线程 */
/* 打印标题 */
tx_log("调用线程======[%s]\r\n", p_tcb->tx_thread_name);
tx_log("CPU利用率 = %5.2f%%\r\n", OSCPUUsage);
tx_log("任务执行时间 = %.9fs\r\n", (double) _tx_execution_thread_time_total / SystemCoreClock);
tx_log("空闲执行时间 = %.9fs\r\n", (double) _tx_execution_idle_time_total / SystemCoreClock);
tx_log("中断执行时间 = %.9fs\r\n", (double) _tx_execution_isr_time_total / SystemCoreClock);
tx_log("系统总执行时间 = %.9fs\r\n", (double) (_tx_execution_thread_time_total + \
_tx_execution_idle_time_total + \
_tx_execution_isr_time_total) / SystemCoreClock);
tx_log("===============================================================\r\n");
tx_log(" 任务优先级 任务栈大小 当前使用栈 最大栈使用 任务名\r\n");
tx_log(" Prio StackSize CurStack MaxStack Taskname\r\n");
/* 遍历任务控制列表TCB list),打印所有的任务的优先级和名称 */
while (p_tcb != (TX_THREAD *) 0) {
tx_log(" %2d %5d %5d %5d %s\r\n",
p_tcb->tx_thread_priority,
p_tcb->tx_thread_stack_size,
(int) p_tcb->tx_thread_stack_end - (int) p_tcb->tx_thread_stack_ptr,
(int) p_tcb->tx_thread_stack_end - (int) p_tcb->tx_thread_stack_highest_ptr,
p_tcb->tx_thread_name);
p_tcb = p_tcb->tx_thread_created_next;
if (p_tcb == _tx_thread_identify()) break;
}
}
/*
*********************************************************************************************************
* 内部函数
*********************************************************************************************************
*/
static VOID task_cpu_stat_entry(ULONG input) {
EXECUTION_TIME TolTime, IdleTime, deltaTolTime, deltaIdleTime;
uint32_t uiCount = 0;
(void) input;
/* 计算CPU利用率 */
IdleTime = _tx_execution_idle_time_total;
TolTime = _tx_execution_thread_time_total + _tx_execution_isr_time_total + _tx_execution_idle_time_total;
while (1) {
/* CPU利用率统计 */
uiCount++;
if (uiCount == 20) {
uiCount = 0;
deltaIdleTime = _tx_execution_idle_time_total - IdleTime;
deltaTolTime =
_tx_execution_thread_time_total + _tx_execution_isr_time_total + _tx_execution_idle_time_total -
TolTime;
OSCPUUsage = (double) deltaIdleTime / deltaTolTime;
OSCPUUsage = 100 - OSCPUUsage * 100;
IdleTime = _tx_execution_idle_time_total;
TolTime = _tx_execution_thread_time_total + _tx_execution_isr_time_total + _tx_execution_idle_time_total;
}
tx_thread_sleep(10);
}
}
串口监测线程(用于和串口助手进行指令通讯)
/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-4-4 shchl first version
*/
#include "includes.h"
#if 1
#define APP_TASK_SERIAL_MONI_STK_SIZE 2048
#define APP_TASK_SERIAL_MONI_PRIO 10
/*
*******************************************************************************************************
* 外部引入变量
*******************************************************************************************************
*/
/*
*******************************************************************************************************
* 变量
*******************************************************************************************************
*/
/*
*********************************************************************************************************
* 静态全局变量
*********************************************************************************************************
*/
static TX_THREAD serial_moni_thread;
static ULONG serial_moni_task_stk[TX_CONV_STACK_SIZE(APP_TASK_SERIAL_MONI_STK_SIZE)];
/*
*********************************************************************************************************
* 函数声明
*********************************************************************************************************
*/
static void serial_moni_entry(ULONG input);
/*
*********************************************************************************************************
* 外部函数
*********************************************************************************************************
*/
/**
* @brief cpu 状态任务
*/
void tx_task_serial_monitor_create() {
tx_thread_create(&serial_moni_thread, /* 任务控制块地址 */
"serial_moni", /* 任务名 */
serial_moni_entry, /* 启动任务函数地址 */
0, /* 传递给任务的参数 */
&serial_moni_task_stk[0], /* 堆栈基地址 */
APP_TASK_SERIAL_MONI_STK_SIZE, /* 堆栈空间大小 */
APP_TASK_SERIAL_MONI_PRIO, /* 任务优先级*/
APP_TASK_SERIAL_MONI_PRIO, /* 任务抢占阀值 */
TX_NO_TIME_SLICE, /* 不开启时间片 */
TX_AUTO_START); /* 创建后立即启动 */
}
/*
*********************************************************************************************************
* 内部函数
*********************************************************************************************************
*/
static void serial_moni_entry(ULONG input) {
static uint8_t buf[256];
while (1) {
uint8_t *ptr = buf;
while (comGetChar(COM1, ptr)) {
ptr++;
if (ptr > buf + 256) {
break;
}
}
if (ptr != buf) {
*ptr = '\0';
if (strstr((const char *) buf, "printf")) {
app_task_info_out();
} else {
}
}
tx_thread_sleep(10);
}
}
#endif