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

277 lines
7.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @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