upload.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. #include "upload.h"
  2. #include "user_uart.h"
  3. #include "user_crc16.h"
  4. #include "base64.h"
  5. #include "string.h"
  6. #include "user_server.h"
  7. modbus_work_s upload_work = {
  8. .rtu_addr = DEV_UART_ADDR,
  9. .tx_size = 0,
  10. .rx_size = 0,
  11. .tx_buffer = {0},
  12. .rx_buffer = {0},
  13. .rtu_rec = {0},
  14. .modbusRx_stat = false,
  15. .modbusTx_stat = false,
  16. };
  17. static uint32_t upload_offline_timeout = 0;
  18. static bool upload_offline_stat = true;
  19. static void set_upload_offline(bool stat);
  20. /*******************************************************************************
  21. * @函数名称 uploadRx_receive
  22. * @函数说明 处理接收数据
  23. * @输入参数 data:数据指针
  24. size:数据长度
  25. * @输出参数 无
  26. * @返回参数 无
  27. *******************************************************************************/
  28. static void uploadRx_receive(uint8_t *data, uint16_t size)
  29. {
  30. memcpy(upload_work.rx_buffer, data, size);
  31. upload_work.rx_size = size;
  32. #if USE_BASE64 == 1
  33. uint8_t data[MODBUS_DATA_SIZE] = {0};
  34. if(upload_work.rx_buffer[upload_work.rx_size - 2] == '\r'
  35. && upload_work.rx_buffer[upload_work.rx_size - 1] == '\n')
  36. {
  37. upload_work.rx_buffer[upload_work.rx_size - 2] = '\0';
  38. int len = base64_decode((char *)upload_work.rx_buffer, data);
  39. memcpy((void *)&(upload_work.rtu_rec), data, len);
  40. memcpy((void *)&(upload_work.rtu_rec.crc), &(data[len - 2]), 2);
  41. upload_work.rtu_rec.dataSize = len - 6;
  42. upload_work.modbusRx_stat = true;
  43. }
  44. #else
  45. memcpy((void *)&(upload_work.rtu_rec), upload_work.rx_buffer, upload_work.rx_size);
  46. memcpy((void *)&(upload_work.rtu_rec.crc), &(upload_work.rx_buffer[upload_work.rx_size - 2]), 2);
  47. upload_work.rtu_rec.dataSize = upload_work.rx_size - 6;
  48. upload_work.modbusRx_stat = true;
  49. #endif
  50. }
  51. /*******************************************************************************
  52. * @函数名称 uploadTx_send
  53. * @函数说明 发送数据
  54. * @输入参数 无
  55. * @输出参数 无
  56. * @返回参数 无
  57. *******************************************************************************/
  58. static void uploadTx_send(uint8_t *data, int size)
  59. {
  60. #if USE_BASE64 == 1
  61. base64_encode(data, (char *)upload_work.tx_buffer, size);
  62. int len = strlen((char *)upload_work.tx_buffer);
  63. upload_work.tx_buffer[len] = '\r';
  64. upload_work.tx_buffer[len + 1] = '\n';
  65. upload_work.tx_buffer[len + 2] = '\0';
  66. upload_work.tx_size = len + 2;
  67. #else
  68. memcpy(upload_work.tx_buffer, data, size);
  69. upload_work.tx_size = size;
  70. #endif
  71. upload_work.modbusTx_stat = true;
  72. vUser_usart2_send(upload_work.tx_buffer, upload_work.tx_size);
  73. }
  74. /*******************************************************************************
  75. * @函数名称 rtu_protocol_rd_dev_type
  76. * @函数说明 设置设备类型数据
  77. * @输入参数 data:数据指针
  78. * @输出参数 无
  79. * @返回参数 无
  80. *******************************************************************************/
  81. static uint8_t * rtu_protocol_rd_dev_type(uint8_t *data)
  82. {
  83. *data++ = DEV_TYPE >> 8;
  84. *data++ = DEV_TYPE;
  85. return data;
  86. }
  87. /*******************************************************************************
  88. * @函数名称 rtu_protocol_rd_version
  89. * @函数说明 设置版本号数据
  90. * @输入参数 data:数据指针
  91. * @输出参数 无
  92. * @返回参数 无
  93. *******************************************************************************/
  94. static uint8_t * rtu_protocol_rd_version(uint8_t *data)
  95. {
  96. *data++ = HARDWARE_VERSION;
  97. *data++ = SOFTWARE_VERSION;
  98. return data;
  99. }
  100. /*******************************************************************************
  101. * @函数名称 rtu_protocol_coll_stat
  102. * @函数说明 设置主板状态数据
  103. * @输入参数 data:数据指针
  104. * @输出参数 无
  105. * @返回参数 无
  106. *******************************************************************************/
  107. static uint8_t * rtu_protocol_coll_stat(uint8_t *data)
  108. {
  109. uint16_t value = 0;
  110. memcpy((void *)&value, (void *)&(coll_data.coll_stat), 2);
  111. *data++ = value >> 8;
  112. *data++ = value;
  113. return data;
  114. }
  115. /*******************************************************************************
  116. * @函数名称 rtu_protocol_coll_count
  117. * @函数说明 设置包含的主板数
  118. * @输入参数 data:数据指针
  119. * @输出参数 无
  120. * @返回参数 无
  121. *******************************************************************************/
  122. static uint8_t * rtu_protocol_coll_count(uint8_t *data)
  123. {
  124. uint16_t value = 0;
  125. memcpy((void *)&value, (void *)&(coll_data.count), 2);
  126. *data++ = value >> 8;
  127. *data++ = value;
  128. return data;
  129. }
  130. /*******************************************************************************
  131. * @函数名称 rtu_protocol_sw_low_stat
  132. * @函数说明 设置采集到的所有开关量
  133. * @输入参数 data:数据指针
  134. * @输出参数 无
  135. * @返回参数 无
  136. *******************************************************************************/
  137. static uint8_t * rtu_protocol_sw_low_stat(uint8_t *data)
  138. {
  139. uint16_t value = 0;
  140. for(int i = 0; i < 8; i++)
  141. {
  142. value <<= 2;
  143. value += coll_data.sw_stat[7 - i];
  144. }
  145. *data++ = (uint8_t)(value >> 8);
  146. *data++ = (uint8_t)value;
  147. return data;
  148. }
  149. /*******************************************************************************
  150. * @函数名称 rtu_protocol_sw_low_stat
  151. * @函数说明 设置采集到的所有开关量
  152. * @输入参数 data:数据指针
  153. * @输出参数 无
  154. * @返回参数 无
  155. *******************************************************************************/
  156. static uint8_t * rtu_protocol_sw_high_stat(uint8_t *data)
  157. {
  158. uint16_t value = 0;
  159. for(int i = 0; i < 8; i++)
  160. {
  161. value <<= 2;
  162. value += coll_data.sw_stat[7 - i + 8];
  163. }
  164. *data++ = (uint8_t)(value >> 8);
  165. *data++ = (uint8_t)value;
  166. return data;
  167. }
  168. /*******************************************************************************
  169. * @函数名称 rtu_protocol_send
  170. * @函数说明 发送数据
  171. * @输入参数 data:数据指针
  172. size:数据长度
  173. * @输出参数 无
  174. * @返回参数 无
  175. *******************************************************************************/
  176. static void rtu_protocol_send(uint8_t *data, int size)
  177. {
  178. uint16_t crc = 0xFFFF;
  179. crc = GetCRC16(data, size, crc);
  180. memcpy(&data[size], &crc, 2);
  181. uploadTx_send(data, size + 2);
  182. }
  183. /*******************************************************************************
  184. * @函数名称 rtu_protocol_rd_reg_parsing
  185. * @函数说明 解析接收到的上位机数据
  186. * @输入参数 rec:数据
  187. * @输出参数 无
  188. * @返回参数 无
  189. *******************************************************************************/
  190. static bool rtu_protocol_rd_reg_parsing(rtu_rec_s *rec)
  191. {
  192. uint8_t data[MODBUS_DATA_SIZE] = {0};
  193. uint16_t dataSize = 0;
  194. data[0] = upload_work.rtu_addr;
  195. data[1] = CMD_RD_REG;
  196. dataSize = rec->data[0];
  197. dataSize <<= 8;
  198. dataSize += rec->data[1];
  199. data[2] = dataSize * 2;
  200. uint16_t reg_addr = 0;
  201. reg_addr = rec->regAddr[0];
  202. reg_addr <<= 8;
  203. reg_addr += rec->regAddr[1];
  204. uint8_t *ptr = &data[3];
  205. switch(reg_addr)
  206. {
  207. case REG_DEV_TYPE_ADDR: ptr = rtu_protocol_rd_dev_type(ptr);
  208. case 0x0001: ptr += 4;
  209. case REG_VERSION_ADDR:ptr = rtu_protocol_rd_version(ptr);
  210. case 0x0004: ptr += 24;
  211. case REG_COLL_STAT_ADDR: ptr = rtu_protocol_coll_stat(ptr);
  212. case REG_COLL_COUNT_ADDR: ptr = rtu_protocol_coll_count(ptr);
  213. case REG_COLL_SW_HIGH_STAT_ADDR: ptr = rtu_protocol_sw_high_stat(ptr);
  214. case REG_COLL_SW_LOW_STAT_ADDR: ptr = rtu_protocol_sw_low_stat(ptr);
  215. default:break;
  216. }
  217. rtu_protocol_send(data, dataSize * 2 + 3);
  218. return true;
  219. }
  220. /*******************************************************************************
  221. * @函数名称 rtu_protocol_wr_reg_return
  222. * @函数说明 写入数据成功返回
  223. * @输入参数 rec:数据
  224. * @输出参数 无
  225. * @返回参数 无
  226. *******************************************************************************/
  227. static void rtu_protocol_wr_reg_return(rtu_rec_s *rec)
  228. {
  229. uint8_t data[MODBUS_DATA_SIZE] = {0};
  230. data[0] = rec->addr;
  231. data[1] = rec->func;
  232. data[2] = rec->regAddr[0];
  233. data[3] = rec->regAddr[1];
  234. memcpy(&data[4], rec->data, rec->dataSize);
  235. memcpy(&data[rec->dataSize + 4], (uint8_t *)&(rec->crc), 2);
  236. uploadTx_send(data, rec->dataSize + 6);
  237. }
  238. /*******************************************************************************
  239. * @函数名称 rtu_protocol_wr_coll_sw_high_stat_parsing
  240. * @函数说明 设置存取状态指令返回解析
  241. * @输入参数 rec:数据
  242. * @输出参数 无
  243. * @返回参数 无
  244. *******************************************************************************/
  245. static bool rtu_protocol_wr_coll_sw_high_stat_parsing(rtu_rec_s *rec)
  246. {
  247. uint16_t temp = 0;
  248. temp = rec->data[0];
  249. temp <<= 8;
  250. temp += rec->data[1];
  251. for(int i = 0; i < 8; i++)
  252. {
  253. if((temp & (1 << (i + 8))) != 0)
  254. {
  255. if((temp & (1 << i)) != 0)
  256. {
  257. vUser_server_set_items_stat(i + 8, PUT_ITEMS_STAT);
  258. }
  259. else{
  260. vUser_server_set_items_stat(i + 8, TAKE_ITEMS_STAT);
  261. }
  262. }
  263. else{
  264. vUser_server_set_items_stat(i, NO_ITEMS_STAT);
  265. }
  266. }
  267. rtu_protocol_wr_reg_return(rec);
  268. return true;
  269. }
  270. /*******************************************************************************
  271. * @函数名称 rtu_protocol_wr_coll_sw_low_stat_parsing
  272. * @函数说明 设置存取状态指令返回解析
  273. * @输入参数 rec:数据
  274. * @输出参数 无
  275. * @返回参数 无
  276. *******************************************************************************/
  277. static bool rtu_protocol_wr_coll_sw_low_stat_parsing(rtu_rec_s *rec)
  278. {
  279. uint16_t temp = 0;
  280. temp = rec->data[0];
  281. temp <<= 8;
  282. temp += rec->data[1];
  283. for(int i = 0; i < 8; i++)
  284. {
  285. if((temp & (1 << (i + 8))) != 0)
  286. {
  287. if((temp & (1 << i)) != 0)
  288. {
  289. vUser_server_set_items_stat(i, PUT_ITEMS_STAT);
  290. }
  291. else{
  292. vUser_server_set_items_stat(i, TAKE_ITEMS_STAT);
  293. }
  294. }
  295. else{
  296. vUser_server_set_items_stat(i, NO_ITEMS_STAT);
  297. }
  298. }
  299. rtu_protocol_wr_reg_return(rec);
  300. return true;
  301. }
  302. /*******************************************************************************
  303. * @函数名称 rtu_protocol_wr_reg_parsing
  304. * @函数说明 写指令数据解析
  305. * @输入参数 rec:数据
  306. * @输出参数 无
  307. * @返回参数 无
  308. *******************************************************************************/
  309. static bool rtu_protocol_wr_reg_parsing(rtu_rec_s *rec)
  310. {
  311. bool stat = false;
  312. uint16_t reg_addr = 0;
  313. reg_addr = rec->regAddr[0];
  314. reg_addr <<= 8;
  315. reg_addr += rec->regAddr[1];
  316. switch(reg_addr)
  317. {
  318. case REG_COLL_SW_HIGH_STAT_ADDR: stat = rtu_protocol_wr_coll_sw_high_stat_parsing(rec);break;
  319. case REG_COLL_SW_LOW_STAT_ADDR: stat = rtu_protocol_wr_coll_sw_low_stat_parsing(rec);break;
  320. default:break;
  321. }
  322. return stat;
  323. }
  324. /*******************************************************************************
  325. * @函数名称 rtu_protocol_wr_multi_coll_sw_stat_parsing
  326. * @函数说明 设置存取状态指令返回解析
  327. * @输入参数 rec:数据
  328. * @输出参数 无
  329. * @返回参数 无
  330. *******************************************************************************/
  331. static bool rtu_protocol_wr_multi_coll_sw_stat_parsing(rtu_wr_multi_s *wr_multi)
  332. {
  333. bool stat = false;
  334. uint16_t regCount = 0;
  335. regCount = wr_multi->regCount[0];
  336. regCount <<= 8;
  337. regCount += wr_multi->regCount[1];
  338. if(regCount == 2 && wr_multi->count == 4)
  339. {
  340. uint32_t temp = 0;
  341. temp += *wr_multi->data++;
  342. temp <<= 8;
  343. temp += *wr_multi->data++;
  344. temp <<= 8;
  345. temp += *wr_multi->data++;
  346. temp <<= 8;
  347. temp += *wr_multi->data++;
  348. for(int i = 0; i < 16; i++)
  349. {
  350. if((temp & (1 << (i + 16))) != 0)
  351. {
  352. if((temp & (1 << i)) != 0)
  353. {
  354. vUser_server_set_items_stat(i, PUT_ITEMS_STAT);
  355. }
  356. else{
  357. vUser_server_set_items_stat(i, TAKE_ITEMS_STAT);
  358. }
  359. }
  360. else{
  361. vUser_server_set_items_stat(i, NO_ITEMS_STAT);
  362. }
  363. }
  364. stat = true;
  365. }
  366. return stat;
  367. }
  368. /*******************************************************************************
  369. * @函数名称 rtu_protocol_wr_multi_reg_parsing
  370. * @函数说明 解析接收到的上位机数据
  371. * @输入参数 rec:数据
  372. * @输出参数 无
  373. * @返回参数 无
  374. *******************************************************************************/
  375. static bool rtu_protocol_wr_multi_reg_parsing(rtu_rec_s *rec)
  376. {
  377. bool stat = false;
  378. uint8_t data[MODBUS_DATA_SIZE] = {0};
  379. rtu_wr_multi_s wr_multi;
  380. uint16_t reg_addr = 0;
  381. wr_multi.addr = upload_work.rtu_addr;
  382. wr_multi.func = CMD_WR_MULTI_REG;
  383. wr_multi.regAddr[0] = rec->regAddr[0];
  384. wr_multi.regAddr[1] = rec->regAddr[1];
  385. wr_multi.regCount[0] = rec->data[0];
  386. wr_multi.regCount[1] = rec->data[1];
  387. wr_multi.count = rec->data[2];
  388. wr_multi.data = &(rec->data[3]);
  389. reg_addr = wr_multi.regAddr[0];
  390. reg_addr <<= 8;
  391. reg_addr += wr_multi.regAddr[1];
  392. switch(reg_addr)
  393. {
  394. case REG_COLL_SW_HIGH_STAT_ADDR: stat = rtu_protocol_wr_multi_coll_sw_stat_parsing(&wr_multi);
  395. default:break;
  396. }
  397. if(stat == true)
  398. {
  399. memcpy(data, (uint8_t *)&wr_multi, 6);
  400. rtu_protocol_send(data, 6);
  401. }
  402. return stat;
  403. }
  404. /*******************************************************************************
  405. * @函数名称 rtu_protocol_parsing
  406. * @函数说明 解析接收到的上位机数据
  407. * @输入参数 rec:数据
  408. * @输出参数 无
  409. * @返回参数 无
  410. *******************************************************************************/
  411. static bool rtu_protocol_parsing(rtu_rec_s *rec)
  412. {
  413. uint16_t crc = 0xFFFF;
  414. crc = GetCRC16((uint8_t *)rec, rec->dataSize + 4, crc);
  415. if(crc != rec->crc)
  416. {
  417. return false;
  418. }
  419. if(rec->addr != upload_work.rtu_addr)
  420. {
  421. return false;
  422. }
  423. if(rec->func == CMD_RD_REG)
  424. {
  425. if(true == rtu_protocol_rd_reg_parsing(rec))
  426. {
  427. set_upload_offline(false);
  428. return true;
  429. }
  430. }
  431. else if(rec->func == CMD_WR_REG)
  432. {
  433. if(true == rtu_protocol_wr_reg_parsing(rec))
  434. {
  435. set_upload_offline(false);
  436. return true;
  437. }
  438. }
  439. else if(rec->func == CMD_WR_MULTI_REG)
  440. {
  441. if(true == rtu_protocol_wr_multi_reg_parsing(rec))
  442. {
  443. set_upload_offline(false);
  444. return true;
  445. }
  446. }
  447. return false;
  448. }
  449. static void set_upload_offline(bool stat)
  450. {
  451. if(stat == true)
  452. {
  453. upload_offline_timeout = 5000;
  454. if(upload_offline_stat == false)
  455. {
  456. upload_offline_stat = true;
  457. }
  458. }
  459. else{
  460. if(upload_offline_stat == true)
  461. {
  462. upload_offline_stat = false;
  463. }
  464. }
  465. }
  466. /*******************************************************************************
  467. * @函数名称 vUpload_tick
  468. * @函数说明 任务计时器
  469. * @输入参数 无
  470. * @输出参数 无
  471. * @返回参数 无
  472. *******************************************************************************/
  473. void vUpload_tick(void)
  474. {
  475. if(upload_offline_timeout > 0)
  476. {
  477. upload_offline_timeout--;
  478. }
  479. else{
  480. set_upload_offline(true);
  481. }
  482. }
  483. /*******************************************************************************
  484. * @函数名称 upload_pro
  485. * @函数说明 任务
  486. * @输入参数 无
  487. * @输出参数 无
  488. * @返回参数 无
  489. *******************************************************************************/
  490. void vUpload_pro(void)
  491. {
  492. if(upload_work.modbusRx_stat == true)
  493. {
  494. upload_work.modbusRx_stat = false;
  495. rtu_protocol_parsing(&(upload_work.rtu_rec));
  496. }
  497. }
  498. /*******************************************************************************
  499. * @函数名称 vUpload_init
  500. * @函数说明 初始化
  501. * @输入参数 无
  502. * @输出参数 无
  503. * @返回参数 无
  504. *******************************************************************************/
  505. void vUpload_init(void)
  506. {
  507. user_uart_param_s param = {
  508. .baudrate = 115200,
  509. .wordlength = USART_WordLength_8b,
  510. .stopbit = USART_StopBits_1,
  511. .parity = USART_Parity_No,
  512. };
  513. vUser_usart2_init(&param);
  514. vUser_usart2_set_data_upload_func(uploadRx_receive);
  515. }