• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "adc_test.h"
10 #include "adc_if.h"
11 #include "hdf_base.h"
12 #include "hdf_io_service_if.h"
13 #include "hdf_log.h"
14 #include "osal_mem.h"
15 #include "securec.h"
16 #include "osal_thread.h"
17 #include "osal_time.h"
18 
19 
20 #define HDF_LOG_TAG adc_test_c
21 
22 #define TEST_ADC_VAL_NUM         50
23 #define ADC_TEST_WAIT_TIMES      100
24 #define ADC_TEST_WAIT_TIMEOUT    20
25 #define ADC_TEST_STACK_SIZE      (1024 * 64)
26 
AdcTestGetConfig(struct AdcTestConfig * config)27 static int32_t AdcTestGetConfig(struct AdcTestConfig *config)
28 {
29     int32_t ret;
30     struct HdfSBuf *reply = NULL;
31     struct HdfIoService *service = NULL;
32     const void *buf = NULL;
33     uint32_t len;
34 
35     HDF_LOGD("%s: enter", __func__);
36     service = HdfIoServiceBind("ADC_TEST");
37     if (service == NULL) {
38         return HDF_ERR_NOT_SUPPORT;
39     }
40 
41     do {
42         reply = HdfSbufObtain(sizeof(*config) + sizeof(uint64_t));
43         if (reply == NULL) {
44             HDF_LOGE("%s: failed to obtain reply", __func__);
45             ret = HDF_ERR_MALLOC_FAIL;
46             break;
47         }
48 
49         ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply);
50         if (ret != HDF_SUCCESS) {
51             HDF_LOGE("%s: remote dispatch failed", __func__);
52             break;
53         }
54 
55         if (!HdfSbufReadBuffer(reply, &buf, &len)) {
56             HDF_LOGE("%s: read buf failed", __func__);
57             ret = HDF_ERR_IO;
58             break;
59         }
60 
61         if (len != sizeof(*config)) {
62             HDF_LOGE("%s: config size:%zu, read size:%u", __func__, sizeof(*config), len);
63             ret = HDF_ERR_IO;
64             break;
65         }
66 
67         if (memcpy_s(config, sizeof(*config), buf, sizeof(*config)) != EOK) {
68             HDF_LOGE("%s: memcpy buf failed", __func__);
69             ret = HDF_ERR_IO;
70             break;
71         }
72         HDF_LOGD("%s: exit", __func__);
73         ret = HDF_SUCCESS;
74     } while (0);
75     HdfSbufRecycle(reply);
76     HdfIoServiceRecycle(service);
77     return ret;
78 }
79 
AdcTesterGet(void)80 static struct AdcTester *AdcTesterGet(void)
81 {
82     int32_t ret;
83     static struct AdcTester tester;
84     static bool hasInit = false;
85 
86     HDF_LOGE("%s: enter", __func__);
87     if (hasInit) {
88         return &tester;
89     }
90     ret = AdcTestGetConfig(&tester.config);
91     if (ret != HDF_SUCCESS) {
92         HDF_LOGE("%s: read config failed:%d", __func__, ret);
93         return NULL;
94     }
95     tester.handle = AdcOpen(tester.config.devNum);
96     if (tester.handle == NULL) {
97         HDF_LOGE("%s: open adc device:%u failed", __func__, tester.config.devNum);
98         return NULL;
99     }
100     hasInit = true;
101     HDF_LOGI("%s: done", __func__);
102     return &tester;
103 }
104 
AdcTestRead(void)105 static int32_t AdcTestRead(void)
106 {
107     struct AdcTester *tester = NULL;
108     uint32_t value[TEST_ADC_VAL_NUM];
109     int32_t ret;
110     int i;
111 
112     HDF_LOGI("%s: enter", __func__);
113     tester = AdcTesterGet();
114     if (tester == NULL) {
115         HDF_LOGE("%s: get tester failed", __func__);
116         return HDF_ERR_INVALID_OBJECT;
117     }
118     for (i = 0; i < TEST_ADC_VAL_NUM; i++) {
119         value[i] = 0;
120         ret = AdcRead(tester->handle, tester->config.channel, &value[i]);
121         if (ret != HDF_SUCCESS || value[i] >= (1U << tester->config.dataWidth)) {
122             HDF_LOGE("%s: read value failed, ret:%d", __func__, ret);
123             return HDF_ERR_IO;
124         }
125     }
126     HDF_LOGI("%s: ADC device num is %u", __func__, tester->config.devNum);
127 
128     HDF_LOGI("%s: done", __func__);
129     return HDF_SUCCESS;
130 }
131 
AdcTestThreadFunc(void * param)132 static int AdcTestThreadFunc(void *param)
133 {
134     struct AdcTester *tester = NULL;
135     uint32_t val;
136     int i;
137     int32_t ret;
138 
139     HDF_LOGI("%s: enter", __func__);
140     tester = AdcTesterGet();
141     if (tester == NULL) {
142         HDF_LOGE("%s: get tester failed", __func__);
143         *((int32_t *)param) = 1;
144         return HDF_ERR_INVALID_OBJECT;
145     }
146 
147     for (i = 0; i < ADC_TEST_WAIT_TIMES; i++) {
148         ret = AdcRead(tester->handle, tester->config.channel, &val);
149         if (ret != HDF_SUCCESS) {
150             HDF_LOGE("%s: AdcRead failed, ret:%d", __func__, ret);
151             *((int32_t *)param) = 1;
152             return HDF_ERR_IO;
153         }
154     }
155 
156     *((int32_t *)param) = 1;
157     HDF_LOGI("%s: done", __func__);
158     return val;
159 }
160 
AdcTestStartThread(struct OsalThread * thread1,struct OsalThread * thread2,const int32_t * count1,const int32_t * count2)161 static int32_t AdcTestStartThread(struct OsalThread *thread1, struct OsalThread *thread2,
162     const int32_t *count1, const int32_t *count2)
163 {
164     int32_t ret;
165     uint32_t time = 0;
166     struct OsalThreadParam cfg1;
167     struct OsalThreadParam cfg2;
168 
169     if (memset_s(&cfg1, sizeof(cfg1), 0, sizeof(cfg1)) != EOK ||
170         memset_s(&cfg2, sizeof(cfg2), 0, sizeof(cfg2)) != EOK) {
171         HDF_LOGE("%s:memset_s failed.", __func__);
172         return HDF_ERR_IO;
173     }
174 
175     cfg1.name = "AdcTestThread-1";
176     cfg2.name = "AdcTestThread-2";
177     cfg1.priority = cfg2.priority = OSAL_THREAD_PRI_DEFAULT;
178     cfg1.stackSize = cfg2.stackSize = ADC_TEST_STACK_SIZE;
179 
180     ret = OsalThreadStart(thread1, &cfg1);
181     if (ret != HDF_SUCCESS) {
182         HDF_LOGE("start test thread1 failed:%d", ret);
183         return ret;
184     }
185 
186     ret = OsalThreadStart(thread2, &cfg2);
187     if (ret != HDF_SUCCESS) {
188         HDF_LOGE("start test thread2 failed:%d", ret);
189     }
190 
191     while (*count1 == 0 || *count2 == 0) {
192         HDF_LOGV("waitting testing thread finish...");
193         OsalMSleep(ADC_TEST_WAIT_TIMES);
194         time++;
195         if (time > ADC_TEST_WAIT_TIMEOUT) {
196             break;
197         }
198     }
199     return ret;
200 }
201 
AdcTestMultiThread(void)202 static int32_t AdcTestMultiThread(void)
203 {
204     int32_t ret;
205     struct OsalThread thread1;
206     struct OsalThread thread2;
207     int32_t count1 = 0;
208     int32_t count2 = 0;
209 
210     ret = OsalThreadCreate(&thread1, (OsalThreadEntry)AdcTestThreadFunc, (void *)&count1);
211     if (ret != HDF_SUCCESS) {
212         HDF_LOGE("create test thread1 failed:%d", ret);
213         return ret;
214     }
215 
216     ret = OsalThreadCreate(&thread2, (OsalThreadEntry)AdcTestThreadFunc, (void *)&count2);
217     if (ret != HDF_SUCCESS) {
218         (void)OsalThreadDestroy(&thread1);
219         HDF_LOGE("create test thread1 failed:%d", ret);
220         return ret;
221     }
222 
223     ret = AdcTestStartThread(&thread1, &thread2, &count1, &count2);
224     if (ret != HDF_SUCCESS) {
225         HDF_LOGE("test start thread failed:%d", ret);
226     }
227 
228     (void)OsalThreadDestroy(&thread1);
229     (void)OsalThreadDestroy(&thread2);
230     return ret;
231 }
232 
AdcTestReliability(void)233 static int32_t AdcTestReliability(void)
234 {
235     struct AdcTester *tester = NULL;
236     uint32_t val;
237 
238     HDF_LOGI("%s: enter", __func__);
239     tester = AdcTesterGet();
240     if (tester == NULL || tester->handle == NULL) {
241         return HDF_ERR_INVALID_OBJECT;
242     }
243     HDF_LOGD("%s: test dfr for AdcRead ...", __func__);
244     // invalid handle
245     (void)AdcRead(NULL, tester->config.channel, &val);
246     // invalid channel
247     (void)AdcRead(tester->handle, tester->config.maxChannel + 1, &val);
248     // invalid val pointer
249     (void)AdcRead(tester->handle, tester->config.channel, NULL);
250     HDF_LOGI("%s: done", __func__);
251     return HDF_SUCCESS;
252 }
253 
AdcIfPerformanceTest(void)254 static int32_t AdcIfPerformanceTest(void)
255 {
256 #ifdef __LITEOS__
257     // liteos the accuracy of the obtained time is too large and inaccurate.
258     return HDF_SUCCESS;
259 #endif
260     struct AdcTester *tester = NULL;
261     uint64_t startMs;
262     uint64_t endMs;
263     uint64_t useTime;    // ms
264     uint32_t val;
265     int32_t ret;
266 
267     tester = AdcTesterGet();
268     if (tester == NULL || tester->handle == NULL) {
269         HDF_LOGE("%s:get tester fail", __func__);
270         return HDF_ERR_INVALID_OBJECT;
271     }
272 
273     startMs = OsalGetSysTimeMs();
274     ret = AdcRead(tester->handle, tester->config.channel, &val);
275     if (ret == HDF_SUCCESS) {
276         endMs = OsalGetSysTimeMs();
277         useTime = endMs - startMs;
278         HDF_LOGI("----->interface performance test:[start - end] < 1ms[%s]\r\n", useTime < 1 ? "yes" : "no");
279         return HDF_SUCCESS;
280     }
281     return HDF_FAILURE;
282 }
283 
284 struct AdcTestEntry {
285     int cmd;
286     int32_t (*func)(void);
287     const char *name;
288 };
289 
290 static struct AdcTestEntry g_entry[] = {
291     { ADC_TEST_CMD_READ, AdcTestRead, "AdcTestRead" },
292     { ADC_TEST_CMD_MULTI_THREAD, AdcTestMultiThread, "AdcTestMultiThread" },
293     { ADC_TEST_CMD_RELIABILITY, AdcTestReliability, "AdcTestReliability" },
294     { ADC_IF_PERFORMANCE_TEST, AdcIfPerformanceTest, "AdcIfPerformanceTest" },
295 };
296 
AdcTestExecute(int cmd)297 int32_t AdcTestExecute(int cmd)
298 {
299     uint32_t i;
300     int32_t ret = HDF_ERR_NOT_SUPPORT;
301 
302     if (cmd > ADC_TEST_CMD_MAX) {
303         HDF_LOGE("%s: invalid cmd:%d", __func__, cmd);
304         ret = HDF_ERR_NOT_SUPPORT;
305         HDF_LOGE("[%s][======cmd:%d====ret:%d======]", __func__, cmd, ret);
306         return ret;
307     }
308 
309     for (i = 0; i < sizeof(g_entry) / sizeof(g_entry[0]); i++) {
310         if (g_entry[i].cmd != cmd || g_entry[i].func == NULL) {
311             continue;
312         }
313         ret = g_entry[i].func();
314         break;
315     }
316 
317     HDF_LOGE("[%s][======cmd:%d====ret:%d======]", __func__, cmd, ret);
318     return ret;
319 }
320