1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-06-19 Sherman the first version
9 */
10
11 #include <string.h>
12 #include <stdlib.h>
13
14 #define DBG_TAG "example"
15 #define DBG_LVL DBG_LOG
16 #include <rtdbg.h>
17 #include <rtlink_dev.h>
18
19 enum
20 {
21 NONE_TEST = 0,
22 SHORT_FRAME_TEST,
23 LONG_FRAME_TEST
24 };
25 static rt_uint8_t speed_test_type = NONE_TEST;
26
27 static struct rt_link_device rtlink_dev = {0};
28 #define RTLINK01 "rtlink01"
29 #define TEST_CONTEXT "This message is sent by RT-Link"
30 rt_uint8_t test_buff[1024] = {0};
31
rtlink_dev_rx_ind(rt_device_t dev,rt_size_t size)32 static rt_err_t rtlink_dev_rx_ind(rt_device_t dev, rt_size_t size)
33 {
34 RT_ASSERT(dev != RT_NULL);
35 LOG_I("rx_ind: dev name %s, rx size %d", dev->parent.name, size);
36 return RT_EOK;
37 }
38
rtlink_dev_tx_done(rt_device_t dev,void * buffer)39 static rt_err_t rtlink_dev_tx_done(rt_device_t dev, void *buffer)
40 {
41 RT_ASSERT(dev != RT_NULL);
42 struct rt_link_device *rtlink_dev = (struct rt_link_device *)dev;
43 LOG_I("tx_done: dev name %s, buffer 0x%p errno %d", dev->parent.name, buffer, rtlink_dev->service.err);
44 rt_free(buffer);
45 return RT_EOK;
46 }
47
48 #ifdef RT_USING_POSIX_DEVIO
49 #include <dfs_file.h>
50 #include <unistd.h>
51 #include <stdio.h>
52 #include <sys/stat.h>
53 #include <sys/statfs.h>
54 #include <poll.h>
55 #include <sys/select.h>
56
57 #define RTLINK01_PATH "/dev/rtlink01"
58 int fd = -1;
59
rtlink_fopen(int argc,char * argv[])60 static void rtlink_fopen(int argc, char *argv[])
61 {
62 fd = open(RTLINK01_PATH, O_RDWR | O_NONBLOCK);
63
64 if (fd < 0)
65 {
66 LOG_E("open rt_link failed!");
67 }
68 }
69 MSH_CMD_EXPORT(rtlink_fopen, rtlink posix interface example);
70
rtlink_fclose(int argc,char * argv[])71 static void rtlink_fclose(int argc, char *argv[])
72 {
73 LOG_D("colse %d", fd);
74 close(fd);
75 fd = -1;
76 }
77 MSH_CMD_EXPORT(rtlink_fclose, rtlink posix interface example);
78
rtlink_fread(int argc,char * argv[])79 static void rtlink_fread(int argc, char *argv[])
80 {
81 int read_len;
82 read_len = read(fd, test_buff, sizeof(test_buff));
83 LOG_D("read len %d", read_len);
84 LOG_HEX("read", 8, test_buff, 32);
85 }
86 MSH_CMD_EXPORT(rtlink_fread, rtlink posix interface example);
87
rtlink_fwrite(int argc,char * argv[])88 static void rtlink_fwrite(int argc, char *argv[])
89 {
90 char *data = RT_NULL;
91 rt_size_t length = 0;
92 rt_uint16_t count = 0;
93 rt_size_t ret = 0;
94
95 if (argc == 1)
96 {
97 data = rt_malloc(sizeof(TEST_CONTEXT));
98 if (data)
99 {
100 length = sizeof(TEST_CONTEXT) - 1;
101 rt_memcpy(data, TEST_CONTEXT, sizeof(TEST_CONTEXT) - 1);
102 ret = write(fd, data, length);
103 }
104 LOG_I("write data(0x%p) result: %d.", data, ret);
105 }
106 else if (argc >= 3)
107 {
108 if (strcmp(argv[1], "-l") == 0)
109 {
110 data = rt_malloc(atoi((const char *)argv[2]));
111 if (data)
112 {
113 for (count = 0; count < atoi((const char *)argv[2]); count++)
114 {
115 data[count] = (count % 93 + 33);
116 }
117 length = atoi((const char *)argv[2]);
118 ret = write(fd, data, length);
119 }
120 LOG_I("write data(0x%p) result: %d.", data, ret);
121 }
122 else
123 {
124 LOG_E("Invalid parameter.");
125 }
126 }
127 }
128 MSH_CMD_EXPORT(rtlink_fwrite, rtlink posix interface example);
129
130 #define RTLINK02 "rtlink02"
131 #define RTLINK02_PATH "/dev/rtlink02"
132 static struct rt_link_device rtlink_fd = {0};
133 rt_uint8_t fd_buff[1024] = {0};
134
listen_thread(void * param)135 static void listen_thread(void *param)
136 {
137 int fd = open(RTLINK02_PATH, O_RDWR | O_NONBLOCK);
138 if (fd < 0)
139 {
140 LOG_E("open (%s) failed", RTLINK02);
141 return;
142 }
143 while (1)
144 {
145 rt_uint8_t *write_buf = RT_NULL;
146 int write_len = 0;
147 fd_set readfds, writefds;
148 FD_ZERO(&readfds);
149 FD_ZERO(&writefds);
150 FD_SET(fd, &readfds);
151 FD_SET(fd, &writefds);
152
153 int ret = select(fd + 1, &readfds, &writefds, RT_NULL, RT_NULL);
154 LOG_D("select ret(%d), read (%d), write (%d)", ret, readfds, writefds);
155 if (FD_ISSET(fd, &readfds))
156 {
157 LOG_I("POLLIN");
158 int read_len = read(fd, fd_buff, sizeof(test_buff));
159 LOG_D("read len %d", read_len);
160 LOG_HEX("read", 8, test_buff, 32);
161 }
162
163 if (FD_ISSET(fd, &writefds))
164 {
165 LOG_I("POLLOUT");
166 write_buf = rt_malloc(1024);
167 if (write_buf)
168 {
169 write_len = write(fd, write_buf, 1024);
170 LOG_D("write %d", write_len);
171 }
172 }
173
174 rt_thread_delay(500);
175 }
176 LOG_I("fd (%s) listen thread exit", RTLINK02);
177 }
178
rtlink_fselect()179 static void rtlink_fselect()
180 {
181 /* step1: register rtlink to to the device framework */
182 rt_link_dev_register(&rtlink_fd, RTLINK02,
183 RT_DEVICE_FLAG_RDWR |
184 RT_DEVICE_FLAG_REMOVABLE |
185 RT_DEVICE_FLAG_STANDALONE,
186 RT_NULL);
187
188 /* step2: Initialize the rlink device as the default configuration, */
189 rt_device_t device = rt_device_find(RTLINK02);
190 if (device == RT_NULL)
191 {
192 LOG_E("device not find!");
193 return ;
194 }
195 rt_device_init(device);
196
197 /* step3: config rtlink device rx/tx callback, channel, send timeout */
198 rt_device_set_rx_indicate(device, rtlink_dev_rx_ind);
199 rt_device_set_tx_complete(device, rtlink_dev_tx_done);
200 struct rt_link_service service;
201 service.service = RT_LINK_SERVICE_MNGT;
202 service.timeout_tx = RT_WAITING_NO;
203 rt_device_control(device, RT_DEVICE_CTRL_CONFIG, &service);
204
205 rt_thread_t tid = rt_thread_create(RTLINK02, listen_thread, RT_NULL, 1024, 21, 20);
206 if (tid)
207 {
208 rt_thread_startup(tid);
209 }
210 }
211 MSH_CMD_EXPORT(rtlink_fselect, rtlink posix interface example);
212 #endif /* RT_USING_POSIX_DEVIO */
213
rtlink_dread(void)214 static void rtlink_dread(void)
215 {
216 rt_size_t read_len = 0;
217 rt_device_t dev = rt_device_find(RTLINK01);
218 if (dev == RT_NULL)
219 {
220 LOG_E("dev %s not find ", RTLINK01);
221 return;
222 }
223
224 read_len = rt_device_read(dev, 0, test_buff, sizeof(test_buff));
225
226 LOG_D("read len %d", read_len);
227 LOG_HEX("read", 8, test_buff, 32);
228 }
229 MSH_CMD_EXPORT(rtlink_dread, rtlink device interface example);
230
rt_link_speed_test(void * paremeter)231 void rt_link_speed_test(void *paremeter)
232 {
233 int ret;
234 rt_uint8_t *send_buf, *data;
235 rt_size_t bufflen = 0;
236 rt_size_t sentlen = 0;
237 rt_size_t count = 0;
238 rt_tick_t tick1, tick2;
239 rt_size_t total = 0;
240 rt_uint32_t integer, decimal;
241 rt_device_t dev = rt_device_find(RTLINK01);
242 if (dev == RT_NULL)
243 {
244 LOG_E("dev %s not find!", RTLINK01);
245 return ;
246 }
247
248 if (speed_test_type == SHORT_FRAME_TEST)
249 {
250 bufflen = 988;
251 }
252 else
253 {
254 bufflen = 3036;
255 }
256
257 send_buf = rt_malloc(bufflen);
258 if (send_buf != RT_NULL)
259 {
260 data = send_buf;
261 for (count = 0; count < bufflen; count++)
262 {
263 *data++ = (count % 93 + 33);
264 }
265 }
266 else
267 {
268 rt_kprintf("speed of send buffer malloc failed.");
269 return;
270 }
271
272 tick1 = rt_tick_get();
273 while (speed_test_type)
274 {
275 ret = rt_device_write(dev, 0, send_buf, bufflen);
276
277 if (ret == RT_EOK)
278 {
279 sentlen += bufflen;
280 }
281
282 tick2 = rt_tick_get();
283 if (tick2 - tick1 >= RT_TICK_PER_SECOND)
284 {
285 total = sentlen * RT_TICK_PER_SECOND / 125 / (tick2 - tick1);
286 integer = total / 1000;
287 decimal = total % 1000;
288 LOG_I("%d.%03d0 Mbps!", integer, decimal);
289 sentlen = 0;
290 tick1 = tick2;
291 }
292 }
293 rt_free(send_buf);
294 LOG_W("speed test end, type %d", speed_test_type);
295 }
296
create_thead_to_test_speed(rt_uint8_t mutil_num)297 void create_thead_to_test_speed(rt_uint8_t mutil_num)
298 {
299 rt_uint8_t i = 0;
300
301 LOG_D("Speed test type [%02d], mutil [%02d]", speed_test_type, mutil_num);
302 for (i = 0; i < mutil_num; i++)
303 {
304 rt_thread_t tid;
305 char tid_name[RT_NAME_MAX + 1] = {0};
306
307 rt_snprintf(tid_name, sizeof(tid_name), "lny_s%03d", i + 1);
308 tid = rt_thread_create(tid_name, rt_link_speed_test, RT_NULL, 1024, 20, 10);
309 rt_thread_startup(tid);
310 LOG_I("Speed test thread[%s] startup", tid_name);
311 }
312 }
313
rtlink_dwrite(int argc,char * argv[])314 static rt_err_t rtlink_dwrite(int argc, char *argv[])
315 {
316 char *data = RT_NULL;
317 rt_size_t length = 0;
318 rt_uint16_t count = 0;
319 rt_size_t ret = -RT_ERROR;
320
321 rt_device_t dev = rt_device_find(RTLINK01);
322 if (dev == RT_NULL)
323 {
324 LOG_E("device not find!");
325 return ret;
326 }
327
328 if (argc == 1)
329 {
330 data = rt_malloc(sizeof(TEST_CONTEXT));
331 length = sizeof(TEST_CONTEXT) - 1;
332 rt_memcpy(data, TEST_CONTEXT, sizeof(TEST_CONTEXT) - 1);
333
334 ret = rt_device_write(dev, 0, data, length);
335 LOG_I("write data(0x%p) result: %d.", data, ret);
336 }
337 else if (argc >= 3)
338 {
339 if (strcmp(argv[1], "-l") == 0)
340 {
341 data = rt_malloc(atoi((const char *)argv[2]));
342 for (count = 0; count < atoi((const char *)argv[2]); count++)
343 {
344 data[count] = (count % 93 + 33);
345 }
346 length = atoi((const char *)argv[2]);
347 ret = rt_device_write(dev, 0, data, length);
348 LOG_I("write data(0x%p) result: %d.", data, ret);
349 }
350 else
351 {
352 LOG_E("Invalid parameter.");
353 }
354 }
355 return ret;
356 }
357 MSH_CMD_EXPORT(rtlink_dwrite, rtlink device interface example);
358
rtlink_dinit(void)359 static void rtlink_dinit(void)
360 {
361 /* step1: register rtlink to to the device framework */
362 rt_link_dev_register(&rtlink_dev, RTLINK01,
363 RT_DEVICE_FLAG_RDWR |
364 RT_DEVICE_FLAG_REMOVABLE |
365 RT_DEVICE_FLAG_STANDALONE,
366 RT_NULL);
367
368 /* step2: Initialize the rlink device as the default configuration, */
369 rt_device_t device = rt_device_find(RTLINK01);
370 if (device == RT_NULL)
371 {
372 LOG_E("device not find!");
373 return ;
374 }
375 rt_device_init(device);
376
377 /* step3: config rtlink device rx/tx callback, channel, send timeout */
378 rt_device_set_rx_indicate(device, rtlink_dev_rx_ind);
379 rt_device_set_tx_complete(device, rtlink_dev_tx_done);
380 struct rt_link_service service;
381 service.service = RT_LINK_SERVICE_SOCKET;
382 service.timeout_tx = RT_WAITING_FOREVER;
383 service.flag = RT_LINK_FLAG_ACK | RT_LINK_FLAG_CRC;
384 rt_device_control(device, RT_DEVICE_CTRL_CONFIG, &service);
385 }
386 MSH_CMD_EXPORT(rtlink_dinit, rtlink device interface example);
387
rtlink_dopen()388 static void rtlink_dopen()
389 {
390 /* step4: open rtlink device, attach the service channel */
391 rt_device_t device = rt_device_find(RTLINK01);
392 if (device == RT_NULL)
393 {
394 LOG_E("device not find!");
395 return ;
396 }
397 rt_err_t ret = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
398 LOG_I("dev open ret %d", ret);
399 }
400 MSH_CMD_EXPORT(rtlink_dopen, rtlink device interface example);
401