1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 */
9
10 #include <rtthread.h>
11 #include <rthw.h>
12 #include "cpuusage.h"
13 #include "lcd.h"
14
15 #ifdef RT_USING_RTGUI
16 #include <rtgui/event.h>
17 #include <rtgui/rtgui_server.h>
18 #include <rtgui/rtgui_system.h>
19 #endif
20
21 #define CPU_USAGE_CALC_TICK 10
22 #define CPU_USAGE_LOOP 100
23
24 static rt_uint8_t cpu_usage_major = 0, cpu_usage_minor= 0;
25 static rt_uint32_t total_count = 0;
26
cpu_usage_idle_hook()27 static void cpu_usage_idle_hook()
28 {
29 rt_tick_t tick;
30 rt_uint32_t count;
31 volatile rt_uint32_t loop;
32
33 if (total_count == 0)
34 {
35 loop = 0;
36
37 /* get total count */
38 rt_enter_critical();
39 tick = rt_tick_get();
40 while(rt_tick_get() - tick < CPU_USAGE_CALC_TICK)
41 {
42 total_count ++;
43 while (loop < CPU_USAGE_LOOP) loop ++;
44 }
45 rt_exit_critical();
46 }
47
48 count = 0;
49 loop = 0;
50 /* get CPU usage */
51 tick = rt_tick_get();
52 while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK)
53 {
54 count ++;
55 while (loop < CPU_USAGE_LOOP) loop ++;
56 }
57
58 /* calculate major and minor */
59 if (count < total_count)
60 {
61 count = total_count - count;
62 cpu_usage_major = (count * 100) / total_count;
63 cpu_usage_minor = ((count * 100) % total_count) * 100 / total_count;
64 }
65 else
66 {
67 total_count = count;
68
69 /* no CPU usage */
70 cpu_usage_major = 0;
71 cpu_usage_minor = 0;
72 }
73 }
74
cpu_usage_get(rt_uint8_t * major,rt_uint8_t * minor)75 void cpu_usage_get(rt_uint8_t *major, rt_uint8_t *minor)
76 {
77 RT_ASSERT(major != RT_NULL);
78 RT_ASSERT(minor != RT_NULL);
79
80 *major = cpu_usage_major;
81 *minor = cpu_usage_minor;
82 }
83
cpu_usage_init()84 void cpu_usage_init()
85 {
86 /* set idle thread hook */
87 rt_thread_idle_sethook(cpu_usage_idle_hook);
88 }
89 extern struct rt_messagequeue mq;
90 extern rt_thread_t info_tid;
cpu_thread_entry(void * parameter)91 static void cpu_thread_entry(void *parameter)
92 {
93 #ifdef RT_USING_RTGUI
94 struct rtgui_event_command ecmd;
95
96 RTGUI_EVENT_COMMAND_INIT(&ecmd);
97 ecmd.type = RTGUI_CMD_USER_INT;
98 ecmd.command_id = CPU_UPDATE;
99 #else
100 struct lcd_msg msg;
101 #endif
102
103 while (1)
104 {
105 #ifdef RT_USING_RTGUI
106 rtgui_thread_send(info_tid, &ecmd.parent, sizeof(ecmd));
107 #else
108 msg.type = CPU_MSG;
109 msg.major = cpu_usage_major;
110 msg.minor = cpu_usage_minor;
111 rt_mq_send(&mq, &msg, sizeof(msg));
112 #endif
113 rt_thread_delay(20);
114 }
115 }
116
117 static rt_thread_t cpu_thread;
rt_hw_cpu_init(void)118 void rt_hw_cpu_init(void)
119 {
120 cpu_usage_init();
121 cpu_thread = rt_thread_create("cpu", cpu_thread_entry, RT_NULL, 384, 27, 5);
122 if(cpu_thread != RT_NULL)
123 rt_thread_startup(cpu_thread);
124 }
125