rtlink.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320
  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-02-02 xiangxistu the first version
  9. * 2021-03-19 Sherman Optimize the transfer process
  10. * 2021-04-20 Sherman Optimize memory footprint
  11. * 2021-05-10 Sherman Add rtlink_status MSH command;
  12. * Optimize transmission timer Settings;
  13. * Fix known bugs
  14. * 2021-08-06 Sherman Add NACK, NCRC, non-blocking transmit mode;
  15. * Add service connection status;
  16. */
  17. #include <rtthread.h>
  18. #include <rtdevice.h>
  19. #include <board.h>
  20. #include <rthw.h>
  21. #include <rtlink.h>
  22. #include <rtlink_hw.h>
  23. #include <rtlink_utils.h>
  24. #define DBG_ENABLE
  25. #ifdef USING_RT_LINK_DEBUG
  26. #define DBG_LVL DBG_LOG
  27. #else
  28. #define DBG_LVL DBG_INFO
  29. #endif
  30. #define DBG_TAG "rtlink"
  31. #define DBG_COLOR
  32. #include <rtdbg.h>
  33. #ifdef RT_LINK_USING_SPI
  34. #define RT_LINK_LONG_FRAME_TIMEOUT 50
  35. #define RT_LINK_SENT_FRAME_TIMEOUT 100
  36. #else
  37. #define RT_LINK_LONG_FRAME_TIMEOUT 100
  38. #define RT_LINK_SENT_FRAME_TIMEOUT 100
  39. #endif /* RT_LINK_USING_SPI */
  40. #define RT_LINK_RECV_DATA_SEQUENCE 0
  41. #define RT_LINK_INIT_FRAME_SEQENCE 129
  42. #define RT_LINK_THREAD_NAME "rtlink"
  43. #define RT_LINK_THREAD_TICK 20
  44. #define RT_LINK_THREAD_PRIORITY 25
  45. #define RT_LINK_THREAD_STACK_SIZE 1024 /* 32 bytes aligned */
  46. #define RT_LINK_FRAME_SENT 1
  47. #define RT_LINK_FRAME_NOSEND 0
  48. typedef enum
  49. {
  50. FIND_FRAME_HEAD = 0,
  51. PARSE_FRAME_HEAD = 1,
  52. PARSE_FRAME_EXTEND = 2,
  53. PARSE_FRAME_SEQ = 3,
  54. CHECK_FRAME_CRC = 4,
  55. HEADLE_FRAME_DATA = 5,
  56. } rt_link_frame_parse_t;
  57. /* rtlink SCB(Session control block) */
  58. static struct rt_link_session *rt_link_scb = RT_NULL;
  59. struct rt_link_session *rt_link_get_scb(void)
  60. {
  61. return rt_link_scb;
  62. }
  63. static rt_int16_t rt_link_check_seq(rt_uint8_t new, rt_uint8_t used)
  64. {
  65. rt_int16_t compare_seq = 0;
  66. compare_seq = new - used;
  67. if (compare_seq < 0)
  68. {
  69. compare_seq = compare_seq + 256;
  70. }
  71. return compare_seq;
  72. }
  73. static int rt_link_frame_init(struct rt_link_frame *frame, rt_uint8_t config)
  74. {
  75. if (frame == RT_NULL)
  76. {
  77. return -RT_ERROR;
  78. }
  79. /* set frame control information */
  80. rt_memset(&frame->head, 0, sizeof(struct rt_link_frame_head));
  81. if (config & RT_LINK_FLAG_CRC)
  82. {
  83. frame->head.crc = 1;
  84. }
  85. if (config & RT_LINK_FLAG_ACK)
  86. {
  87. frame->head.ack = 1;
  88. }
  89. frame->head.magicid = RT_LINK_FRAME_HEAD;
  90. /* frame data information */
  91. rt_memset(&frame->extend, 0, sizeof(struct rt_link_extend));
  92. frame->crc = 0;
  93. frame->real_data = RT_NULL;
  94. frame->data_len = 0;
  95. frame->index = 0;
  96. frame->total = 0;
  97. frame->attribute = RT_LINK_RESERVE_FRAME;
  98. frame->issent = RT_LINK_FRAME_NOSEND;
  99. rt_slist_init(&frame->slist);
  100. return RT_EOK;
  101. }
  102. /* remove the sending list node*/
  103. static void rt_link_frame_remove(struct rt_link_service *service)
  104. {
  105. RT_ASSERT(service != RT_NULL);
  106. struct rt_link_frame *find_frame = RT_NULL;
  107. rt_uint8_t total = 0;
  108. rt_slist_t *tem_list = rt_slist_first(&rt_link_scb->tx_data_slist);
  109. if (tem_list != RT_NULL)
  110. {
  111. do
  112. {
  113. find_frame = rt_container_of(tem_list, struct rt_link_frame, slist);
  114. tem_list = rt_slist_next(tem_list);
  115. if (find_frame->head.service == service->service)
  116. {
  117. if (total == 0)
  118. {
  119. total = find_frame->total;
  120. }
  121. /* The data frame order is appended to the list,
  122. with total counting starting at 1 and index counting from 0 */
  123. LOG_D("remove seq(%d) serv (%d)", find_frame->head.sequence, service->service);
  124. rt_enter_critical();
  125. rt_slist_remove(&rt_link_scb->tx_data_slist, &find_frame->slist);
  126. rt_exit_critical();
  127. total--;
  128. rt_memset(find_frame, 0, sizeof(struct rt_link_frame));
  129. rt_free(find_frame);
  130. }
  131. } while ((total > 0) && (tem_list != RT_NULL));
  132. }
  133. }
  134. /* Configure the extended field of the frame */
  135. static rt_err_t rt_link_frame_extend_config(struct rt_link_frame *frame, rt_link_frame_attr_e attribute, rt_uint16_t parameter)
  136. {
  137. frame->head.extend = 1;
  138. frame->extend.attribute = attribute;
  139. frame->extend.parameter = parameter;
  140. return RT_EOK;
  141. }
  142. static int rt_link_command_frame_send(rt_uint8_t serv, rt_uint8_t sequence, rt_link_frame_attr_e attribute, rt_uint16_t parameter)
  143. {
  144. struct rt_link_frame command_frame = {0};
  145. rt_uint8_t data[sizeof(command_frame.head) + sizeof(command_frame.extend)] = {0};
  146. rt_uint8_t data_len = 0;
  147. /* command frame don't need crc and ack ability */
  148. rt_link_frame_init(&command_frame, RT_NULL);
  149. data_len += sizeof(command_frame.head);
  150. rt_link_frame_extend_config(&command_frame, attribute, parameter);
  151. rt_memcpy(data + data_len, &command_frame.extend, sizeof(command_frame.extend));
  152. data_len += sizeof(command_frame.extend);
  153. command_frame.head.sequence = sequence;
  154. command_frame.head.service = serv;
  155. rt_memcpy(data, &command_frame.head, sizeof(command_frame.head));
  156. rt_link_hw_send(data, data_len);
  157. return RT_EOK;
  158. }
  159. static void rt_link_service_send_finish(rt_link_err_e err)
  160. {
  161. struct rt_link_frame *frame = RT_NULL;
  162. rt_uint8_t service = RT_LINK_SERVICE_MAX;
  163. void *buffer = RT_NULL;
  164. rt_slist_t *tem_list = rt_slist_first(&rt_link_scb->tx_data_slist);
  165. if (tem_list == RT_NULL)
  166. {
  167. return ;
  168. }
  169. frame = rt_container_of(tem_list, struct rt_link_frame, slist);
  170. if (frame)
  171. {
  172. service = frame->head.service;
  173. buffer = frame->real_data - (frame->index * RT_LINK_MAX_DATA_LENGTH);
  174. rt_link_scb->service[service]->err = err;
  175. rt_link_scb->sendtimer.parameter = 0;
  176. rt_link_frame_remove(rt_link_scb->service[service]);
  177. if (rt_link_scb->service[service]->timeout_tx != RT_WAITING_NO)
  178. {
  179. rt_event_send(&rt_link_scb->sendevent, (0x01 << service));
  180. }
  181. else
  182. {
  183. rt_link_scb->service[service]->send_cb(rt_link_scb->service[service], buffer);
  184. }
  185. }
  186. }
  187. static rt_size_t frame_send(struct rt_link_frame *frame)
  188. {
  189. rt_size_t length = 0;
  190. rt_uint8_t *data = RT_NULL;
  191. rt_memset(rt_link_scb->sendbuffer, 0, sizeof(rt_link_scb->sendbuffer));
  192. data = rt_link_scb->sendbuffer;
  193. length = RT_LINK_HEAD_LENGTH;
  194. if (frame->head.crc)
  195. {
  196. length += RT_LINK_CRC_LENGTH;
  197. }
  198. if (frame->head.extend)
  199. {
  200. length += RT_LINK_EXTEND_LENGTH;
  201. }
  202. length += frame->data_len;
  203. frame->head.length = frame->data_len;
  204. rt_memcpy(data, &frame->head, RT_LINK_HEAD_LENGTH);
  205. data = data + RT_LINK_HEAD_LENGTH;
  206. if (frame->head.extend)
  207. {
  208. rt_memcpy(data, &frame->extend, RT_LINK_EXTEND_LENGTH);
  209. data = data + RT_LINK_EXTEND_LENGTH;
  210. }
  211. if (frame->attribute == RT_LINK_SHORT_DATA_FRAME || frame->attribute == RT_LINK_LONG_DATA_FRAME)
  212. {
  213. rt_memcpy(data, frame->real_data, frame->data_len);
  214. data = data + frame->data_len;
  215. }
  216. if (frame->head.crc)
  217. {
  218. frame->crc = rt_link_scb->calculate_crc(RT_FALSE, rt_link_scb->sendbuffer, length - RT_LINK_CRC_LENGTH);
  219. rt_memcpy(data, &frame->crc, RT_LINK_CRC_LENGTH);
  220. }
  221. LOG_D("frame send seq(%d) len(%d) attr:(%d), crc:(0x%08x).", frame->head.sequence, length, frame->attribute, frame->crc);
  222. return rt_link_hw_send(rt_link_scb->sendbuffer, length);
  223. }
  224. /* performs data transmission */
  225. static rt_err_t rt_link_frame_send(rt_slist_t *slist)
  226. {
  227. rt_uint8_t is_finish = RT_FALSE;
  228. struct rt_link_frame *frame = RT_NULL;
  229. rt_uint8_t send_max = RT_LINK_ACK_MAX;
  230. /* if slist is tx_data_slist, we should send all data on the slist*/
  231. if (slist == &rt_link_scb->tx_data_slist)
  232. {
  233. slist = rt_slist_next(&rt_link_scb->tx_data_slist);
  234. }
  235. if (slist == RT_NULL)
  236. {
  237. LOG_W("send data list NULL");
  238. return -RT_ERROR;
  239. }
  240. do
  241. {
  242. /* get frame for send */
  243. frame = rt_container_of(slist, struct rt_link_frame, slist);
  244. slist = rt_slist_next(slist);
  245. if (frame_send(frame) == 0)
  246. {
  247. rt_link_scb->service[frame->head.service]->err = RT_LINK_EIO;
  248. goto __err;
  249. }
  250. frame->issent = RT_LINK_FRAME_SENT;
  251. if ((slist == RT_NULL) || (frame->index + 1 >= frame->total))
  252. {
  253. send_max = 0;
  254. is_finish = RT_TRUE;
  255. }
  256. else
  257. {
  258. send_max >>= 1;
  259. }
  260. }while (send_max);
  261. if ((is_finish) && (frame->head.ack == 0))
  262. {
  263. /* NACK frame send finish, remove after sending */
  264. rt_link_service_send_finish(RT_LINK_EOK);
  265. if (slist != RT_NULL)
  266. {
  267. LOG_D("Continue sending");
  268. rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT);
  269. }
  270. }
  271. else
  272. {
  273. rt_int32_t timeout = RT_LINK_SENT_FRAME_TIMEOUT;
  274. rt_timer_control(&rt_link_scb->sendtimer, RT_TIMER_CTRL_SET_TIME, &timeout);
  275. rt_timer_start(&rt_link_scb->sendtimer);
  276. }
  277. return RT_EOK;
  278. __err:
  279. return -RT_ERROR;
  280. }
  281. static void _stop_recv_long(void)
  282. {
  283. rt_timer_stop(&rt_link_scb->longframetimer);
  284. if (rt_link_scb->rx_record.dataspace != RT_NULL)
  285. {
  286. rt_free(rt_link_scb->rx_record.dataspace);
  287. rt_link_scb->rx_record.dataspace = RT_NULL;
  288. }
  289. rt_link_scb->rx_record.long_count = 0;
  290. rt_link_scb->rx_record.total = 0;
  291. }
  292. static rt_err_t rt_link_frame_stop_receive(struct rt_link_frame *frame)
  293. {
  294. rt_memset(frame, 0, sizeof(struct rt_link_frame));
  295. if (rt_link_scb->rx_record.dataspace)
  296. {
  297. rt_free(rt_link_scb->rx_record.dataspace);
  298. }
  299. rt_link_scb->rx_record.dataspace = RT_NULL;
  300. rt_link_scb->rx_record.long_count = 0;
  301. rt_link_scb->rx_record.total = 0;
  302. rt_timer_stop(&rt_link_scb->recvtimer);
  303. rt_link_scb->recvtimer.parameter = 0;
  304. return RT_EOK;
  305. }
  306. static rt_err_t rt_link_resend_handle(struct rt_link_frame *receive_frame)
  307. {
  308. struct rt_link_frame *find_frame = RT_NULL;
  309. rt_slist_t *tem_list = RT_NULL;
  310. tem_list = rt_slist_first(&rt_link_scb->tx_data_slist);
  311. while (tem_list != RT_NULL)
  312. {
  313. find_frame = rt_container_of(tem_list, struct rt_link_frame, slist);
  314. if (find_frame->head.sequence == receive_frame->head.sequence)
  315. {
  316. LOG_D("resend frame(%d)", find_frame->head.sequence);
  317. frame_send(find_frame);
  318. break;
  319. }
  320. tem_list = tem_list->next;
  321. }
  322. if (tem_list == RT_NULL)
  323. {
  324. LOG_D("frame resent failed, can't find(%d).", receive_frame->head.sequence);
  325. rt_link_command_frame_send(receive_frame->head.service,
  326. receive_frame->head.sequence,
  327. RT_LINK_SESSION_END, RT_NULL);
  328. }
  329. return RT_EOK;
  330. }
  331. static rt_err_t rt_link_confirm_handle(struct rt_link_frame *receive_frame)
  332. {
  333. static struct rt_link_frame *send_frame = RT_NULL;
  334. rt_slist_t *tem_list = RT_NULL;
  335. rt_uint16_t seq_offset = 0;
  336. LOG_D("confirm seq(%d) frame", receive_frame->head.sequence);
  337. rt_timer_stop(&rt_link_scb->sendtimer);
  338. if (rt_link_scb->service[receive_frame->head.service] != RT_NULL)
  339. {
  340. rt_link_scb->service[receive_frame->head.service]->state = RT_LINK_CONNECT;
  341. }
  342. if (rt_link_scb->state != RT_LINK_CONNECT)
  343. {
  344. /* The handshake success and resends the data frame */
  345. rt_link_scb->state = RT_LINK_CONNECT;
  346. if (rt_slist_first(&rt_link_scb->tx_data_slist))
  347. {
  348. rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT);
  349. }
  350. return RT_EOK;
  351. }
  352. /* Check to see if the frame is send for confirm */
  353. tem_list = rt_slist_first(&rt_link_scb->tx_data_slist);
  354. if (tem_list == RT_NULL)
  355. {
  356. return -RT_ERROR;
  357. }
  358. send_frame = rt_container_of(tem_list, struct rt_link_frame, slist);
  359. seq_offset = rt_link_check_seq(receive_frame->head.sequence, send_frame->head.sequence);
  360. if (seq_offset <= send_frame->total)
  361. {
  362. rt_link_service_send_finish(RT_LINK_EOK);
  363. rt_link_scb->state = RT_LINK_CONNECT;
  364. tem_list = rt_slist_first(&rt_link_scb->tx_data_slist);
  365. if (tem_list != RT_NULL)
  366. {
  367. LOG_D("Continue sending");
  368. rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT);
  369. }
  370. }
  371. return RT_EOK;
  372. }
  373. /* serv type rt_link_service_e */
  374. static void rt_link_recv_finish(rt_uint8_t serv, void *data, rt_size_t size)
  375. {
  376. if (rt_link_scb->service[serv] == RT_NULL)
  377. {
  378. rt_link_command_frame_send(serv, 0, RT_LINK_DETACH_FRAME, RT_NULL);
  379. return;
  380. }
  381. if (rt_link_scb->service[serv]->recv_cb == RT_NULL)
  382. {
  383. rt_free(data);
  384. LOG_W("service %d haven't been registered.", serv);
  385. }
  386. else
  387. {
  388. rt_link_scb->service[serv]->recv_cb(rt_link_scb->service[serv], data, size);
  389. }
  390. }
  391. static rt_err_t rt_link_short_handle(struct rt_link_frame *receive_frame)
  392. {
  393. LOG_D("Seq(%d) short data", receive_frame->head.sequence);
  394. rt_link_scb->rx_record.dataspace = rt_malloc(receive_frame->data_len);
  395. if (rt_link_scb->rx_record.dataspace != RT_NULL)
  396. {
  397. if (receive_frame->head.ack)
  398. {
  399. rt_link_command_frame_send(receive_frame->head.service,
  400. receive_frame->head.sequence,
  401. RT_LINK_CONFIRM_FRAME, RT_NULL);
  402. }
  403. rt_link_scb->rx_record.rx_seq = receive_frame->head.sequence;
  404. rt_link_hw_copy(rt_link_scb->rx_record.dataspace, receive_frame->real_data, receive_frame->data_len);
  405. rt_link_recv_finish(receive_frame->head.service, rt_link_scb->rx_record.dataspace, receive_frame->data_len);
  406. rt_link_scb->rx_record.dataspace = RT_NULL;
  407. }
  408. else
  409. {
  410. LOG_W("short data %dB alloc failed", receive_frame->data_len);
  411. }
  412. receive_frame->real_data = RT_NULL;
  413. return 0;
  414. }
  415. static void _long_handle_first(struct rt_link_frame *receive_frame)
  416. {
  417. if (receive_frame->extend.parameter % RT_LINK_MAX_DATA_LENGTH == 0)
  418. {
  419. receive_frame->total = receive_frame->extend.parameter / RT_LINK_MAX_DATA_LENGTH;
  420. }
  421. else
  422. {
  423. receive_frame->total = receive_frame->extend.parameter / RT_LINK_MAX_DATA_LENGTH + 1;
  424. }
  425. rt_link_scb->rx_record.total = receive_frame->total;
  426. rt_link_scb->rx_record.dataspace = rt_malloc(receive_frame->extend.parameter);
  427. if (rt_link_scb->rx_record.dataspace == RT_NULL)
  428. {
  429. LOG_W("long data (%dB) alloc failed.", receive_frame->extend.parameter);
  430. }
  431. }
  432. static void _long_handle_second(struct rt_link_frame *receive_frame)
  433. {
  434. static rt_uint8_t ack_mask = RT_LINK_ACK_MAX;
  435. rt_size_t offset = 0; /* offset, count from 0 */
  436. receive_frame->index = rt_link_check_seq(receive_frame->head.sequence, rt_link_scb->rx_record.rx_seq) - 1;
  437. LOG_D("seq(%d), rxseq(%d), index(%d), total(%d), count(0x%x)"
  438. , receive_frame->head.sequence
  439. , rt_link_scb->rx_record.rx_seq
  440. , receive_frame->index
  441. , receive_frame->total
  442. , rt_link_scb->rx_record.long_count);
  443. if ((receive_frame->index > RT_LINK_FRAMES_MAX) || (rt_link_scb->rx_record.long_count & (0x01 << receive_frame->index)))
  444. {
  445. LOG_D("ERR:index %d, rx_seq %d", receive_frame->index, rt_link_scb->rx_record.rx_seq);
  446. }
  447. else if (rt_link_scb->rx_record.dataspace != RT_NULL)
  448. {
  449. rt_link_scb->rx_record.long_count |= (0x01 << receive_frame->index);
  450. offset = RT_LINK_MAX_DATA_LENGTH * receive_frame->index;
  451. rt_link_hw_copy(rt_link_scb->rx_record.dataspace + offset, receive_frame->real_data, receive_frame->data_len);
  452. if (receive_frame->head.ack)
  453. {
  454. if (rt_link_utils_num1(rt_link_scb->rx_record.long_count) == rt_link_scb->rx_record.total)
  455. {
  456. rt_link_command_frame_send(receive_frame->head.service,
  457. (rt_link_scb->rx_record.rx_seq + rt_link_scb->rx_record.total),
  458. RT_LINK_CONFIRM_FRAME, RT_NULL);
  459. }
  460. else if ((rt_link_scb->rx_record.long_count & ack_mask) == ack_mask)
  461. {
  462. rt_link_command_frame_send(receive_frame->head.service,
  463. (rt_link_scb->rx_record.rx_seq + rt_link_utils_num1(ack_mask)),
  464. RT_LINK_CONFIRM_FRAME, RT_NULL);
  465. ack_mask |= ack_mask << rt_link_utils_num1(RT_LINK_ACK_MAX);
  466. }
  467. }
  468. /* receive a complete package */
  469. if (rt_link_utils_num1(rt_link_scb->rx_record.long_count) == rt_link_scb->rx_record.total)
  470. {
  471. rt_timer_stop(&rt_link_scb->longframetimer);
  472. rt_link_recv_finish(receive_frame->head.service, rt_link_scb->rx_record.dataspace, receive_frame->extend.parameter);
  473. rt_enter_critical();
  474. /* empty rx_record */
  475. rt_link_scb->rx_record.rx_seq += rt_link_scb->rx_record.total;
  476. rt_link_scb->rx_record.dataspace = RT_NULL;
  477. rt_link_scb->rx_record.long_count = 0;
  478. rt_link_scb->rx_record.total = 0;
  479. ack_mask = RT_LINK_ACK_MAX;
  480. rt_exit_critical();
  481. }
  482. else if (rt_link_hw_recv_len(rt_link_scb->rx_buffer) < (receive_frame->data_len % RT_LINK_MAX_DATA_LENGTH))
  483. {
  484. rt_int32_t timeout = RT_LINK_LONG_FRAME_TIMEOUT;
  485. rt_timer_control(&rt_link_scb->longframetimer, RT_TIMER_CTRL_SET_TIME, &timeout);
  486. rt_timer_start(&rt_link_scb->longframetimer);
  487. }
  488. }
  489. }
  490. static rt_err_t rt_link_long_handle(struct rt_link_frame *receive_frame)
  491. {
  492. if (rt_link_scb->rx_record.long_count == 0)
  493. {
  494. /* Receive this long package for the first time:
  495. * calculates the total number of frames,
  496. * requests space, and turns on the receive timer */
  497. _long_handle_first(receive_frame);
  498. }
  499. if (rt_link_scb->rx_record.total > 0)
  500. {
  501. /* Intermediate frame processing:
  502. * serial number repeated check,
  503. * receive completion check, reply to ACK */
  504. _long_handle_second(receive_frame);
  505. }
  506. receive_frame->real_data = RT_NULL;
  507. return RT_EOK;
  508. }
  509. static rt_err_t rt_link_handshake_handle(struct rt_link_frame *receive_frame)
  510. {
  511. LOG_D("HANDSHAKE: seq(%d) param(%d)", receive_frame->head.sequence, receive_frame->extend.parameter);
  512. rt_link_scb->state = RT_LINK_CONNECT;
  513. /* sync requester tx seq, responder rx seq = requester tx seq */
  514. rt_link_scb->rx_record.rx_seq = receive_frame->head.sequence;
  515. /* sync requester rx seq, responder tx seq = requester rx seq */
  516. rt_link_scb->tx_seq = receive_frame->extend.parameter;
  517. if (rt_link_scb->service[receive_frame->head.service] != RT_NULL)
  518. {
  519. rt_link_scb->service[receive_frame->head.service]->state = RT_LINK_CONNECT;
  520. rt_link_command_frame_send(receive_frame->head.service,
  521. receive_frame->head.sequence,
  522. RT_LINK_CONFIRM_FRAME, RT_NULL);
  523. }
  524. else
  525. {
  526. rt_link_command_frame_send(receive_frame->head.service,
  527. receive_frame->head.sequence,
  528. RT_LINK_DETACH_FRAME, RT_NULL);
  529. }
  530. return RT_EOK;
  531. }
  532. static rt_err_t rt_link_detach_handle(struct rt_link_frame *receive_frame)
  533. {
  534. if (rt_link_scb->service[receive_frame->head.service] != RT_NULL)
  535. {
  536. rt_link_scb->service[receive_frame->head.service]->state = RT_LINK_DISCONN;
  537. }
  538. return RT_EOK;
  539. }
  540. static rt_err_t rt_link_session_end_handle(struct rt_link_frame *receive_frame)
  541. {
  542. rt_link_frame_stop_receive(receive_frame);
  543. return RT_EOK;
  544. }
  545. /* Discriminate frame type */
  546. static rt_err_t rt_link_parse_frame(struct rt_link_frame *receive_frame)
  547. {
  548. switch (receive_frame->attribute)
  549. {
  550. case RT_LINK_RESEND_FRAME:
  551. rt_link_resend_handle(receive_frame);
  552. break;
  553. case RT_LINK_CONFIRM_FRAME:
  554. rt_link_confirm_handle(receive_frame);
  555. break;
  556. case RT_LINK_HANDSHAKE_FRAME:
  557. rt_link_handshake_handle(receive_frame);
  558. break;
  559. case RT_LINK_SESSION_END:
  560. rt_link_session_end_handle(receive_frame);
  561. break;
  562. case RT_LINK_DETACH_FRAME:
  563. rt_link_detach_handle(receive_frame);
  564. break;
  565. case RT_LINK_SHORT_DATA_FRAME:
  566. rt_link_short_handle(receive_frame);
  567. break;
  568. case RT_LINK_LONG_DATA_FRAME:
  569. rt_link_long_handle(receive_frame);
  570. break;
  571. default:
  572. return -RT_ERROR;
  573. }
  574. return RT_EOK;
  575. }
  576. /* RT_LINK_READ_CHECK_EVENT handle */
  577. static void rt_link_frame_check(void)
  578. {
  579. static struct rt_link_frame receive_frame = {0};
  580. static rt_link_frame_parse_t analysis_status = FIND_FRAME_HEAD;
  581. static rt_uint8_t *data = RT_NULL;
  582. static rt_uint16_t buff_len = RT_LINK_HEAD_LENGTH;
  583. struct rt_link_frame *send_frame = RT_NULL;
  584. rt_tick_t timeout = 0;
  585. rt_uint32_t temporary_crc = 0;
  586. rt_uint8_t offset = 0;
  587. rt_size_t recv_len = rt_link_hw_recv_len(rt_link_scb->rx_buffer);
  588. while (recv_len > 0)
  589. {
  590. switch (analysis_status)
  591. {
  592. case FIND_FRAME_HEAD:
  593. {
  594. /* if we can't find frame head, throw that data */
  595. if ((*rt_link_scb->rx_buffer->read_point & RT_LINK_FRAME_HEAD_MASK) == RT_LINK_FRAME_HEAD)
  596. {
  597. analysis_status = PARSE_FRAME_HEAD;
  598. break;
  599. }
  600. rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1);
  601. break;
  602. }
  603. case PARSE_FRAME_HEAD:
  604. {
  605. if (recv_len < buff_len)
  606. {
  607. LOG_D("HEAD: actual: %d, need: %d.", recv_len, buff_len);
  608. return ;
  609. }
  610. /* Data is an offset address */
  611. data = rt_link_scb->rx_buffer->read_point;
  612. rt_link_frame_init(&receive_frame, RT_NULL);
  613. rt_link_hw_copy((rt_uint8_t *)&receive_frame.head, data, sizeof(struct rt_link_frame_head));
  614. rt_link_hw_buffer_point_shift(&data, sizeof(struct rt_link_frame_head));
  615. LOG_D("HEAD: seq(%d) serv(%d) ack(%d) crc(%d) ext(%d) len(%d) attr(%d)(0x%x)"
  616. , receive_frame.head.sequence
  617. , receive_frame.head.service
  618. , receive_frame.head.ack
  619. , receive_frame.head.crc
  620. , receive_frame.head.extend
  621. , receive_frame.head.length
  622. , receive_frame.extend.attribute
  623. , receive_frame.extend.parameter);
  624. receive_frame.data_len = receive_frame.head.length;
  625. if (receive_frame.head.service >= RT_LINK_SERVICE_MAX)
  626. {
  627. rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1);
  628. goto __find_head;
  629. }
  630. if (receive_frame.head.extend)
  631. {
  632. buff_len += RT_LINK_EXTEND_LENGTH;
  633. analysis_status = PARSE_FRAME_EXTEND;
  634. }
  635. else
  636. {
  637. receive_frame.attribute = RT_LINK_SHORT_DATA_FRAME;
  638. analysis_status = PARSE_FRAME_SEQ;
  639. }
  640. }
  641. case PARSE_FRAME_EXTEND:
  642. {
  643. if (receive_frame.head.extend)
  644. {
  645. if (recv_len < buff_len)
  646. {
  647. LOG_D("EXTEND: actual: %d, need: %d.", recv_len, buff_len);
  648. /* should set timer, control receive frame timeout, one shot */
  649. timeout = 50;
  650. rt_timer_control(&rt_link_scb->recvtimer, RT_TIMER_CTRL_SET_TIME, &timeout);
  651. rt_timer_start(&rt_link_scb->recvtimer);
  652. return;
  653. }
  654. rt_timer_stop(&rt_link_scb->recvtimer);
  655. rt_link_hw_copy((rt_uint8_t *)&receive_frame.extend, data, sizeof(struct rt_link_extend));
  656. rt_link_hw_buffer_point_shift(&data, sizeof(struct rt_link_extend));
  657. if (receive_frame.extend.attribute < RT_LINK_RESERVE_FRAME)
  658. {
  659. receive_frame.attribute = receive_frame.extend.attribute;
  660. }
  661. else
  662. {
  663. LOG_D("EXTEND: attr(%d) err", receive_frame.extend.attribute);
  664. rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1);
  665. goto __find_head;
  666. }
  667. }
  668. analysis_status = PARSE_FRAME_SEQ;
  669. }
  670. case PARSE_FRAME_SEQ:
  671. {
  672. switch (receive_frame.attribute)
  673. {
  674. case RT_LINK_CONFIRM_FRAME:
  675. case RT_LINK_RESEND_FRAME:
  676. {
  677. /* Check the send sequence */
  678. offset = rt_link_check_seq(receive_frame.head.sequence, rt_link_scb->tx_seq);
  679. if (rt_slist_first(&rt_link_scb->tx_data_slist) != RT_NULL)
  680. {
  681. send_frame = rt_container_of(rt_link_scb->tx_data_slist.next, struct rt_link_frame, slist);
  682. if (offset > send_frame->total)
  683. {
  684. /* exceptional frame, ignore it */
  685. LOG_D("seq (%d) failed, tx_seq (%d).offset=(%d) total= (%d)", receive_frame.head.sequence, rt_link_scb->tx_seq, offset, send_frame->total);
  686. rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1);
  687. goto __find_head;
  688. }
  689. }
  690. break;
  691. }
  692. case RT_LINK_LONG_DATA_FRAME:
  693. case RT_LINK_SHORT_DATA_FRAME:
  694. case RT_LINK_SESSION_END:
  695. {
  696. /* Check the receive sequence */
  697. offset = rt_link_check_seq(receive_frame.head.sequence, rt_link_scb->rx_record.rx_seq) - 1;
  698. if (offset > RT_LINK_FRAMES_MAX)
  699. {
  700. /* exceptional frame, ignore it */
  701. LOG_D("seq (%d) failed, rx_seq (%d) offset=(%d) attr= (%d) status (%d)", receive_frame.head.sequence, rt_link_scb->rx_record.rx_seq, offset, receive_frame.attribute, rt_link_scb->state);
  702. rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1);
  703. goto __find_head;
  704. }
  705. }
  706. case RT_LINK_HANDSHAKE_FRAME:
  707. case RT_LINK_DETACH_FRAME:
  708. analysis_status = HEADLE_FRAME_DATA;
  709. break;
  710. default:
  711. LOG_D("quick filter error frame.");
  712. rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1);
  713. goto __find_head;
  714. }
  715. buff_len += receive_frame.data_len;
  716. if (receive_frame.head.crc)
  717. {
  718. buff_len += RT_LINK_CRC_LENGTH;
  719. analysis_status = CHECK_FRAME_CRC;
  720. }
  721. else
  722. {
  723. analysis_status = HEADLE_FRAME_DATA;
  724. }
  725. /* fill real data point */
  726. receive_frame.real_data = data;
  727. }
  728. case CHECK_FRAME_CRC:
  729. {
  730. if (receive_frame.head.crc)
  731. {
  732. if (recv_len < buff_len)
  733. {
  734. LOG_D("CRC: actual: %d, need: %d.", recv_len, buff_len);
  735. /* should set timer, control receive frame timeout, one shot */
  736. timeout = 50;
  737. rt_timer_control(&rt_link_scb->recvtimer, RT_TIMER_CTRL_SET_TIME, &timeout);
  738. rt_timer_start(&rt_link_scb->recvtimer);
  739. return;
  740. }
  741. rt_timer_stop(&rt_link_scb->recvtimer);
  742. rt_link_hw_buffer_point_shift(&data, receive_frame.data_len);
  743. rt_link_hw_copy((rt_uint8_t *)&receive_frame.crc, data, RT_LINK_CRC_LENGTH);
  744. temporary_crc = rt_link_scb->calculate_crc(RT_TRUE, rt_link_scb->rx_buffer->read_point, buff_len - RT_LINK_CRC_LENGTH);
  745. if (receive_frame.crc != temporary_crc)
  746. {
  747. /* check failed. ready resent */
  748. LOG_D("CRC: calc:(0x%08x) ,recv:(0x%08x).", temporary_crc, receive_frame.crc);
  749. rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, 1);
  750. goto __find_head;
  751. }
  752. }
  753. analysis_status = HEADLE_FRAME_DATA;
  754. }
  755. case HEADLE_FRAME_DATA:
  756. {
  757. if (recv_len < buff_len)
  758. {
  759. LOG_D("PARSE: actual: %d, need: %d.", recv_len, buff_len);
  760. /* should set timer, control receive frame timeout, one shot */
  761. timeout = 50;
  762. rt_timer_control(&rt_link_scb->recvtimer, RT_TIMER_CTRL_SET_TIME, &timeout);
  763. rt_timer_start(&rt_link_scb->recvtimer);
  764. return;
  765. }
  766. LOG_D("PARSE: buff_len (%d) r (0x%p) w (0x%p)"
  767. , buff_len, rt_link_scb->rx_buffer->read_point
  768. , rt_link_scb->rx_buffer->write_point);
  769. rt_timer_stop(&rt_link_scb->recvtimer);
  770. rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, buff_len);
  771. rt_link_parse_frame(&receive_frame);
  772. data = RT_NULL;
  773. buff_len = RT_LINK_HEAD_LENGTH;
  774. analysis_status = FIND_FRAME_HEAD;
  775. break;
  776. }
  777. default:
  778. __find_head:
  779. LOG_D("to find head (%d)", analysis_status);
  780. rt_link_frame_stop_receive(&receive_frame);
  781. buff_len = RT_LINK_HEAD_LENGTH;
  782. analysis_status = FIND_FRAME_HEAD;
  783. break;
  784. }
  785. recv_len = rt_link_hw_recv_len(rt_link_scb->rx_buffer);
  786. }
  787. }
  788. static void rt_link_send_ready(void)
  789. {
  790. struct rt_link_frame *frame = RT_NULL;
  791. rt_uint8_t seq = rt_link_scb->tx_seq;
  792. if (rt_slist_next(&rt_link_scb->tx_data_slist))
  793. {
  794. frame = rt_container_of(rt_slist_next(&rt_link_scb->tx_data_slist), struct rt_link_frame, slist);
  795. }
  796. if (rt_link_scb->state != RT_LINK_CONNECT)
  797. {
  798. rt_link_scb->state = RT_LINK_DISCONN;
  799. rt_link_command_frame_send(RT_LINK_SERVICE_RTLINK, seq,
  800. RT_LINK_HANDSHAKE_FRAME, rt_link_scb->rx_record.rx_seq);
  801. rt_int32_t timeout = 50;
  802. rt_timer_control(&rt_link_scb->sendtimer, RT_TIMER_CTRL_SET_TIME, &timeout);
  803. rt_timer_start(&rt_link_scb->sendtimer);
  804. }
  805. else
  806. {
  807. /* Avoid sending the first data frame multiple times */
  808. if ((frame != RT_NULL) && (frame->issent == RT_LINK_FRAME_NOSEND))
  809. {
  810. if (RT_EOK != rt_link_frame_send(&rt_link_scb->tx_data_slist))
  811. {
  812. rt_link_scb->state = RT_LINK_DISCONN;
  813. rt_link_service_send_finish(RT_LINK_EIO);
  814. }
  815. }
  816. }
  817. }
  818. static void rt_link_frame_recv_timeout(void)
  819. {
  820. /* The receiving frame timeout and a new receive begins */
  821. rt_link_hw_buffer_point_shift(&rt_link_scb->rx_buffer->read_point, rt_link_hw_recv_len(rt_link_scb->rx_buffer));
  822. }
  823. static void rt_link_send_timeout(void)
  824. {
  825. LOG_D("send count(%d)", (rt_uint32_t)rt_link_scb->sendtimer.parameter);
  826. if ((rt_uint32_t)rt_link_scb->sendtimer.parameter >= 5)
  827. {
  828. rt_timer_stop(&rt_link_scb->sendtimer);
  829. LOG_W("Send timeout, please check the link status!");
  830. rt_link_scb->sendtimer.parameter = 0x00;
  831. rt_link_service_send_finish(RT_LINK_ETIMEOUT);
  832. }
  833. else
  834. {
  835. if (rt_slist_next(&rt_link_scb->tx_data_slist))
  836. {
  837. struct rt_link_frame *frame = rt_container_of(rt_slist_next(&rt_link_scb->tx_data_slist), struct rt_link_frame, slist);
  838. frame->issent = RT_LINK_FRAME_NOSEND;
  839. rt_link_command_frame_send(RT_LINK_SERVICE_RTLINK,
  840. frame->head.sequence,
  841. RT_LINK_HANDSHAKE_FRAME,
  842. rt_link_scb->rx_record.rx_seq);
  843. }
  844. }
  845. }
  846. static void rt_link_long_recv_timeout(void)
  847. {
  848. if ((rt_uint32_t)rt_link_scb->longframetimer.parameter >= 5)
  849. {
  850. LOG_W("long package receive timeout");
  851. rt_link_scb->longframetimer.parameter = 0x00;
  852. _stop_recv_long();
  853. rt_timer_stop(&rt_link_scb->longframetimer);
  854. }
  855. else
  856. {
  857. rt_uint8_t total = rt_link_scb->rx_record.total;
  858. for (; total > 0; total--)
  859. {
  860. if (((rt_link_scb->rx_record.long_count >> (total - 1)) & 0x01) == 0x00)
  861. {
  862. /* resend command */
  863. rt_link_command_frame_send(RT_LINK_SERVICE_RTLINK,
  864. (rt_link_scb->rx_record.rx_seq + total),
  865. RT_LINK_RESEND_FRAME, RT_NULL);
  866. }
  867. }
  868. }
  869. }
  870. void rt_link_thread(void *parameter)
  871. {
  872. rt_uint32_t recved = 0;
  873. while (1)
  874. {
  875. rt_event_recv(&rt_link_scb->event,
  876. RT_LINK_READ_CHECK_EVENT |
  877. RT_LINK_SEND_READY_EVENT |
  878. RT_LINK_SEND_TIMEOUT_EVENT |
  879. RT_LINK_RECV_TIMEOUT_FRAME_EVENT |
  880. RT_LINK_RECV_TIMEOUT_LONG_EVENT,
  881. RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
  882. RT_WAITING_FOREVER,
  883. &recved);
  884. if (recved & RT_LINK_READ_CHECK_EVENT)
  885. {
  886. rt_link_frame_check();
  887. }
  888. if (recved & RT_LINK_SEND_READY_EVENT)
  889. {
  890. rt_link_send_ready();
  891. }
  892. if (recved & RT_LINK_SEND_TIMEOUT_EVENT)
  893. {
  894. rt_link_send_timeout();
  895. }
  896. if (recved & RT_LINK_RECV_TIMEOUT_FRAME_EVENT)
  897. {
  898. rt_link_frame_recv_timeout();
  899. }
  900. if (recved & RT_LINK_RECV_TIMEOUT_LONG_EVENT)
  901. {
  902. rt_link_long_recv_timeout();
  903. }
  904. }
  905. }
  906. static void rt_link_sendtimer_callback(void *parameter)
  907. {
  908. rt_uint32_t count = (rt_uint32_t)rt_link_scb->sendtimer.parameter + 1;
  909. rt_link_scb->sendtimer.parameter = (void *)count;
  910. rt_event_send(&rt_link_scb->event, RT_LINK_SEND_TIMEOUT_EVENT);
  911. }
  912. static void rt_link_recvtimer_callback(void *parameter)
  913. {
  914. rt_event_send(&rt_link_scb->event, RT_LINK_RECV_TIMEOUT_FRAME_EVENT);
  915. }
  916. static void rt_link_receive_long_frame_callback(void *parameter)
  917. {
  918. rt_uint32_t count = (rt_uint32_t)rt_link_scb->longframetimer.parameter + 1;
  919. rt_link_scb->longframetimer.parameter = (void *)count;
  920. rt_event_send(&rt_link_scb->event, RT_LINK_RECV_TIMEOUT_LONG_EVENT);
  921. }
  922. /**
  923. * rtlink send data interface
  924. * @param service Registered service channel, struct rt_link_service
  925. * @param data send data
  926. * @param size send data size
  927. * @return The actual size of the data sent
  928. * */
  929. rt_size_t rt_link_send(struct rt_link_service *service, const void *data, rt_size_t size)
  930. {
  931. RT_ASSERT(service != RT_NULL);
  932. rt_uint32_t recved = 0;
  933. rt_uint8_t total = 0; /* The total number of frames to send */
  934. rt_uint8_t index = 0; /* The index of the split packet */
  935. rt_size_t offset = 0; /* The offset of the send data */
  936. rt_size_t send_len = 0;
  937. struct rt_link_frame *send_frame = RT_NULL;
  938. rt_link_frame_attr_e attribute = RT_LINK_SHORT_DATA_FRAME;
  939. if ((size == 0) || (data == RT_NULL))
  940. {
  941. service->err = RT_LINK_ERR;
  942. goto __exit;
  943. }
  944. service->err = RT_LINK_EOK;
  945. if (size % RT_LINK_MAX_DATA_LENGTH == 0)
  946. {
  947. total = size / RT_LINK_MAX_DATA_LENGTH;
  948. }
  949. else
  950. {
  951. total = size / RT_LINK_MAX_DATA_LENGTH + 1;
  952. }
  953. if (total > RT_LINK_FRAMES_MAX)
  954. {
  955. service->err = RT_LINK_ENOMEM;
  956. goto __exit;
  957. }
  958. else if (total > 1)
  959. {
  960. attribute = RT_LINK_LONG_DATA_FRAME;
  961. }
  962. do
  963. {
  964. send_frame = rt_malloc(sizeof(struct rt_link_frame));
  965. if (send_frame == RT_NULL)
  966. {
  967. service->err = RT_LINK_ENOMEM;
  968. goto __exit;
  969. }
  970. rt_link_frame_init(send_frame, service->flag);
  971. send_frame->head.sequence = ++rt_link_scb->tx_seq;
  972. send_frame->head.service = service->service;
  973. send_frame->real_data = (rt_uint8_t *)data + offset;
  974. send_frame->index = index;
  975. send_frame->total = total;
  976. if (attribute == RT_LINK_LONG_DATA_FRAME)
  977. {
  978. send_frame->attribute = RT_LINK_LONG_DATA_FRAME;
  979. if (offset + RT_LINK_MAX_DATA_LENGTH > size)
  980. {
  981. send_frame->data_len = size - offset;
  982. }
  983. else
  984. {
  985. send_frame->data_len = RT_LINK_MAX_DATA_LENGTH;
  986. offset += RT_LINK_MAX_DATA_LENGTH;
  987. }
  988. rt_link_frame_extend_config(send_frame, RT_LINK_LONG_DATA_FRAME, size);
  989. }
  990. else
  991. {
  992. send_frame->attribute = RT_LINK_SHORT_DATA_FRAME;
  993. send_frame->data_len = size;
  994. }
  995. /* append the frame on the tail of list */
  996. LOG_D("append send slist, seq(%d), len(%d)", send_frame->head.sequence, send_frame->data_len);
  997. rt_slist_append(&rt_link_scb->tx_data_slist, &send_frame->slist);
  998. index++;
  999. send_len += send_frame->data_len;
  1000. }while(total > index);
  1001. /* Notify the core thread to send packet */
  1002. rt_event_send(&rt_link_scb->event, RT_LINK_SEND_READY_EVENT);
  1003. if (service->timeout_tx != RT_WAITING_NO)
  1004. {
  1005. /* Wait for the packet to send the result */
  1006. rt_err_t ret = rt_event_recv(&rt_link_scb->sendevent, (0x01 << service->service),
  1007. RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
  1008. service->timeout_tx, &recved);
  1009. if (ret == -RT_ETIMEOUT)
  1010. {
  1011. service->err = RT_LINK_ETIMEOUT;
  1012. send_len = 0;
  1013. }
  1014. }
  1015. __exit:
  1016. return send_len;
  1017. }
  1018. void rtlink_status(void)
  1019. {
  1020. rt_kprintf("rtlink(v%s) status:\n", RT_LINK_VER);
  1021. if (rt_link_scb != RT_NULL)
  1022. {
  1023. rt_kprintf("\tlink status=%d\n", rt_link_scb->state);
  1024. rt_kprintf("\trx seq=%d\n", rt_link_scb->rx_record.rx_seq);
  1025. rt_kprintf("\ttx seq=%d\n", rt_link_scb->tx_seq);
  1026. rt_kprintf("\trecv len=%d\n", rt_link_hw_recv_len(rt_link_scb->rx_buffer));
  1027. rt_tick_t state = 0;
  1028. rt_timer_control(&rt_link_scb->longframetimer, RT_TIMER_CTRL_GET_STATE, &state);
  1029. rt_kprintf("\tlong timer state=%d\n", state);
  1030. rt_timer_control(&rt_link_scb->sendtimer, RT_TIMER_CTRL_GET_STATE, &state);
  1031. rt_kprintf("\tsend timer state=%d\n", state);
  1032. rt_kprintf("\tevent set=0x%08x\n", rt_link_scb->event.set);
  1033. if (rt_link_scb->tx_data_slist.next)
  1034. {
  1035. rt_slist_t *data = RT_NULL;
  1036. rt_slist_for_each(data, &rt_link_scb->tx_data_slist)
  1037. {
  1038. rt_kprintf("\tsend data list: serv %u\t", ((struct rt_link_frame_head *)data)->service);
  1039. rt_kprintf(" seq %u\t", ((struct rt_link_frame_head *)data)->sequence);
  1040. rt_kprintf(" len %u\n", ((struct rt_link_frame_head *)data)->length);
  1041. }
  1042. }
  1043. else
  1044. {
  1045. rt_kprintf("\tsend data list: NULL\n");
  1046. }
  1047. rt_uint8_t serv = RT_LINK_SERVICE_MAX - 1;
  1048. while (serv--)
  1049. {
  1050. rt_kprintf("\tservices [%d](0x%p)\n", serv, rt_link_scb->service[serv]);
  1051. }
  1052. }
  1053. else
  1054. {
  1055. rt_kprintf("status NULL, please check the initialization status!\n");
  1056. }
  1057. }
  1058. MSH_CMD_EXPORT(rtlink_status, Display RTLINK status);
  1059. /**
  1060. * rtlink deinit the interface
  1061. * */
  1062. rt_err_t rt_link_deinit(void)
  1063. {
  1064. rt_enter_critical();
  1065. rt_link_hw_deinit();
  1066. if (rt_link_scb)
  1067. {
  1068. rt_timer_detach(&rt_link_scb->longframetimer);
  1069. rt_timer_detach(&rt_link_scb->sendtimer);
  1070. rt_timer_detach(&rt_link_scb->recvtimer);
  1071. rt_event_detach(&rt_link_scb->event);
  1072. rt_free(rt_link_scb);
  1073. rt_link_scb = RT_NULL;
  1074. }
  1075. rt_thread_t thread = rt_thread_find(RT_LINK_THREAD_NAME);
  1076. if (thread)
  1077. {
  1078. rt_thread_delete(thread);
  1079. }
  1080. rt_exit_critical();
  1081. return RT_EOK;
  1082. }
  1083. MSH_CMD_EXPORT(rt_link_deinit, rt link deinit);
  1084. /**
  1085. * rtlink initializes the interface, usually automatically.
  1086. * @return int Function Execution Result
  1087. * */
  1088. int rt_link_init(void)
  1089. {
  1090. rt_err_t result = RT_EOK;
  1091. rt_thread_t thread = RT_NULL;
  1092. if (rt_link_scb != RT_NULL)
  1093. {
  1094. goto __exit;
  1095. }
  1096. rt_link_scb = rt_malloc(sizeof(struct rt_link_session));
  1097. if (rt_link_scb == RT_NULL)
  1098. {
  1099. result = -RT_ENOMEM;
  1100. goto __exit;
  1101. }
  1102. rt_memset(rt_link_scb, 0, sizeof(struct rt_link_session));
  1103. rt_event_init(&rt_link_scb->event, "rtlink", RT_IPC_FLAG_FIFO);
  1104. rt_event_control(&rt_link_scb->event, RT_IPC_CMD_RESET, RT_NULL);
  1105. rt_event_init(&rt_link_scb->sendevent, "send_rtlink", RT_IPC_FLAG_FIFO);
  1106. rt_event_control(&rt_link_scb->sendevent, RT_IPC_CMD_RESET, RT_NULL);
  1107. rt_timer_init(&rt_link_scb->sendtimer, "tx_time", rt_link_sendtimer_callback,
  1108. RT_NULL, 0, RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_PERIODIC);
  1109. rt_timer_init(&rt_link_scb->recvtimer, "rx_time", rt_link_recvtimer_callback,
  1110. RT_NULL, 0, RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT);
  1111. rt_timer_init(&rt_link_scb->longframetimer, "rxl_time", rt_link_receive_long_frame_callback,
  1112. RT_NULL, 0, RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_PERIODIC);
  1113. rt_link_scb->rx_record.rx_seq = 255;
  1114. rt_slist_init(&rt_link_scb->tx_data_slist);
  1115. rt_link_scb->tx_seq = RT_LINK_INIT_FRAME_SEQENCE;
  1116. /* create rtlink core work thread */
  1117. thread = rt_thread_create(RT_LINK_THREAD_NAME,
  1118. rt_link_thread,
  1119. RT_NULL,
  1120. RT_LINK_THREAD_STACK_SIZE,
  1121. RT_LINK_THREAD_PRIORITY,
  1122. RT_LINK_THREAD_TICK);
  1123. if (thread == RT_NULL)
  1124. {
  1125. result = -RT_ENOMEM;
  1126. goto __exit;
  1127. }
  1128. rt_thread_startup(thread);
  1129. rt_link_scb->state = RT_LINK_INIT;
  1130. __exit:
  1131. if (result != RT_EOK)
  1132. {
  1133. LOG_E("rtlink init failed.");
  1134. rt_link_deinit();
  1135. }
  1136. else
  1137. {
  1138. LOG_I("rtlink init success(VER:%s).", RT_LINK_VER);
  1139. }
  1140. return result;
  1141. }
  1142. #ifdef RT_LINK_AUTO_INIT
  1143. INIT_ENV_EXPORT(rt_link_init);
  1144. #endif
  1145. MSH_CMD_EXPORT(rt_link_init, rt link init);
  1146. /**
  1147. * rtlink service attach
  1148. * @param service Registered service channel, struct rt_link_service
  1149. * @return Function Execution Result
  1150. * */
  1151. rt_err_t rt_link_service_attach(struct rt_link_service *serv)
  1152. {
  1153. RT_ASSERT(serv != RT_NULL);
  1154. if (serv->service >= RT_LINK_SERVICE_MAX)
  1155. {
  1156. LOG_W("Invalid parameter.");
  1157. return -RT_EINVAL;
  1158. }
  1159. rt_uint8_t seq = rt_link_scb->tx_seq;
  1160. rt_link_hw_init();
  1161. rt_link_scb->service[serv->service] = serv;
  1162. serv->state = RT_LINK_INIT;
  1163. LOG_I("rt link attach service[%02d].", serv->service);
  1164. if (rt_slist_next(&rt_link_scb->tx_data_slist))
  1165. {
  1166. struct rt_link_frame *frame = rt_container_of(rt_slist_next(&rt_link_scb->tx_data_slist), struct rt_link_frame, slist);
  1167. seq = frame->head.sequence;
  1168. }
  1169. rt_link_command_frame_send(serv->service, seq, RT_LINK_HANDSHAKE_FRAME, rt_link_scb->rx_record.rx_seq);
  1170. return RT_EOK;
  1171. }
  1172. /**
  1173. * rtlink service detach
  1174. * @param service Registered service channel, struct rt_link_service
  1175. * @return rt_err_t Function Execution Result
  1176. * */
  1177. rt_err_t rt_link_service_detach(struct rt_link_service *serv)
  1178. {
  1179. RT_ASSERT(serv != RT_NULL);
  1180. if (serv->service >= RT_LINK_SERVICE_MAX)
  1181. {
  1182. LOG_W("Invalid parameter.");
  1183. return -RT_EINVAL;
  1184. }
  1185. rt_link_command_frame_send(serv->service,
  1186. rt_link_scb->tx_seq,
  1187. RT_LINK_DETACH_FRAME,
  1188. rt_link_scb->rx_record.rx_seq);
  1189. serv->state = RT_LINK_DISCONN;
  1190. rt_link_scb->service[serv->service] = RT_NULL;
  1191. LOG_I("rt link detach service[%02d].", serv->service);
  1192. return RT_EOK;
  1193. }