stm32开发之threadx整合letter-shell 组件记录

前言

  1. 使用过rt-thread的shell 命令交互的方式,觉得比较方便,所以在threadx中也移植个shell的组件。这里使用的是letter-shell
  2. letter-shell 核心的逻辑在于组件通过链接文件自动初始化或自动添加的两种方式,方便开发
  3. 源码仓库

实验(核心代码)

在这里插入图片描述

shell 线程组件

/*
 * Copyright (c) 2024-2024,shchl
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-4-16     shchl   first version
 */
#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 系统状态,保证编译器不报错,因为这个是在汇编文件中定义的*/
/*
*******************************************************************************************************
*                               变量
*******************************************************************************************************
*/
TX_THREAD shell_thread;
/*
*********************************************************************************************************
*                                       静态全局变量
*********************************************************************************************************
*/
static Shell g_shell; /*全局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);
/*
*********************************************************************************************************
*                                      外部函数
*********************************************************************************************************
*/
/**
 * @brief 控制台shell 组件初始化
 * @return
 */
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);

    /*创建shell 线程*/

    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); /*shell 控制台组件初始化*/
/*
*********************************************************************************************************
*                                      内部函数
*********************************************************************************************************
*/

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 交互来打印)

/*
 * 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
/*
*******************************************************************************************************
*                               外部引入变量
*******************************************************************************************************
*/
#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;    /* CPU百分比 */
/*
*********************************************************************************************************
*                                       静态全局变量
*********************************************************************************************************
*/
static TX_THREAD cpu_stat_task_thread;
/*
*********************************************************************************************************
*                                      函数声明
*********************************************************************************************************
*/
static VOID task_cpu_stat_entry(ULONG input);
/*
*********************************************************************************************************
*                                      外部函数
*********************************************************************************************************
*/
/**
 * @brief cpu 状态任务
 * @param first_thread 第一个启动的任务线程首地址
 */
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);

/*
*********************************************************************************************************
*	函 数 名: 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);
#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(" 任务优先级 任务栈大小 当前使用栈  最大栈使用 状态   任务名\r\n");
    tx_log("   Prio     StackSize   CurStack    MaxStack    State   Taskname\r\n");
    /* 遍历任务控制列表TCB list),打印所有的任务的优先级和名称 */
    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;
    /* 计算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);
    }
#else

    while (1) {

        bsp_Idle();
        tx_thread_sleep(10);
    }


#endif
}

#ifdef SHELL_USING_CMD_EXPORT

/*shell 脚本来管理*/
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

测试结果

在这里插入图片描述

在这里插入图片描述

总结

  1. 在使用shell 和threadx 组合的时候,shell 加锁和解锁时,判断os是否启动,没有启动直接返回即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/547328.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ECMA进阶1之从0~1搭建react同构体系项目1

ECMA进阶 ES6项目实战前期介绍SSRpnpm 包管理工具package.json 项目搭建初始化配置引入encode-fe-lint 基础环境的配置修改package.jsonbabel相关tsconfig相关postcss相关补充scripts脚本webpack配置base.config.tsclient.config.tsserver.config.ts src环境server端&#xff1…

链表--经典题

题目一:移除链表元素 示例 1: 输入:head [1,2,6,3,4,5,6], val 6 输出:[1,2,3,4,5]示例 2: 输入:head [], val 1 输出:[]示例 3: 输入:head [7,7,7,7], val 7 输出…

【转】关于vsCode创建后,不显示NPM脚本解决

刚刚使用vue ui新建了个vue项目,打开vs-code发现,无论怎么设置都找不到NPM脚本显示,苦恼了很久,突然发现!打开了package-lock.json,然后立马把vs-code关闭,重新打开,就显示了npm脚本…

计算机网络(三)数据链路层

数据链路层 基本概念 数据链路层功能: 在物理层提供服务的基础上向网络层提供服务,主要作用是加强物理层传输原始比特流的功能,将物理层提供的可能出错的物理连接改在为逻辑上无差错的数据链路,使之对网络层表现为一条无差错的…

03-echarts如何画立体柱状图

echarts如何画立体柱状图 一、创建盒子1、创建盒子2、初始化盒子(先绘制一个基本的二维柱状图的样式)1、创建一个初始化图表的方法2、在mounted中调用这个方法3、在方法中写options和绘制图形 二、画图前知识1、坐标2、柱状图图解分析 三、构建方法1、创…

构建高效协同平台架构:实现团队协作的新高度

