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