前言
使用过rt-thread的shell 命令交互的方式,觉得比较方便,所以在threadx中也移植个shell的组件。这里使用的是letter-shell letter-shell 核心的逻辑在于组件通过链接文件自动初始化或自动添加的两种方式,方便开发 源码仓库
实验(核心代码)
shell 线程组件
# include "includes.h" # if 1 # include "shell.h"
# include "tx_initialize.h" # define SHELL_STACK_SIZE 2048
# define SHELL_THREAD_PRIORITY 18
extern TX_MUTEX console_lock;
extern ULONG _tx_thread_system_state;
TX_THREAD shell_thread;
static Shell g_shell;
static char shell_cache_buf[ TX_LOG_BUF_SZ] ;
static signed short console_write_handle ( char * data, unsigned short len) ; static signed short console_read_handle ( char * dst, unsigned short read_len) ; static int console_lock_handle ( struct shell_def * self) ; static int console_unlock_handle ( struct shell_def * self) ; static void shell_thread_entry ( ULONG input) ;
int app_shell_console_component_init ( ) { g_shell. write = console_write_handle; g_shell. read = console_read_handle; g_shell. lock = console_lock_handle; g_shell. unlock = console_unlock_handle; shellInit ( & g_shell, shell_cache_buf, TX_LOG_BUF_SZ) ; tx_thread_create ( & shell_thread, "shell" , shell_thread_entry, 0 , app_malloc ( SHELL_STACK_SIZE) , SHELL_STACK_SIZE, SHELL_THREAD_PRIORITY, SHELL_THREAD_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START) ; return TX_SUCCESS;
} TX_APP_DEFINE_EXPORT ( app_shell_console_component_init) ;
static signed short console_write_handle ( char * data, unsigned short len) { comSendBuf ( COM1, ( uint8_t * ) data, len) ; return ( signed short ) len; } static signed short console_read_handle ( char * dst, unsigned short read_len) { signed short readCnt = 0 ; while ( read_len) { if ( comGetChar ( COM1, ( uint8_t * ) dst) == 1 ) { readCnt++ ; read_len-- ; } else { break ; } } return readCnt;
} static int console_lock_handle ( struct shell_def * self) { if ( TX_THREAD_GET_SYSTEM_STATE ( ) == TX_INITIALIZE_IS_FINISHED) { return tx_mutex_get ( & console_lock, TX_WAIT_FOREVER) ; } return TX_SUCCESS;
} static int console_unlock_handle ( struct shell_def * self) { if ( TX_THREAD_GET_SYSTEM_STATE ( ) == TX_INITIALIZE_IS_FINISHED) { return tx_mutex_put ( & console_lock) ; } return TX_SUCCESS;
} static void shell_thread_entry ( ULONG input) { while ( 1 ) { shellTask ( & g_shell) ; tx_thread_sleep ( 10 ) ; }
} # endif
CPU 状态信息(使用shell 交互来打印)
# include "includes.h"
# define APP_TASK_CPU_STAT_PRIO 30
# define APP_TASK_CPU_STAT_STK_SIZE 1024
# if defined ( TX_EXECUTION_PROFILE_ENABLE)
extern EXECUTION_TIME _tx_execution_idle_time_total;
extern EXECUTION_TIME _tx_execution_thread_time_total;
extern EXECUTION_TIME _tx_execution_isr_time_total;
# endif
__IO double OSCPUUsage;
static TX_THREAD cpu_stat_task_thread;
static VOID task_cpu_stat_entry ( ULONG input) ;
int tx_task_cpu_stat_create ( ) { tx_thread_create ( & cpu_stat_task_thread, "app_cpu_stat" , task_cpu_stat_entry, 0 , app_malloc ( APP_TASK_CPU_STAT_STK_SIZE) , APP_TASK_CPU_STAT_STK_SIZE, APP_TASK_CPU_STAT_PRIO, APP_TASK_CPU_STAT_PRIO, TX_NO_TIME_SLICE, TX_AUTO_START) ; return TX_SUCCESS;
} TX_THREAD_EXPORT ( tx_task_cpu_stat_create) ; void app_task_info_out ( void ) { TX_THREAD * p_tcb = _tx_thread_identify ( ) ;
# if defined ( TX_EXECUTION_PROFILE_ENABLE) 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) ;
# endif tx_log ( "===============================================================\r\n" ) ;
tx_log ( " Prio StackSize CurStack MaxStack State Taskname\r\n" ) ; while ( p_tcb != ( TX_THREAD * ) 0 ) { tx_log ( " %2d %5d %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_state, 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) {
# if defined ( TX_EXECUTION_PROFILE_ENABLE) EXECUTION_TIME TolTime, IdleTime, deltaTolTime, deltaIdleTime; uint32_t uiCount = 0 ; ( void ) input; IdleTime = _tx_execution_idle_time_total; TolTime = _tx_execution_thread_time_total + _tx_execution_isr_time_total + _tx_execution_idle_time_total; while ( 1 ) { 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 ) ; }
# else while ( 1 ) { bsp_Idle ( ) ; tx_thread_sleep ( 10 ) ; } # endif
} # ifdef SHELL_USING_CMD_EXPORT
SHELL_EXPORT_CMD ( SHELL_CMD_PERMISSION ( 0 ) | SHELL_CMD_TYPE ( SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN, ps, app_task_info_out, "cpu statue info print" ) ; # endif
测试结果
总结
在使用shell 和threadx 组合的时候,shell 加锁和解锁时,判断os是否启动,没有启动直接返回即可