• 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 "dac_test.h"
10 #include "hdf_io_service_if.h"
11 #include "hdf_log.h"
12 #include "osal_thread.h"
13 #include "osal_time.h"
14 #include "securec.h"
15 
16 #define HDF_LOG_TAG dac_test_c
17 #define DAC_TEST_WAIT_TIMES        100
18 #define TEST_DAC_VAL_NUM           50
19 #define DAC_TEST_STACK_SIZE        (1024 * 64)
20 #define DAC_TEST_WAIT_TIMEOUT      20
21 
DacTestGetConfig(struct DacTestConfig * config)22 static int32_t DacTestGetConfig(struct DacTestConfig *config)
23 {
24     int32_t ret;
25     struct HdfSBuf *reply = NULL;
26     struct HdfIoService *service = NULL;
27     const void *buf = NULL;
28     uint32_t len;
29 
30     service = HdfIoServiceBind("DAC_TEST");
31     if (service == NULL) {
32         return HDF_ERR_NOT_SUPPORT;
33     }
34 
35     reply = HdfSbufObtain(sizeof(*config) + sizeof(uint64_t));
36     if (reply == NULL) {
37         HDF_LOGE("%s: failed to obtain reply", __func__);
38         return HDF_ERR_MALLOC_FAIL;
39     }
40 
41     ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply);
42     if (ret != HDF_SUCCESS) {
43         HDF_LOGE("%s: remote dispatch failed", __func__);
44         HdfSbufRecycle(reply);
45         return ret;
46     }
47 
48     if (!HdfSbufReadBuffer(reply, &buf, &len)) {
49         HDF_LOGE("%s: read buf failed", __func__);
50         HdfSbufRecycle(reply);
51         return HDF_ERR_IO;
52     }
53 
54     if (len != sizeof(*config)) {
55         HDF_LOGE("%s: config size:%zu, read size:%u", __func__, sizeof(*config), len);
56         HdfSbufRecycle(reply);
57         return HDF_ERR_IO;
58     }
59 
60     if (memcpy_s(config, sizeof(*config), buf, sizeof(*config)) != EOK) {
61         HDF_LOGE("%s: memcpy buf failed", __func__);
62         HdfSbufRecycle(reply);
63         return HDF_ERR_IO;
64     }
65     HdfSbufRecycle(reply);
66     HDF_LOGD("%s: exit", __func__);
67     return HDF_SUCCESS;
68 }
69 
DacTesterGet(void)70 struct DacTester *DacTesterGet(void)
71 {
72     int32_t ret;
73     static struct DacTester tester;
74 
75     ret = DacTestGetConfig(&tester.config);
76     if (ret != HDF_SUCCESS) {
77         HDF_LOGE("%s: write config failed:%d", __func__, ret);
78         return NULL;
79     }
80     tester.handle = DacOpen(tester.config.devNum);
81     if (tester.handle == NULL) {
82         HDF_LOGE("%s: open dac device:%u failed", __func__, tester.config.devNum);
83         return NULL;
84     }
85     return &tester;
86 }
87 
DacTesterPut(struct DacTester * tester)88 static void DacTesterPut(struct DacTester *tester)
89 {
90     if (tester == NULL) {
91         HDF_LOGE("%s: tester is NULL", __func__);
92         return;
93     }
94     DacClose(tester->handle);
95     tester->handle = NULL;
96 }
97 
DacTestWrite(void)98 int32_t DacTestWrite(void)
99 {
100     struct DacTester *tester = NULL;
101     uint32_t value[TEST_DAC_VAL_NUM];
102     int32_t ret;
103     int i;
104 
105     tester = DacTesterGet();
106     if (tester == NULL || tester->handle == NULL) {
107         HDF_LOGE("%s: get tester failed", __func__);
108         return HDF_ERR_INVALID_OBJECT;
109     }
110     for (i = 0; i < TEST_DAC_VAL_NUM; i++) {
111         value[i] = i;
112         ret = DacWrite(tester->handle, tester->config.channel, value[i]);
113         if (ret != HDF_SUCCESS) {
114             HDF_LOGE("%s: write value failed:%u, ret:%d", __func__, value[i], ret);
115             DacTesterPut(tester);
116             return HDF_ERR_IO;
117         }
118     }
119 
120     DacTesterPut(tester);
121     return HDF_SUCCESS;
122 }
123 
DacTestThreadFunc(void * param)124 static int DacTestThreadFunc(void *param)
125 {
126     struct DacTester *tester = NULL;
127     uint32_t val;
128     uint32_t i;
129     int32_t ret;
130 
131     tester = DacTesterGet();
132     if (tester == NULL) {
133         HDF_LOGE("%s: get tester failed", __func__);
134         *((int32_t *)param) = 1;
135         return HDF_ERR_INVALID_OBJECT;
136     }
137     for (i = 0; i < DAC_TEST_WAIT_TIMES; i++) {
138         val = i;
139         ret = DacWrite(tester->handle, tester->config.channel, val);
140         if (ret != HDF_SUCCESS) {
141             HDF_LOGE("%s: DacWrite failed, ret:%d", __func__, ret);
142             *((int32_t *)param) = 1;
143             DacTesterPut(tester);
144             return HDF_ERR_IO;
145         }
146     }
147 
148     *((int32_t *)param) = 1;
149     DacTesterPut(tester);
150     return val;
151 }
152 
DacTestMultiThread(void)153 int32_t DacTestMultiThread(void)
154 {
155     int32_t ret;
156     uint32_t time;
157     struct OsalThread thread1, thread2;
158     struct OsalThreadParam cfg1, cfg2;
159     int32_t count1, count2;
160 
161     count1 = 0;
162     count2 = 0;
163     time = 0;
164     ret = OsalThreadCreate(&thread1, (OsalThreadEntry)DacTestThreadFunc, (void *)&count1);
165     if (ret != HDF_SUCCESS) {
166         HDF_LOGE("create test thread1 fail:%d", ret);
167         return HDF_FAILURE;
168     }
169 
170     ret = OsalThreadCreate(&thread2, (OsalThreadEntry)DacTestThreadFunc, (void *)&count2);
171     if (ret != HDF_SUCCESS) {
172         HDF_LOGE("create test thread1 fail:%d", ret);
173         return HDF_FAILURE;
174     }
175 
176     cfg1.name = "DacTestThread-1";
177     cfg2.name = "DacTestThread-2";
178     cfg1.priority = cfg2.priority = OSAL_THREAD_PRI_DEFAULT;
179     cfg1.stackSize = cfg2.stackSize = DAC_TEST_STACK_SIZE;
180 
181     ret = OsalThreadStart(&thread1, &cfg1);
182     if (ret != HDF_SUCCESS) {
183         HDF_LOGE("start test thread1 fail:%d", ret);
184         return HDF_FAILURE;
185     }
186 
187     ret = OsalThreadStart(&thread2, &cfg2);
188     if (ret != HDF_SUCCESS) {
189         HDF_LOGE("start test thread2 fail:%d", ret);
190         return HDF_FAILURE;
191     }
192 
193     while (count1 == 0 || count2 == 0) {
194         HDF_LOGE("waitting testing thread finish...");
195         OsalMSleep(DAC_TEST_WAIT_TIMES);
196         time++;
197         if (time > DAC_TEST_WAIT_TIMEOUT) {
198             break;
199         }
200     }
201 
202     (void)OsalThreadDestroy(&thread1);
203     (void)OsalThreadDestroy(&thread2);
204     return HDF_SUCCESS;
205 }
206 
DacTestReliability(void)207 int32_t DacTestReliability(void)
208 {
209     struct DacTester *tester = NULL;
210     uint32_t val;
211 
212     val = 0;
213     tester = DacTesterGet();
214     if (tester == NULL || tester->handle == NULL) {
215         return HDF_ERR_INVALID_OBJECT;
216     }
217     HDF_LOGD("%s: test dfr for DacRead ...", __func__);
218     // invalid handle
219     (void)DacWrite(NULL, tester->config.channel, val);
220     // invalid channel
221     (void)DacWrite(tester->handle, tester->config.maxChannel + 1, val);
222     DacTesterPut(tester);
223     return HDF_SUCCESS;
224 }
225 
DacIfPerformanceTest(void)226 static int32_t DacIfPerformanceTest(void)
227 {
228 #ifdef __LITEOS__
229     // liteos the accuracy of the obtained time is too large and inaccurate.
230     return HDF_SUCCESS;
231 #endif
232 
233     uint64_t startMs;
234     uint64_t endMs;
235     uint64_t useTime;    // ms
236     struct DacTester *tester = NULL;
237     int32_t ret;
238     uint32_t val;
239 
240     val = 0;
241     tester = DacTesterGet();
242     if (tester == NULL || tester->handle == NULL) {
243         HDF_LOGE("%s: get tester failed", __func__);
244         return HDF_ERR_INVALID_OBJECT;
245     }
246 
247     startMs = OsalGetSysTimeMs();
248     ret = DacWrite(tester->handle, tester->config.channel, val);
249     if (ret != HDF_SUCCESS) {
250         HDF_LOGE("%s: write value failed:%u, ret:%d", __func__, val, ret);
251         DacTesterPut(tester);
252         return HDF_ERR_IO;
253     }
254     endMs = OsalGetSysTimeMs();
255 
256     useTime = endMs - startMs;
257     HDF_LOGI("----->interface performance test:[start:%lld(ms) - end:%lld(ms) = %lld (ms)] < 1ms[%d]\r\n",
258         startMs, endMs, useTime, useTime < 1 ? true : false);
259     DacTesterPut(tester);
260     return HDF_SUCCESS;
261 }
262 
263 struct DacTestEntry {
264     int cmd;
265     int32_t (*func)(void);
266     const char *name;
267 };
268 static struct DacTestEntry g_entry[] = {
269     { DAC_TEST_CMD_WRITE, DacTestWrite, "DacTestWrite" },
270     { DAC_TEST_CMD_MULTI_THREAD, DacTestMultiThread, "DacTestMultiThread" },
271     { DAC_TEST_CMD_RELIABILITY, DacTestReliability, "DacTestReliability" },
272     { DAC_TEST_CMD_IF_PERFORMANCE, DacIfPerformanceTest, "DacIfPerformanceTest" },
273 };
274 
DacTestExecute(int cmd)275 int32_t DacTestExecute(int cmd)
276 {
277     uint32_t i;
278     int32_t ret = HDF_ERR_NOT_SUPPORT;
279 
280     if (cmd > DAC_TEST_CMD_MAX) {
281         HDF_LOGE("%s: invalid cmd:%d", __func__, cmd);
282         ret = HDF_ERR_NOT_SUPPORT;
283         HDF_LOGE("[%s][======cmd:%d====ret:%d======]", __func__, cmd, ret);
284         return ret;
285     }
286 
287     for (i = 0; i < sizeof(g_entry) / sizeof(g_entry[0]); i++) {
288         if (g_entry[i].cmd != cmd || g_entry[i].func == NULL) {
289             continue;
290         }
291         ret = g_entry[i].func();
292         break;
293     }
294 
295     HDF_LOGE("[%s][======cmd:%d====ret:%d======]", __func__, cmd, ret);
296     return ret;
297 }
298