Nano版源码官网下载
https://github.com/RT-Thread/rtthread-nano/archive/refs/heads/master.zip
1. 代码结构
2.代码
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);
}
}
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;
}
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
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);
}
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