JT-DT-YD4N02B_4G_RTT_MRS/bsp/src/bsp_cpu_usage.c

277 lines
7.1 KiB
C
Raw Normal View History

2024-12-30 11:50:48 +08:00
/*
* @Author : stark1898y 1658608470@qq.com
* @Date : 2024-09-13 15:23:04
* @LastEditors : stark1898y 1658608470@qq.com
* @LastEditTime : 2024-09-13 15:41:24
* @FilePath : \JT-DT-YD4N02A_RTT_MRS-4G\bsp\src\bsp_cpu_usage.c
* @Description :
*
* Copyright (c) 2024 by yzy, All Rights Reserved.
*/
#include <rthw.h>
#include <rtthread.h>
#include "bsp_cpu_usage.h"
#define LOG_TAG "bsp_cpu_usage" // 该模块对应的标签。不定义时默认NO_TAG
#define LOG_LVL LOG_LVL_DBG // 该模块对应的日志输出级别。不定义时,默认:调试级别
#include <ulog.h> // 必须在 LOG_TAG 与 LOG_LVL 下面
#if 1
#define CPU_USAGE_CALC_TICK 1000
#define CPU_USAGE_LOOP 100
static rt_uint8_t cpu_usage_major = 0, cpu_usage_minor = 0;
static rt_uint32_t total_count = 0;
static void _CPU_Usage_IdleHook(void)
{
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;
}
int CPU_Usage_Init()
{
LOG_I("CPU Usage Init");
/* 设置空闲线程钩子函数 */
return rt_thread_idle_sethook(_CPU_Usage_IdleHook);
}
#ifdef RT_USING_COMPONENTS_INIT
INIT_PREV_EXPORT(CPU_Usage_Init);
#endif
//static rt_thread_t get_cpu_use_thread = RT_NULL;
//
//static void get_cpu_use_thread_entry(void *parameter)
//{
// rt_uint8_t major, minor;
//
// while (1)
// {
// /* 获取CPU利用率数据 */
// CPU_Usage_Get(&major, &minor);
//
// /* 打印CPU利用率 */
// rt_kprintf("CPU利用率 = %d.%d%%\r\n", major, minor);
//
// rt_thread_delay(1000); /* 延时1000个tick */
// }
//}
//static void hook_of_scheduler(struct rt_thread* from, struct rt_thread* to)
//{
// rt_kprintf("from: %s --> to: %s \n", from->name , to->name);
//}
int CPU_Usage(void)
{
/* 设置调度器钩子 */
// rt_scheduler_sethook(hook_of_scheduler);
// CPU_Usage_Init();
// get_cpu_use_thread = /* 线程控制块指针 */
// rt_thread_create("get_cpu_use", /* 线程名字 */
// get_cpu_use_thread_entry, /* 线程入口函数 */
// RT_NULL, /* 线程入口函数参数 */
// 512, /* 线程栈大小 */
// 5, /* 线程的优先级 */
// 20); /* 线程时间片 */
//
// /* 启动线程,开启调度 */
// if (get_cpu_use_thread != RT_NULL)
// rt_thread_startup(get_cpu_use_thread);
// else
// return -1;
rt_uint8_t major, minor;
/* 获取CPU利用率数据 */
CPU_Usage_Get(&major, &minor);
/* 打印CPU利用率 */
LOG_D("CPU利用率 = %d.%d%%", major, minor);
return 0;
}
#ifdef FINSH_USING_MSH
MSH_CMD_EXPORT(CPU_Usage, CPU_Usage);
#endif
#endif
#if 0
#include <rtdevice.h>
#define HWTIMER_DEV_NAME "timer1"
/* 递增 count 作为 cpu tick 使用,不可被设置,只可单调递增 */
rt_uint64_t count = 0;
/* 当 CPU tick 到达 timeout_tick 时触发回调 */
rt_uint64_t timeout_tick = 0;
void (*hwtimer_timeout)(void *param);
void *parameter = RT_NULL;
/* 精度 ns */
static float cortexm_cputime_getres(void)
{
return 10000;
}
/* cpu tick */
static uint64_t cortexm_cputime_gettime(void)
{
return count;
}
// /* 设置超时时间及函数 */
// static int cortexm_cputime_settimeout(uint64_t tick, void (*timeout)(void *param), void *param)
// {
// timeout_tick = tick;
// hwtimer_timeout = timeout;
// parameter = param;
// return 0;
// }
/* 定义 ops */
const static struct rt_clock_cputime_ops _cpustime_ops =
{
cortexm_cputime_getres,
cortexm_cputime_gettime
// cortexm_cputime_settimeout
};
/* 初始化 ops */
int cortexm_cputime_init(void)
{
/* bsp 在这样使用的时候,不用管内部有没有实现,这个函数会覆盖掉内部的实现 */
clock_cpu_setops(&_cpustime_ops);
return 0;
}
INIT_BOARD_EXPORT(cortexm_cputime_init);
/* 硬件定时器超时函数 */
static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size)
{
count++;
if(count == timeout_tick)
{
/* 到达指定时间后清空到达时间,并触发回调 */
timeout_tick = 0;
if(hwtimer_timeout != RT_NULL)
hwtimer_timeout(parameter);
}
return 0;
}
/* 硬件定时器初始化 */
static int hwtimer_init()
{
rt_err_t ret = RT_EOK;
rt_hwtimerval_t timeout_s;
rt_device_t hw_dev = RT_NULL;
rt_hwtimer_mode_t mode;
rt_uint32_t freq = 1000000;
hw_dev = rt_device_find(HWTIMER_DEV_NAME);
if (hw_dev == RT_NULL)
{
/* 硬件定时器失败时,清空设置超时的函数,使 cputime 不可用,
使 rt_cputime_sleep() */
// _cpustime_ops.cputime_settimeout = RT_NULL;
LOG_E("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEV_NAME);
return RT_ERROR;
}
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
if (ret != RT_EOK)
{
// _cpustime_ops.cputime_settimeout = RT_NULL;
LOG_E("open %s device failed!\n", HWTIMER_DEV_NAME);
return ret;
}
/* 设置硬件定时器的超时时间 */
rt_device_set_rx_indicate(hw_dev, timeout_cb);
rt_device_control(hw_dev, HWTIMER_CTRL_FREQ_SET, &freq);
mode = HWTIMER_MODE_PERIOD;
ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);
if (ret != RT_EOK)
{
// _cpustime_ops.cputime_settimeout = RT_NULL;
LOG_E("set mode failed! ret is :%d\n", ret);
return ret;
}
timeout_s.sec = 0;
timeout_s.usec = 10;
/* 设置硬件定时器的精度,这里应和上述的 cortexm_cputime_getres 函数保持一致 */
if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s))
{
// _cpustime_ops.cputime_settimeout = RT_NULL;
LOG_E("set timeout value failed\n");
return RT_ERROR;
}
return ret;
}
INIT_APP_EXPORT(hwtimer_init);
#endif