RT-Thread 28. Nano实现MSH及CPU利用率显示

Nano版源码官网下载

https://github.com/RT-Thread/rtthread-nano/archive/refs/heads/master.zip

1. 代码结构
2.代码

//main.c

c 复制代码
#include "gd32f3x0.h"
#include <rthw.h>
#include <rtthread.h>
#include "cpuusage.h"

#define delay_ms(x)   rt_thread_mdelay(x)

static rt_thread_t led_thread = RT_NULL;
static rt_thread_t cpu_usage_thread = RT_NULL;

/******************************************************************************
* @ 函数名  : cpu_usage_thread_entry
* @ 功  能  : 线程入口函数
* @ 参  数  : parameter 外部传入的参数
* @ 返回值  : 无
******************************************************************************/
static void cpu_usage_thread_entry(void *parameter)
{
	rt_uint8_t major, minor;
	
	while(1)
	{
		// 获取 CPU 利用率
		cpu_usage_get(&major, &minor);
		
		rt_kprintf("CPU 利用率:%d.%d %\r\n", major, minor);
		rt_thread_mdelay(1000);  // 500个tick(500ms)
	}
}

/******************************************************************************
* @ 函数名  : led_thread_entry
* @ 功  能  : 线程入口函数
* @ 参  数  : parameter 外部传入的参数
* @ 返回值  : 无
******************************************************************************/
static void led_thread_entry(void *parameter)
{
	rt_uint32_t i;
  
  /* enable the LED GPIO clock */
  rcu_periph_clock_enable(RCU_GPIOB);
  /* configure led GPIO port */ 
  gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_2);
  gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);  
  gpio_bit_set(GPIOB, GPIO_PIN_2);	
	while(1)
	{
		gpio_bit_toggle(GPIOB, GPIO_PIN_2);  // LED0 电平切换
		
		for(i = 0; i < 200000; i++); // 模拟占用 CPU 资源
		rt_thread_delay(100);  // 10个tick(10ms)
	}
}


/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
  #if 1
  	// 创建一个动态线程
	led_thread =                                  // 线程控制块指针
	rt_thread_create("led_thread",                // 线程名字
	                led_thread_entry,             // 线程入口函数
	                RT_NULL,                      // 入口函数参数
	                255,                          // 线程栈大小
				    4,                            // 线程优先级
				    20);                          // 线程时间片
	
	// 开启线程调度
	if(led_thread != RT_NULL)
		rt_thread_startup(led_thread);

  // CPU 使用率统计初始化
	cpu_usage_init();
  
  	// 创建一个动态线程
	cpu_usage_thread =                             // 线程控制块指针
	rt_thread_create("cpu_usage_thread",           // 线程名字
	                cpu_usage_thread_entry,        // 线程入口函数
	                RT_NULL,                       // 入口函数参数
	                255,                           // 线程栈大小
                  5,                             // 线程优先级
                  20);                           // 线程时间片
	
	// 开启线程调度
	if(cpu_usage_thread != RT_NULL)
  {
		rt_thread_startup(cpu_usage_thread);
  }
  #endif

  /* enable the LED GPIO clock */
  rcu_periph_clock_enable(RCU_GPIOB);
  /* configure led GPIO port */ 
  gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1);
  gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);  
  gpio_bit_set(GPIOB, GPIO_PIN_1);
  
  while(1){
      /* turn on led1 */
      gpio_bit_write(GPIOB, GPIO_PIN_1, RESET);
//        rt_kprintf("Hello\n");
      delay_ms(1000);
      
      /* turn off led1 */
      gpio_bit_write(GPIOB, GPIO_PIN_1, SET);
      delay_ms(1000);
  }
}

//board.c

c 复制代码
/*
 * Copyright (c) 2006-2019, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2017-07-24     Tanek        the first version
 * 2018-11-12     Ernest Chen  modify copyright
 */

#include "gd32f3x0.h"
#include <rthw.h>
#include <rtthread.h>

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
/*
 * Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
 * the RT_HEAP_SIZE max value = (sram size - ZI size), 2048 means 2048 bytes
 */
#define RT_HEAP_SIZE (4*1024)

static rt_uint8_t rt_heap[RT_HEAP_SIZE];
RT_WEAK void *rt_heap_begin_get(void)
{
    return rt_heap;
}

