bsp_packet.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /******************************************************************************
  2. 版权所有: @copyright (C) 2024-2034 HaiYang Technology Corp. All rights reserved.
  3. 文件名称: shm_comm_packet.c
  4. 文件版本: 01.01
  5. 创建作者: zhaoyang
  6. 创建日期: 2025-08-25
  7. 功能说明: 共享内存通信打包
  8. 其它说明:
  9. 修改记录:
  10. */
  11. /*------------------------------- 头文件 --------------------------------------
  12. */
  13. #include "bsp_shm.h"
  14. #include <stdbool.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. /*------------------------------- 宏定义 --------------------------------------
  18. */
  19. /*------------------------------ 类型结构 -------------------------------------
  20. */
  21. //CRC-16 表
  22. const unsigned short UserLookup[256]=
  23. {
  24. 0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
  25. 0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,
  26. 0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,
  27. 0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,
  28. 0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,
  29. 0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,
  30. 0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,
  31. 0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,
  32. 0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,
  33. 0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,
  34. 0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,
  35. 0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,
  36. 0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,
  37. 0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,
  38. 0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,
  39. 0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,
  40. 0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,
  41. 0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,
  42. 0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,
  43. 0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,
  44. 0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,
  45. 0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,
  46. 0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,
  47. 0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,
  48. 0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,
  49. 0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,
  50. 0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,
  51. 0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,
  52. 0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,
  53. 0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,
  54. 0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,
  55. 0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040
  56. };
  57. /*------------------------------ 函数声明 -------------------------------------
  58. */
  59. /*------------------------------ 外部函数 -------------------------------------
  60. 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
  61. */
  62. /**************************************************************************
  63. 函数名称:CrcStr
  64. 函数版本:1.00
  65. 作者:
  66. 创建日期:2005.4.13
  67. 函数功能说明:计算1个字节数组的CRC-16
  68. 输入参数: p =数组的开始地址
  69. len =数组长度
  70. 返回值: crc =计算后的CRC-16结果
  71. 更新信息:
  72. 更新日志1:
  73. 日期:
  74. 修改者:
  75. 修改内容:
  76. 修改原因:
  77. ***************************************************************************/
  78. static unsigned short CrcStr(unsigned char *p,int len)
  79. {
  80. unsigned short crc=0;
  81. bool bZero=true;
  82. while(len-->0)
  83. {
  84. if(*p!=0)bZero=false;
  85. crc=UserLookup[(crc&0xff)^(*p++)]^(crc>>8);
  86. }
  87. if(bZero)crc=0x5678; //若全为0,crc返回就不要为零
  88. return crc;
  89. }
  90. /******************************************************************************
  91. 函数名称: shm_comm_packet_write
  92. 函数版本: 01.01
  93. 创建作者: zhaoyang
  94. 创建日期: 2025-08-25
  95. 函数说明: 向共享内存写入数据(自动处理A,B,crc).
  96. 参数说明:
  97. addr:共享内存的地址
  98. data:写入数据
  99. len:写入数据长度
  100. 返回值: 成功返回写入数据的长度, 失败返回-1
  101. 修改记录:
  102. 使用说明:
  103. 输入参数data为带有A,B和crc的结构体,len为整个结构体的长度
  104. 应用层不需要理会A,B和crc.
  105. */
  106. int shm_comm_packet_write(uint32_t addr, uint8_t *data, uint32_t len)
  107. {
  108. uint16_t A;
  109. int ret;
  110. uint16_t crc = 0;
  111. if(data == NULL)
  112. return -1;
  113. if(len == 0 )
  114. return -1;
  115. //A++
  116. memcpy(&A,&SHM_BASE_W[addr],2);
  117. A++;
  118. memcpy(&SHM_BASE_W[addr],&A,2);
  119. //写数据区
  120. ret = shm_write(addr+4, data+4, len-6);
  121. if(ret == -1)
  122. return -1;
  123. //crc
  124. crc = CrcStr(data+4, len-6);//CRC
  125. memcpy(&SHM_BASE_W[addr+len-2],&crc,2);
  126. //B++
  127. memcpy(&SHM_BASE_W[addr+2],&A,2); //A和B保证一样
  128. return ret+6;//加上A,B,crc的长度
  129. }
  130. /******************************************************************************
  131. 函数名称: shm_comm_packet_read
  132. 函数版本: 01.01
  133. 创建作者: zhaoyang
  134. 创建日期: 2025-08-25
  135. 函数说明: 读取共享内存的数据(自动处理A,B,crc).
  136. 参数说明:
  137. addr:所以读取共享内存的地址
  138. len:需要读取数据的长度
  139. out_data:输出buf
  140. out_data_size:输出buf的长度
  141. 返回值:
  142. 成功返回读取数据的长度,
  143. 失败返回 <0
  144. 修改记录:
  145. 使用说明:
  146. 输入参数out_data为带有A,B和crc的结构体,len为整个结构体的长度
  147. 应用层不需要理会A,B和crc.
  148. */
  149. int shm_comm_packet_read(uint32_t addr, uint32_t len, uint8_t *out_data, uint32_t out_data_size)
  150. {
  151. uint16_t A,B;
  152. //uint16_t last_A = 0;
  153. //uint16_t last_B = 0;
  154. int ret;
  155. uint16_t crc = 0;
  156. uint16_t read_crc = 0;
  157. //shm_read(addr, 2, (uint8_t*)&last_A, sizeof(last_A));
  158. //shm_read(addr+2, 2, (uint8_t*)&last_B, sizeof(last_B));
  159. //printf("last_A=%X, last_B=%X\n", last_A,last_B);
  160. //if(last_A == last_B)
  161. {
  162. //idle
  163. ret = shm_read(addr, len, out_data, out_data_size);
  164. A = out_data[0]+((uint16_t)out_data[1]<<8);
  165. B = out_data[2]+((uint16_t)out_data[3]<<8);
  166. //printf("A=%X, B=%X\n", A,B);
  167. if((A == B) )//&& (A == last_A))
  168. {
  169. //在拷贝过程中,数据没有被修改
  170. crc = CrcStr(out_data+4,len-6);
  171. read_crc = out_data[len-2]+((uint16_t)out_data[len-1]<<8);
  172. //printf("cal crc=%04X, read crc=%04X\n", crc,read_crc);
  173. if(crc != read_crc)
  174. {
  175. //crc error
  176. return -3;
  177. }
  178. }
  179. else
  180. {
  181. //busy 裸核正在写数据
  182. return -2;
  183. }
  184. }
  185. //else
  186. //{
  187. //busy 裸核正在写数据
  188. // return -2;
  189. //}
  190. return ret;
  191. }
  192. /******************************************************************************
  193. 函数名称: shm_comm_packet_read_noABcrc
  194. 函数版本: 01.01
  195. 创建作者: zhaoyang
  196. 创建日期: 2025-08-25
  197. 函数说明: 读取共享内存的数据(结构体不存在A,B,crc).
  198. 参数说明:
  199. addr:所以读取共享内存的地址
  200. len:需要读取数据的长度
  201. out_data:输出buf
  202. out_data_size:输出buf的长度
  203. 返回值:
  204. 成功返回读取数据的长度,
  205. 失败返回 <0
  206. 修改记录:
  207. 使用说明:
  208. 如:Ad7616采样点结构
  209. 本函数只处理不含有A,B和crc的结构体
  210. */
  211. int shm_comm_packet_read_noABcrc(uint32_t addr, uint32_t len, uint8_t *out_data, uint32_t out_data_size)
  212. {
  213. int ret;
  214. ret = shm_read(addr, len, out_data, out_data_size);
  215. return ret;
  216. }
  217. /*------------------------------ 测试函数 -------------------------------------
  218. */
  219. typedef struct testtt_t
  220. {
  221. uint16_t A;
  222. uint16_t B;
  223. uint16_t rc[16];
  224. uint16_t crc;
  225. }testtt_t;
  226. testtt_t aabfd,readaaaa;
  227. void shm_comm_test(void)
  228. {
  229. int i;
  230. int ret = 0;
  231. for(i=0;i<16;i++)
  232. {
  233. aabfd.rc[i]=i+2;
  234. printf("aabfd.rc[%d]=%X\n",i,aabfd.rc[i]);
  235. }
  236. ret = shm_comm_packet_write(0,(uint8_t*)&aabfd,sizeof(aabfd));
  237. printf("shm_comm_packet_write ret=%d\n",ret);
  238. if(ret > 0)
  239. {
  240. for(i=0;i<ret;i++)
  241. {
  242. printf("%X ",SHM_BASE_W[i]);
  243. }
  244. printf("\n ");
  245. }
  246. ret = shm_comm_packet_read(0, sizeof(readaaaa), (uint8_t*)&readaaaa, sizeof(readaaaa));
  247. printf("shm_comm_packet_read ret=%d\n",ret);
  248. if(ret > 0)
  249. {
  250. for(i=0;i<16;i++)
  251. {
  252. printf("%X ",readaaaa.rc[i]);
  253. }
  254. printf("\n ");
  255. }
  256. }
  257. /*------------------------------ 文件结束 -------------------------------------
  258. */