PC.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  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();
  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 uart2_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. if (RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_RBNE)) // 接收寄存器不空
  45. {
  46. uint8_t Serial_RxData;
  47. Serial_RxData = usart_data_receive(USART2);
  48. if (ota_data.ota_flag==0&&RxState==OTA_EVENT)
  49. {
  50. RxState=0;//ota更新中断后状态归位
  51. }
  52. if (RxState == 0) // 等待包头
  53. {
  54. if (Serial_RxData == Top) // 获取到包头则切换到识别功能模式
  55. {
  56. RxState = 1;
  57. RxPacket.data_cnt = 0;
  58. RxPacket.data[RxPacket.data_cnt] = Serial_RxData;
  59. }
  60. }
  61. else if (RxState == 1) // 接收数据
  62. {
  63. RxPacket.data_cnt++;
  64. RxPacket.data[RxPacket.data_cnt] = Serial_RxData;
  65. if (RxPacket.data_cnt >= 3) // 接收完数据
  66. {
  67. RxState = 2; // 前导数据位已经接收完毕、转化状态接收尾部数据
  68. }
  69. }
  70. else if (RxState == 2) // 等待包尾
  71. {
  72. if (Serial_RxData == END) // 进入了结束位
  73. {
  74. if (RxPacket.data[1] == WIRTE_GATEWAY_JSON_CONFIG) // 当为写入json数据后进入状态3、将对应数据放到usart0_buf中
  75. {
  76. RxState = 3;
  77. dma_channel_disable(DMA0, DMA_CH4);
  78. uart2_json_buf_num = 0;
  79. }
  80. else if (RxPacket.data[1] == OTA_EVENT) // 进入了OTA事件此时的状态会处于接收程序状态、一直等待OTA的结束标志位
  81. {
  82. RxState = 4;
  83. ota_data.data_cnt=0;
  84. memset(ota_data.data,0,133);//清空数据
  85. ota_data.ota_flag=1;
  86. }
  87. else // 其他情况则将状态归位
  88. {
  89. RxState = 0;
  90. }
  91. }
  92. }
  93. else if (RxState == 3) // 接收到json信息进入进行处理
  94. {
  95. UART0_RX_STAT = 0x01;
  96. UART0_RX_BUF[uart2_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. dma_channel_enable(DMA0, DMA_CH4);
  124. write_json_config();
  125. break;
  126. case SET_GATEWAY_PLATFORM:
  127. break;
  128. default:
  129. break;
  130. }
  131. }
  132. // 此时不在ota升级的分支时,防止其他错误指令造成的数据状态不归位情况
  133. if (ota_data.ota_flag == 0)
  134. {
  135. RxState = 0;
  136. }
  137. else if(ota_data.ota_flag==1)
  138. {
  139. ota_data.done=1;
  140. }
  141. usart_data_receive(USART2);
  142. }
  143. }
  144. /*
  145. * 函数名:void readGatewayMessage()
  146. * 输入参数:无
  147. * 输出参数:无
  148. * 返回值:无
  149. * 函数作用:读取gateway内部配置信息
  150. */
  151. void readGatewayMessage(void)
  152. {
  153. CONFIG_PARAMS *gateway;
  154. gateway = get_config_params();
  155. uint8_t *gatewayMessageData=malloc(100);
  156. memset(gatewayMessageData,0,100);
  157. gatewayMessageData[0]=Top;
  158. gatewayMessageData[1]=READ_ID;
  159. uint8_t deviceIdLen=strlen(gateway->deviceId);
  160. uint8_t versionLen=strlen(gateway->version);
  161. memcpy(gatewayMessageData+2,gateway->deviceId,deviceIdLen);
  162. gatewayMessageData[deviceIdLen+2]=0x3B;
  163. memcpy(gatewayMessageData+2+1+deviceIdLen,gateway->version,versionLen);
  164. uint16_t CRC16=mmodbus_crc16(gatewayMessageData+1,strlen(gatewayMessageData)-1);
  165. gatewayMessageData[deviceIdLen+2+1+versionLen+1] = (uint8_t) (CRC16 & 0x00FF);
  166. gatewayMessageData[deviceIdLen+2+1+versionLen] = (uint8_t) ((CRC16 & 0xFF00)>>8);
  167. gatewayMessageData[deviceIdLen+2+1+versionLen+2]=END;
  168. gatewayMessageData[deviceIdLen+2+1+versionLen+2+1]='\0';
  169. gd_com_232_send(gatewayMessageData,strlen(gatewayMessageData));
  170. free(gatewayMessageData);
  171. }
  172. /*
  173. * 函数名:void readSIMCARD()
  174. * 输入参数:无
  175. * 输出参数:无
  176. * 返回值:无
  177. * 函数作用:读出sim卡的相关配置
  178. */
  179. void readSIMCARD()
  180. {
  181. CONFIG_PARAMS *gateway;
  182. gateway = get_config_params();
  183. uint8_t *gatewayConfigData=malloc(1024);
  184. memset(gatewayConfigData,0,1024);
  185. uint8_t Operators[16];
  186. bool Networkstatu;
  187. uint8_t SIMCard=0; //状态0 正常 状态1异常
  188. uint8_t ICCID[20];
  189. uint8_t IMMIE[15];
  190. 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+
  191. uint8_t Signal_strength; //信号强度
  192. //查询运营商
  193. EC800MSendCmd(CMD_SERVICE_Operatortyp, strlen(CMD_SERVICE_Operatortyp));
  194. if(WaitField("+COPS: 0,0,",100)) //+COPS:0,0,"%s"为运营商,+COPS:0为无sim卡
  195. {
  196. sscanf(UART0_RX_BUF, "AT+COPS?\r\r\n+COPS: 0,0,\"%[^\"]\",%s", Operators, &Networktyp);
  197. }
  198. else
  199. {
  200. strcpy(Operators,""); //未读取到sim卡信息
  201. Networktyp=NULL;
  202. }
  203. Clear_DMA_Buffer();
  204. //查询注册状态
  205. EC800MSendCmd(CMD_SERVICE_Networktyp,strlen(CMD_SERVICE_Networktyp));
  206. WaitField("OK",100);
  207. char* status_str=strstr(UART0_RX_BUF, "+CREG:");
  208. if(status_str != NULL) //不为NULL则为有信号
  209. {
  210. sscanf(status_str, "+CREG: %*d,%d", &Networkstatu); //原先0未注册 1注册,取反后1未注册0注册
  211. }
  212. //查询sim卡iccid
  213. EC800MSendCmd(CMD_SERVICE_SIMcardICCID,strlen(CMD_SERVICE_SIMcardICCID));
  214. WaitField("OK",100);
  215. char* ICCID_str=strstr(UART0_RX_BUF,"+QCCID:");
  216. if(ICCID_str != NULL)
  217. {
  218. sscanf(ICCID_str,"+QCCID: %s",ICCID);
  219. //查询信号强度
  220. EC800MSendCmd(CMD_SERVICE_Signalstrength,strlen(CMD_SERVICE_Signalstrength));
  221. WaitField("OK",100);
  222. uint8_t rssi;
  223. sscanf(UART0_RX_BUF,"AT+CSQ\r\r\n+CSQ: %d",&rssi);
  224. Signal_strength=(int)(((float)rssi/31)*100); //算出来的百分比不准确log函数的斜率不断降低,此方法算出来的斜线的信号强度,实际信号为log函数,后续修正
  225. Clear_DMA_Buffer();
  226. }
  227. else //为没有sim卡状态
  228. {
  229. memset(ICCID,0,20); //此时无ICCID
  230. Signal_strength=0; //无sim卡直接让其等于0
  231. SIMCard=0; //然后sim状态抛异常
  232. }
  233. Clear_DMA_Buffer();
  234. //查询IMMIE号
  235. EC800MSendCmd(CMD_SERVICE_IMEInumber,strlen(CMD_SERVICE_IMEInumber));
  236. WaitField("OK",100);
  237. sscanf(UART0_RX_BUF,"AT+GSN\r\r\n%s",IMMIE);
  238. Clear_DMA_Buffer();
  239. //查询结束,开始组装json
  240. gatewayConfigData[0]=Top;
  241. gatewayConfigData[1]=READ_GATEWAY_MESSAGE;
  242. sprintf(gatewayConfigData+2,
  243. "{\"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\"}",
  244. gateway->deviceId,"4G_DTU",gateway->gateName,gateway->gatewayMode,gateway->baudrate,gateway->dataBits,gateway->stopBit,gateway->checkBit,
  245. Operators,Networktyp,Networkstatu,SIMCard,ICCID,IMMIE,Signal_strength);
  246. uint16_t CRC16=mmodbus_crc16(gatewayConfigData+1,strlen(gatewayConfigData)-1);
  247. gatewayConfigData[strlen(gatewayConfigData)+1] = (uint8_t) (CRC16 & 0x00FF);
  248. gatewayConfigData[strlen(gatewayConfigData)] = (uint8_t) ((CRC16 & 0xFF00)>>8);
  249. gatewayConfigData[strlen(gatewayConfigData)]=END;
  250. gd_com_232_send(gatewayConfigData,strlen(gatewayConfigData));
  251. free(gatewayConfigData);
  252. }
  253. /*
  254. * 函数名:void readSIMCARD()
  255. * 输入参数:无
  256. * 输出参数:无
  257. * 返回值:无
  258. * 函数作用:读取内部json配置
  259. */
  260. void read_json_config()
  261. {
  262. uint8_t *json_config=malloc(11*1024);//暂时最大空间只能解析10K数据
  263. memset(json_config,0,11*1024);
  264. CONFIG_PARAMS *gateway;
  265. gateway = get_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. gateway->flowControl,
  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()
  354. {
  355. bool success=WaitForUpData();
  356. int8_t resp[10];
  357. memset(resp,0,10);
  358. resp[0]=Top;
  359. resp[1]=WIRTE_GATEWAY_JSON_CONFIG;
  360. resp[2]=success;
  361. uint16_t CRC16=mmodbus_crc16(resp+1,strlen(resp)-1);
  362. resp[strlen(resp)+1] = (uint8_t) (CRC16 & 0x00FF);
  363. resp[strlen(resp)] = (uint8_t) ((CRC16 & 0xFF00)>>8);
  364. resp[strlen(resp)]=END;
  365. gd_com_232_send(resp,strlen(resp));
  366. //配置完成重启设备
  367. NVIC_SystemReset();
  368. }
  369. /*
  370. * 函数名:void ec800m_4G_Data_read(uint8_t *str,uint16_t len)
  371. * 输入参数:无
  372. * 输出参数:str读到的首地址,len读到的数据总长
  373. * 返回值:无
  374. * 函数作用:读取gateway内部配置信息
  375. */
  376. void ec800m_4G_Data_read(uint8_t *str,uint16_t len)
  377. {
  378. EC800MSendCmd(CMD_SERVICE_Operatortyp, strlen(CMD_SERVICE_Operatortyp));
  379. WaitField("+COPS:",100);
  380. }
  381. /*
  382. * 函数名:bool WaitField(char *expectStr, int timeout)
  383. * 输入参数:expectStr 需要匹配的关键字 timeout超时时间
  384. * 输出参数:true flase
  385. * 返回值:无
  386. * 函数作用:从UART0_RX_BUF缓冲区中匹配有无对应关键字有关键字则返回true无返回false且不会清掉里面的数据
  387. */
  388. bool WaitField(char *expectStr, int timeout)
  389. {
  390. bool timeoutFlag = false;
  391. if (timeout >= 0)
  392. {
  393. timeoutFlag = true;
  394. }
  395. while (1)
  396. {
  397. delay_1ms(50);
  398. if (UART0_RX_STAT > 0)
  399. {
  400. UART0_RX_STAT = 0;
  401. char *p=strstr((char *)&UART0_RX_BUF, expectStr);
  402. if (p)
  403. {
  404. return true;
  405. }
  406. }
  407. timeout -= 50;
  408. if (timeoutFlag == true && timeout <= 0)
  409. {
  410. return false;
  411. }
  412. };
  413. }