RT_WEAK void *rt_heap_end_get(void)
{
    return rt_heap + RT_HEAP_SIZE;
}
#endif

/*!
    \brief      configure systick
    \param[in]  none
    \param[out] none
    \retval     none
*/
void systick_config(uint32_t n)
{
    /* setup systick timer for 1000Hz interrupts */
    if(SysTick_Config(SystemCoreClock / n)) {
        /* capture error */
        while(1) {
        }
    }
    /* configure the systick handler priority */
    NVIC_SetPriority(SysTick_IRQn, 0x00U);
}

/**
 * This function will initial your board.
 */
void rt_hw_board_init()
{
    /* System Clock Update */
    SystemCoreClockUpdate();

    /* System Tick Configuration */
    systick_config(RT_TICK_PER_SECOND);

    /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}

void SysTick_Handler(void)
{
    /* enter interrupt */
    rt_interrupt_enter();

    rt_tick_increase();

    /* leave interrupt */
    rt_interrupt_leave();
}


/*!
    \brief      configure the USART0 GPIO ports
    \param[in]  none
    \param[out] none
    \retval     none
*/
void usart1_gpio_config(void)
{
    /* enable COM GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);

    /* connect port to USARTx_Tx */
    gpio_af_set(GPIOA, GPIO_AF_4, GPIO_PIN_8);

    /* connect port to USARTx_Rx */
    gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_15);

    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_8);

    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_15);
}

/*!
    \brief      configure the USART0
    \param[in]  none
    \param[out] none
    \retval     none
*/
void usart1_config(void)
{
    /* enable USART clock */
    rcu_periph_clock_enable(RCU_USART1);

    /* USART configure */
    usart_deinit(USART1);
    usart_word_length_set(USART1, USART_WL_8BIT);
    usart_stop_bit_set(USART1, USART_STB_1BIT);
    usart_parity_config(USART1, USART_PM_NONE);
    usart_baudrate_set(USART1, 115200U);
    usart_receive_config(USART1, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);

    usart_enable(USART1);
}

int uart1_init(void)
{
  usart1_gpio_config();
  usart1_config();
  return 0;
}
INIT_BOARD_EXPORT(uart1_init);

void rt_hw_console_output(const char *str)
{
    rt_size_t i = 0, size = 0;
    char a = '\r';

    size = rt_strlen(str);
    for (i = 0; i < size; i++)
    {
        if (*(str + i) == '\n')
        {
            usart_data_transmit(USART1, a);
          while(RESET == usart_flag_get(USART1,USART_FLAG_TBE));
        }
        usart_data_transmit(USART1, *(str + i));
          while(RESET == usart_flag_get(USART1,USART_FLAG_TBE));
    }  
  
}

char rt_hw_console_getchar(void)
{
    int ch = -1;

    if (usart_flag_get(USART1, USART_FLAG_RBNE) != RESET)
    {
        ch = usart_data_receive(USART1);
    }
    else
    {
        if(usart_flag_get(USART1, USART_FLAG_ORERR) != RESET)
        {
            usart_flag_clear(USART1,USART_FLAG_ORERR);
        }
        rt_thread_mdelay(10);
    }
    return ch;
}

//rtconfig.h

c 复制代码
/* RT-Thread config file */

#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__

// <<< Use Configuration Wizard in Context Menu >>>

// <h>Basic Configuration
// <o>Maximal level of thread priority <8-256>
//  <i>Default: 32
#define RT_THREAD_PRIORITY_MAX  32
// <o>OS tick per second
//  <i>Default: 1000   (1ms)
#define RT_TICK_PER_SECOND  1000
// <o>Alignment size for CPU architecture data access
//  <i>Default: 4
#define RT_ALIGN_SIZE   4
// <o>the max length of object name<2-16>
//  <i>Default: 8
#define RT_NAME_MAX    8
// <c1>Using RT-Thread components initialization
//  <i>Using RT-Thread components initialization
#define RT_USING_COMPONENTS_INIT
// </c>

#define RT_USING_USER_MAIN

// <o>the stack size of main thread<1-4086>
//  <i>Default: 512
#define RT_MAIN_THREAD_STACK_SIZE     512

// </h>

