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