modbus_deal.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. #include "modbus_deal.h"
  2. #include "usart.h"
  3. #include "string.h"
  4. #include "stdio.h"
  5. #include "crc.h"
  6. #include "iap.h"
  7. #include "parameters.h"
  8. #include "modbus_implement.h"
  9. typedef struct _mb_ctx
  10. {
  11. uint8_t* rxbuf;
  12. uint8_t* txbuf;
  13. uint16_t rx_len; //recv data length
  14. uint16_t tx_len; //will be transfer data length
  15. uint16_t txbuf_size;
  16. uint8_t exception_code;
  17. uint8_t func_code; // function code
  18. uint16_t cmd; // register
  19. }MB_CTX;
  20. static MB_CTX g_mb_ctx;
  21. void mb_03_handle(void)
  22. {
  23. uint16_t tx_offset = 0;
  24. uint16_t crc;
  25. uint16_t reg_num = ((uint16_t)g_mb_ctx.rxbuf[4]<<8)|g_mb_ctx.rxbuf[5];
  26. uint16_t read_len = reg_num<<1; // wanted bytes
  27. //
  28. g_mb_ctx.txbuf[0] = g_mb_ctx.rxbuf[0]; // slave addr
  29. g_mb_ctx.txbuf[1] = g_mb_ctx.rxbuf[1]; // func code
  30. g_mb_ctx.txbuf[2] = 0x00;
  31. tx_offset = 3;
  32. switch(g_mb_ctx.cmd){
  33. case Cmd_FirmwareVersion:
  34. if(16 == read_len){
  35. tx_offset += Read_FirmwareVersion(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  36. }else if(18 == read_len){
  37. tx_offset += Read_FirmwareVersion(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  38. tx_offset += Read_HardwareVersion(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  39. }else if(22 == read_len){
  40. tx_offset += Read_FirmwareVersion(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  41. tx_offset += Read_HardwareVersion(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  42. tx_offset += Read_Deviceid(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  43. }else if(24 == read_len){
  44. tx_offset += Read_FirmwareVersion(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  45. tx_offset += Read_HardwareVersion(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  46. tx_offset += Read_Deviceid(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  47. tx_offset += Read_Devicetype(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  48. }else {
  49. g_mb_ctx.exception_code = INVALID_DATA;
  50. }
  51. break;
  52. case Cmd_HardwareVersion:
  53. if(2 == read_len){
  54. tx_offset += Read_HardwareVersion(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  55. }else if(6 == read_len){
  56. tx_offset += Read_HardwareVersion(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  57. tx_offset += Read_Deviceid(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  58. }else if(8 == read_len){
  59. tx_offset += Read_HardwareVersion(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  60. tx_offset += Read_Deviceid(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  61. tx_offset += Read_Devicetype(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  62. }else{
  63. g_mb_ctx.exception_code = INVALID_DATA;
  64. }
  65. break;
  66. case Cmd_DeviceID:
  67. if(4 == read_len){
  68. tx_offset += Read_Deviceid(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  69. }else if(6 == read_len){
  70. tx_offset += Read_Deviceid(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  71. tx_offset += Read_Devicetype(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  72. }else{
  73. g_mb_ctx.exception_code = INVALID_DATA;
  74. }
  75. break;
  76. case Cmd_DeviceType:
  77. if(2 == read_len){
  78. tx_offset += Read_Devicetype(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  79. }else{
  80. g_mb_ctx.exception_code = INVALID_DATA;
  81. }
  82. break;
  83. case Cmd_Addr:
  84. if(2 == read_len){
  85. tx_offset += Read_Addr(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  86. }else if(4 == read_len){
  87. tx_offset += Read_Addr(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  88. tx_offset += Read_Baudrate(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  89. }else {
  90. g_mb_ctx.exception_code = INVALID_DATA;
  91. }
  92. break;
  93. case Cmd_Baudrate:
  94. if(2 == read_len){
  95. tx_offset += Read_Baudrate(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
  96. }else{
  97. g_mb_ctx.exception_code = INVALID_DATA;
  98. }
  99. break;
  100. default:
  101. g_mb_ctx.exception_code = INVALID_COMMAND;
  102. break;
  103. };
  104. if(NO_EXCEPTION == g_mb_ctx.exception_code){
  105. g_mb_ctx.txbuf[2] = (uint8_t)read_len;
  106. g_mb_ctx.tx_len = tx_offset;
  107. }else{
  108. g_mb_ctx.txbuf[1] |= 0x80; // func code
  109. g_mb_ctx.txbuf[2] = g_mb_ctx.exception_code;
  110. g_mb_ctx.tx_len = 3;
  111. }
  112. crc = mb_crc16(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  113. g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)(crc & 0x00ff);
  114. g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)((crc>>8) & 0x00ff);
  115. rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  116. }
  117. void mb_06_handle(void)
  118. {
  119. uint16_t crc;
  120. uint8_t ret_write = RET_OK;
  121. memcpy(g_mb_ctx.txbuf, g_mb_ctx.rxbuf, g_mb_ctx.rx_len);
  122. switch(g_mb_ctx.cmd){
  123. case Cmd_HardwareVersion:
  124. if(2 == g_mb_ctx.rx_len-4-2){
  125. ret_write = Write_HardwareVersion(g_mb_ctx.rxbuf+4, 2);
  126. if(RET_DATAINVALID == ret_write)
  127. g_mb_ctx.exception_code = INVALID_DATA;
  128. }else{
  129. g_mb_ctx.exception_code = INVALID_DATA;
  130. }
  131. break;
  132. case Cmd_DeviceType:
  133. if(2 == g_mb_ctx.rx_len-4-2){
  134. ret_write = Write_Devicetype(g_mb_ctx.rxbuf+4, 2);
  135. if(RET_DATAINVALID == ret_write)
  136. g_mb_ctx.exception_code = INVALID_DATA;
  137. }else{
  138. g_mb_ctx.exception_code = INVALID_DATA;
  139. }
  140. break;
  141. case Cmd_Addr:
  142. if(2 == g_mb_ctx.rx_len-4-2){
  143. ret_write = Write_Addr(g_mb_ctx.rxbuf+4, 2);
  144. if(RET_DATAINVALID == ret_write)
  145. g_mb_ctx.exception_code = INVALID_DATA;
  146. }else{
  147. g_mb_ctx.exception_code = INVALID_DATA;
  148. }
  149. break;
  150. case Cmd_Baudrate:
  151. if(2 == g_mb_ctx.rx_len-4-2){
  152. ret_write = Write_Baudrate(g_mb_ctx.rxbuf+4, 2);
  153. if(RET_DATAINVALID == ret_write)
  154. g_mb_ctx.exception_code = INVALID_DATA;
  155. }else{
  156. g_mb_ctx.exception_code = INVALID_DATA;
  157. }
  158. break;
  159. case Cmd_Reboot:
  160. //NVIC_SystemReset();
  161. ret_write = RET_NEED_REBOOT;
  162. break;
  163. case Cmd_Reset:
  164. ResetConfig();
  165. ret_write = RET_NEED_SAVE|RET_NEED_REBOOT;
  166. //NVIC_SystemReset();
  167. break;
  168. default:
  169. g_mb_ctx.exception_code = INVALID_COMMAND;
  170. break;
  171. };
  172. if(NO_EXCEPTION == g_mb_ctx.exception_code){
  173. g_mb_ctx.tx_len = g_mb_ctx.rx_len;
  174. }else{
  175. g_mb_ctx.txbuf[1] |= 0x80; // func code
  176. g_mb_ctx.txbuf[2] = g_mb_ctx.exception_code;
  177. g_mb_ctx.tx_len = 3;
  178. crc = mb_crc16(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  179. g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)(crc & 0x00ff);
  180. g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)((crc>>8) & 0x00ff);
  181. }
  182. rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  183. if((ret_write&RET_NEED_SAVE) > 0 ){
  184. SaveConfig();
  185. }
  186. if((ret_write&RET_NEED_REBOOT) > 0 ){
  187. //mdelay(200);
  188. HAL_Delay(100);
  189. NVIC_SystemReset();
  190. }
  191. }
  192. void mb_10_handle(void)
  193. {
  194. uint16_t crc;
  195. uint8_t ret_write = RET_OK;
  196. uint16_t reg_num = ((uint16_t)g_mb_ctx.rxbuf[4]<<8)|g_mb_ctx.rxbuf[5];
  197. uint16_t data_len = g_mb_ctx.rxbuf[6];
  198. memcpy(g_mb_ctx.txbuf, g_mb_ctx.rxbuf, g_mb_ctx.rx_len);
  199. // 先判段数据长度是否一致
  200. if(data_len != reg_num*2){
  201. g_mb_ctx.exception_code = INVALID_DATA;
  202. }else{
  203. if(data_len != g_mb_ctx.rx_len-7-2){
  204. g_mb_ctx.exception_code = INVALID_DATA;
  205. }
  206. }
  207. if(NO_EXCEPTION == g_mb_ctx.exception_code){
  208. switch(g_mb_ctx.cmd){
  209. case Cmd_HardwareVersion:
  210. if(8 == data_len){
  211. ret_write |= Write_HardwareVersion(g_mb_ctx.rxbuf+7, 2);
  212. ret_write |= Write_Deviceid(g_mb_ctx.rxbuf+7+2, 4);
  213. ret_write |= Write_Devicetype(g_mb_ctx.rxbuf+7+6, 2);
  214. if(ret_write&RET_DATAINVALID)
  215. g_mb_ctx.exception_code = INVALID_DATA;
  216. }else if(6 == data_len){
  217. ret_write |= Write_HardwareVersion(g_mb_ctx.rxbuf+7, 2);
  218. ret_write |= Write_Deviceid(g_mb_ctx.rxbuf+7+2, 4);
  219. if(ret_write&RET_DATAINVALID)
  220. g_mb_ctx.exception_code = INVALID_DATA;
  221. }else if(2 == g_mb_ctx.rx_len-4-2){
  222. ret_write = Write_HardwareVersion(g_mb_ctx.rxbuf+7, 2);
  223. if(ret_write&RET_DATAINVALID)
  224. g_mb_ctx.exception_code = INVALID_DATA;
  225. }else{
  226. g_mb_ctx.exception_code = INVALID_DATA;
  227. }
  228. break;
  229. case Cmd_DeviceID:
  230. if(6 == data_len){
  231. ret_write |= Write_Deviceid(g_mb_ctx.rxbuf+7, 4);
  232. ret_write |= Write_Devicetype(g_mb_ctx.rxbuf+7+4, 2);
  233. if(ret_write&RET_DATAINVALID)
  234. g_mb_ctx.exception_code = INVALID_DATA;
  235. }else if(4 == data_len){
  236. ret_write |= Write_Deviceid(g_mb_ctx.rxbuf+7, 4);
  237. if(ret_write&RET_DATAINVALID)
  238. g_mb_ctx.exception_code = INVALID_DATA;
  239. }else{
  240. g_mb_ctx.exception_code = INVALID_DATA;
  241. }
  242. break;
  243. case Cmd_DeviceType:
  244. if(2 == data_len){
  245. ret_write |= Write_Devicetype(g_mb_ctx.rxbuf+7, 2);
  246. if(ret_write&RET_DATAINVALID)
  247. g_mb_ctx.exception_code = INVALID_DATA;
  248. }else{
  249. g_mb_ctx.exception_code = INVALID_DATA;
  250. }
  251. break;
  252. case Cmd_Addr:
  253. if(4 == data_len){
  254. ret_write |= Write_Addr(g_mb_ctx.rxbuf+7, 2);
  255. ret_write |= Write_Addr(g_mb_ctx.rxbuf+7+2, 2);
  256. if(ret_write&RET_DATAINVALID)
  257. g_mb_ctx.exception_code = INVALID_DATA;
  258. }else if(2 == data_len){
  259. ret_write |= Write_Addr(g_mb_ctx.rxbuf+7, 2);
  260. if(ret_write&RET_DATAINVALID)
  261. g_mb_ctx.exception_code = INVALID_DATA;
  262. }else{
  263. g_mb_ctx.exception_code = INVALID_DATA;
  264. }
  265. break;
  266. case Cmd_Baudrate:
  267. if(2 == data_len){
  268. ret_write |= Write_Baudrate(g_mb_ctx.rxbuf+7, 2);
  269. if(ret_write&RET_DATAINVALID)
  270. g_mb_ctx.exception_code = INVALID_DATA;
  271. }else{
  272. g_mb_ctx.exception_code = INVALID_DATA;
  273. }
  274. break;
  275. default:
  276. g_mb_ctx.exception_code = INVALID_COMMAND;
  277. break;
  278. };
  279. }
  280. if(NO_EXCEPTION == g_mb_ctx.exception_code){
  281. //只需要收到的前面6个字节的数据
  282. g_mb_ctx.tx_len = 6;
  283. }else{
  284. g_mb_ctx.txbuf[1] |= 0x80; // func code
  285. g_mb_ctx.txbuf[2] = g_mb_ctx.exception_code;
  286. g_mb_ctx.tx_len = 3;
  287. }
  288. crc = mb_crc16(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  289. g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)(crc & 0x00ff);
  290. g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)((crc>>8) & 0x00ff);
  291. rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  292. if((ret_write&RET_NEED_SAVE) > 0 ){
  293. SaveConfig();
  294. }
  295. if((ret_write&RET_NEED_REBOOT) > 0 ){
  296. //mdelay(200);
  297. //__set_FAULTMASK(1);//关闭所有中断
  298. HAL_Delay(100);
  299. NVIC_SystemReset();//复位函数
  300. }
  301. }
  302. void mb_42_handle(void)
  303. {
  304. uint16_t crc;
  305. uint8_t ret_write = RET_OK;
  306. memcpy(g_mb_ctx.txbuf, g_mb_ctx.rxbuf, 4);
  307. g_mb_ctx.tx_len = 4;
  308. if(Cmd_IapUpgrade == g_mb_ctx.cmd){
  309. g_mb_ctx.tx_len += IAP_CmdHandle(g_mb_ctx.rxbuf+g_mb_ctx.tx_len, g_mb_ctx.rx_len-4-2, g_mb_ctx.txbuf+g_mb_ctx.tx_len);
  310. if(1 == iap_reboot){
  311. ret_write |= RET_NEED_REBOOT;
  312. }
  313. }else{
  314. g_mb_ctx.exception_code = INVALID_COMMAND;
  315. }
  316. if(NO_EXCEPTION == g_mb_ctx.exception_code){
  317. //啥都不用做
  318. }else{
  319. g_mb_ctx.txbuf[1] |= 0x80; // func code
  320. g_mb_ctx.txbuf[2] = g_mb_ctx.exception_code;
  321. g_mb_ctx.tx_len = 3;
  322. }
  323. crc = mb_crc16(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  324. g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)(crc & 0x00ff);
  325. g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)((crc>>8) & 0x00ff);
  326. rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  327. if((ret_write&RET_NEED_SAVE) > 0 ){
  328. SaveConfig();
  329. }
  330. if((ret_write&RET_NEED_REBOOT) > 0 ){
  331. //mdelay(200);
  332. HAL_Delay(100);
  333. NVIC_SystemReset();
  334. }
  335. }
  336. void mb_funccodeerror_handle(void)
  337. {
  338. uint16_t crc;
  339. memcpy(g_mb_ctx.txbuf, g_mb_ctx.rxbuf, 4);
  340. g_mb_ctx.txbuf[1] |= 0x80;
  341. g_mb_ctx.txbuf[2] = INVALID_FUNCTION_CODE;
  342. g_mb_ctx.tx_len = 3;
  343. crc = mb_crc16(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  344. g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)(crc & 0x00ff);
  345. g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)((crc>>8) & 0x00ff);
  346. rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  347. }
  348. void mb_handle(void)
  349. {
  350. g_mb_ctx.func_code = g_mb_ctx.rxbuf[1];
  351. g_mb_ctx.cmd = ((uint16_t)g_mb_ctx.rxbuf[2]<<8) | g_mb_ctx.rxbuf[3];
  352. if(MB_FUNC_03 == g_mb_ctx.func_code){
  353. mb_03_handle();
  354. }else if(MB_FUNC_06 == g_mb_ctx.func_code){
  355. mb_06_handle();
  356. }else if(MB_FUNC_10 == g_mb_ctx.func_code){
  357. mb_10_handle();
  358. }else if(MB_FUNC_42 == g_mb_ctx.func_code){
  359. mb_42_handle();
  360. }else{
  361. mb_funccodeerror_handle();
  362. }
  363. }
  364. void Modbus_StartReceive(void)
  365. {
  366. rs485_ReceiveData();
  367. }
  368. void Modbus_DataHandle(void)
  369. {
  370. g_mb_ctx.rxbuf = rs485_info.recv_buffer;
  371. g_mb_ctx.rx_len = rs485_info.recv_len;
  372. g_mb_ctx.txbuf = rs485_info.send_buffer;
  373. g_mb_ctx.txbuf_size = UART_TRANSMIT_DATA_POOL_COUNT;
  374. g_mb_ctx.tx_len = 0;
  375. g_mb_ctx.exception_code = NO_EXCEPTION;
  376. uint16_t crc;
  377. //uint16_t ret_len = 0;
  378. //uint8_t ret_write = RET_OK;
  379. if(g_mb_ctx.rx_len > 2){
  380. //check rs485 addr
  381. if(config->addr == g_mb_ctx.rxbuf[0] || BROADCAST_ADDR == g_mb_ctx.rxbuf[0]){
  382. #if 1
  383. // check crc
  384. crc = ((uint16_t)g_mb_ctx.rxbuf[g_mb_ctx.rx_len-1]<<8) | g_mb_ctx.rxbuf[g_mb_ctx.rx_len-2];
  385. if (crc == mb_crc16(g_mb_ctx.rxbuf, g_mb_ctx.rx_len-2))
  386. {
  387. mb_handle();
  388. }
  389. // printf("recv 444 crc[%x], calculate22 crc[%x] \r\n", crc, mb_crc16(g_mb_ctx.rxbuf, g_mb_ctx.rx_len-2));
  390. #else
  391. memcpy(g_mb_ctx.txbuf, (void *)g_mb_ctx.rxbuf, g_mb_ctx.rx_len);
  392. g_mb_ctx.tx_len = g_mb_ctx.rx_len;
  393. printf("rs485 rev data length:[%d] \r\n", g_mb_ctx.rx_len);
  394. rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
  395. #endif
  396. }
  397. } //END rx_len
  398. if(g_mb_ctx.rx_len > 0){
  399. rs485_ReceiveData();
  400. }
  401. }