upacker.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /**
  2. ******************************************************************************
  3. * @file drv_packer.c
  4. * @author zpw
  5. * @version V1.0
  6. * @date
  7. * @brief 链路层通讯协议
  8. ******************************************************************************
  9. * @attention
  10. * 链路层通讯协议,数据封包解包
  11. ******************************************************************************
  12. */
  13. #include "upacker.h"
  14. static uint8_t frame_decode(upacker_inst_t packer, uint8_t d);
  15. static uint8_t frame_encode(upacker_inst_t packer, uint8_t *data, uint16_t size);
  16. /**
  17. * @brief 使用动态内存时需要初始化
  18. * @note size pack缓存的长度,大于最大的数据包长度就行,使用PACK_SIZE
  19. 无rtos最好用静态内存,不然要改heap
  20. * @param *cmd_packer:
  21. * @param *handler:
  22. * @retval None
  23. */
  24. int upacker_init(upacker_inst_t packer, PACKER_CB h, PACKER_CB s)
  25. {
  26. #if USE_DYNAMIC_MEM
  27. packer->data = (uint8_t *)UP_MALLOC(MAX_PACK_SIZE);
  28. if (!packer->data)
  29. {
  30. return -1;
  31. }
  32. #endif
  33. packer->cb = h;
  34. packer->send = s;
  35. return 0;
  36. }
  37. /**
  38. * @brief 解包输入数据
  39. * @note
  40. * @param cmd_packer:
  41. * @param *buff:
  42. * @param size:
  43. * @retval None
  44. */
  45. void upacker_unpack(upacker_inst_t packer, uint8_t *buff, uint16_t size)
  46. {
  47. for (uint16_t i = 0; i < size; i++)
  48. {
  49. if (frame_decode(packer, buff[i]))
  50. {
  51. //解析成功,回调处理
  52. packer->cb(packer->data, packer->flen);
  53. }
  54. }
  55. }
  56. /**
  57. * @brief 封包数据并发送
  58. * @note
  59. * @param *packer:
  60. * @param *buff:
  61. * @param size:
  62. * @retval None
  63. */
  64. void upacker_pack(upacker_inst_t packer, uint8_t *buff, uint16_t size)
  65. {
  66. frame_encode(packer, buff, size);
  67. }
  68. static uint8_t frame_decode(upacker_inst_t packer, uint8_t d)
  69. {
  70. if (packer->state == 0 && d == STX_L)
  71. {
  72. packer->state = 1;
  73. packer->calc = 0x55;
  74. }
  75. else if (packer->state == 1)
  76. {
  77. packer->flen = d;
  78. packer->calc ^= d;
  79. packer->state = 2;
  80. }
  81. else if (packer->state == 2)
  82. {
  83. //长度信息
  84. packer->flen |= (uint16_t)d << 8;
  85. packer->calc ^= d & 0x3F;
  86. //数据包超长得情况下直接丢包
  87. if ((packer->flen & 0x3FFF) > MAX_PACK_SIZE)
  88. {
  89. packer->state = 0;
  90. }
  91. packer->state = 3;
  92. packer->cnt = 0;
  93. }
  94. else if (packer->state == 3)
  95. {
  96. //header校验
  97. uint8_t hc = ((d & 0x03) << 4) | (packer->flen & 0xC000) >> 12;
  98. packer->check = d;
  99. if (hc != (packer->calc & 0X3C))
  100. {
  101. packer->state = 0;
  102. return 0;
  103. }
  104. packer->state = 4;
  105. packer->flen &= 0x3FFF;
  106. }
  107. else if (packer->state == 4)
  108. {
  109. packer->data[packer->cnt++] = d;
  110. packer->calc ^= d;
  111. if (packer->cnt == packer->flen)
  112. {
  113. packer->state = 0;
  114. //接收完,检查check
  115. if ((packer->calc & 0xFC) == (packer->check & 0XFC))
  116. {
  117. return 1;
  118. }
  119. else
  120. {
  121. return 0;
  122. }
  123. }
  124. }
  125. else
  126. {
  127. packer->state = 0;
  128. }
  129. return 0;
  130. }
  131. static uint8_t frame_encode(upacker_inst_t packer, uint8_t *data, uint16_t size)
  132. {
  133. uint8_t tmp[4] = {0};
  134. uint8_t crc = 0;
  135. if (size > 16384)
  136. {
  137. return 0;
  138. }
  139. tmp[0] = 0x55;
  140. tmp[1] = size & 0xff;
  141. tmp[2] = (size >> 8) & 0x3f; //低14位用来保存size;header校验4位
  142. crc = tmp[0] ^ tmp[1] ^ tmp[2];
  143. tmp[2] |= (crc & 0x0C) << 4; //tmp[2][7:6]保存header检验[3:2]
  144. tmp[3] = 0x03 & (crc >> 4); //tmp[3][1:0]保存header校验[5:4]
  145. for (int i = 0; i < size; i++)
  146. {
  147. crc ^= data[i];
  148. }
  149. tmp[3] |= (crc & 0xfc); //tmp[3][7:2]保存data check[7:2]
  150. packer->send(tmp, 4);
  151. packer->send(data, size);
  152. return 1;
  153. }