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