随着企业规模的扩大和工作方式的变革,团队协作变得愈发重要。在这个数字化时代,构建一个高效的协同平台架构,能够为团队提供强大的工具和资源,实现更加高效、灵活的协作方式。本文将探讨协同平台架构的重要性,并介绍如…

UE5不打包启用像素流 ubuntu22.04

首先查找引擎中像素流的位置: zkzk-ubuntu2023:/media/zk/Data/Linux_Unreal_Engine_5.3.2$ sudo find ./ -name get_ps_servers.sh [sudo] zk 的密码: ./Engine/Plugins/Media/PixelStreaming/Resources/WebServers/get_ps_servers.sh然后在指定路径中…

笔试的解题思路很多,

昨天发的笔试题目,留言的人还挺多,这道笔试题目是字节的嵌入式笔试题目,从面试的朋友描述说,对方的面试过程很专业。 现场写代码, 金三银四一直是铁律,去年我一个朋友离职后,也是最近这几天拿到…

【C语言】预处理

个人主页点这里~ 预处理 一、预处理符号二、#define定义常量三、#define定义宏四、带有副作用的宏参数五、宏替换的规则六、宏与函数的对比(一)、宏的优势(二)、宏的劣势(三)、宏和函数的对比 七、#和##1、…

Emacs之增加/取消输入括号自动匹配(一百三十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

vue webpack打包配置生成的源映射文件不包含源代码内容、加密混淆压缩

前言:此案例使用的是vue-cli5 一、webpack源码泄露造成的安全问题 我们在打包后部署到服务器上时,能直接在webpack文件下看到我们项目源码,代码检测出来是不安全的。如下两种配置解决方案: 1、直接在项目的vue.config.js文件中加…

C语言 | Leetcode C语言题解之第30题串联所有单词的子串

题目: 题解: typedef struct {char key[32];int val;UT_hash_handle hh; } HashItem;int* findSubstring(char * s, char ** words, int wordsSize, int* returnSize){ int m wordsSize, n strlen(words[0]), ls strlen(s);int *res (int *)mall…

【测试开发学习历程】python常用的模块(中)

目录 5 time模块 5.1、Python中的四种格式的时间: 5.2、time模块中的常用函数 6 I/O流操作 6.1 创建文件 6.2 读取一个文件存入到另外一个文件 6.3 with open as 结构 6.4 open和with open as的区别 7 Excel的操作模块-openpyxl 7.1、新建Excel文件进行读…

11.范式与反范式设计

范式 1.问题 MySQL的库表设计,在很多时候我们都是率性而为,往往在前期的设计中考虑不全面,同时对于库表结构的划分也并不明确,所以很多时候在开发过程中,代码敲着敲着会去重构某张表结构,甚至大面积重构多…

bestvike 资料 --Spring Boot 2.5.0

Spring Boot 2.5.0 SSM环境搭建 springspringmvcmybatisspring springmvc mybatis # 项目 - 需求分析 概要设计(库表设计) 详细设计(验证库表正确性) 编码(环境搭建业务代码) 测试 部署上线# 员工添加 查询所有功能 SSM - 库表 库: ssm 数据库:mysql 表: id na…

spring-cloud微服务gateway

核心部分:routes(路由), predicates(断言),filters(过滤器) id:可以理解为是这组配置的一个id值,请保证他的唯一的,可以设置为和服务名一致 uri:可以理解为是通过条件匹配之后需要路由到&…

RabbbitMQ基本使用及其五种工作模型

初识MQ 同步通讯和异步通讯 什么是同步通讯呢?举个例子,你认识了一个小姐姐,聊的很火热,于是你们慢慢开始打电话,视频聊天,这种方式就成为同步通讯,那什么是一部通讯呢,同样的&…

gitlab(docker)安装及使用

GitLab GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务。 下载(docker) 查询docker镜像gitlab-ce gitlab-ce是它的社区版 [rootlocalhost ~]# docker search gitlab-ce NAME …

OpenCV基本图像处理操作(六)——直方图与模版匹配

直方图 cv2.calcHist(images,channels,mask,histSize,ranges) images: 原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如[img]channels: 同样用中括号括来它会告函数我们统幅图 像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的…

SETR——Rethinking系列工作,展示使用纯transformer在语义分割任务上是可行的,但需要很强的训练技巧

题目:Rethinking Semantic Segmentation from a Sequence-to-Sequence Perspective with Transformers 作者: 开源:https://fudan-zvg.github.io/SETR 1.研究背景 1.1 为什么要研究这个问题? 自[ 36 ]的开创性工作以来,现有的语义分割模型主要是**基于全卷积网络( FCN )的…