stn32开发之threadx使用记录(一)

前言

  1. 先让threadx在板子上跑起来再说;
  2. 使用的芯片stm32f407zgt6
  3. 开发环境使用的是clion+cubemx
  4. 编译使用的是arm-none-gcc

实现效果

  1. 定时打印输出
  2. 添加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利用率)

  1. 自己实现参考安富莱论坛

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

测试结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

詩不诉卿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值