PC.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. #include "gd32f10x.h"
  2. #include "usart.h"
  3. #include "device_message.h"
  4. #include "PC.h"
  5. #include "parseDeviceMessage.h"
  6. #include "ec800m.h"
  7. #include "string.h"
  8. #include "mmodbus.h"
  9. #include "otaEvent.h"
  10. #define Top 0xEE //自定义协议帧起始符号
  11. #define END 0xBB //自定义协议帧结束
  12. #define READ_ID 0x01 // 读取设备id、固件版本号
  13. #define READ_GATEWAY_MESSAGE 0x02 // 读取网关设备信息
  14. #define READ_GATEWAY_JSON_CONFIG 0x03 // 读取JSON配置
  15. #define WIRTE_GATEWAY_JSON_CONFIG 0x04 // 写入JSON配置
  16. #define OTA_EVENT 0x05 // 进入程序更新
  17. #define SET_GATEWAY_PLATFORM 0x06 // 设置物联网平台
  18. bool WaitField(char *expectStr, int timeout);
  19. void readGatewayConfig(void); //读取设备系列DTU/LORA等等
  20. void readGatewayMessage(void); //读取sim卡相关信息
  21. void readSIMCARD(void);
  22. void read_json_config();
  23. void write_json_config(char *json);
  24. void ec800m_4G_Data_read(uint8_t *str,uint16_t len);
  25. volatile int RxState;
  26. usart2_data_buf_t RxPacket;
  27. volatile uint32_t json_buf_num;//串口232配置数据长度
  28. /*
  29. 此中断处理逻辑较为复杂
  30. 总共有两条线路
  31. 1、自定义协议的线路
  32. 对于自定义协议当其接收到了开始位之后、进入功能判断对其具体功能做出具体的响应、
  33. 其中又分为两种情况:
  34. (1)查询某一属性值、其长度并不会超过5、在接收完毕后即可进行状态归位操作
  35. (2)写入操作、其在后续会跟一些不定长的数据包、无法判断其具体长度。所以要在空闲中断中进行状态
  36. 归位操作。
  37. 2、OTA升级的线路
  38. 对于OTA升级的操作、其上位机要先导要传一段自定义协议的数据将状态转化为升级状态、之后等待
  39. 从机回应进入等待升级状态、直到最后一个数据包结束标志抵达后才进行状态清零。或者超时之后进行了状态
  40. 归位操作。
  41. */
  42. void USART2_IRQHandler(void)
  43. {
  44. char *writeJSON=NULL;
  45. if (RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_RBNE)) // 接收寄存器不空
  46. {
  47. uint8_t Serial_RxData;
  48. Serial_RxData = usart_data_receive(USART2);
  49. if (ota_data.ota_flag==0&&RxState==OTA_EVENT)
  50. {
  51. RxState=0;//ota更新中断后状态归位
  52. }
  53. if (RxState == 0) // 等待包头
  54. {
  55. if (Serial_RxData == Top) // 获取到包头则切换到识别功能模式
  56. {
  57. RxState = 1;
  58. RxPacket.data_cnt = 0;
  59. RxPacket.data[RxPacket.data_cnt] = Serial_RxData;
  60. }
  61. }
  62. else if (RxState == 1) // 接收数据
  63. {
  64. RxPacket.data_cnt++;
  65. RxPacket.data[RxPacket.data_cnt] = Serial_RxData;
  66. if (RxPacket.data_cnt >= 3) // 接收完数据
  67. {
  68. RxState = 2; // 前导数据位已经接收完毕、转化状态接收尾部数据
  69. }
  70. }
  71. else if (RxState == 2) // 等待包尾
  72. {
  73. if (Serial_RxData == END) // 进入了结束位
  74. {
  75. if (RxPacket.data[1] == WIRTE_GATEWAY_JSON_CONFIG) // 当为写入json数据后进入状态3、将对应数据放到usart0_buf中
  76. {
  77. RxState = 3;
  78. writeJSON=malloc(40*1024);
  79. json_buf_num = 0;
  80. }
  81. else if (RxPacket.data[1] == OTA_EVENT) // 进入了OTA事件此时的状态会处于接收程序状态、一直等待OTA的结束标志位
  82. {
  83. RxState = 4;
  84. ota_data.data_cnt=0;
  85. memset(ota_data.data,0,133);//清空数据
  86. ota_data.ota_flag=1;
  87. }
  88. else // 其他情况则将状态归位
  89. {
  90. RxState = 0;
  91. }
  92. }
  93. }
  94. else if (RxState == 3) // 接收到json信息进入进行处理
  95. {
  96. writeJSON[json_buf_num++]=Serial_RxData;
  97. }
  98. else if (RxState == 4) //进入OTA升级路线
  99. {
  100. ota_data.data[ota_data.data_cnt] = Serial_RxData;
  101. ota_data.data_cnt++;
  102. }
  103. // 清除中断标志
  104. usart_interrupt_flag_clear(USART2, USART_INT_FLAG_RBNE);
  105. }
  106. if ((RxPacket.data_cnt > 0) && RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_IDLE))
  107. {
  108. // 进入空闲中断后通过功能位进行判断其具体作用,并给予相应响应
  109. if (RxPacket.data[0] == Top)
  110. {
  111. switch (RxPacket.data[1])
  112. {
  113. case READ_ID:
  114. // readGatewayMessage();
  115. break;
  116. case READ_GATEWAY_MESSAGE:
  117. // readSIMCARD();
  118. break;
  119. case READ_GATEWAY_JSON_CONFIG:
  120. // read_json_config();
  121. break;
  122. case WIRTE_GATEWAY_JSON_CONFIG:
  123. // write_json_config(writeJSON);
  124. break;
  125. case SET_GATEWAY_PLATFORM:
  126. break;
  127. default:
  128. break;
  129. }
  130. }
  131. // 此时不在ota升级的分支时,防止其他错误指令造成的数据状态不归位情况
  132. if (ota_data.ota_flag == 0)
  133. {
  134. RxState = 0;
  135. }
  136. else if(ota_data.ota_flag==1)
  137. {
  138. ota_data.done=1;
  139. }
  140. usart_data_receive(USART2);
  141. }
  142. }
  143. /*
  144. * 函数名:void readGatewayMessage()
  145. * 输入参数:无
  146. * 输出参数:无
  147. * 返回值:无
  148. * 函数作用:读取gateway内部配置信息
  149. */
  150. void readGatewayMessage(void)
  151. {
  152. GATEWAY_PARAMS *gateway;
  153. gateway = get_gateway_config_params();
  154. uint8_t *gatewayMessageData=malloc(100);
  155. memset(gatewayMessageData,0,100);
  156. gatewayMessageData[0]=Top;
  157. gatewayMessageData[1]=READ_ID;
  158. uint8_t deviceIdLen=strlen((char *)&gateway->deviceId);
  159. uint8_t versionLen=strlen((char *)&gateway->version);
  160. memcpy(gatewayMessageData+2,gateway->deviceId,deviceIdLen);
  161. gatewayMessageData[deviceIdLen+2]=0x3B;
  162. memcpy(gatewayMessageData+2+1+deviceIdLen,gateway->version,versionLen);
  163. uint16_t CRC16=mmodbus_crc16(gatewayMessageData+1,strlen((char *)&gatewayMessageData)-1);
  164. gatewayMessageData[deviceIdLen+2+1+versionLen+1] = (uint8_t) (CRC16 & 0x00FF);
  165. gatewayMessageData[deviceIdLen+2+1+versionLen] = (uint8_t) ((CRC16 & 0xFF00)>>8);
  166. gatewayMessageData[deviceIdLen+2+1+versionLen+2]=END;
  167. gatewayMessageData[deviceIdLen+2+1+versionLen+2+1]='\0';
  168. gd_com_232_send(gatewayMessageData,strlen((char* )&gatewayMessageData));
  169. free(gatewayMessageData);
  170. }
  171. /*
  172. * 函数名:void readSIMCARD()
  173. * 输入参数:无
  174. * 输出参数:无
  175. * 返回值:无
  176. * 函数作用:读出sim卡的相关配置
  177. */
  178. void readSIMCARD()
  179. {
  180. GATEWAY_PARAMS *gateway;
  181. gateway = get_gateway_config_params();
  182. char *gatewayConfigData=malloc(1024);
  183. memset(gatewayConfigData,0,1024);
  184. uint8_t Operators[16];
  185. int Networkstatu;
  186. uint8_t SIMCard=0; //状态0 正常 状态1异常
  187. uint8_t ICCID[20];
  188. uint8_t IMMIE[15];
  189. uint8_t Networktyp; //0 GSM 2 UTRAN 3 GSM W/EGPRS 4 UTRAN W/HSDPA 5 UTRAN W/HSUPA 6 UTRAN W/HSDPA and HSUPA 7 E-UTRAN 8 UTRAN HSPA+
  190. uint8_t Signal_strength; //信号强度
  191. //查询运营商
  192. EC800MSendCmd(CMD_SERVICE_Operatortyp, strlen(CMD_SERVICE_Operatortyp));
  193. if(WaitField("+COPS: 0,0,",100)) //+COPS:0,0,"%s"为运营商,+COPS:0为无sim卡
  194. {
  195. sscanf((char *)&UART0_RX_BUF, "AT+COPS?\r\r\n+COPS: 0,0,\"%[^\"]\",%s", Operators, &Networktyp);
  196. }
  197. else
  198. {
  199. strcpy((char *)&Operators,""); //未读取到sim卡信息
  200. Networktyp=NULL;
  201. }
  202. Clear_DMA_Buffer();
  203. //查询注册状态
  204. EC800MSendCmd(CMD_SERVICE_Networktyp,strlen(CMD_SERVICE_Networktyp));
  205. WaitField("OK",100);
  206. char* status_str=strstr((char *)&UART0_RX_BUF, "+CREG:");
  207. if(status_str != NULL) //不为NULL则为有信号
  208. {
  209. sscanf(status_str, "+CREG: %*d,%d", &Networkstatu); //原先0未注册 1注册,取反后1未注册0注册
  210. }
  211. //查询sim卡iccid
  212. EC800MSendCmd(CMD_SERVICE_SIMcardICCID,strlen(CMD_SERVICE_SIMcardICCID));
  213. WaitField("OK",100);
  214. char* ICCID_str=strstr((char *)&UART0_RX_BUF,"+QCCID:");
  215. if(ICCID_str != NULL)
  216. {
  217. sscanf(ICCID_str,"+QCCID: %s",ICCID);
  218. //查询信号强度
  219. EC800MSendCmd(CMD_SERVICE_Signalstrength,strlen(CMD_SERVICE_Signalstrength));
  220. WaitField("OK",100);
  221. int rssi;
  222. sscanf((char *)&UART0_RX_BUF,"AT+CSQ\r\r\n+CSQ: %d",&rssi);
  223. Signal_strength=(int)(((float)rssi/31)*100); //算出来的百分比不准确log函数的斜率不断降低,此方法算出来的斜线的信号强度,实际信号为log函数,后续修正
  224. Clear_DMA_Buffer();
  225. }
  226. else //为没有sim卡状态
  227. {
  228. memset(ICCID,0,20); //此时无ICCID
  229. Signal_strength=0; //无sim卡直接让其等于0
  230. SIMCard=0; //然后sim状态抛异常
  231. }
  232. Clear_DMA_Buffer();
  233. //查询IMMIE号
  234. EC800MSendCmd(CMD_SERVICE_IMEInumber,strlen(CMD_SERVICE_IMEInumber));
  235. WaitField("OK",100);
  236. sscanf((char *)&UART0_RX_BUF,"AT+GSN\r\r\n%s",IMMIE);
  237. Clear_DMA_Buffer();
  238. //查询结束,开始组装json
  239. gatewayConfigData[0]=Top;
  240. gatewayConfigData[1]=READ_GATEWAY_MESSAGE;
  241. sprintf(gatewayConfigData+2,
  242. "{\"UniqueId\":\"%s\",\"Equipmentname\":\"%s\",\"Equipmenttype\":\"%s\",\"Workmode\":\"%s\",\"baudrate\":%d,\"dataBit\":%d,\"stopBit\":%d,\"checkBit\":%d,\"Operatortype\":\"%s\",\"Networktype\":\"%c\",\"Networkstatus\":\"%d\",\"SIMcardstatus\":\"%d\",\"SIMcardICCID\":\"%s\",\"IMEInumber\":\"%s\",\"Signalstrength\":\"%d\"}",
  243. gateway->deviceId,"4G_DTU",gateway->gateName,gateway->gatewayMode,gateway->baudrate,gateway->dataBits,gateway->stopBit,gateway->checkBit,
  244. Operators,Networktyp,Networkstatu,SIMCard,ICCID,IMMIE,Signal_strength);
  245. uint16_t CRC16=mmodbus_crc16(gatewayConfigData+1,strlen(gatewayConfigData)-1);
  246. gatewayConfigData[strlen(gatewayConfigData)+1] = (uint8_t) (CRC16 & 0x00FF);
  247. gatewayConfigData[strlen(gatewayConfigData)] = (uint8_t) ((CRC16 & 0xFF00)>>8);
  248. gatewayConfigData[strlen(gatewayConfigData)]=END;
  249. gd_com_232_send(gatewayConfigData,strlen(gatewayConfigData));
  250. free(gatewayConfigData);
  251. }
  252. #if 0
  253. /*
  254. * 函数名:void readSIMCARD()
  255. * 输入参数:无
  256. * 输出参数:无
  257. * 返回值:无
  258. * 函数作用:读取内部json配置
  259. */
  260. void read_json_config()
  261. {
  262. char *json_config=malloc(11*1024);//暂时最大空间只能解析10K数据
  263. memset(json_config,0,11*1024);
  264. GATEWAY_PARAMS *gateway;
  265. gateway = get_gateway_config_params();
  266. //帧头
  267. json_config[0]=Top;
  268. json_config[1]=READ_GATEWAY_JSON_CONFIG;
  269. //数据包json最外层
  270. sprintf(json_config+2,"{\"host\":\"%s\",\"port\":%d,\"messageTopic\":\"%s\",\"commandTopic\":\"%s\",\"baudrate\":%d,\"dataBit\":%d,\"stopBit\":%d,\"checkBit\":%d,\"flowControl\":%d,\"deviceId\":\"%s\",\"dataSource\":%d,\"version645\":%d,\"inboundTime\":%d,\"pollTime\":%d,",
  271. gateway->host,
  272. gateway->port,
  273. gateway->messageTopic,
  274. gateway->commandTopic,
  275. gateway->baudrate,
  276. gateway->dataBits,
  277. gateway->stopBit,
  278. gateway->checkBit,
  279. 0,
  280. gateway->deviceId,
  281. gateway->dataSource,
  282. gateway->dataType645,
  283. gateway->inboundTime,
  284. gateway->pollTime);
  285. //读指令头部
  286. sprintf(json_config+strlen(json_config),"\"sensorData\":[");
  287. //读指令数据包
  288. for (int i = 0; i < gateway->device_read_data_num; i++)
  289. {
  290. if (gateway->dataSource == MODBUS)
  291. {
  292. sprintf(json_config+strlen(json_config),"{\"rFunctionCode\":%d,\"registerAddress\":%d,\"slaveAddress\":%d,\"registerByteNum\":%d,\"identifier\":\"%s\",\"deviceId\":\"%s\",\"precise\":%d,\"bigLittleFormat\":%d},",
  293. gateway->device_read_data[i].mdbFunctionCode,
  294. gateway->device_read_data[i].mdbRegister,
  295. gateway->device_read_data[i].mdbSlave,
  296. gateway->device_read_data[i].registerLength,
  297. gateway->device_read_data[i].keyword,
  298. gateway->device_read_data[i].deviceId,
  299. gateway->device_read_data[i].decimalPoint,
  300. gateway->device_read_data[i].bigLittleFormat);
  301. }
  302. else if(gateway->dataSource == DLT645)
  303. {
  304. sprintf(json_config+strlen(json_config),
  305. "{\"identifier\":\"%s\",\"deviceID645\":\"%02x%02x%02x%02x%02x%02x\",\"identifier645\":%d,\"deviceId\":\"%s\"},",
  306. gateway->device_read_data[i].keyword,
  307. gateway->device_read_data[i].deviceID645[0],
  308. gateway->device_read_data[i].deviceID645[1],
  309. gateway->device_read_data[i].deviceID645[2],
  310. gateway->device_read_data[i].deviceID645[3],
  311. gateway->device_read_data[i].deviceID645[4],
  312. gateway->device_read_data[i].deviceID645[5],
  313. gateway->device_read_data[i].dataType645,
  314. gateway->device_read_data[i].deviceId);
  315. }
  316. }
  317. //特殊处理数据包括号最后一个逗号,清空
  318. memset(json_config+strlen(json_config)-1,0,1);
  319. //读指令数据包尾部以及写指令数据包头部
  320. sprintf(json_config+strlen(json_config),"],\"commandData\":[");
  321. //写数据包内容 写数据包目前只有MODBUS含有
  322. for (int i = 0; i < gateway->device_write_data_num; i++)
  323. {
  324. sprintf(json_config+strlen(json_config),"{\"deviceId\":\"%s\",\"identifier\":\"%s\",\"registerAddress\":%d,\"slaveAddress\":%d,\"wFunctionCode\":%d,\"registerByteNum\":%d,\"bigLittleFormat\":%d},",
  325. gateway->device_write_data[i].deviceId,
  326. gateway->device_write_data[i].keyword,
  327. gateway->device_write_data[i].mdbRegister,
  328. gateway->device_write_data[i].mdbSlave,
  329. gateway->device_write_data[i].mdbFunctionCode,
  330. gateway->device_write_data[i].registerLength,
  331. gateway->device_write_data[i].bigLittleFormat);
  332. }
  333. //特殊处理数据包括号最后一个逗号,清空
  334. memset(json_config+strlen(json_config)-1,0,1);
  335. //写数据包结尾以及json结尾
  336. sprintf(json_config+strlen(json_config),"]}");
  337. //CRC校验
  338. uint16_t CRC16=mmodbus_crc16(json_config+1,strlen(json_config)-1);
  339. json_config[strlen(json_config)+1] = (uint8_t) (CRC16 & 0x00FF);
  340. json_config[strlen(json_config)] = (uint8_t) ((CRC16 & 0xFF00)>>8);
  341. //帧尾
  342. json_config[strlen(json_config)]=END;
  343. gd_com_232_send(json_config,strlen(json_config));
  344. free(json_config);
  345. }
  346. /*
  347. * 函数名:void write_json_config()
  348. * 输入参数:无
  349. * 输出参数:无
  350. * 返回值:无
  351. * 函数作用:读取内部json配置
  352. */
  353. void write_json_config(char *json)
  354. {
  355. UART0_RX_STAT=0x01; //复用代码
  356. bool success=WaitForUpData(json);
  357. int8_t resp[10];
  358. memset(resp,0,10);
  359. resp[0]=Top;
  360. resp[1]=WIRTE_GATEWAY_JSON_CONFIG;
  361. resp[2]=success;
  362. uint16_t CRC16=mmodbus_crc16(resp+1,strlen(resp)-1);
  363. resp[strlen(resp)+1] = (uint8_t) (CRC16 & 0x00FF);
  364. resp[strlen(resp)] = (uint8_t) ((CRC16 & 0xFF00)>>8);
  365. resp[strlen(resp)]=END;
  366. gd_com_232_send(resp,strlen(resp));
  367. //配置完成重启设备
  368. NVIC_SystemReset();
  369. }
  370. /*
  371. * 函数名:void ec800m_4G_Data_read(uint8_t *str,uint16_t len)
  372. * 输入参数:无
  373. * 输出参数:str读到的首地址,len读到的数据总长
  374. * 返回值:无
  375. * 函数作用:读取gateway内部配置信息
  376. */
  377. void ec800m_4G_Data_read(uint8_t *str,uint16_t len)
  378. {
  379. EC800MSendCmd(CMD_SERVICE_Operatortyp, strlen(CMD_SERVICE_Operatortyp));
  380. WaitField("+COPS:",100);
  381. }
  382. #endif
  383. /*
  384. * 函数名:bool WaitField(char *expectStr, int timeout)
  385. * 输入参数:expectStr 需要匹配的关键字 timeout超时时间
  386. * 输出参数:true flase
  387. * 返回值:无
  388. * 函数作用:从UART0_RX_BUF缓冲区中匹配有无对应关键字有关键字则返回true无返回false且不会清掉里面的数据
  389. */
  390. bool WaitField(char *expectStr, int timeout)
  391. {
  392. bool timeoutFlag = false;
  393. if (timeout >= 0)
  394. {
  395. timeoutFlag = true;
  396. }
  397. while (1)
  398. {
  399. delay_1ms(50);
  400. if (UART0_RX_STAT > 0)
  401. {
  402. UART0_RX_STAT = 0;
  403. char *p=strstr((char *)&UART0_RX_BUF, expectStr);
  404. if (p)
  405. {
  406. return true;
  407. }
  408. }
  409. timeout -= 50;
  410. if (timeoutFlag == true && timeout <= 0)
  411. {
  412. return false;
  413. }
  414. };
  415. }