• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_STACK_SIZE        (1024 * 64)
25 
AdcTestGetConfig(struct AdcTestConfig * config)26 static int32_t AdcTestGetConfig(struct AdcTestConfig *config)
27 {
28     int32_t ret;
29     struct HdfSBuf *reply = NULL;
30     struct HdfIoService *service = NULL;
31     const void *buf = NULL;
32     uint32_t len;
33 
34     HDF_LOGD("%s: enter", __func__);
35     service = HdfIoServiceBind("ADC_TEST");
36     if (service == NULL) {
37         return HDF_ERR_NOT_SUPPORT;
38     }
39 
40     reply = HdfSbufObtain(sizeof(*config) + sizeof(uint64_t));
41     if (reply == NULL) {
42         HDF_LOGE("%s: failed to obtain reply", __func__);
43         return HDF_ERR_MALLOC_FAIL;
44     }
45 
46     ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply);
47     if (ret != HDF_SUCCESS) {
48         HDF_LOGE("%s: remote dispatch failed", __func__);
49         return ret;
50     }
51 
52     if (!HdfSbufReadBuffer(reply, &buf, &len)) {
53         HDF_LOGE("%s: read buf failed", __func__);
54         HdfSbufRecycle(reply);
55         return HDF_ERR_IO;
56     }
57 
58     if (len != sizeof(*config)) {
59         HDF_LOGE("%s: config size:%zu, read size:%u", __func__, sizeof(*config), len);
60         HdfSbufRecycle(reply);
61         return HDF_ERR_IO;
62     }
63 
64     if (memcpy_s(config, sizeof(*config), buf, sizeof(*config)) != EOK) {
65         HDF_LOGE("%s: memcpy buf failed", __func__);
66         HdfSbufRecycle(reply);
67         return HDF_ERR_IO;
68     }
69     HdfSbufRecycle(reply);
70     HDF_LOGD("%s: exit", __func__);
71     return HDF_SUCCESS;
72 }
73 
AdcTesterGet(void)74 struct AdcTester *AdcTesterGet(void)
75 {
76     int32_t ret;
77     static struct AdcTester tester;
78     static bool hasInit = false;
79 
80     HDF_LOGE("%s: enter", __func__);
81     if (hasInit) {
82         return &tester;
83     }
84     ret = AdcTestGetConfig(&tester.config);
85     if (ret != HDF_SUCCESS) {
86         HDF_LOGE("%s: read config failed:%d", __func__, ret);
87         return NULL;
88     }
89     tester.handle = AdcOpen(tester.config.devNum);
90     if (tester.handle == NULL) {
91         HDF_LOGE("%s: open adc device:%u failed", __func__, tester.config.devNum);
92         return NULL;
93     }
94     hasInit = true;
95     HDF_LOGI("%s: done", __func__);
96     return &tester;
97 }
98 
AdcTestRead(void)99 int32_t AdcTestRead(void)
100 {
101     struct AdcTester *tester = NULL;
102     uint32_t value[TEST_ADC_VAL_NUM];
103     int32_t ret;
104     int i;
105 
106     HDF_LOGI("%s: enter", __func__);
107     tester = AdcTesterGet();
108     if (tester == NULL) {
109         HDF_LOGE("%s: get tester failed", __func__);
110         return HDF_ERR_INVALID_OBJECT;
111     }
112     for (i = 0; i < TEST_ADC_VAL_NUM; i++) {
113         value[i] = 0;
114         ret = AdcRead(tester->handle, tester->config.channel, &value[i]);
115         if (ret != HDF_SUCCESS || value[i] >= (1U << tester->config.dataWidth)) {
116             HDF_LOGE("%s: read value failed, ret:%d", __func__, ret);
117             return HDF_ERR_IO;
118         }
119     }
120 
121     HDF_LOGI("%s: done", __func__);
122     return HDF_SUCCESS;
123 }
124 
AdcTestThreadFunc(void * param)125 static int AdcTestThreadFunc(void *param)
126 {
127     struct AdcTester *tester = NULL;
128     uint32_t val;
129     int i;
130     int32_t ret;
131 
132     HDF_LOGI("%s: enter", __func__);
133     tester = AdcTesterGet();
134     if (tester == NULL) {
135         HDF_LOGE("%s: get tester failed", __func__);
136         *((int32_t *)param) = 1;
137         return HDF_ERR_INVALID_OBJECT;
138     }
139 
140     for (i = 0; i < ADC_TEST_WAIT_TIMES; i++) {
141         ret = AdcRead(tester->handle, tester->config.channel, &val);
142         if (ret != HDF_SUCCESS) {
143             HDF_LOGE("%s: AdcRead failed, ret:%d", __func__, ret);
144             *((int32_t *)param) = 1;
145             return HDF_ERR_IO;
146         }
147     }
148 
149     *((int32_t *)param) = 1;
150     HDF_LOGI("%s: done", __func__);
151     return val;
152 }
153 
AdcTestMultiThread(void)154 int32_t AdcTestMultiThread(void)
155 {
156     int32_t ret;
157     struct OsalThread thread1, thread2;
158     struct OsalThreadParam cfg1, cfg2;
159     int32_t count1 = 0;
160     int32_t count2 = 0;
161 
162     HDF_LOGI("%s: enter", __func__);
163     ret = OsalThreadCreate(&thread1, (OsalThreadEntry)AdcTestThreadFunc, (void *)&count1);
164     if (ret != HDF_SUCCESS) {
165         HDF_LOGE("create test thread1 fail:%d", ret);
166         return HDF_FAILURE;
167     }
168 
169     ret = OsalThreadCreate(&thread2, (OsalThreadEntry)AdcTestThreadFunc, (void *)&count2);
170     if (ret != HDF_SUCCESS) {
171         HDF_LOGE("create test thread1 fail:%d", ret);
172         return HDF_FAILURE;
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 fail:%d", ret);
183         return HDF_FAILURE;
184     }
185 
186     ret = OsalThreadStart(&thread2, &cfg2);
187     if (ret != HDF_SUCCESS) {
188         HDF_LOGE("start test thread2 fail:%d", ret);
189         return HDF_FAILURE;
190     }
191 
192     while (count1 == 0 || count2 == 0) {
193         HDF_LOGE("waitting testing thread finish...");
194         OsalMSleep(ADC_TEST_WAIT_TIMES);
195     }
196 
197     (void)OsalThreadDestroy(&thread1);
198     (void)OsalThreadDestroy(&thread2);
199     HDF_LOGI("%s: done", __func__);
200     return HDF_SUCCESS;
201 }
202 
AdcTestReliability(void)203 int32_t AdcTestReliability(void)
204 {
205     struct AdcTester *tester = NULL;
206     uint32_t val;
207 
208     HDF_LOGI("%s: enter", __func__);
209     tester = AdcTesterGet();
210     if (tester == NULL || tester->handle == NULL) {
211         return HDF_ERR_INVALID_OBJECT;
212     }
213     HDF_LOGD("%s: test dfr for AdcRead ...", __func__);
214     // invalid handle
215     (void)AdcRead(NULL, tester->config.channel, &val);
216     // invalid channel
217     (void)AdcRead(tester->handle, tester->config.maxChannel + 1, &val);
218     // invalid val pointer
219     (void)AdcRead(tester->handle, tester->config.channel, NULL);
220     HDF_LOGI("%s: done", __func__);
221     return HDF_SUCCESS;
222 }
223 
AdcIfPerformanceTest(void)224 static int32_t AdcIfPerformanceTest(void)
225 {
226 #ifdef __LITEOS__
227     // liteos the accuracy of the obtained time is too large and inaccurate.
228     return HDF_SUCCESS;
229 #endif
230     struct AdcTester *tester = NULL;
231     uint64_t startMs;
232     uint64_t endMs;
233     uint64_t useTime;    // ms
234     uint32_t val;
235     int32_t ret;
236 
237     tester = AdcTesterGet();
238     if (tester == NULL || tester->handle == NULL) {
239         HDF_LOGE("%s:get tester fail", __func__);
240         return HDF_ERR_INVALID_OBJECT;
241     }
242 
243     startMs = OsalGetSysTimeMs();
244     ret = AdcRead(tester->handle, tester->config.channel, &val);
245     if (ret == HDF_SUCCESS) {
246         endMs = OsalGetSysTimeMs();
247         useTime = endMs - startMs;
248         HDF_LOGI("----->interface performance test:[start:%lld(ms) - end:%lld(ms) = %lld (ms)] < 1ms[%d]\r\n",
249             startMs, endMs, useTime, useTime < 1 ? true : false);
250     }
251     return HDF_FAILURE;
252 }
253 
254 struct AdcTestEntry {
255     int cmd;
256     int32_t (*func)(void);
257     const char *name;
258 };
259 
260 static struct AdcTestEntry g_entry[] = {
261     { ADC_TEST_CMD_READ, AdcTestRead, "AdcTestRead" },
262     { ADC_TEST_CMD_MULTI_THREAD, AdcTestMultiThread, "AdcTestMultiThread" },
263     { ADC_TEST_CMD_RELIABILITY, AdcTestReliability, "AdcTestReliability" },
264     { ADC_IF_PERFORMANCE_TEST, AdcIfPerformanceTest, "AdcIfPerformanceTest" },
265 };
266 
AdcTestExecute(int cmd)267 int32_t AdcTestExecute(int cmd)
268 {
269     uint32_t i;
270     int32_t ret = HDF_ERR_NOT_SUPPORT;
271 
272     if (cmd > ADC_TEST_CMD_MAX) {
273         HDF_LOGE("%s: invalid cmd:%d", __func__, cmd);
274         ret = HDF_ERR_NOT_SUPPORT;
275         HDF_LOGE("[%s][======cmd:%d====ret:%d======]", __func__, cmd, ret);
276         return ret;
277     }
278 
279     for (i = 0; i < sizeof(g_entry) / sizeof(g_entry[0]); i++) {
280         if (g_entry[i].cmd != cmd || g_entry[i].func == NULL) {
281             continue;
282         }
283         ret = g_entry[i].func();
284         break;
285     }
286 
287     HDF_LOGE("[%s][======cmd:%d====ret:%d======]", __func__, cmd, ret);
288     return ret;
289 }
290