1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * cpu_test.c -- cpu test application
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
5*4882a593Smuzhiyun * Author: Panzhenzhuan Wang <randy.wang@rock-chips.com>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Licensed under the Apache License, Version 2.0 (the "License");
8*4882a593Smuzhiyun * you may not use this file except in compliance with the License.
9*4882a593Smuzhiyun * You may obtain a copy of the License at
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * http://www.apache.org/licenses/LICENSE-2.0
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * Unless required by applicable law or agreed to in writing, software
14*4882a593Smuzhiyun * distributed under the License is distributed on an "AS IS" BASIS,
15*4882a593Smuzhiyun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*4882a593Smuzhiyun * See the License for the specific language governing permissions and
17*4882a593Smuzhiyun * limitations under the License.
18*4882a593Smuzhiyun */
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /* Get CPU frequency */
21*4882a593Smuzhiyun #include <stdio.h>
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun /* error ����������ͷ�ļ�*/
24*4882a593Smuzhiyun #include <errno.h>
25*4882a593Smuzhiyun #include <stdlib.h>
26*4882a593Smuzhiyun #include <string.h>
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #include <sys/types.h>
29*4882a593Smuzhiyun #include <sys/stat.h>
30*4882a593Smuzhiyun #include <fcntl.h>
31*4882a593Smuzhiyun #include "cpu_test.h"
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #define LOG_TAG "cpu_test"
34*4882a593Smuzhiyun #include "common.h"
35*4882a593Smuzhiyun #define CPU_PROC_ERR -55
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define _CPU_FREQ_TABLE_PATH "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_available_frequencies"
38*4882a593Smuzhiyun #define _CPU_FREQ_TXT "/data/cfg/rk_pcba_test/cpu%d_freq_table.txt"
39*4882a593Smuzhiyun #define _CPU_FREQ_GET "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq"
40*4882a593Smuzhiyun #define _CPU_FREQ_SET "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_setspeed"
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun int cpu_num0 = 0;
43*4882a593Smuzhiyun CPU_FREQ cpu_0;
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun int cpu_num1 = 0;
46*4882a593Smuzhiyun CPU_FREQ cpu_1;
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun int cpu_num2 = 0;
49*4882a593Smuzhiyun CPU_FREQ cpu_2;
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun int cpu_num3 = 0;
52*4882a593Smuzhiyun CPU_FREQ cpu_3;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun int cpu_space = 0;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun //��һ�CPU frequency test=========================
57*4882a593Smuzhiyun //===================================================
58*4882a593Smuzhiyun /* ��CPU����Ƶ�ʼ���Ƶ������*/
Insert_list(CPU_FREQ * head,CPU_FREQ * item)59*4882a593Smuzhiyun void Insert_list(CPU_FREQ *head, CPU_FREQ *item)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun CPU_FREQ *p1 = NULL, *p0 = NULL;
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun p1 = head;
64*4882a593Smuzhiyun p0 = item;
65*4882a593Smuzhiyun p0->next = NULL;
66*4882a593Smuzhiyun if (head == NULL) {
67*4882a593Smuzhiyun head = p0;
68*4882a593Smuzhiyun } else {
69*4882a593Smuzhiyun while (p1 && p1->next)
70*4882a593Smuzhiyun p1 = p1->next;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun if (p1->freq == 0){
73*4882a593Smuzhiyun p1->freq = p0->freq;
74*4882a593Smuzhiyun free(p0); //��Ҫ�ͷ�p0����Ȼitem�ڴ�й©
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun else
77*4882a593Smuzhiyun p1->next = p0;
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun /* 1����ȡCPU֧�ֵ�frequency table, �����ؿ���CPUƵ�ʸ���*/
get_cpu_freq_table(int cpu_num,CPU_FREQ * cpu_freq_head)82*4882a593Smuzhiyun int get_cpu_freq_table(int cpu_num, CPU_FREQ *cpu_freq_head)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun char freq_table_path[512];
86*4882a593Smuzhiyun char freq_table_file[128];
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun printf("\n=================function :%s start \tcpu number: %d==================\n",__func__,cpu_num);
89*4882a593Smuzhiyun /* ��ȡCPU number ��Ӧ��frequency table ·��*/
90*4882a593Smuzhiyun memset(freq_table_path, 0, sizeof(freq_table_path));
91*4882a593Smuzhiyun sprintf(freq_table_path, _CPU_FREQ_TABLE_PATH, cpu_num);
92*4882a593Smuzhiyun printf("cpu: %d; freq_table_path is: %s\n",cpu_num,freq_table_path);
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun /* ��CPU frequency table���뵽�ļ��� */
95*4882a593Smuzhiyun char cmd[1024];
96*4882a593Smuzhiyun memset(cmd, 0, sizeof(cmd));
97*4882a593Smuzhiyun memset(freq_table_file, 0,sizeof(freq_table_file));
98*4882a593Smuzhiyun sprintf(freq_table_file, _CPU_FREQ_TXT, cpu_num);
99*4882a593Smuzhiyun printf("cpu: %d; freq_table_file is: %s\n",cpu_num,freq_table_file);
100*4882a593Smuzhiyun sprintf(cmd, "busybox cat %s > %s", freq_table_path, freq_table_file);
101*4882a593Smuzhiyun if(system(cmd)<0)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun perror("system(cmd)");
104*4882a593Smuzhiyun return -1;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun /* �����п��ܵ�CPUƵ�ʼ��뵽������, ����ӡ�����õ�Ƶ�ʸ���*/
107*4882a593Smuzhiyun FILE *fp_read = NULL;
108*4882a593Smuzhiyun char buf[64];
109*4882a593Smuzhiyun CPU_FREQ *new_freq;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun fp_read = fopen(freq_table_file, "r");
112*4882a593Smuzhiyun if (NULL==fp_read) {
113*4882a593Smuzhiyun printf("%s open err:%s\r\n", freq_table_file,strerror(errno));
114*4882a593Smuzhiyun return -1;
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun //��ȡ�ļ��и�Ƶ��ֵ�������뵽��cpu_freq_headΪͷ��������
117*4882a593Smuzhiyun int freq_num = 0; //����Ƶ�ʸ���
118*4882a593Smuzhiyun while(!feof(fp_read)&&(fp_read!=NULL))
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun fscanf(fp_read,"%s",buf);
121*4882a593Smuzhiyun new_freq = calloc(1,sizeof(CPU_FREQ));
122*4882a593Smuzhiyun if (new_freq == NULL)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun printf("%s:calloc err\r\n", __func__);
125*4882a593Smuzhiyun return -1;
126*4882a593Smuzhiyun break;
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun new_freq->freq = atoi(buf);
129*4882a593Smuzhiyun printf("cpu frequency num:%d,frequency is %d MHz\r\n",freq_num,new_freq->freq/1000);
130*4882a593Smuzhiyun Insert_list(cpu_freq_head, new_freq);
131*4882a593Smuzhiyun freq_num++;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun fclose(fp_read);
134*4882a593Smuzhiyun remove(freq_table_file);
135*4882a593Smuzhiyun printf("cpu %d has %d availble frequencies\n",cpu_num,freq_num);
136*4882a593Smuzhiyun printf("\n=================function :%s finish \tcpu number: %d==================\n",__func__,cpu_num);
137*4882a593Smuzhiyun return freq_num;
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun /* 2����ȡ��ǰǰCPU����Ƶ�ʣ���ӡ���������� */
get_curl_freq(int cpu_num)141*4882a593Smuzhiyun int get_curl_freq(int cpu_num)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun FILE *pp;
144*4882a593Smuzhiyun char cmd[512];
145*4882a593Smuzhiyun char cpufreq[64];
146*4882a593Smuzhiyun int cpu_curl_freq =0;
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun printf("\n=================function :%s start \tcpu number: %d==================\n",__func__,cpu_num);
149*4882a593Smuzhiyun /* ��ȡCPU 0/1/2/3 ��Ӧ�ĵ�ǰ����frequency·��*/
150*4882a593Smuzhiyun memset(cmd, 0, sizeof(cmd));
151*4882a593Smuzhiyun sprintf(cmd, "busybox cat %s", _CPU_FREQ_GET);
152*4882a593Smuzhiyun sprintf(cmd, cmd, cpu_num);
153*4882a593Smuzhiyun printf("cpu: %d; get current frequency cmd is: %s\n",cpu_num,cmd);
154*4882a593Smuzhiyun pp = popen(cmd, "r");
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun //����ļ���ʧ�ܣ������������Ϣ
157*4882a593Smuzhiyun if (!pp)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun printf("%s open err:%s\r\n", __func__,strerror(errno)); //ʹ��strerror��������������
160*4882a593Smuzhiyun return -1;
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun if (fgets(cpufreq, sizeof(cpufreq), pp) == NULL) {
163*4882a593Smuzhiyun printf("popen read from %s is NULL!\n",cmd);
164*4882a593Smuzhiyun pclose(pp);
165*4882a593Smuzhiyun return -1;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun pclose(pp);
168*4882a593Smuzhiyun cpu_curl_freq = atoi(cpufreq);
169*4882a593Smuzhiyun printf("cpu��%d ; current frequency is: %d MHz\n",cpu_num,cpu_curl_freq/1000);
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun printf("\n=================function :%s finish \tcpu number: %d==================\n",__func__,cpu_num);
172*4882a593Smuzhiyun return cpu_curl_freq;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun /* 3������CPUһ��֧�ֵ�CPU frequency */
176*4882a593Smuzhiyun //����CPU ģʽ
cpu_set_mode(char * mode)177*4882a593Smuzhiyun int cpu_set_mode(char *mode)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun char cmd[512];
180*4882a593Smuzhiyun printf("\n=================== function :%s start======================\n",__func__);
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun if (cpu_num0 > 0) {
183*4882a593Smuzhiyun memset(cmd, 0, sizeof(cmd));
184*4882a593Smuzhiyun sprintf(cmd, "echo " "%s" " > %s", mode,_CPU_0_FREQ_GOVERNOR);
185*4882a593Smuzhiyun system(cmd);
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun if (cpu_num1 > 0) {
189*4882a593Smuzhiyun memset(cmd, 0, sizeof(cmd));
190*4882a593Smuzhiyun sprintf(cmd, "echo " "%s" " > %s", mode,_CPU_1_FREQ_GOVERNOR);
191*4882a593Smuzhiyun system(cmd);
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun if (cpu_num2 > 0) {
195*4882a593Smuzhiyun memset(cmd, 0, sizeof(cmd));
196*4882a593Smuzhiyun sprintf(cmd, "echo " "%s" " > %s", mode,_CPU_2_FREQ_GOVERNOR);
197*4882a593Smuzhiyun system(cmd);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun if (cpu_num3 > 0) {
201*4882a593Smuzhiyun memset(cmd, 0, sizeof(cmd));
202*4882a593Smuzhiyun sprintf(cmd, "echo " "%s" " > %s", mode,_CPU_3_FREQ_GOVERNOR);
203*4882a593Smuzhiyun system(cmd);
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun printf("\n=================== function :%s finish======================\n",__func__);
206*4882a593Smuzhiyun return 0;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun //����CPU �б������Ƶ�ʣ��������õ�Ƶ��
set_curl_freq(int cpu_num,int freq_num)210*4882a593Smuzhiyun int set_curl_freq(int cpu_num, int freq_num)
211*4882a593Smuzhiyun {
212*4882a593Smuzhiyun char cmd[512];
213*4882a593Smuzhiyun char CPU_FREQ_SET_PATH[128];
214*4882a593Smuzhiyun CPU_FREQ *cpu_freq;
215*4882a593Smuzhiyun CPU_FREQ *p;
216*4882a593Smuzhiyun int freq_set = 0;
217*4882a593Smuzhiyun printf("\n=================== function :%s start======================\n",__func__);
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun //ѡ��CPU_num��Ӧ��Ƶ������
220*4882a593Smuzhiyun switch(cpu_num){
221*4882a593Smuzhiyun case 0:
222*4882a593Smuzhiyun cpu_freq = &cpu_0;break;
223*4882a593Smuzhiyun case 1:
224*4882a593Smuzhiyun cpu_freq = &cpu_1;break;
225*4882a593Smuzhiyun case 2:
226*4882a593Smuzhiyun cpu_freq = &cpu_2;break;
227*4882a593Smuzhiyun case 3:
228*4882a593Smuzhiyun cpu_freq = &cpu_3;break;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun p = cpu_freq;
232*4882a593Smuzhiyun while(p) {
233*4882a593Smuzhiyun if ((--freq_num) <= 0)
234*4882a593Smuzhiyun break;
235*4882a593Smuzhiyun if (p->next)
236*4882a593Smuzhiyun p = p->next;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun /* ����CPU Ƶ��*/
240*4882a593Smuzhiyun freq_set = p->freq;
241*4882a593Smuzhiyun memset(cmd, 0, sizeof(cmd));
242*4882a593Smuzhiyun sprintf(CPU_FREQ_SET_PATH,_CPU_FREQ_SET,cpu_num);
243*4882a593Smuzhiyun sprintf(cmd, "echo %d > %s", freq_set, CPU_FREQ_SET_PATH);
244*4882a593Smuzhiyun printf("cpu: %d; set current frequency cmd is: %s\n",cpu_num,cmd);
245*4882a593Smuzhiyun system(cmd);
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun printf("\n=================== function :%s finish======================\n",__func__);
248*4882a593Smuzhiyun return freq_set;
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun
cpu_test(void * argv)252*4882a593Smuzhiyun void *cpu_test(void *argv)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun char cmd[128];
255*4882a593Smuzhiyun int test_flag=0;
256*4882a593Smuzhiyun printf("======= cpu frequency test starting ========\n\n");
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun /* 1�����ȴ�ӡ��ÿ��CPU֧�ֵ�CPU frequency table */
259*4882a593Smuzhiyun /* get all freq */
260*4882a593Smuzhiyun printf("********************get cpu frequency table start ***************\n");
261*4882a593Smuzhiyun cpu_num0 = get_cpu_freq_table(0,&cpu_0);
262*4882a593Smuzhiyun cpu_num1 = get_cpu_freq_table(1,&cpu_1);
263*4882a593Smuzhiyun // cpu_num2 = get_cpu_freq_table(2,&cpu_2);
264*4882a593Smuzhiyun // cpu_num3 = get_cpu_freq_table(3,&cpu_3);
265*4882a593Smuzhiyun if(-1 == cpu_num0|| -1== cpu_num1||-1 ==cpu_num2 || -1 ==cpu_num3)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun test_flag = -1;
268*4882a593Smuzhiyun goto fail;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun printf("********************get cpu frequency table finish***************\n\n");
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun /* 2��Ȼ���ӡ��ĿǰCPU���е�frequency */
274*4882a593Smuzhiyun printf("********************get current cpu frequency start ***************\n");
275*4882a593Smuzhiyun int cpu_0_freq,cpu_1_freq;
276*4882a593Smuzhiyun cpu_0_freq = get_curl_freq(0);
277*4882a593Smuzhiyun cpu_1_freq = get_curl_freq(1);
278*4882a593Smuzhiyun if(cpu_0_freq == -1 || cpu_1_freq==-1)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun test_flag = -1;
281*4882a593Smuzhiyun goto fail;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun printf("********************get current cpu frequency finish ***************\n\n");
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun /* 3������CPUһ��֧�ֵ�CPU frequency */
286*4882a593Smuzhiyun printf("********************set cpu frequency start ***************\n");
287*4882a593Smuzhiyun /* set mode to userspace */
288*4882a593Smuzhiyun test_flag = cpu_set_mode(_CPU_MODE_USER);
289*4882a593Smuzhiyun int freq_get,freq_set =-1;
290*4882a593Smuzhiyun int cpu_num = 0; //ѡ��CPU 0
291*4882a593Smuzhiyun int freq_num = rand()%cpu_num0; //���ѡ��CPU֧��Ƶ���б��е�һ����ܳ���
292*4882a593Smuzhiyun freq_set = set_curl_freq(cpu_num, freq_num);
293*4882a593Smuzhiyun printf("********************set cpu frequency finish ***************\n");
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun /* 4����ȡCPU��frequency�� �鿴�Ƿ������õ�һ��*/
296*4882a593Smuzhiyun freq_get = get_curl_freq(cpu_num);
297*4882a593Smuzhiyun if(freq_set == freq_get)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun printf("Cpu frequency set and get is equal; is %d MHz\n",freq_set/1000);
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun else{
302*4882a593Smuzhiyun printf("Cpu frequency set and get is not equal; set failed\n");
303*4882a593Smuzhiyun printf("Cpu frequency set is :%d MHz\n",freq_set);
304*4882a593Smuzhiyun printf("Cpu frequency get is :%d MHz\n",freq_get);
305*4882a593Smuzhiyun test_flag = -1;
306*4882a593Smuzhiyun goto fail;
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun printf("======= cpu frequency test success ========\n");
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun return (void*)test_flag;
311*4882a593Smuzhiyun fail:
312*4882a593Smuzhiyun printf("======= cpu frequency test failed ========\n");
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun return (void*)test_flag;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun //����������cpu_test
main(int argc,char * argv[])318*4882a593Smuzhiyun int main(int argc, char *argv[])
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun int test_flag = 0,err_code = 0;
321*4882a593Smuzhiyun char buf[COMMAND_VALUESIZE] = "cpu_test";
322*4882a593Smuzhiyun char result[COMMAND_VALUESIZE] = RESULT_PASS;
323*4882a593Smuzhiyun test_flag = (int)cpu_test(argv[0]);
324*4882a593Smuzhiyun if(test_flag < 0)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun strcpy(result,RESULT_FAIL);
327*4882a593Smuzhiyun err_code = CPU_PROC_ERR;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun send_msg_to_server(buf, result, err_code);
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun
333