// <h>Debug Configuration
// <c1>enable kernel debug configuration
//  <i>Default: enable kernel debug configuration
//#define RT_DEBUG
// </c>
// <o>enable components initialization debug configuration<0-1>
//  <i>Default: 0
#define RT_DEBUG_INIT 0
// <c1>thread stack over flow detect
//  <i> Diable Thread stack over flow detect
//#define RT_USING_OVERFLOW_CHECK
// </c>
// </h>

// <h>Hook Configuration
// <c1>using hook
//  <i>using hook
//#define RT_USING_HOOK
// </c>
// <c1>using idle hook
//  <i>using idle hook
#define RT_USING_IDLE_HOOK
// </c>
// </h>

// <e>Software timers Configuration
// <i> Enables user timers
#define RT_USING_TIMER_SOFT         0
#if RT_USING_TIMER_SOFT == 0
    #undef RT_USING_TIMER_SOFT
#endif
// <o>The priority level of timer thread <0-31>
//  <i>Default: 4
#define RT_TIMER_THREAD_PRIO        4
// <o>The stack size of timer thread <0-8192>
//  <i>Default: 512
#define RT_TIMER_THREAD_STACK_SIZE  512
// </e>

// <h>IPC(Inter-process communication) Configuration
// <c1>Using Semaphore
//  <i>Using Semaphore
#define RT_USING_SEMAPHORE
// </c>
// <c1>Using Mutex
//  <i>Using Mutex
//#define RT_USING_MUTEX
// </c>
// <c1>Using Event
//  <i>Using Event
//#define RT_USING_EVENT
// </c>
// <c1>Using MailBox
//  <i>Using MailBox
#define RT_USING_MAILBOX
// </c>
// <c1>Using Message Queue
//  <i>Using Message Queue
//#define RT_USING_MESSAGEQUEUE
// </c>
// </h>

// <h>Memory Management Configuration
// <c1>Dynamic Heap Management
//  <i>Please modify RT_HEAP_SIZE if RT_USING_HEAP is enabled 
#define RT_USING_HEAP
// </c>
// <c1>using small memory
//  <i>using small memory
#define RT_USING_SMALL_MEM
// </c>
// <c1>using tiny size of memory
//  <i>using tiny size of memory
//#define RT_USING_TINY_SIZE
// </c>
// </h>

// <h>Console Configuration
// <c1>Using console
//  <i>Using console
#define RT_USING_CONSOLE
// </c>

// <o>the buffer size of console <1-1024>
//  <i>the buffer size of console
//  <i>Default: 128  (128Byte)
#define RT_CONSOLEBUF_SIZE          256
// </h>

// <h>FinSH Configuration
// <c1>include finsh config
//  <i>Select this choice if you using FinSH 
#include "finsh_config.h"
// </c>
// </h>

// <h>Device Configuration
// <c1>using device framework
//  <i>using device framework
#define RT_USING_DEVICE
// </c>
// </h>

// <<< end of configuration section >>>

#endif

//finsh_port.c

c 复制代码
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 */

#include <rthw.h>
#include <rtconfig.h>

#ifndef RT_USING_FINSH
#error Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h 
#endif

#ifdef RT_USING_FINSH

RT_WEAK char rt_hw_console_getchar(void)
{
    /* Note: the initial value of ch must < 0 */
    int ch = -1;

//#error "TODO 4: Read a char from the uart and assign it to 'ch'."

    return ch;
}

#endif /* RT_USING_FINSH */

//finsh_config.h

c 复制代码
/* FinSH config file */

#ifndef __MSH_CFG_H__
#define __MSH_CFG_H__

// <<< Use Configuration Wizard in Context Menu >>>
#define RT_USING_FINSH
#define FINSH_USING_MSH
#define FINSH_USING_MSH_ONLY
// <h>FinSH Configuration
// <o>the priority of finsh thread <1-30>
//  <i>the priority of finsh thread
//  <i>Default: 21
#define FINSH_THREAD_PRIORITY       21
// <o>the stack of finsh thread <1-4096>
//  <i>the stack of finsh thread
//  <i>Default: 4096  (4096Byte)
#define FINSH_THREAD_STACK_SIZE     1024

#define FINSH_USING_SYMTAB
// <c1>Enable command description
//  <i>Enable command description
#define FINSH_USING_DESCRIPTION
//  </c>
// </h>

