rtlink_dev_example.c 11 KB

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