// <<< end of configuration section >>>
#endif

//cpuusage.c

c 复制代码
#include <rthw.h>
#include"cpuusage.h"

#define CPU_USAGE_CALC_TICK    1000  // 计算周期
#define CPU_USAGE_LOOP        10

static rt_uint8_t  cpu_usage_major = 0, cpu_usage_minor= 0;
static rt_uint32_t total_count = 0;

static void cpu_usage_idle_hook()
{
    rt_tick_t tick;
    rt_uint32_t count;
	volatile rt_uint32_t loop;

	if (total_count == 0) {                            
		/* get total count */
        rt_enter_critical();                                
        tick = rt_tick_get();                               
		while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK) {
            total_count ++;                         
            loop = 0;
			while (loop < CPU_USAGE_LOOP) loop ++;
        }
        rt_exit_critical();
    }

    count = 0;
	/* get CPU usage */
    tick = rt_tick_get();                           
	while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK) {
        count ++;                                   
        loop  = 0;
	while (loop < CPU_USAGE_LOOP) loop ++;
    }

	/* calculate major and minor */
	if (count < total_count) {                          
        count = total_count - count;
        cpu_usage_major = (count * 100) / total_count;
        cpu_usage_minor = ((count * 100) % total_count) * 100 / total_count;
    } else {
        total_count = count;                               

		/* no CPU usage */
    	cpu_usage_major = 0;
    	cpu_usage_minor = 0;
    }
}

void cpu_usage_get(rt_uint8_t *major, rt_uint8_t *minor)
{
    RT_ASSERT(major != RT_NULL);
    RT_ASSERT(minor != RT_NULL);

    *major = cpu_usage_major;                               
    *minor = cpu_usage_minor;
}

void cpu_usage_init()
{
/* 设置空闲线程钩子函数 */
    rt_thread_idle_sethook(cpu_usage_idle_hook);    
}

//cpuusage.h

c 复制代码
#ifndef __CPUUSAGE_H__
#define __CPUUSAGE_H__
#include <rtthread.h>
#include <rthw.h>

/* 获取 cpu 利用率 */
void cpu_usage_init(void);
void cpu_usage_get(rt_uint8_t *major, rt_uint8_t *minor);

#endif
3.输出
bash 复制代码
\ | /
- RT -     Thread Operating System
 / | \     3.1.5 build Feb  2 2024
 2006 - 2020 Copyright by rt-thread team
CPU 利用率:0.0 %
msh >CPU 利用率:0.0 %
CPU 利用率:0.0 %
CPU 利用率:8.68 %
CPU 利用率:10.48 %
CPU 利用率:9.14 %
CPU 利用率:8.70 %
CPU 利用率:10.49 %
CPU 利用率:9.14 %
CPU 利用率:8.70 %
msh >free

total memory: 4072
used memory : 2760
maximum allocated memory: 2760
相关推荐
重生之我是数学王子3 小时前
点亮核心板小灯 STM32U575
stm32·单片机·嵌入式硬件
end_SJ3 小时前
初学stm32 --- 定时器中断
stm32·单片机·嵌入式硬件
南城花随雪。3 小时前
单片机:实现数码管动态显示(0~99999999)74hc138驱动(附带源码)
单片机·嵌入式硬件
南城花随雪。5 小时前
单片机:实现信号发生器(附带源码)
单片机·嵌入式硬件
灵槐梦7 小时前
【速成51单片机】2.点亮LED
c语言·开发语言·经验分享·笔记·单片机·51单片机
三月七(爱看动漫的程序员)7 小时前
HiQA: A Hierarchical Contextual Augmentation RAG for Multi-Documents QA---附录
人工智能·单片机·嵌入式硬件·物联网·机器学习·语言模型·自然语言处理
新晨单片机设计8 小时前
【087】基于51单片机智能宠物喂食器【Proteus仿真+Keil程序+报告+原理图】
嵌入式硬件·51单片机·proteus·宠物·ad原理图
大风起兮129 小时前
STM32HAL库中RTC闹钟设置时分秒,年月日
stm32·嵌入式硬件
超能力MAX9 小时前
IIC驱动EEPROM
单片机·嵌入式硬件·fpga开发
QQ5471760529 小时前
stm32实现回调功能
stm32·单片机·嵌入式硬件