zhao006 5 달 전
부모
커밋
fca089aff6
61개의 변경된 파일7305개의 추가작업 그리고 226개의 파일을 삭제
  1. 68 0
      app/DLT645/include/dlt645.h
  2. 11 0
      app/DLT645/include/dlt645_1997.h
  3. 53 0
      app/DLT645/include/dlt645_1997_private.h
  4. 11 0
      app/DLT645/include/dlt645_2007.h
  5. 128 0
      app/DLT645/include/dlt645_2007_private.h
  6. 56 0
      app/DLT645/include/dlt645_private.h
  7. 114 0
      app/DLT645/port/dlt645_port.c
  8. 10 0
      app/DLT645/port/dlt645_port.h
  9. 131 0
      app/DLT645/source/dlt645.c
  10. 141 0
      app/DLT645/source/dlt645_1997.c
  11. 279 0
      app/DLT645/source/dlt645_2007.c
  12. 289 0
      app/DLT645/source/dlt645_data.c
  13. 22 0
      app/HARDWARE/include/led.h
  14. 74 0
      app/HARDWARE/include/malloc.h
  15. 12 0
      app/HARDWARE/include/timer.h
  16. 95 0
      app/HARDWARE/include/usart.h
  17. 56 0
      app/HARDWARE/source/led.c
  18. 226 0
      app/HARDWARE/source/malloc.c
  19. 27 0
      app/HARDWARE/source/timer.c
  20. 705 0
      app/HARDWARE/source/usart.c
  21. BIN
      app/MDKProject/Objects/dtu_lan_gateway.axf
  22. 364 164
      app/MDKProject/dtu_lan_gateway.uvoptx
  23. 129 8
      app/MDKProject/dtu_lan_gateway.uvprojx
  24. 168 0
      app/MODBUS/mmodbus.h
  25. 18 0
      app/MODBUS/mmodbusConfig.h
  26. 600 0
      app/MODBUS/modbus.c
  27. 0 0
      app/MODBUS/modbus.h
  28. 1 1
      app/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c
  29. 1 0
      app/Middlewares/Third_Party/mqttclient/mqttclient/mqttclient.c
  30. 41 0
      app/SYSTEM/include/data_task.h
  31. 123 0
      app/SYSTEM/include/gateway_message.h
  32. 23 0
      app/SYSTEM/include/http_client.h
  33. 1 1
      app/SYSTEM/include/log.h
  34. 34 0
      app/SYSTEM/include/lte.h
  35. 40 0
      app/SYSTEM/include/lte_mqtt.h
  36. 1 0
      app/SYSTEM/include/myFile.h
  37. 10 0
      app/SYSTEM/include/sys_http.h
  38. 17 0
      app/SYSTEM/include/sys_mqtt.h
  39. 20 0
      app/SYSTEM/include/sys_udp.h
  40. 50 0
      app/SYSTEM/include/tcp_server.h
  41. 11 0
      app/SYSTEM/include/updata.h
  42. 495 0
      app/SYSTEM/source/data_task.c
  43. 313 0
      app/SYSTEM/source/gateway_message.c
  44. 455 0
      app/SYSTEM/source/http_clinet.c
  45. 3 3
      app/SYSTEM/source/log.c
  46. 411 0
      app/SYSTEM/source/lte.c
  47. 328 0
      app/SYSTEM/source/lte_mqtt.c
  48. 48 24
      app/SYSTEM/source/myFile.c
  49. 72 0
      app/SYSTEM/source/sys_http.c
  50. 146 0
      app/SYSTEM/source/sys_mqtt.c
  51. 113 0
      app/SYSTEM/source/sys_udp.c
  52. 393 0
      app/SYSTEM/source/tcp_server.c
  53. 1 1
      app/SYSTEM/source/udp.c
  54. 150 0
      app/SYSTEM/source/updata.c
  55. 1 1
      app/USER/include/FreeRTOSConfig.h
  56. 3 0
      app/USER/include/app_ethernet.h
  57. 4 1
      app/USER/include/main.h
  58. 13 0
      app/USER/source/app_ethernet.c
  59. 13 1
      app/USER/source/ethernetif.c
  60. 182 21
      app/USER/source/main.c
  61. 1 0
      app/USER/source/stm32f2xx_it.c

+ 68 - 0
app/DLT645/include/dlt645.h

@@ -0,0 +1,68 @@
+#ifndef _DLT645_H
+#define _DLT645_H
+
+#include "stm32f2xx.h"
+#include <stdint.h>
+#include "FreeRTOS.h"
+#include "task.h"
+#define DL645_MAX_READ_LEN 200 //读数据的最大数据长度
+#define DL645_MAX_WRITE_LEN 50 //写数据的最大数据长度
+
+// port setting
+#define DLT645_DEFAULT_RESPONSE_TIMEOUT 500 //500ms
+#define MAX_DEVICE_NAME_LEN 10              //最大设备名长度
+
+#define dlt_malloc malloc
+#define dlt_free free
+#define gettick()                           ( xTaskGetTickCount() )
+//DLT645 环境结构体
+typedef struct dlt645
+{
+    uint8_t addr[6];    //从机地址
+    uint8_t debug;      //调试标志
+    int (*write)(struct dlt645 *ctx, uint8_t *buf, uint16_t len);     //底层写函数
+    int (*read) (struct dlt645 *ctx, uint8_t *msg, uint16_t len);     //底层读函数
+    void *port_data;                                            //移植层拓展接口
+} dlt645_t;
+
+typedef enum
+{
+    DLT645_2007 = 1,
+    DLT645_1997
+} dlt645_protocal;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#define DLT_RXSIZE 200
+
+// DLT645采集使用的串口名
+#define DLT645_USART 			USART_485
+#define DLT645_CTRL_GPIO 	USART_485_DE_GPIO_PORT
+#define DLT645_CTRL_PIN		USART_485_DE_PIN
+
+// DL/T 645硬件拓展结构体
+typedef struct
+{
+	uint8_t dlt645_Tx; // 用于串口接收的状态
+	uint32_t timeout;  //
+	uint8_t rxBuf[DLT_RXSIZE];
+	uint8_t done;
+	uint8_t index;
+} dlt645_port_t;
+
+extern dlt645_port_t dlt645_port;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//设置从机地址
+extern void dlt645_set_addr(dlt645_t *ctx, uint8_t *addr);
+//设置调试开关
+extern int dlt645_set_debug(dlt645_t *ctx, int flag);
+//数据采集
+extern int dlt645_read_data(dlt645_t *ctx, uint32_t code, uint8_t *read_data, dlt645_protocal protocal);
+//十进制转BCD码(32位)
+extern uint32_t dec_to_bcd(uint32_t val);
+//字符串转BCD形式
+extern int str_to_bcd(char *str, uint8_t *bcd_store_address, uint16_t bcd_len);
+
+extern void dlt645_init(uint32_t timeout);
+extern void dlt_callback(UART_HandleTypeDef *husart);
+
+#endif

+ 11 - 0
app/DLT645/include/dlt645_1997.h

@@ -0,0 +1,11 @@
+#ifndef __DLT645_1997_H
+#define __DLT645_1997_H
+
+#include "dlt645.h"
+
+//基于 DLT645 2007 协议读取数据
+int dlt645_1997_read_data(dlt645_t *ctx, uint32_t code, uint8_t *read_data);
+//基于 DLT645 2007 协议校验数据
+int dlt645_1997_recv_check(uint8_t *msg, int len, uint8_t *addr, uint32_t code);
+
+#endif /* __DLT645_1997_H */

+ 53 - 0
app/DLT645/include/dlt645_1997_private.h

@@ -0,0 +1,53 @@
+#ifndef __DLT645_1997_PRIVATE_H
+#define __DLT645_1997_PRIVATE_H
+
+#define DL645_1997_RD_CMD_LEN 14 //读取数据命令的长度
+
+//功能码
+#define C_1997_CODE_BRC 0x08    //广播校时
+#define C_1997_CODE_RD 0x01     //读数据
+#define C_1997_CODE_RDM 0x02    //读后续数据
+#define C_1997_CODE_WR 0x04     //写数据
+#define C_1997_CODE_WRA 0x0A    //写设备地址
+#define C_1997_CODE_BR 0x0C     //更改通信速率
+#define C_1997_CODE_PD 0x0F     //修改密码
+#define C_1997_CODE_XL 0x10     //最大需量清零
+#define C_1997_CEODE_RR 0x03    //重读数据
+
+
+#define ERR_1997_RATE 0x40  //费率数超
+#define ERR_1997_DAY 0x20   //日时段数超
+#define ERR_1997_YEAR 0x10  //年时区数超
+#define ERR_1997_BR 0x08    //通信速率不能更改
+#define ERR_1997_PD 0x04    //密码错误/未授权
+#define ERR_1997_DATA 0x02  //无请求数据
+#define ERR_1997_OTHER 0x01 //其他错误
+
+// DLT645 1997 数据标识
+#define DIC_B611 0xB611 //A相电压
+#define DIC_B612 0xB612 //B相电压
+#define DIC_B613 0xB613 //C相电压
+#define DIC_B691 0xB691 //AB线电压
+#define DIC_B692 0xB692 //BC线电压
+#define DIC_B693 0xB693 //CA线电压
+
+#define DIC_B621 0xB621 //A相电流
+#define DIC_B622 0xB622 //B相电流
+#define DIC_B623 0xB623 //C相电流
+
+#define DIC_B630 0xB630 //总有功功率
+#define DIC_B631 0xB631 //A相有功功率
+#define DIC_B632 0xB632 //B相有功功率
+#define DIC_B633 0xB633 //C相有功功率
+
+#define DIC_B640 0xB640 //总无功功率
+#define DIC_B641 0xB641 //A相无功功率
+#define DIC_B642 0xB642 //B相无功功率
+#define DIC_B643 0xB643 //C相无功功率
+
+#define DIC_B660 0xB660 //总视在功率
+#define DIC_B661 0xB661 //A相视在功率
+#define DIC_B662 0xB662 //B相视在功率
+#define DIC_B663 0xB663 //C相视在功率
+
+#endif /* __DLT645_1997_PRIVATE_H */

+ 11 - 0
app/DLT645/include/dlt645_2007.h

@@ -0,0 +1,11 @@
+#ifndef __DLT645_2007_H
+#define __DLT645_2007_H
+
+#include "dlt645.h"
+
+//基于 DLT645 2007 协议读取数据
+int dlt645_2007_read_data(dlt645_t *ctx, uint32_t code, uint8_t *read_data);
+//基于 DLT645 2007 协议校验数据
+int dlt645_2007_recv_check(uint8_t *msg, int len, uint8_t *addr, uint32_t code);
+
+#endif /* __DLT645_2007_H */

+ 128 - 0
app/DLT645/include/dlt645_2007_private.h

@@ -0,0 +1,128 @@
+#ifndef __DLT645_2007_PRIVATE_H
+#define __DLT645_2007_PRIVATE_H
+
+
+#define DL645_2007_RD_CMD_LEN 16 //读取数据命令的长度
+
+//功能码
+#define C_2007_CODE_BRC 0x08    //广播校时
+#define C_2007_CODE_RD 0X11     //读数据
+#define C_2007_CODE_RDM 0x12    //读后续数据
+#define C_2007_CODE_RDA 0x13    //读通信地址
+#define C_2007_CODE_WR 0x14     //写数据
+#define C_2007_CODE_WRA 0x15    //写通信地址
+#define C_2007_CODE_DJ 0x16     //冻结
+#define C_2007_CODE_BR 0x17     //更改通信速率
+#define C_2007_CODE_PD 0x18     //修改密码
+#define C_2007_CODE_XL 0x19     //最大需量清零
+#define C_2007_CODE_DB 0x1a     //电表清零
+#define C_2007_CODE_MSG 0x1b    //事件清零
+
+
+#define ERR_2007_RATE 0x40  //费率数超
+#define ERR_2007_DAY 0x20   //日时段数超
+#define ERR_2007_YEAR 0x10  //年时区数超
+#define ERR_2007_BR 0x08    //通信速率不能更改
+#define ERR_2007_PD 0x04    //密码错误/未授权
+#define ERR_2007_DATA 0x02  //无请求数据
+#define ERR_2007_OTHER 0x01 //其他错误
+
+
+
+
+#define DIC_0 0x0         //组合有功总电能
+#define DIC_100 0x100     //组合有功费率1电能
+#define DIC_200 0x200     //组合有功费率2电能
+#define DIC_300 0x300     //组合有功费率3电能
+#define DIC_400 0x400     //组合有功费率4电能
+#define DIC_10000 0x10000 //正向有功总电能
+#define DIC_10001 0x10001 //(上1结算日 即上月)正向有功总电能
+#define DIC_10100 0x10100 //正向有功费率1电能
+#define DIC_10002 0x10002 //(上2结算日 即上月)正向有功总电能
+
+#define DIC_10200 0x10200 //正向有功费率2电能
+#define DIC_10300 0x10300 //正向有功费率3电能
+#define DIC_10400 0x10400 //正向有功费率4电能
+#define DIC_20000 0x20000 //反向有功总电能
+#define DIC_20100 0x20100 //反向有功费率1电能
+#define DIC_20200 0x20200 //反向有功费率2电能
+#define DIC_20300 0x20300 //反向有功费率3电能
+#define DIC_20400 0x20400 //反向有功费率4电能
+#define DIC_30000 0x30000 //组合无功1总电能
+#define DIC_40000 0x40000 //组合无功2总电能
+#define DIC_50000 0x50000 //第一象限无功电能
+#define DIC_60000 0x60000 //第二象限无功电能
+#define DIC_70000 0x70000 //第三象限无功电能
+#define DIC_80000 0x80000 //第四象限无功电能
+#define DIC_90000 0x90000 //正向视在总电能
+
+#define DIC_1010000 0X01010000//正向正向有功总最大需量及发生时间
+#define DIC_1010100 0x01010100//正向有功费率 1 最大需量及发生时间
+
+
+#define DIC_1020000 0x01020000//反向有功总最大需量及发生时间
+#define DIC_1010001 0x01010001//正向有功总最大需量及发生时间
+#define DIC_1020001 0X01020001//反向有功总最大需量及发生时间
+
+#define DIC_201FF00 0x201FF00	//电压数据块
+#define DIC_2010100 0x2010100 //A相电压
+#define DIC_2010200 0x2010200 //B相电压
+#define DIC_2010300 0x2010300 //C相电压
+#define DIC_2020100 0x2020100 //A相电流
+#define DIC_2020200 0x2020200 //B相电流
+#define DIC_2020300 0x2020300 //C相电流
+#define DIC_2030000 0x2030000 //总有功功率
+#define DIC_2030100 0x2030100 //A相有功功率
+#define DIC_2030200 0x2030200 //B相有功功率
+#define DIC_2030300 0x2030300 //C相有功功率
+
+#define DIC_2040000 0x2040000 //总无功功率
+#define DIC_2040100 0x2040100 //A相无功功率
+#define DIC_2040200 0x2040200 //B相无功功率
+#define DIC_2040300 0x2040300 //C相无功功率
+#define DIC_2050000 0x2050000 //总视在功率
+#define DIC_2050100 0x2050100 //A相视在功率
+#define DIC_2050200 0x2050200 //B相视在功率
+#define DIC_2050300 0x2050300 //C相视在功率
+#define DIC_2060000 0x2060000 //总功率因素
+#define DIC_2060100 0x2060100 //A相功率因素
+#define DIC_2060200 0x2060200 //B相功率因素
+#define DIC_2060300 0x2060300 //C相功率因素
+#define DIC_20C0100 0x20C0100 //AB线电压
+#define DIC_20C0200 0x20C0200 //BC线电压
+#define DIC_20C0300 0x20C0300 //CA线电压
+#define DIC_2800002 0x2800002 //频率
+#define DIC_2800007 0x2800007//表内温度
+#define DIC_4000101 0x4000101 //年月日星期
+#define DIC_4000102 0x4000102 //时分秒
+#define DIC_5060001 0x5060001 //上一次日冻结时间
+#define DIC_5060101 0x5060101 //上一次日冻结正向有功电能
+
+
+
+#define DIC_30C0000 0x30C0000 //过流总次数,总时间
+#define DIC_30C0101 0x30C0101 //上一次A相过流记录
+
+#define DIC_3300100 0x3300100 //电表清零总次数
+#define DIC_3300101 0x3300101 //电表清零记录
+
+#define DIC_4000501 0x4000501
+#define DIC_4000502 0x4000502
+#define DIC_4000503 0x4000503
+#define DIC_4000504 0x4000504
+#define DIC_4000505 0x4000505
+#define DIC_4000506 0x4000506
+#define DIC_4000507 0x4000507
+
+#define DIC_4000403 0x4000403 //资产管理编码
+
+#define DIC_4000701 0x4000701 //信号强度
+
+#define DIC_4000702 0x4000702 //版本号
+
+
+
+#define DIC_7000001 0x7000001 //master_api_key
+#define DIC_7000002 0x7000002 //device_id
+
+#endif /* __DLT645_2007_PRIVATE_H */

+ 56 - 0
app/DLT645/include/dlt645_private.h

@@ -0,0 +1,56 @@
+#ifndef _DLT645_PRIVATE_H
+#define _DLT645_PRIVATE_H
+
+#include "dlt645.h"
+
+#ifdef DLT645_DEBUG
+#define DLT645_LOG kprintf
+#else
+#define DLT645_LOG(...)
+#endif
+
+#define DL645_START_CODE 0x68
+#define DL645_STOP_CODE 0x16
+
+#define DL645_PREMBLE_ENABLE 0 //前导码使能标记
+#define DL645_PREMBLE 0xFE     //前导码
+
+#define DL645_ADDR_LEN 6    //设备地址长度
+#define DL645_CONTROL_POS 8 //控制码位置
+#define DL645_LEN_POS 9     //长度位置
+#define DL645_DATA_POS 10   //数据位置
+#define DL645_WR_LEN 50     //写入数据命令的长度
+#define DL645_RESP_LEN 60   //读取数据命令的长度
+
+#define C_TD_MASK 0x80      //主从标志位
+#define C_TD_POS 7          //主从标志位比特位
+#define C_TD_MASTER 0       //主站发出的命令帧
+#define C_TD_SLAVE 1        //从站发出的应答帧
+
+#define C_ACK_MASK 0x40     //从站是否正确应答标志位
+#define C_ACK_POS 6         //从站应答标志位比特位
+#define C_ACK_OK 0          //从站应答正确
+#define C_ACK_ERR 1         //从站应答错误
+
+#define C_FU_MASK 0x20      //是否有后续帧标志位
+#define C_FU_POS 5          //后续帧标志位比特位
+#define C_FU_NONE 0         //无后续帧
+#define C_FU_EXT 1          //有后续帧
+
+#define C_CODE_MASK 0x1F    //功能码标志位
+
+
+
+//645 公共校验
+extern int dlt645_common_check(uint8_t *msg, int len, uint8_t *addr);
+//645 和校验
+extern int _crc(uint8_t *msg, int len);
+//645 调用底层接口接收数据
+extern int dlt645_receive_msg(dlt645_t *ctx, uint8_t *msg, uint16_t len, uint32_t code, dlt645_protocal protocal);
+//645 调用底层接口发送
+extern int dlt645_send_msg(dlt645_t *ctx, uint8_t *msg, int len);
+//将接收到的dlt645数据包中的数据转化为整数
+extern int data_package_translate_to_int(uint8_t *read_data, uint16_t len);
+//根据数据格式将645协议读取的数据转换为真实数据并存储
+extern int dlt645_data_parse_by_format_to_float(uint8_t *read_data, uint16_t read_len, const char *data_format, uint8_t *store_address);
+#endif

+ 114 - 0
app/DLT645/port/dlt645_port.c

@@ -0,0 +1,114 @@
+/*************************************************
+ Copyright (c) 2019
+ All rights reserved.
+ File name:     dlt645_port.c
+ Description:   DLT645 移植&使用例程文件
+ History:
+ 1. Version:
+	Date:       2019-09-19
+	Author:     wangjunjie
+	Modify:
+*************************************************/
+#include "dlt645.h"
+#include "stm32f2xx.h"
+#include "timer.h"
+#include "usart.h"
+#include "string.h"
+#include "led.h"
+
+
+dlt645_port_t dlt645_port;
+//static dlt645_port_t dlt645_port;
+
+// dlt645 环境结构体
+dlt645_t dlt645;
+
+void dlt_callback(UART_HandleTypeDef *husart)
+{
+	 if(__HAL_UART_GET_FLAG(husart, UART_FLAG_RXNE) && __HAL_UART_GET_IT_SOURCE(husart, UART_IT_RXNE))
+	{
+		if (dlt645_port.index < DLT_RXSIZE - 1)
+		{
+				dlt645_port.rxBuf[dlt645_port.index] = husart->Instance->DR;
+				dlt645_port.index++;
+			}
+		else
+		{
+				uint8_t data = husart->Instance->DR;
+		}
+	}
+	if((dlt645_port.index > 0) && RESET != __HAL_USART_GET_FLAG(&USART_InitStruct_485, USART_FLAG_IDLE))
+	{                           
+		uint8_t temp;                            
+		temp=husart->Instance->SR;             //先读sr再读DR才能清除idle中断
+		temp=husart->Instance->DR;
+		dlt645_port.done = 1;
+	}	
+}
+/**
+ * Name:    dlt645_hw_read
+ * Brief:   dlt645 硬件层接收数据
+ * Input:
+ *  @ctx:   645运行环境
+ *  @msg:   接收数据存放地址
+ *  @len:   数据最大接收长度
+ * Output:  读取数据的长度
+ */
+static int dlt645_hw_read(dlt645_t *ctx, uint8_t *msg, uint16_t len)
+{
+	int dataLength = 0;
+	int startTime = gettick();
+	while (1)
+	{
+		if (gettick() - startTime > dlt645_port.timeout * 1000 )
+			return 0;
+		if (dlt645_port.done == 1)
+		{
+			dataLength = dlt645_port.index;
+			memcpy(msg, &(dlt645_port.rxBuf[4]), len-4);
+			dataLength = dlt645_port.index-4;
+			return dataLength;
+		}
+	}
+}
+
+/**
+ * Name:    dlt645_hw_write
+ * Brief:   dlt645 硬件层发送数据
+ * Input:
+ *  @ctx:   645运行环境
+ *  @buf:   待发送数据
+ *  @len:   发送长度
+ * Output:  实际发送的字节数,错误返回-1
+ */
+static int dlt645_hw_write(dlt645_t *ctx, uint8_t *buf, uint16_t len)
+{
+	memset(dlt645_port.rxBuf, 0, DLT_RXSIZE);
+	delay_ms(10);
+	USART_485_Send(buf,len);
+	dlt645_port.index = 0;
+	dlt645_port.done = 0;
+	return len;
+}
+
+
+
+
+
+
+void dlt645_init(uint32_t timeout)
+{
+	HAL_GPIO_WritePin(DLT645_CTRL_GPIO,DLT645_CTRL_PIN,1);
+	dlt645_port.timeout = timeout;
+	dlt645_port.dlt645_Tx = 0;
+	dlt645_port.index = 0;
+}
+
+// 645结构体注册
+static dlt645_t dlt645 = {
+	{0},
+	0,
+	dlt645_hw_write,
+	dlt645_hw_read,
+	(void *)&dlt645_port
+};

+ 10 - 0
app/DLT645/port/dlt645_port.h

@@ -0,0 +1,10 @@
+#ifndef __DLT645_PORT_H
+#define __DLT645_PORT_H
+#include "dlt645.h"
+
+//对外提供环境声明
+extern dlt645_t dlt645;
+//645采集硬件层初始化
+int dlt645_port_init(void);
+
+#endif

+ 131 - 0
app/DLT645/source/dlt645.c

@@ -0,0 +1,131 @@
+/*************************************************
+ Copyright (c) 2019
+ All rights reserved.
+ File name:     dlt645.c
+ Description:   
+ History:
+ 1. Version:    
+    Date:       2019-09-20
+    Author:     wangjunjie
+    Modify:     
+*************************************************/
+#include "dlt645_private.h"
+#include "dlt645_1997.h"
+#include "dlt645_2007.h"
+#include "string.h"
+
+/**
+ * Name:    dlt645_receive_msg
+ * Brief:   645协议调用底层接收数据
+ * Input:
+ *  @ctx:       645环境句柄
+ *  @msg:       数据包存储地址
+ *  @len:       最大接收长度
+ *  @addr:      从站地址
+ *  @code:      数据标识   
+ *  @protocal:  645协议类型  
+ * Output:  接收成功:0,接收失败:-1
+ */
+int dlt645_receive_msg(dlt645_t *ctx, uint8_t *msg, uint16_t len, uint32_t code, dlt645_protocal protocal)
+{
+    int msg_len = ctx->read(ctx, msg, len);
+	
+    if (protocal == DLT645_1997)
+    {
+        return dlt645_1997_recv_check(msg, msg_len, ctx->addr, code);
+    }
+    else if (protocal == DLT645_2007)
+    {
+        return dlt645_2007_recv_check(msg, msg_len, ctx->addr, code);
+    }
+    else
+    {
+        return -1;
+    }
+}
+
+/**
+ * Name:    dlt645_send_msg
+ * Brief:   645协议调用底层发送数据
+ * Input:
+ *  @ctx:       645环境句柄
+ *  @msg:       发送的数据首地址
+ *  @len:       发送长度 
+ * Output:  实际发送的字节数,错误返回-1
+ */
+int dlt645_send_msg(dlt645_t *ctx, uint8_t *msg, int len)
+{
+    msg[0] = DL645_START_CODE;
+    msg[DL645_ADDR_LEN + 1] = DL645_START_CODE;
+    msg[len - 1] = DL645_STOP_CODE;
+    msg[len - 2] = _crc(msg, len - 2);
+
+    return ctx->write(ctx, msg, len);
+}
+
+/**
+ * Name:    dlt645_set_addr
+ * Brief:   设置从站地址
+ * Input:
+ *  @ctx:       645环境句柄
+ *  @addr:      从站地址
+ * Output:  None
+ */
+void dlt645_set_addr(dlt645_t *ctx, uint8_t *addr)
+{
+    uint8_t addr_temp[6];
+    memset(addr_temp, 0, 6);
+
+    //转换字节序
+    for (int i = 0; i < 6; i++)
+    {
+        addr_temp[5 - i] = addr[i];
+    }
+    memcpy(ctx->addr, addr_temp, DL645_ADDR_LEN);
+}
+
+/**
+ * Name:    dlt645_set_debug
+ * Brief:   设置调试模式
+ * Input:
+ *  @ctx:       645环境句柄
+ *  @flag:      调试标志
+ * Output:  None
+ */
+int dlt645_set_debug(dlt645_t *ctx, int flag)
+{
+    ctx->debug = flag;
+    return 0;
+}
+
+/**
+ * Name:    dlt645_read_data(用户调用)
+ * Brief:   根据645协议类型读取数据
+ * Input:
+ *  @ctx:           645环境句柄
+ *  @addr:          从站地址
+ *  @code:          标识符
+ *  @read_data:     读取数据存储地址
+ *  @protocal:      协议类型
+ * Output:  成功返回数据长度,失败返回-1
+ */
+int dlt645_read_data(dlt645_t *ctx,
+                     uint32_t code,
+                     uint8_t *read_data,
+                     dlt645_protocal protocal)
+{
+    int rs = -1;
+    switch (protocal)
+    {
+    case DLT645_1997:
+        rs = dlt645_1997_read_data(ctx, code, read_data);
+        break;
+    case DLT645_2007:
+        rs = dlt645_2007_read_data(ctx, code, read_data);
+        break;
+    default:
+        DLT645_LOG("unrecognized protocal!\r\n");
+        break;
+    }
+    return rs;
+}

+ 141 - 0
app/DLT645/source/dlt645_1997.c

@@ -0,0 +1,141 @@
+/*************************************************
+ Copyright (c) 2019
+ All rights reserved.
+ File name:     dlt645_1997.c
+ Description:   DLT645 1997版本
+ History:
+ 1. Version:    
+    Date:       2019-09-19
+    Author:     wangjunjie
+    Modify:     
+*************************************************/
+#include "dlt645_private.h"
+#include "dlt645_1997_private.h"
+#include "string.h"
+
+/**
+ * Name:    dlt645_1997_recv_check
+ * Brief:   DLT645-1997 数据校验
+ * Input:
+ *  @msg:   校验数据包
+ *  @len:   数据包长度
+ *  @addr:  从站地址
+ *  @code:  操作码
+ * Output:  校验成功:0 ,失败 -1
+ */
+int dlt645_1997_recv_check(uint8_t *msg, int len, uint8_t* addr, uint32_t code)
+{
+    if (dlt645_common_check(msg, len, addr) < 0)
+    {
+        return -1;
+    }
+    if (msg[DL645_CONTROL_POS] == 0x84)
+        return 0;
+
+    uint8_t *code_buf = (uint8_t *)&code;
+
+    for (uint8_t i = 0; i < 2; i++)
+    {
+        code_buf[i] += 0x33;
+    }
+
+    if (*((uint16_t *)(msg + DL645_DATA_POS)) != code)
+        return -1;
+
+    return 0;
+}
+
+/**
+ * Name:    dlt645_1997_parsing_data
+ * Brief:   DLT645-1997 数据包解析
+ * Input:
+ *  @code:          标识符
+ *  @read_data:     数据包指针
+ *  @len:           数据包长度
+ *  @real_val:      数据存储地址
+ * Output:  数据包长度
+ */
+static int dlt645_1997_parsing_data(uint32_t code, uint8_t *read_data, uint16_t len, uint8_t *real_val)
+{
+    switch (code)
+    {
+    case DIC_B611:
+    case DIC_B612:
+    case DIC_B613:
+    case DIC_B691:
+    case DIC_B692:
+    case DIC_B693:
+    {
+        dlt645_data_parse_by_format_to_float(read_data, 2, "XXX", real_val);
+        break;
+    }
+    case DIC_B621:
+    case DIC_B622:
+    case DIC_B623:
+    {
+        dlt645_data_parse_by_format_to_float(read_data, 2, "XX.XX", real_val);
+        break;
+    }
+    case DIC_B630:
+    case DIC_B631:
+    case DIC_B632:
+    case DIC_B633:
+    {
+        dlt645_data_parse_by_format_to_float(read_data, 3, "XX.XXXX", real_val);
+        break;
+    }
+    default:
+    {
+        for (uint16_t i = 0; i < len; i++)
+        {
+            real_val[i] = ((read_data[i] - 0x33) & 0x0f) + ((read_data[i] - 0x33) >> 4) * 10;
+        }
+        break;
+    }
+    }
+    return len;
+}
+
+/**
+ * Name:    dlt645_1997_read_data
+ * Brief:   DLT645-1997 数据读取
+ * Input:
+ *  @ctx:           645句柄
+ *  @addr:          从站地址
+ *  @code:          数据标识
+ *  @read_data:     数据存储地址
+ * Output:  成功返回数据长度,失败返回-1
+ */
+int dlt645_1997_read_data(dlt645_t *ctx,
+                          uint32_t code,
+                          uint8_t *read_data)
+{
+    uint8_t send_buf[DL645_1997_RD_CMD_LEN];
+    uint8_t read_buf[DL645_RESP_LEN];
+
+    memset(read_buf, 0, sizeof(read_buf));
+    memset(send_buf, 0, sizeof(send_buf));
+
+    memcpy(send_buf + 1, ctx->addr, DL645_ADDR_LEN);
+    send_buf[DL645_CONTROL_POS] = C_1997_CODE_RD;
+    send_buf[DL645_LEN_POS] = 2;
+
+    uint8_t send_code[2] = {0};
+    send_code[0] = (code & 0xff) + 0x33;
+    send_code[1] = ((code >> 8) & 0xff) + 0x33;
+    memcpy(send_buf + DL645_DATA_POS, send_code, 2);
+
+    if (dlt645_send_msg(ctx, send_buf, DL645_1997_RD_CMD_LEN) < 0)
+    {
+        DLT645_LOG("send data error!\n");
+        return -1;
+    }
+
+    if (dlt645_receive_msg(ctx, read_buf, DL645_RESP_LEN, code, DLT645_1997) < 0)
+    {
+        DLT645_LOG("receive msg error!\n");
+        return -1;
+    }
+
+    return dlt645_1997_parsing_data(code, read_buf + DL645_DATA_POS + 2, read_buf[DL645_LEN_POS] - 2, read_data);
+}

+ 279 - 0
app/DLT645/source/dlt645_2007.c

@@ -0,0 +1,279 @@
+/*************************************************
+ Copyright (c) 2019
+ All rights reserved.
+ File name:     dlt645_2007.c
+ Description:   DLT645 2007版本
+ History:
+ 1. Version:
+    Date:       2019-09-19
+    Author:     wangjunjie
+    Modify:
+*************************************************/
+#include "dlt645_private.h"
+#include "dlt645_2007_private.h"
+#include "string.h"
+
+/**
+ * Name:    dlt645_2007_recv_check
+ * Brief:   DLT645-2007 数据校验
+ * Input:
+ *  @msg:   校验数据包
+ *  @len:   数据包长度
+ *  @addr:  从站地址
+ *  @code:  操作码
+ * Output:  None
+ */
+int dlt645_2007_recv_check(uint8_t *msg, int len, uint8_t *addr, uint32_t code)
+{
+    if (dlt645_common_check(msg, len, addr) < 0)
+    {
+        return -1;
+    }
+    if (msg[DL645_CONTROL_POS] == 0x94)
+        return 0;
+
+    uint8_t *code_buf = (uint8_t *)&code;
+
+    for (uint8_t i = 0; i < 4; i++)
+    {
+        code_buf[i] += 0x33;
+    }
+
+    if (*((uint32_t *)(msg + DL645_DATA_POS)) != code)
+        return -1;
+
+    return 0;
+}
+
+/**
+ * Name:    dlt645_2007_parsing_data
+ * Brief:   DLT645-2007 数据包解析
+ * Input:
+ *  @code:          标识符
+ *  @read_data:     数据包指针
+ *  @len:           数据包长度
+ *  @real_val:      数据存储地址
+ * Output:  数据包长度
+ */
+int dlt645_2007_parsing_data(uint32_t code, uint8_t *read_data, uint16_t len, uint8_t *real_val)
+{
+    switch (code)
+    {
+    case DIC_0:
+    case DIC_100:
+    case DIC_200: 
+    case DIC_300:
+    case DIC_400:
+    case DIC_10000:
+    case DIC_10100:
+		case DIC_10001:
+		case DIC_10002:
+    case DIC_10200:
+    case DIC_10300:
+    case DIC_10400:
+    case DIC_20000:
+    case DIC_20100:
+    case DIC_20200:
+    case DIC_20300:
+    case DIC_20400:
+    case DIC_30000:
+    case DIC_40000:
+    case DIC_50000:
+    case DIC_60000:
+    case DIC_70000:
+    case DIC_80000:
+    case DIC_90000:
+    {
+        dlt645_data_parse_by_format_to_float(read_data, 4, "XXXXXX.XX", real_val);
+        break;
+    }
+    // 包含日期信息其原长度为8但其包含五个字节的日期时间长度所以read_data前三个字节为为数据信息,后五个字节为日期时间
+    case DIC_1010000:
+    case DIC_1020000:
+    case DIC_1010001:
+    case DIC_1020001:
+    {
+        dlt645_data_parse_by_format_to_float(read_data, 3, "XX.XXXX", real_val);
+        // 将剩余的 5 个字节拼接到 real_val 后面
+        for (int i = 0; i < 5; i++)
+        {
+            real_val[4 + i] = read_data[3 + i]-0x33;
+        }
+        break;
+    }
+		case DIC_201FF00:
+    case DIC_2010100:
+    case DIC_2010200:
+    case DIC_2010300:
+    case DIC_20C0100:
+    case DIC_20C0200:
+    case DIC_20C0300:
+    {
+        dlt645_data_parse_by_format_to_float(read_data, 2, "XXX.X", real_val);
+        break;
+    }
+    case DIC_2020100:
+    case DIC_2020200:
+    case DIC_2020300:
+    {
+        dlt645_data_parse_by_format_to_float(read_data, 3, "XXX.XXX", real_val);
+        break;
+    }
+    case DIC_2030000:
+    case DIC_2030100:
+    case DIC_2030200:
+    case DIC_2030300:
+    case DIC_2040000:
+    case DIC_2040100:
+    case DIC_2040200:
+    case DIC_2040300:
+    case DIC_2050000:
+    case DIC_2050100:
+    case DIC_2050200:
+    case DIC_2050300:
+    {
+        dlt645_data_parse_by_format_to_float(read_data, 3, "XX.XXXX", real_val);
+        break;
+    }
+    case DIC_2060000:
+    case DIC_2060100:
+    case DIC_2060200:
+    case DIC_2060300:
+    {
+        dlt645_data_parse_by_format_to_float(read_data, 2, "X.XXX", real_val);
+        break;
+    }
+    case DIC_2800002:
+    {
+        dlt645_data_parse_by_format_to_float(read_data, 2, "XX.XX", real_val);
+        break;
+    }
+		case DIC_5060101:
+		//case DIC_5040001:
+		{
+			for (uint16_t i = 0; i < len; i++)
+        {
+            real_val[i] = ((read_data[i] - 0x33) & 0x0f) + ((read_data[i] - 0x33) >> 4) * 10;
+        }
+			break;
+		}
+    case DIC_4000403:
+    case DIC_7000001:
+    case DIC_7000002:
+        for (uint16_t i = 0; i < len; i++)
+        {
+            real_val[i] = read_data[i] - 0x33;
+        }
+        break;
+    default:
+        for (uint16_t i = 0; i < len; i++)
+        {
+            real_val[i] = ((read_data[i] - 0x33) & 0x0f) + ((read_data[i] - 0x33) >> 4) * 10;
+        }
+        break;
+    }
+    return len;
+}
+
+/**
+ * Name:    dlt645_2007_read_data
+ * Brief:   DLT645-2007 数据读取
+ * Input:
+ *  @ctx:           645句柄
+ *  @addr:          从站地址
+ *  @code:          数据标识
+ *  @read_data:     数据存储地址
+ * Output:  None
+ */
+int dlt645_2007_read_data(dlt645_t *ctx,
+                          uint32_t code,
+                          uint8_t *read_data)
+{
+    uint8_t send_buf[DL645_2007_RD_CMD_LEN];
+    uint8_t read_buf[DL645_RESP_LEN];
+
+    memset(read_buf, 0, sizeof(read_buf));
+    memset(send_buf, 0, sizeof(send_buf));
+
+    memcpy(send_buf + 1, ctx->addr, DL645_ADDR_LEN);
+
+    send_buf[DL645_CONTROL_POS] = C_2007_CODE_RD;
+    send_buf[DL645_LEN_POS] = 4;
+
+    uint8_t send_code[4] = {0};
+    send_code[0] = (code & 0xff) + 0x33;
+    send_code[1] = ((code >> 8) & 0xff) + 0x33;
+    send_code[2] = ((code >> 16) & 0xff) + 0x33;
+    send_code[3] = ((code >> 24) & 0xff) + 0x33;
+
+    memcpy(send_buf + DL645_DATA_POS, send_code, 4);
+    if (dlt645_send_msg(ctx, send_buf, DL645_2007_RD_CMD_LEN) < 0)
+    {
+        DLT645_LOG("send data error!\n");
+        return -1;
+    }
+
+    if (dlt645_receive_msg(ctx, read_buf, DL645_RESP_LEN, code, DLT645_2007) < 0)
+    {
+        DLT645_LOG("receive msg error!\n");
+        return -1;
+    }
+
+    return dlt645_2007_parsing_data(code, read_buf + DL645_DATA_POS + 4, read_buf[DL645_LEN_POS] - 4, read_data);
+    // #define DL645_DATA_POS 10   //数据位置
+}
+
+/**
+ * Name:    dlt645_write_data
+ * Brief:   DLT645-2007 数据写入
+ * Input:
+ *  @ctx:           645句柄
+ *  @addr:          从站地址
+ *  @code:          数据标识
+ *  @write_data:    写入数据的指针
+ *  @write_len:     写入长度
+ * Output:  None
+ */
+int dlt645_write_data(dlt645_t *ctx,
+                      uint32_t addr,
+                      uint32_t code,
+                      uint8_t *write_data,
+                      uint8_t write_len)
+{
+    uint8_t send_buf[DL645_WR_LEN];
+    uint8_t read_buf[DL645_RESP_LEN];
+
+    memset(read_buf, 0, sizeof(read_buf));
+    memset(send_buf, 0, sizeof(send_buf));
+
+    memcpy(send_buf + 1, ctx->addr, DL645_ADDR_LEN);
+
+    send_buf[DL645_CONTROL_POS] = C_2007_CODE_WR;
+    send_buf[DL645_LEN_POS] = 12 + write_len;
+
+    uint8_t send_code[4] = {0};
+    send_code[0] = (code & 0xff) + 0x33;
+    send_code[1] = ((code >> 8) & 0xff) + 0x33;
+    send_code[2] = ((code >> 16) & 0xff) + 0x33;
+    send_code[3] = ((code >> 24) & 0xff) + 0x33;
+
+    for (uint8_t i = 0; i < write_len; i++)
+    {
+        write_data[i] += 0x33;
+    }
+
+    memcpy(send_buf + DL645_DATA_POS, send_code, 4);
+    memcpy(send_buf + DL645_DATA_POS + 12, write_data, write_len);
+    if (dlt645_send_msg(ctx, send_buf, 24 + write_len) < 0)
+    {
+        DLT645_LOG("send data error!\n");
+        return -1;
+    }
+
+    if (dlt645_receive_msg(ctx, read_buf, DL645_RESP_LEN, code, DLT645_2007) < 0)
+    {
+        DLT645_LOG("receive msg error!\n");
+        return -1;
+    }
+    return 0;
+}

+ 289 - 0
app/DLT645/source/dlt645_data.c

@@ -0,0 +1,289 @@
+/*************************************************
+ Copyright (c) 2019
+ All rights reserved.
+ File name:     dlt645_data.c
+ Description:   DLT645 数据处理源文件
+ History:
+ 1. Version:    
+    Date:       2019-09-20
+    Author:     wangjunjie
+    Modify:     
+*************************************************/
+#include "dlt645_private.h"
+#include <string.h>
+#include "data_task.h"
+
+//字节位置枚举类型
+typedef enum
+{
+    BYTE_RESET = 0,   //重置
+    BYTE_LOW_ADDRESS, //低位
+    BYTE_HIGH_ADDRESS //高位
+} byte_part;
+
+/**
+ * Name:    _crc
+ * Brief:   crc和校验
+ * Input:
+ *  @msg:   校验数据包
+ *  @len:   数据包长度
+ * Output:  校验值
+ */
+int _crc(uint8_t *msg, int len)
+{
+    uint8_t crc = 0;
+    while (len--)
+    {
+        crc += *msg++;
+    }
+    return crc;
+}
+
+/**
+ * Name:    dlt645_common_check
+ * Brief:   645协议接收数据公共部分校验
+ * Input:
+ *  @msg:   校验数据包
+ *  @len:   数据包长度
+ *  @addr:  从站地址
+ * Output:  校验成功:0,校验失败:-1
+ */
+int dlt645_common_check(uint8_t *msg, int len, uint8_t *addr)
+{
+    //数据包长度校验
+    if (len < 7)
+    {
+        return -1;
+    }
+    //数据帧标志校验
+    if (msg[0] != DL645_START_CODE ||
+        msg[DL645_ADDR_LEN + 1] != DL645_START_CODE ||
+        msg[len - 1] != DL645_STOP_CODE)
+    {
+        DLT645_LOG("check code error!\n");
+        return -1;
+    }
+    //CRC校验
+    uint8_t crc = _crc(msg, len - 2);
+    if (crc != msg[len - 2])
+    {
+        DLT645_LOG("check crc error!\n");
+        return -1;
+    }
+    //控制码主从校验
+    if ((msg[DL645_CONTROL_POS] & C_TD_MASK) == (C_TD_MASTER << C_TD_POS))
+    {
+        DLT645_LOG("check control direction error!\n");
+        return -1;
+    }
+    //控制码应答校验
+    if ((msg[DL645_CONTROL_POS] & C_ACK_MASK) == (C_ACK_ERR << C_ACK_POS))
+    {
+        DLT645_LOG("check ACK error!\n");
+        return msg[len - 3];
+    }
+    //从站地址校验
+    if (memcmp(msg + 1, addr, 6) != 0)
+    {
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * Name:    dec2bcd
+* Brief:   十进制转BCD码(目前支持32位数字大小)
+ * Input:
+ *  @val:   十进制值
+ * Output:  BCD码值
+ */
+uint32_t dec_to_bcd(uint32_t val)
+{
+    uint32_t data = 0;
+
+    if (val < 100)
+    {
+        uint8_t byte0 = val % 10;
+        uint8_t byte1 = val / 10;
+        data = (byte1 << 4) + byte0;
+    }
+    else if (val < 10000)
+    {
+        uint8_t byte0 = val % 10;
+        uint8_t byte1 = (val / 10) % 10;
+        uint8_t byte2 = (val / 100) % 10;
+        uint8_t byte3 = (val / 1000) % 10;
+        data = (byte3 << 12) +
+               (byte2 << 8) +
+               (byte1 << 4) + byte0;
+    }
+    else if (val < 1000000)
+    {
+        uint8_t byte0 = val % 10;
+        uint8_t byte1 = (val / 10) % 10;
+        uint8_t byte2 = (val / 100) % 10;
+        uint8_t byte3 = (val / 1000) % 10;
+        uint8_t byte4 = (val / 10000) % 10;
+        uint8_t byte5 = (val / 100000) % 10;
+        data = (byte5 << 20) +
+               (byte4 << 16) +
+               (byte3 << 12) +
+               (byte2 << 8) +
+               (byte1 << 4) + byte0;
+    }
+    else if (val < 100000000)
+    {
+        uint8_t byte0 = val % 10;
+        uint8_t byte1 = (val / 10) % 10;
+        uint8_t byte2 = (val / 100) % 10;
+        uint8_t byte3 = (val / 1000) % 10;
+        uint8_t byte4 = (val / 10000) % 10;
+        uint8_t byte5 = (val / 100000) % 10;
+        uint8_t byte6 = (val / 1000000) % 10;
+        uint8_t byte7 = (val / 10000000) % 10;
+        data = (byte7 << 28) +
+               (byte6 << 24) +
+               (byte5 << 20) +
+               (byte4 << 16) +
+               (byte3 << 12) +
+               (byte2 << 8) +
+               (byte1 << 4) + byte0;
+    }
+    return data;
+}
+
+/**
+ * Name:    str_to_bcd
+ * Brief:   字符串转BCD形式
+ * Input:
+ *  @str:               要转换的字符串
+ *  @bcd_store_address: 转换后的存储地址
+ *  @bcd_len:           BCD码总长度
+ * Output:  成功0,失败-1
+ */
+int str_to_bcd(char *str, uint8_t *bcd_store_address, uint16_t bcd_len)
+{
+    //字符串偏移
+    int str_pos = bcd_len * 2 - strlen(str);
+    //字符串比BCD码长度长
+    if (str_pos < 0)
+    {
+        return -1;
+    }
+    memset(bcd_store_address, 0, bcd_len);
+
+    for (int i = 0; i < strlen(str); i++)
+    {
+        if (str[i] >= '0' && str[i] <= '9')
+        {
+            bcd_store_address[(i + str_pos) / 2] |= (str[i] - '0') << (4 * ((i + 1 + (strlen(str) % 2)) % 2));
+        }
+        else
+        {
+            //当前字符不为数字,返回错误
+            return -1;
+        }
+    }
+    return 0;
+}
+
+/**
+ * Name:    data_package_translate_to_int
+ * Brief:   将接收到的dlt645数据包中的数据转化为整数
+ * Input:
+ *  @read_data: 数据首地址
+ *  @len:       数据长度
+ * Output:  转化后的整数
+ */
+int data_package_translate_to_int(uint8_t *read_data, uint16_t len)
+{
+    //权值
+    uint8_t number_weight = 0;
+    //当前数组下标索引
+    uint8_t current_index = 0;
+    //当前解析字节位
+    uint8_t current_byte_part = BYTE_RESET;
+    //当前整数值
+    int i_value = 0;
+
+    while (len--)
+    {
+        current_byte_part = BYTE_LOW_ADDRESS;
+        do
+        {
+            switch (current_byte_part)
+            {
+            //当前处理字节低位
+            case BYTE_LOW_ADDRESS:
+                i_value += ((read_data[current_index] - 0x33) & 0x0f) * my_pow(10,number_weight);
+                number_weight++;
+                current_byte_part = BYTE_HIGH_ADDRESS;
+                break;
+            //当前处理字节高位
+            case BYTE_HIGH_ADDRESS:
+                i_value += ((read_data[current_index] - 0x33) >> 4) * my_pow(10,number_weight);
+                number_weight++;
+                current_byte_part = BYTE_RESET;
+                break;
+            }
+        } while (current_byte_part != BYTE_RESET);
+        current_index++;
+    }
+    return i_value;
+}
+
+/**
+ * Name:    dlt645_data_parse_by_format_to_float
+ * Brief:   根据数据格式将645协议读取的数据转换为真实数据并存储
+ *          !真实数据为浮点数据,需要注意的是无论读取数据长度是多少,存储数据长度都应是4字节
+ * Input:
+ *  @read_data:     645协议读取的数据
+ *  @read_len:      读取数据的长度
+ *  @data_format:   转换的数据格式,如 XX.XX,XX.XXX
+ * Output:  转换成功返回0,失败返回-1
+ */
+int dlt645_data_parse_by_format_to_float(uint8_t *read_data, uint16_t read_len, const char *data_format, uint8_t *store_address)
+{
+    //权值
+    int num_weight = 0;
+    int ival = data_package_translate_to_int(read_data, read_len);
+
+    for (int i = 0; i < strlen(data_format); i++)
+    {
+        if (*(data_format + i) == '.')
+        {
+            num_weight = strlen(data_format) - i - 1;
+            if (num_weight < 0)
+            {
+                return -1;
+            }
+            break;
+        }
+    }
+    float fval = ival / my_pow(10,num_weight);
+    memcpy(store_address, &fval, 4);
+    return 0;
+}
+
+int dlt645_data_parse_by_format_to_float_and_DATE(uint8_t *read_data, uint16_t read_len, const char *data_format, uint8_t *store_address)
+{
+    int num_weight = 0;
+    int ival = data_package_translate_to_int(read_data, read_len);
+
+    for (int i = 0; i < strlen(data_format); i++)
+    {
+        if (*(data_format + i) == '.')
+        {
+            num_weight = strlen(data_format) - i - 1;
+            if (num_weight < 0)
+            {
+                return -1;
+            }
+            break;
+        }
+    }
+    float fval = ival / my_pow(10,num_weight);
+    memcpy(store_address, &fval, 4);
+    return 0;
+}

+ 22 - 0
app/HARDWARE/include/led.h

@@ -0,0 +1,22 @@
+#ifndef __LED_H
+#define	__LED_H
+#include "stm32f2xx.h"
+//Òý½Å¶¨Òå
+/*******************************************************/
+
+#define LED_PIN                  	GPIO_PIN_6                                   
+
+#define NET_STATUS_LED_PIN                  GPIO_PIN_8                                      
+
+#define STATUS_LED_PIN                  GPIO_PIN_7                                       
+
+/************************************************************/
+
+
+void LED_GPIO_Config(void);
+void NET_STATUS_LED_Config(void);
+void STATUS_LED_Config(void);
+
+					
+#endif
+

+ 74 - 0
app/HARDWARE/include/malloc.h

@@ -0,0 +1,74 @@
+#ifndef __MALLOC_H
+#define __MALLOC_H
+
+
+
+#include "stm32f2xx.h"
+
+ 
+ 
+#ifndef NULL
+#define NULL 0
+#endif
+
+//定义两个内存池
+#define SRAMIN	 0		//内部内存池
+#define SRAMEX   1		//外部内存池 
+
+#define SRAMBANK 	2	  //定义支持的SRAM块数.	
+
+
+//mem1内存参数设定.mem1完全处于内部SRAM里面.
+#define MEM1_BLOCK_SIZE			32  	  						              //内存块大小为32字节
+#define MEM1_MAX_SIZE			  2*1024  						              //最大管理内存 40K
+#define MEM1_ALLOC_TABLE_SIZE	MEM1_MAX_SIZE/MEM1_BLOCK_SIZE 	//内存表大小
+
+
+//mem2内存参数设定.mem2的内存池处于外部SRAM里面
+#define MEM2_BLOCK_SIZE			32  	  						              //内存块大小为32字节
+#define MEM2_MAX_SIZE			  512 *1024  					              //最大管理内存512K
+#define MEM2_ALLOC_TABLE_SIZE	MEM2_MAX_SIZE/MEM2_BLOCK_SIZE 	//内存表大小 
+		 
+ 
+ 
+//内存管理控制器
+struct _m_mallco_dev
+{
+	void    ( * init ) ( uint8_t );				 //初始化
+	uint8_t ( * perused ) ( uint8_t );		 //内存使用率
+	uint8_t  * membase [ SRAMBANK ];		   //内存池 管理SRAMBANK个区域的内存
+	uint16_t * memmap [ SRAMBANK ]; 		   //内存管理状态表
+	uint8_t    memrdy [ SRAMBANK ]; 			 //内存管理是否就绪
+};
+extern struct _m_mallco_dev mallco_dev;	 //在mallco.c里面定义
+
+
+void mymemset(void *s,uint8_t c,uint32_t count);	    //设置内存
+void mymemcpy(void *des,void *src,uint32_t n);        //复制内存     
+void my_mem_init(uint8_t memx);				                //内存管理初始化函数(外/内部调用)
+uint32_t my_mem_malloc(uint8_t memx,uint32_t size);	  //内存分配(内部调用)
+uint8_t my_mem_free(uint8_t memx,uint32_t offset);		//内存释放(内部调用)
+uint8_t my_mem_perused(uint8_t memx);				          //获得内存使用率(外/内部调用) 
+
+
+//用户调用函数
+void myfree(uint8_t memx,void *ptr);  			           //内存释放(外部调用)
+void *mymalloc(uint8_t memx,uint32_t size);			       //内存分配(外部调用)
+void *myrealloc(uint8_t memx,void *ptr,uint32_t size); //重新分配内存(外部调用)
+
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 12 - 0
app/HARDWARE/include/timer.h

@@ -0,0 +1,12 @@
+#ifndef __TIMER_H
+#define	__TIMER_H
+
+#include "stm32f2xx.h"
+#include "stm32f2xx_hal.h"
+
+
+void TIMER_config(void);
+void delay_ms(uint32_t nms);
+
+#endif
+

+ 95 - 0
app/HARDWARE/include/usart.h

@@ -0,0 +1,95 @@
+#ifndef __DEBUG_USART_H
+#define	__DEBUG_USART_H
+
+#include "stm32f2xx.h"
+#include <stdio.h>
+#include "main.h"
+#include "myFile.h"
+
+
+
+extern UART_HandleTypeDef	 USART_InitStruct_485;
+extern UART_HandleTypeDef  USART_InitStruct_232;
+extern UART_HandleTypeDef  USART_InitStruct_DEBUG;
+extern DMA_HandleTypeDef 	DMA_DEBUG_RX;
+
+
+//繫祇貢왯多신땍屢
+/*******************************************************/
+#define DEBUG_USART                             USART6
+#define DEBUG_USART_BAUDRATE                    115200  //눔왯꺼景쪽
+
+#define DEBUG_USART_RX_GPIO_PORT                GPIOC
+#define DEBUG_USART_RX_PIN                      GPIO_PIN_7
+
+#define DEBUG_USART_TX_GPIO_PORT                GPIOC
+#define DEBUG_USART_TX_PIN                      GPIO_PIN_6
+
+#define DEBUG_USART_IRQHandler                  USART6_IRQHandler
+#define DEBUG_USART_IRQ                 				USART6_IRQn
+
+//繫祇貢왯DMA
+#define DEBUG_USART_DR_BASE               (USART6_BASE+0x04)		//DR셍닸포
+#define DEBUG_USART_DMA_CLK               RCC_AHB1Periph_DMA2	
+#define DEBUG_USART_DMA_CHANNEL           DMA_CHANNEL_5
+#define DEBUG_USART_DMA_STREAM            DMA2_Stream1
+
+#define BUFF_SIZE                     		5000//35 * 1024				//dma왕쇌댕鬼 64k
+
+/************************************************************/
+//232多신땍屢
+
+#define USART_232                             USART1
+#define USART_232_BAUDRATE                    115200  //눔왯꺼景쪽
+
+#define USART_232_RX_GPIO_PORT                GPIOA
+#define USART_232_RX_PIN                      GPIO_PIN_10
+
+#define USART_232_TX_GPIO_PORT                GPIOA
+#define USART_232_TX_PIN                      GPIO_PIN_9
+
+#define USART_232_IRQHandler                  USART1_IRQHandler
+#define USART_232_IRQ                 				USART1_IRQn
+
+#define RX_BUFFER_SIZE 												3 * 1024
+
+//485多신땍屢
+#define USART_485                             USART3
+#define USART_485_BAUDRATE                    9600 //눔왯꺼景쪽
+
+#define USART_485_RX_GPIO_PORT                GPIOC
+#define USART_485_RX_PIN                      GPIO_PIN_11
+
+#define USART_485_TX_GPIO_PORT                GPIOC
+#define USART_485_TX_PIN                      GPIO_PIN_10
+
+#define USART_485_IRQHandler                  USART3_IRQHandler
+#define USART_485_IRQ                 				USART3_IRQn
+//485왠齡多신
+#define USART_485_DE_GPIO_PORT 								GPIOC
+#define USART_485_DE_PIN											GPIO_PIN_12
+
+void DEBUG_USART_Config(void);
+void USART_DMA_Config(void);
+
+
+void USART_232_config(void);
+void USART_232_Send(uint8_t *message,uint16_t size);
+void USART_232_task_creat(void);
+
+
+void USART_485_config(void);
+void USART_485_DE_TX(void);
+void USART_485_DE_RX(void);
+void Config_485_Port(uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity, uint8_t flowcontrol);
+void USART_485_Send(uint8_t *message,uint16_t size);
+
+
+extern uint8_t UART6_RX_BUF[BUFF_SIZE];
+extern uint8_t UART6_RX_STAT;
+extern uint32_t UART6_RX_NUM;
+
+
+extern uint8_t rx_232_Buffer[RX_BUFFER_SIZE];
+
+#endif /* __USART_H */

+ 56 - 0
app/HARDWARE/source/led.c

@@ -0,0 +1,56 @@
+#include "led.h"
+
+void LED_GPIO_Config(void)
+{		
+		/*开启LED相关的GPIO外设时钟*/
+		__HAL_RCC_GPIOF_CLK_ENABLE();
+		/*定义一个GPIO_InitTypeDef类型的结构体*/
+    GPIO_InitTypeDef GPIO_InitStruct = {0};
+			/*选择要控制的GPIO引脚*/															   
+    GPIO_InitStruct.Pin = LED_PIN;
+		/*设置引脚模式为输出模式*/
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+		/*设置引脚为上拉模式*/
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+		/*设置引脚速率 */  
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+		/*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
+    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);	
+}
+
+void NET_STATUS_LED_Config(void)
+{
+		/*开启LED相关的GPIO外设时钟*/
+		__HAL_RCC_GPIOF_CLK_ENABLE();
+		/*定义一个GPIO_InitTypeDef类型的结构体*/
+    GPIO_InitTypeDef GPIO_InitStruct = {0};
+			/*选择要控制的GPIO引脚*/															   
+    GPIO_InitStruct.Pin = NET_STATUS_LED_PIN;
+		/*设置引脚模式为输出模式*/
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+		/*设置引脚为上拉模式*/
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+		/*设置引脚速率 */  
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+		/*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
+    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);	
+}
+
+void STATUS_LED_Config(void)
+{
+		/*开启LED相关的GPIO外设时钟*/
+		__HAL_RCC_GPIOF_CLK_ENABLE();
+		/*定义一个GPIO_InitTypeDef类型的结构体*/
+    GPIO_InitTypeDef GPIO_InitStruct = {0};
+			/*选择要控制的GPIO引脚*/															   
+    GPIO_InitStruct.Pin = STATUS_LED_PIN;
+		/*设置引脚模式为输出模式*/
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+		/*设置引脚为上拉模式*/
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+		/*设置引脚速率 */  
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+		/*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
+    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+}
+

+ 226 - 0
app/HARDWARE/source/malloc.c

@@ -0,0 +1,226 @@
+#include "malloc.h"	    
+
+
+
+//内存池(32字节对齐)
+__align(32) uint8_t mem1base[MEM1_MAX_SIZE];													//内部SRAM内存池
+__align(32) uint8_t mem2base[MEM2_MAX_SIZE] __attribute__((at(0X68000000)));					//外部SRAM内存池
+
+
+//内存管理表
+uint16_t mem1mapbase[MEM1_ALLOC_TABLE_SIZE];													//内部SRAM内存池MAP
+uint16_t mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0X68000000+MEM2_MAX_SIZE)));	//外部SRAM内存池MAP
+
+
+//内存管理参数	   
+const uint32_t memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE};			//内存表大小
+const uint32_t memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE};						      //内存分块大小
+const uint32_t memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE};								          //内存总大小
+
+
+//内存管理控制器
+struct _m_mallco_dev mallco_dev=
+{
+	my_mem_init,				             //内存初始化
+	my_mem_perused,				           //内存使用率
+	mem1base,mem2base,			         //内存池
+	mem1mapbase,mem2mapbase,	       //内存管理状态表
+	0,0,  		 				               //内存管理未就绪
+};
+
+
+
+//复制内存
+//*des:目的地址
+//*src:源地址
+//n:需要复制的内存长度(字节为单位)
+void mymemcpy(void *des,void *src,uint32_t n)  
+{  
+	uint8_t *xdes=des;
+	uint8_t *xsrc=src; 
+	
+	
+	while(n--)*xdes++=*xsrc++;  
+	
+}  
+
+
+//设置内存
+//*s:内存首地址
+//c :要设置的值
+//count:需要设置的内存大小(字节为单位)
+void mymemset(void *s,uint8_t c,uint32_t count)  
+{  
+	uint8_t *xs = s;  
+
+
+	while(count--)*xs++=c;  
+	
+}	   
+
+
+//内存管理初始化  
+//memx:所属内存块
+void my_mem_init(uint8_t memx)  
+{  
+	mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);//内存状态表数据清零  
+	mymemset(mallco_dev.membase[memx], 0,memsize[memx]);	//内存池所有数据清零  
+	mallco_dev.memrdy[memx]=1;								//内存管理初始化OK  
+}  
+
+
+//获取内存使用率
+//memx:所属内存块
+//返回值:使用率(0~100)
+uint8_t my_mem_perused(uint8_t memx)  
+{  
+	uint32_t used=0;  
+	uint32_t i;  
+	
+	
+	for(i=0;i<memtblsize[memx];i++)  
+	{  
+			if(mallco_dev.memmap[memx][i])used++; 
+	} 
+	
+	return (used*100)/(memtblsize[memx]);  
+	
+}  
+
+
+//内存分配(内部调用)
+//memx:所属内存块
+//size:要分配的内存大小(字节)
+//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址 
+uint32_t my_mem_malloc(uint8_t memx,uint32_t size)  
+{  
+	signed long offset=0;  
+	uint32_t nmemb;	//需要的内存块数  
+	uint32_t cmemb=0;//连续空内存块数
+	uint32_t i;  
+	
+	
+	if(!mallco_dev.memrdy[memx])mallco_dev.init(memx);//未初始化,先执行初始化 
+	
+	if(size==0)
+		return 0XFFFFFFFF;//不需要分配
+	
+	nmemb=size/memblksize[memx];  	//获取需要分配的连续内存块数
+	
+	if(size%memblksize[memx])nmemb++; 
+	
+	for(offset=memtblsize[memx]-1;offset>=0;offset--)//搜索整个内存控制区  
+	{     
+		if(!mallco_dev.memmap[memx][offset])cmemb++;//连续空内存块数增加
+		else cmemb=0;								//连续内存块清零
+		
+		if(cmemb==nmemb)							//找到了连续nmemb个空内存块
+		{
+			for(i=0;i<nmemb;i++)  					//标注内存块非空 
+			{  
+					mallco_dev.memmap[memx][offset+i]=nmemb;  
+			}  
+			return (offset*memblksize[memx]);//返回偏移地址  
+		}
+		
+	}  
+	
+	return 0XFFFFFFFF;//未找到符合分配条件的内存块  
+	
+}  
+
+
+//释放内存(内部调用) 
+//memx:所属内存块
+//offset:内存地址偏移
+//返回值:0,释放成功;1,释放失败;  
+uint8_t my_mem_free(uint8_t memx,uint32_t offset)  
+{  
+	int i;  
+	
+	
+	if(!mallco_dev.memrdy[memx])//未初始化,先执行初始化
+	{
+	mallco_dev.init(memx);    
+			return 1;//未初始化  
+	}  
+	
+	if(offset<memsize[memx])//偏移在内存池内. 
+	{  
+			int index=offset/memblksize[memx];			//偏移所在内存块号码  
+			int nmemb=mallco_dev.memmap[memx][index];	//内存块数量
+			for(i=0;i<nmemb;i++)  						//内存块清零
+			{  
+					mallco_dev.memmap[memx][index+i]=0;  
+			}  
+			return 0;  
+	}
+	else 
+		return 2;//偏移超区了.  
+	
+}  
+
+
+//释放内存(外部调用) 
+//memx:所属内存块
+//ptr:内存首地址 
+void myfree(uint8_t memx,void *ptr)  
+{  
+	uint32_t offset;   
+	
+	
+	if(ptr==NULL)return;//地址为0.  
+	offset=(uint32_t)ptr-(uint32_t)mallco_dev.membase[memx];     
+	my_mem_free(memx,offset);	//释放内存     
+	
+}  
+
+
+//分配内存(外部调用)
+//memx:所属内存块
+//size:内存大小(字节)
+//返回值:分配到的内存首地址.
+void *mymalloc(uint8_t memx,uint32_t size)  
+{  
+	uint32_t offset;   
+	
+	
+	offset=my_mem_malloc(memx,size);  	   	 
+	
+	if(offset==0XFFFFFFFF)return NULL;  
+	else return (void*)((uint32_t)mallco_dev.membase[memx]+offset);  
+	
+}  
+
+
+//重新分配内存(外部调用)
+//memx:所属内存块
+//*ptr:旧内存首地址
+//size:要分配的内存大小(字节)
+//返回值:新分配到的内存首地址.
+void *myrealloc(uint8_t memx,void *ptr,uint32_t size)  
+{  
+	uint32_t offset;    
+	
+	
+	offset=my_mem_malloc(memx,size);   	
+	if(offset==0XFFFFFFFF)return NULL;     
+	else  
+	{  									   
+		mymemcpy((void*)((uint32_t)mallco_dev.membase[memx]+offset),ptr,size);	//拷贝旧内存内容到新内存   
+		myfree(memx,ptr);  											  		//释放旧内存
+		return (void*)((uint32_t)mallco_dev.membase[memx]+offset);  				//返回新内存首地址
+	}  
+	
+}
+
+
+
+
+
+
+
+
+
+
+

+ 27 - 0
app/HARDWARE/source/timer.c

@@ -0,0 +1,27 @@
+#include "timer.h"
+		
+TIM_HandleTypeDef htim7;
+
+void TIMER_config()
+{
+		__HAL_RCC_TIM7_CLK_ENABLE();
+
+    htim7.Instance = TIM7;
+    htim7.Init.Prescaler = 59999;
+    htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
+    htim7.Init.Period = 5999;
+    HAL_TIM_Base_Init(&htim7);
+		__HAL_TIM_ENABLE(&htim7);
+
+}
+
+void delay_ms(uint32_t ms)
+{
+		uint32_t start_time = __HAL_TIM_GET_COUNTER(&htim7); // 获取当前定时器计数值
+    while ((TIM7->CNT - start_time) < ms); // 等待经过指定的延时时间
+}
+
+void TIM7_IRQHandler(void)
+{
+    HAL_TIM_IRQHandler(&htim7);
+}

+ 705 - 0
app/HARDWARE/source/usart.c

@@ -0,0 +1,705 @@
+#include "usart.h"
+#include "mmodbus.h"
+#include "dlt645.h"
+#include "gateway_message.h"
+#include "tcp_server.h"
+#include "timer.h"
+#include "updata.h"
+
+
+uint8_t rxByte;
+uint8_t rx_232_Buffer[RX_BUFFER_SIZE];
+uint8_t recv_232_done;
+unsigned int rxIndex = 0;
+
+uint8_t UART6_RX_BUF[BUFF_SIZE];
+uint8_t UART6_RX_STAT=0;
+uint32_t UART6_RX_NUM = 0;	
+
+UART_HandleTypeDef 	USART_InitStruct_485;
+UART_HandleTypeDef  USART_InitStruct_232;
+UART_HandleTypeDef  USART_InitStruct_DEBUG;
+DMA_HandleTypeDef 	DMA_DEBUG_RX;
+
+//重定向c库函数printf到串口,重定向后可使用printf函数
+int fputc(int ch, FILE *f)
+{
+		/* 发送一个字节数据到串口 */
+		USART_232->DR = (ch & (uint16_t)0x01FF);
+		
+		/* 等待发送完毕 */
+		while (__HAL_UART_GET_FLAG(&USART_InitStruct_232, USART_FLAG_TXE) == RESET);	
+		return (ch);
+}
+
+
+/*           232串口配置             */
+
+void USART_232_config(void)
+{
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+		__HAL_RCC_USART1_CLK_ENABLE();
+  
+		GPIO_InitTypeDef GPIO_InitStruct = {0};
+    GPIO_InitStruct.Pin = USART_232_TX_PIN | USART_232_RX_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
+    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+	
+		USART_InitStruct_232.Instance = USART_232;
+		USART_InitStruct_232.Init.BaudRate = USART_232_BAUDRATE;
+		USART_InitStruct_232.Init.WordLength = UART_WORDLENGTH_8B;
+		USART_InitStruct_232.Init.StopBits = UART_STOPBITS_1;
+		USART_InitStruct_232.Init.Parity = UART_PARITY_NONE;
+		USART_InitStruct_232.Init.Mode = UART_MODE_TX_RX;
+		USART_InitStruct_232.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+		USART_InitStruct_232.Init.OverSampling = UART_OVERSAMPLING_8;
+		HAL_UART_Init(&USART_InitStruct_232);
+		
+		HAL_NVIC_SetPriority(USART_232_IRQ, 1, 0);
+    HAL_NVIC_EnableIRQ(USART_232_IRQ);
+	
+//		HAL_UART_Receive_IT(&USART_InitStruct_232, &rxByte, 1);
+		__HAL_UART_ENABLE_IT(&USART_InitStruct_232, UART_IT_RXNE); // 使能接收中断	
+		__HAL_UART_ENABLE_IT(&USART_InitStruct_232, UART_IT_IDLE); // 使能空闲中断	
+}
+
+void USART_232_IRQHandler(void){
+//    HAL_UART_IRQHandler(&USART_InitStruct_232);
+	if(__HAL_UART_GET_FLAG(&USART_InitStruct_232, UART_FLAG_RXNE) && __HAL_UART_GET_IT_SOURCE(&USART_InitStruct_232, UART_IT_RXNE))
+	{
+				rx_232_Buffer[rxIndex] = USART_InitStruct_232.Instance->DR;
+				rxIndex++;
+	}
+	if (RESET != __HAL_UART_GET_FLAG(&USART_InitStruct_232, USART_FLAG_IDLE) && __HAL_UART_GET_IT_SOURCE(&USART_InitStruct_232, UART_IT_IDLE))
+	{	
+		uint8_t i;
+		i = USART_InitStruct_232.Instance->SR;
+		i = USART_InitStruct_232.Instance->DR;
+		rxIndex = 0;
+		recv_232_done = 1;
+		return;
+	}
+	USART1->DR;
+}
+
+void USART_232_Send(uint8_t *message,uint16_t size)
+{
+	recv_232_done = 0;
+	HAL_UART_Transmit(&USART_InitStruct_232, message,size,HAL_MAX_DELAY);
+}
+
+
+
+
+/*           485串口配置             */
+void USART_485_DE_init()
+{
+		__HAL_RCC_GPIOC_CLK_ENABLE();
+		GPIO_InitTypeDef GPIO_InitStruct = {0};
+		GPIO_InitStruct.Pin = USART_485_DE_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+    HAL_GPIO_Init(USART_485_DE_GPIO_PORT, &GPIO_InitStruct);
+}
+void USART_485_DE_TX()
+{
+	HAL_GPIO_WritePin(USART_485_DE_GPIO_PORT,USART_485_DE_PIN,1);
+}
+void USART_485_DE_RX()
+{
+	HAL_GPIO_WritePin(USART_485_DE_GPIO_PORT,USART_485_DE_PIN,0);
+}
+
+// 485发送数据
+void USART_485_Send(uint8_t *message,uint16_t size)
+{
+	uint16_t i=0;
+	USART_485_DE_TX();
+	HAL_UART_Transmit(&USART_InitStruct_485, message, size, HAL_MAX_DELAY);
+	USART_485_DE_RX();
+}
+// USART_485 初始化
+void USART_485_config()
+{
+		USART_485_DE_init();
+	
+		__HAL_RCC_USART3_CLK_ENABLE();
+		__HAL_RCC_GPIOC_CLK_ENABLE();
+	
+    GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+    // 配置 GPIOC Pin 11 和 10 分别作为 USART3 的 RX 和 TX 引脚
+    GPIO_InitStruct.Pin = USART_485_RX_PIN | USART_485_TX_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
+    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+    USART_InitStruct_485.Instance = USART_485;
+    USART_InitStruct_485.Init.BaudRate = USART_485_BAUDRATE;
+    USART_InitStruct_485.Init.WordLength = UART_WORDLENGTH_8B;
+    USART_InitStruct_485.Init.StopBits = UART_STOPBITS_1;
+    USART_InitStruct_485.Init.Parity = UART_PARITY_NONE;
+    USART_InitStruct_485.Init.Mode = UART_MODE_TX_RX; // 既支持发送也支持接收
+    USART_InitStruct_485.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+    USART_InitStruct_485.Init.OverSampling = UART_OVERSAMPLING_16;
+    HAL_UART_Init(&USART_InitStruct_485);
+
+		HAL_NVIC_SetPriority(USART_485_IRQ, 0, 0);
+    HAL_NVIC_EnableIRQ(USART_485_IRQ);
+		// 初始化 DE 引脚 接收数据
+    HAL_GPIO_WritePin(USART_485_DE_GPIO_PORT,USART_485_DE_PIN,GPIO_PIN_RESET); 
+		
+//		HAL_UART_Receive_IT(&USART_InitStruct_485, &rxByte, 1);
+		__HAL_UART_ENABLE_IT(&USART_InitStruct_485, UART_IT_RXNE); // 使能接收中断	
+		__HAL_UART_ENABLE_IT(&USART_InitStruct_485, UART_IT_IDLE); // 使能空闲中断	
+}
+
+/*
+ *  函数名:void Config_485_Port(uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity, uint8_t flowcontrol)
+ *  输入参数:baudrate,databits,stopbits,parity,flowcontol 串口的配置参数
+ *  输出参数:无
+ *  返回值:无
+ *  函数作用:根据输入参数进行配置485串口参数
+ */
+void Config_485_Port(uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity, uint8_t flowcontrol)
+{
+		uint8_t wordLength;
+		if(parity!=0)
+		{
+			wordLength=databits+1;
+		}else wordLength=databits;
+
+		__HAL_RCC_USART3_CLK_ENABLE();
+		__HAL_RCC_GPIOC_CLK_ENABLE();
+	
+		GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+		// 配置 GPIOC Pin 11 和 10 分别作为 USART3 的 RX 和 TX 引脚
+    GPIO_InitStruct.Pin = USART_485_RX_PIN | USART_485_TX_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
+    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+		USART_InitStruct_485.Instance = USART_485;
+    USART_InitStruct_485.Init.BaudRate = USART_485_BAUDRATE;
+    USART_InitStruct_485.Init.WordLength = UART_WORDLENGTH_8B;
+    USART_InitStruct_485.Init.StopBits = UART_STOPBITS_1;
+    USART_InitStruct_485.Init.Parity = UART_PARITY_NONE;
+    USART_InitStruct_485.Init.Mode = UART_MODE_TX_RX; // 既支持发送也支持接收
+    USART_InitStruct_485.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+    USART_InitStruct_485.Init.OverSampling = UART_OVERSAMPLING_16;
+    HAL_UART_Init(&USART_InitStruct_485);
+
+		HAL_NVIC_SetPriority(USART_485_IRQ, 0, 0);
+    HAL_NVIC_EnableIRQ(USART_485_IRQ);
+		// 初始化 DE 引脚 接收数据
+    HAL_GPIO_WritePin(USART_485_DE_GPIO_PORT,USART_485_DE_PIN,GPIO_PIN_RESET); 
+		
+//		HAL_UART_Receive_IT(&USART_InitStruct_485, &rxByte, 1);
+		__HAL_UART_ENABLE_IT(&USART_InitStruct_485, UART_IT_RXNE); // 使能接收中断	
+		__HAL_UART_ENABLE_IT(&USART_InitStruct_485, UART_IT_IDLE); // 使能空闲中断	
+	
+}
+
+void USART_485_IRQHandler(void){
+			GATEWAY_PARAMS *get;
+			get= get_gateway_config_params();
+			if(get->device_params->protocol == 3)
+			mmodbus_callback(&USART_InitStruct_485);
+			else if(get->device_params->protocol == 1 || get->device_params->protocol == 2)
+			dlt_callback(&USART_InitStruct_485);
+}
+
+
+void DEBUG_USART_Config(void)
+{
+	GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+  // Enable USART6 clock
+  __HAL_RCC_USART6_CLK_ENABLE();
+  // Enable GPIOC clock
+  __HAL_RCC_GPIOC_CLK_ENABLE();
+
+  // Configure USART6 pins
+	GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN | DEBUG_USART_TX_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+  GPIO_InitStruct.Alternate = GPIO_AF8_USART6;// Connect USART6 pins to AF8
+  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+	
+	// Configure USART6
+	USART_InitStruct_DEBUG.Instance = DEBUG_USART;
+	USART_InitStruct_DEBUG.Init.BaudRate = DEBUG_USART_BAUDRATE;
+	USART_InitStruct_DEBUG.Init.WordLength = UART_WORDLENGTH_8B;
+	USART_InitStruct_DEBUG.Init.StopBits = UART_STOPBITS_1;
+	USART_InitStruct_DEBUG.Init.Parity = UART_PARITY_NONE;
+	USART_InitStruct_DEBUG.Init.Mode = UART_MODE_TX_RX; // 既支持发送也支持接收
+	USART_InitStruct_DEBUG.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+	USART_InitStruct_DEBUG.Init.OverSampling = UART_OVERSAMPLING_16;
+	HAL_UART_Init(&USART_InitStruct_DEBUG);
+
+	HAL_NVIC_SetPriority(DEBUG_USART_IRQ, 2, 1);
+  HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ);
+	
+	// Enable USART6
+	__HAL_UART_ENABLE_IT(&USART_InitStruct_DEBUG, UART_IT_IDLE); // 使能空闲中断
+//	__HAL_UART_ENABLE_IT(&USART_InitStruct_DEBUG, UART_IT_RXNE); // 使能接收中断		
+	__HAL_DMA_ENABLE(&DMA_DEBUG_RX);						//使能DMA
+  __HAL_UART_ENABLE(&USART_InitStruct_DEBUG);
+//	__HAL_UART_CLEAR_FLAG(&USART_InitStruct_DEBUG, USART_FLAG_TC);
+	
+}
+
+
+void DEBUG_USART_IRQHandler(void)
+{	
+	uint16_t clear;
+	if(RESET != __HAL_UART_GET_FLAG(&USART_InitStruct_DEBUG, UART_FLAG_IDLE)) // 判断是否是空闲中断
+	{
+		__HAL_UART_CLEAR_IDLEFLAG(&USART_InitStruct_DEBUG); //清空空闲中断标志位
+		//关闭DMA
+		__HAL_DMA_DISABLE(&DMA_DEBUG_RX);
+//		HAL_UART_DMAStop(&USART_InitStruct_DEBUG); 
+		UART6_RX_NUM = BUFF_SIZE - __HAL_DMA_GET_COUNTER(&DMA_DEBUG_RX);
+		//清除DMA中断
+		__HAL_DMA_CLEAR_FLAG(&DMA_DEBUG_RX,DMA_FLAG_TCIF1_5);
+		__HAL_DMA_ENABLE(&DMA_DEBUG_RX);
+		//接收状态置位
+		UART6_RX_STAT=1;
+	}
+}
+
+void USART_DMA_Config(void)
+{
+	// 使能串口和DMA时钟
+	__HAL_RCC_USART6_CLK_ENABLE();
+	__HAL_RCC_DMA2_CLK_ENABLE();
+  
+	DMA_DEBUG_RX.Instance = DEBUG_USART_DMA_STREAM;
+	DMA_DEBUG_RX.Init.Channel = DEBUG_USART_DMA_CHANNEL;
+	/*方向:从外设到内存*/		
+	DMA_DEBUG_RX.Init.Direction =  DMA_PERIPH_TO_MEMORY;
+	/*外设地址不增*/	 
+	DMA_DEBUG_RX.Init.PeriphInc = DMA_PINC_DISABLE;
+	/*内存地址自增*/
+	DMA_DEBUG_RX.Init.MemInc = DMA_MINC_ENABLE;
+	 /*外设数据单位*/	
+	DMA_DEBUG_RX.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+	/*内存数据单位 8bit*/
+	DMA_DEBUG_RX.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;	
+	/*DMA模式:不断循环*/
+	DMA_DEBUG_RX.Init.Mode = DMA_NORMAL;
+	/*优先级:中*/	
+	DMA_DEBUG_RX.Init.Priority = DMA_PRIORITY_MEDIUM;
+	/*禁用FIFO*/
+	DMA_DEBUG_RX.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+	DMA_DEBUG_RX.Init.FIFOThreshold= DMA_FIFO_THRESHOLD_FULL;  
+	
+	 HAL_DMA_Init(&DMA_DEBUG_RX);
+	__HAL_LINKDMA(&USART_InitStruct_DEBUG, hdmarx, DMA_DEBUG_RX);	
+	
+	 SET_BIT(USART_InitStruct_DEBUG.Instance->CR3, USART_CR3_DMAR);
+	 HAL_DMA_Start(&DMA_DEBUG_RX,DEBUG_USART_DR_BASE, (uint32_t)UART6_RX_BUF, BUFF_SIZE);
+	__HAL_DMA_ENABLE_IT(&DMA_DEBUG_RX,DMA_IT_TC);
+	
+	HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 2, 2);
+  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
+}
+
+
+void DMA2_Stream1_IRQHandler() {
+    if (__HAL_DMA_GET_IT_SOURCE(&DMA_DEBUG_RX,DMA_IT_TC)) 
+		{
+        __HAL_DMA_CLEAR_FLAG(&DMA_DEBUG_RX,DMA_IT_TC);
+    }
+}
+ 
+
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *husart)
+{	
+		// USART 232
+    if(husart->Instance == USART_232)
+		{
+				if (rxIndex < RX_BUFFER_SIZE)
+        {
+            // 将接收到的数据存储在缓冲区中
+						rx_232_Buffer[rxIndex] = rxByte;
+						rxIndex++;
+        }							
+				HAL_UART_Transmit(husart, rx_232_Buffer,rxIndex,HAL_MAX_DELAY);			
+				memset(rx_232_Buffer, 0, rxIndex);
+				rxIndex = 0;
+				HAL_UART_Receive_IT(husart, &rxByte, 1);
+		}
+		
+		// USART 485
+		if(husart->Instance == USART_485)
+		{
+				if (rxIndex < RX_BUFFER_SIZE)
+        {
+            // 将接收到的数据存储在缓冲区中
+						rx_232_Buffer[rxIndex] = rxByte;
+						rxIndex++;
+        }							
+				memset(rx_232_Buffer, 0, rxIndex);
+				rxIndex = 0;
+				HAL_UART_Receive_IT(husart, &rxByte, 1);
+		}
+		if(husart->Instance == USART6)
+		{
+	
+		}
+
+}
+
+
+/*    上位机功能    */
+
+// 储存上位机发送的config数据,并返回上位机操作结果
+void save_config_232(uint8_t* buf)
+{
+		char* saveData = mymalloc(SRAMEX,20 * 1024);//(RECV_BUF_SIZE);// 存储config数据			最大20K,暂定3K
+		if(saveData == NULL) 
+			LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"recv buf malloc fail");
+		memset(saveData,0,strlen(saveData));	
+		// 插入tcp_config标志位,后续不通过http获取默认配置数据
+		sprintf(saveData, "tcp_config");
+		sprintf(saveData + strlen(saveData),"%s",buf);
+		
+		DeleteDirFile("device.txt");
+		write_file("device.txt",saveData,strlen(saveData));// 储存到flash 不用判断失败
+		myfree(SRAMEX, saveData);
+		
+		char* retMsg = mymalloc(SRAMEX,32);
+		memset(retMsg, 0, strlen(retMsg));
+		retMsg = "{\"write_config\":\"success\"}";
+		USART_232_Send((uint8_t*)retMsg, strlen(retMsg));
+		myfree(SRAMEX ,retMsg);
+}
+
+
+void read_device_params(char* device_params)
+{
+	GATEWAY_PARAMS *get;
+	get= get_gateway_config_params();
+	DEVICE_PARAMS *current_device=get->device_params;
+	sprintf(device_params, "{\"read_config\":\"success\",\"baudrate\":%d,\"checkBit\":%d,\"commandTopic\":\"%s\",\"dataBit\":%d,\
+\"deviceId\":\"%s\",\"host\":\"%s\",\"inboundTime\":%d,\"messageTopic\":\"%s\",\"port\":%d,\"stopBit\":%d,\"deviceList\":[",get->baudrate,
+			get->checkBit,get->commandTopic,get->dataBits,get->deviceId,get->host,get->inboundTime,get->messageTopic,get->port,get->stopBit);
+	while(current_device != NULL)
+	{	
+		sprintf(device_params + strlen(device_params),"{\"protocol\":%d,\"bigLittleFormat\":%d,\"deviceId\":\"%s\",\"sensorData\":[",
+												current_device->protocol,current_device->MDBbigLittleFormat,current_device->deviceID);
+			GATEWAY_READ_DLT645_COMMAND *read_dlt645_command = current_device->params->gateway_read_dlt645_command;
+			GATEWAY_READ_MODBUS_COMMAND *read_modbus_command = current_device->params->gateway_read_modbus_command;
+			GATEWAY_WRITE_MODBUS_COMMAND *write_modbus_command = current_device->params->gateway_write_modbus_command;
+			
+			// dlt645 read
+			while(read_dlt645_command != NULL)
+			{	
+				sprintf(device_params + strlen(device_params),"{\"identifier645\":%d,\"identifier\":\"%s\",\"deviceID645\":\"%s\"},",
+											read_dlt645_command->Identification,read_dlt645_command->keyword,read_dlt645_command->deviceID645);
+				read_dlt645_command = read_dlt645_command->nextParams;
+			}
+		
+			// modbus read
+			while(read_modbus_command != NULL)
+			{
+				sprintf(device_params + strlen(device_params),"{\"rFunctionCode\":%d,\"registerAddress\":%d,\"slaveAddress\":%d,\"registerByteNum\":%d,\"identifier\":\"%s\",\"precise\":%d},",
+																											read_modbus_command->functionCode, read_modbus_command->registerAddress,read_modbus_command->slaveAddress,
+																											read_modbus_command->registerByteNum,read_modbus_command->keyword,read_modbus_command->decimalPoint);
+				read_modbus_command = read_modbus_command->nextParams;
+			}
+			
+			// modbus write
+			sprintf(device_params + strlen(device_params)-1,"], \"commandData\":[");//sensorData:[ 
+			while(write_modbus_command != NULL)
+			{
+				sprintf(device_params + strlen(device_params),"{\"registerAddress\":%d,\"slaveAddress\":%d,\"wFunctionCode\":%d,\"registerByteNum\":%d},",
+								write_modbus_command->registerAddress,write_modbus_command->slaveAddress,write_modbus_command->functionCode,write_modbus_command->registerByteNum);
+				write_modbus_command = write_modbus_command->nextParams;
+			}		
+			sprintf(device_params + strlen(device_params)-1,"]},");// commandData:[
+			current_device = current_device->nextDevice;	
+	}
+	sprintf(device_params + strlen(device_params) -1 ,"]}");
+}
+void read_config_232(void)
+{
+	GATEWAY_PARAMS *get;
+	get= get_gateway_config_params();
+	char* device_params = mymalloc(SRAMEX, 3 * 1024);
+	memset(device_params,0,3 * 1024);
+	if(get->device_params == NULL)
+	{
+		sprintf(device_params, "{\"read_config\":\"error\"}");
+		USART_232_Send((uint8_t*)device_params, strlen(device_params));
+	}
+	else
+	{
+		read_device_params(device_params);
+		USART_232_Send((uint8_t*)device_params, strlen(device_params));
+	}
+	myfree(SRAMEX, device_params);
+}
+
+// 设备嗅探
+void find_device_232(void)
+{
+	char deviceId[50];// 发送设备名
+	GATEWAY_PARAMS *get;
+	get= get_gateway_config_params();
+	if(get->device_params == NULL)
+	{	
+//		sprintf(deviceId, "{\"find_device\":\"%s\"}", gatewayId);		
+		sprintf(deviceId, "{\"find_device\":\"error\"}");		
+		USART_232_Send((uint8_t*)deviceId, strlen(deviceId));
+	}
+	else
+	{
+		sprintf(deviceId, "{\"find_device\":\"%s\"}", get->deviceId);		
+		USART_232_Send((uint8_t*)deviceId, strlen(deviceId));
+	}
+	memset(deviceId, 0, 50);
+}
+
+
+// 储存上位机发送的config_add数据,并返回上位机操作结果
+void add_config_232(uint8_t* dataBuf)
+{	
+	GATEWAY_PARAMS *get;
+	get= get_gateway_config_params();
+	DEVICE_PARAMS *device=get->device_params;
+	char* retMsg = mymalloc(SRAMEX,32);
+	memset(retMsg, 0, strlen(retMsg));
+	while(device != NULL)// 一直轮询到当前为NULL
+	{
+		device = device->nextDevice;
+	}
+	addDevice((char*)dataBuf);
+	// 再检查更新后的deviceId是否为NULL
+	if(device == NULL)// error
+	{	
+		retMsg = "{\"write_config\":\"error\"}";
+		USART_232_Send((uint8_t*)retMsg, strlen(retMsg));
+	}
+	else// success
+	{
+		retMsg = "{\"write_config\":\"success\"}";
+		USART_232_Send((uint8_t*)retMsg, strlen(retMsg));
+	}
+		myfree(SRAMEX, retMsg);
+}
+
+
+// 切换工作模式
+void work_mode_232(uint8_t* buf)
+{
+	/* 用标志位开关data_task任务中,发送数据的方式 */
+		// 内置协议模式
+		if(strstr((char*)buf,"protocolsMode") != NULL)
+		{
+			ProtocolsModeFlag = 1;// 开启内置协议模式
+			TransparentModeFlag = 0; // 关闭透明传输模式
+			LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"ProtocolsMode");	
+		}
+		// 透明传输模式
+		if(strstr((char*)buf,"TransparentMode") != NULL)
+		{
+			ProtocolsModeFlag = 0;// 关闭内置协议模式
+			TransparentModeFlag = 1; // 开启透明传输模式
+			LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"TransparentModeFlag");	
+		}
+}
+
+// 更新OTA数据
+void updata_232(void)
+{
+	int recv_size, i;
+
+	uint16_t crc;	
+	uint8_t databuf[1024];// 保存包数据
+	
+	uint16_t packId = 0x01;
+	uint8_t stx = 0x02,eot = 0x04,ack = 0x06,nak = 0x15,C = 0x43;
+
+	// 向上位机发送就绪信号
+	char* retMsg = mymalloc(SRAMEX,32);
+	memset(retMsg, 0, strlen(retMsg));
+	retMsg = "{\"software_update\":\"ready\"}";
+	USART_232_Send((uint8_t*)retMsg,  strlen(retMsg));
+	myfree(SRAMEX, retMsg);
+	memset(rx_232_Buffer, 0, strlen(rx_232_Buffer));
+	delay_ms(300);
+	
+	// 发送第一个C
+	USART_232_Send(&C, 1);
+	delay_ms(300);
+__start:
+	i = 0;
+	//等待接收到消息,最长等待3S
+	while(recv_232_done == 0 && i < 3000) 
+	{
+		delay_ms(1);
+		i++;
+	}
+	if(recv_232_done == 0)	USART_232_Send(&C, 1);//如果还没接收到消息,再发送一个C
+	do{
+			// 接收到结束信号,反馈ack
+			if(rx_232_Buffer[0] == eot)
+			{
+				USART_232_Send(&ack, 1);
+				delay_ms(300);
+				break;
+			}
+			// 检测头标志
+			if(rx_232_Buffer[0] != stx)
+			{
+				USART_232_Send(&nak, 1);
+				delay_ms(300);
+				goto __start;
+			}
+			// 检测包序列
+			if(rx_232_Buffer[1] != packId)
+			{
+				USART_232_Send(&nak, 1);
+				delay_ms(300);
+				goto __start;
+			}
+			// 检测包号反码
+			if(rx_232_Buffer[2] !=(~packId & 0xff))
+			{
+				USART_232_Send(&nak, 1);
+				delay_ms(300);
+				goto __start;
+			}
+			// 提取数据包
+			for(int i = 0; i < 1024; i++)
+			{
+				databuf[i] = rx_232_Buffer[3 + i];
+			}
+			crc = Checkcrc16(databuf, 1024);
+			// 检测数据包的校验码
+			if (((crc & 0x00FF) != rx_232_Buffer[1028]) || (((crc & 0xFF00) >> 8) != rx_232_Buffer[1027]))
+			{	
+				USART_232_Send(&nak, 1);
+				delay_ms(300);
+				goto __start;
+			}
+			// 对数据包进行操作
+			/*                */
+			memset(databuf, 0, sizeof(databuf));
+			
+			// 准备接收下一包数据
+			USART_232_Send(&ack, 1);
+			delay_ms(300);
+			packId += 1;
+
+	}while(recv_232_done);
+
+		// 所有数据包接受完成,准备重启
+		__set_PRIMASK(1);
+		NVIC_SystemReset();
+}
+
+void USART_232_task(void const * argument)
+{
+	int j;
+	char* recv_cmd[] = {"\"cmd\":\"write_config\"","\"cmd\":\"write_config_add\"",
+											"\"cmd\":\"read_config\"","\"cmd\":\"find_device\"",
+											"\"cmd\":\"ip_config\"","\"cmd\":\"toggle_work_mode\"",
+											"\"cmd\":\"software_update\"","\"cmd\":\"reboot\"",
+											"\"cmd\":\"cmd error\""	};
+	while(1)
+	{
+		j = 0;
+		for(int i = 0; i < sizeof(recv_cmd)/sizeof(recv_cmd[0]); i++)
+		{
+			if(strstr((char*)rx_232_Buffer,recv_cmd[i]) != NULL)
+			{
+				i = sizeof(recv_cmd)/sizeof(recv_cmd[0]);
+			}
+			j++;
+		}
+		
+		if (ProtocolsModeFlag) {
+					switch (j) {
+						case WRITE_CONFIG:
+								save_config_232(rx_232_Buffer);
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "write config");
+								__set_PRIMASK(1);
+								NVIC_SystemReset();
+								break;
+						case WRITE_CONFIG_ADD:
+								add_config_232(rx_232_Buffer);
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "write config add");
+								break;
+						case READ_CONFIG:
+								read_config_232();
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "read config");
+								break;
+						case FIND_DEVICE:
+								find_device_232();
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "find device");
+								break;				
+						case TOGGLE_MODE:
+								work_mode_232(rx_232_Buffer);
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "toggle work mode");
+								break;
+						case UPDATE:
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "update");
+								updata_232();
+								break;
+						case REBOOT:
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "reboot");
+								__set_PRIMASK(1);
+								NVIC_SystemReset();
+								break;
+						case CMD_ERROR:
+								goto __exit;
+					}
+				} else {
+					switch (j) {
+						case FIND_DEVICE:
+								find_device_232();
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "find device");
+								break;
+						case TOGGLE_MODE:
+								work_mode_232(rx_232_Buffer);
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "toggle work mode");
+								break;
+						case UPDATE:
+								updata_232();
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "update");
+								break;
+						case REBOOT:
+								LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "reboot");
+								__set_PRIMASK(1);
+								NVIC_SystemReset();	
+								break;
+						case CMD_ERROR:
+								goto __exit;
+				}
+			}
+				memset(rx_232_Buffer, 0, strlen(rx_232_Buffer));
+			__exit:
+				vTaskDelay(500);
+		}
+}
+
+void USART_232_task_creat()
+{
+	osThreadDef(USART_task, USART_232_task, osPriorityNormal, 0, configMINIMAL_STACK_SIZE*4);
+  osThreadCreate(osThread(USART_task), NULL);
+}
+
+/*********************************************END OF FILE**********************/

BIN
app/MDKProject/Objects/dtu_lan_gateway.axf


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 364 - 164
app/MDKProject/dtu_lan_gateway.uvoptx


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 129 - 8
app/MDKProject/dtu_lan_gateway.uvprojx


+ 168 - 0
app/MODBUS/mmodbus.h

@@ -0,0 +1,168 @@
+#ifndef _M_MODBUS_H_
+#define _M_MODBUS_H_
+
+
+/*
+  Author:     Nima Askari
+  WebSite:    http://www.github.com/NimaLTD
+  Instagram:  http://instagram.com/github.NimaLTD
+  Youtube:    https://www.youtube.com/channel/UCUhY7qY1klJm1d2kulr9ckw
+  
+  Version:    1.3.2
+  
+  Reversion History:
+  
+  (1.3.2)
+  Speedup receiver, add write multiple holding
+    
+  (1.3.1)
+  Remove delay in sending function when DMA is disabled
+  
+  (1.3.0)
+  Add 16 bit order
+  
+  (1.2.1)
+  bug fixed.
+  
+  (1.2.0)
+  add read 32bit register order.
+  
+  (1.1.2)
+  fix read holding register.
+  
+  (1.1.1)
+  fix functions name.
+  
+  (1.1.0)
+  add 16bit,32bit,float read.
+  
+  (1.0.1)
+  add delay in receive routin.
+  
+  (1.0.0)
+  First release.
+*/ 
+
+#include "stm32f2xx.h"
+#include  "mmodbusConfig.h"
+//#include  "usart.h"
+#include  <stdbool.h>
+#include  <string.h>
+#include  <stdio.h>
+#include  <stdint.h>
+#include "FreeRTOS.h"
+#include "task.h"
+#define   mmodbus_delay(x) 	delay_ms(x) // vTaskDelay(x)
+
+
+
+/*
+功能码
+MModbusCMD_ReadCoilStatus(读线圈状态):用于读取一个或多个逻辑线圈的状态。
+MModbusCMD_ReadDiscreteInputs(读离散输入状态):用于读取一个或多个数字输入信号的状态。
+MModbusCMD_ReadHoldingRegisters(读保持寄存器):用于读取一个或多个保持寄存器的值。
+MModbusCMD_ReadInputRegisters(读输入寄存器):用于读取一个或多个输入寄存器的值。
+MModbusCMD_WriteSingleCoil(写单个线圈):用于控制单个逻辑线圈的状态。
+MModbusCMD_WriteSingleRegister(写单个保持寄存器):用于写入单个保持寄存器的值。
+MModbusCMD_WriteMultipleCoils(写多个线圈):用于控制多个逻辑线圈的状态。
+MModbusCMD_WriteMultipleRegisters(写多个保持寄存器):用于写入多个保持寄存器的值。
+*/
+typedef enum
+{
+  MModbusCMD_ReadCoilStatus = 1,
+  MModbusCMD_ReadDiscreteInputs = 2,
+  MModbusCMD_ReadHoldingRegisters = 3,
+  MModbusCMD_ReadInputRegisters = 4,
+  MModbusCMD_WriteSingleCoil = 5,
+  MModbusCMD_WriteSingleRegister = 6,
+  MModbusCMD_WriteMultipleCoils = 15,
+  MModbusCMD_WriteMultipleRegisters = 16
+  
+}MModbusCMD_t;
+
+//大小端
+typedef enum
+{
+  MModBus_16bitOrder_AB=1,
+  MModBus_16bitOrder_BA=2,
+  
+}MModBus_16bitOrder_t;
+
+typedef enum
+{
+  MModBus_32bitOrder_ABCD = 0,
+  MModBus_32bitOrder_DCBA,
+  MModBus_32bitOrder_BADC,
+  MModBus_32bitOrder_CDAB,  
+  
+}MModBus_32bitOrder_t;
+
+/*
+	rxIndex:接收缓冲区的当前接收位置。
+	rxBuf:接收缓冲区。
+	rxTime:最近一次接收数据的时间戳。
+	txBusy:发送是否忙碌的标志位。
+	timeout:超时时间。
+	byteOrder16:16 位数据的字节序(即高位字节在前还是低位字节在前)。
+	byteOrder32:32 位数据的字节序。
+	done:数据是否接收完成的标志位。
+	txDmaDone:DMA 发送是否完成的标志位(该成员只在使用 DMA 发送时有效)。
+*/
+typedef struct
+{
+  uint16_t              rxIndex;  
+  uint8_t               rxBuf[_MMODBUS_RXSIZE];
+  uint32_t              rxTime;
+  uint8_t               txBusy;
+  uint32_t              timeout; 
+  MModBus_16bitOrder_t  byteOrder16;
+  MModBus_32bitOrder_t  byteOrder32;
+	uint8_t								done;
+  #if (_MMODBUS_TXDMA == 1)
+  uint8_t             txDmaDone;
+  #endif  
+  
+}MModBus_t;
+
+extern MModBus_t mmodbus;
+//##################################################################################################
+
+void    mmodbus_callback(UART_HandleTypeDef *husart);
+//void 		mmodbus_callback(void);
+bool    mmodbus_sendRaw(uint8_t *data, uint16_t size, uint32_t timeout);
+uint16_t mmodbus_crc16(const uint8_t *nData, uint16_t wLength); 
+void    mmodbus_callback_txDMA(void);
+
+bool    mmodbus_init(uint32_t setTimeout);
+void    mmodbus_set16bitOrder(MModBus_16bitOrder_t MModBus_16bitOrder_);
+void    mmodbus_set32bitOrder(MModBus_32bitOrder_t MModBus_32bitOrder_);
+//  coils numbers 00001 to 09999
+bool    mmodbus_readCoil(uint8_t slaveAddress, uint16_t number, uint8_t *data);
+bool    mmodbus_readCoils(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data);
+//  discrete input 10001 to 19999
+bool    mmodbus_readDiscreteInput(uint8_t slaveAddress, uint16_t number, uint8_t *data);
+bool    mmodbus_readDiscreteInputs(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data);
+//  input register 30001 to 39999
+bool    mmodbus_readInputRegister32f(uint8_t slaveAddress, uint16_t number, float *data);
+bool    mmodbus_readInputRegisters32f(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, float *data);
+bool    mmodbus_readInputRegister32i(uint8_t slaveAddress, uint16_t number, uint32_t *data);
+bool    mmodbus_readInputRegisters32i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint32_t *data);
+bool    mmodbus_readInputRegister16i(uint8_t slaveAddress, uint16_t number, uint16_t *data);
+bool    mmodbus_readInputRegisters16i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint16_t *data);
+//  holding register 40001 to 49999
+bool    mmodbus_readHoldingRegister32f(uint8_t slaveAddress, uint16_t number, float *data);
+bool    mmodbus_readHoldingRegisters32f(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, float *data);
+bool    mmodbus_readHoldingRegister32i(uint8_t slaveAddress, uint16_t number, uint32_t *data);
+bool    mmodbus_readHoldingRegisters32i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint32_t *data);
+bool    mmodbus_readHoldingRegister16i(uint8_t slaveAddress, uint16_t number, uint16_t *data);
+bool    mmodbus_readHoldingRegisters16i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint16_t *data);
+// coils numbers 00001 to 09999
+bool    mmodbus_writeCoil(uint8_t slaveAddress, uint16_t number, uint8_t data);
+//  holding register 40001 to 49999
+bool    mmodbus_writeHoldingRegister16i(uint8_t slaveAddress, uint16_t number, uint16_t data);
+bool    mmodbus_writeHoldingRegisters16i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint16_t *data);
+uint16_t mmodbus_crc16(const uint8_t *nData, uint16_t wLength);
+
+//##################################################################################################
+bool mmodbus_readHoldingRegisters8i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data);
+#endif

+ 18 - 0
app/MODBUS/mmodbusConfig.h

@@ -0,0 +1,18 @@
+#ifndef _MMODBUS_CONFIG_H_
+#define _MMODBUS_CONFIG_H_
+
+#define _MMODBUS_FREERTOS         0
+#define _MMODBUS_RTU              1
+#define _MMODBUS_ASCII            0 //  not implemented yet
+#define _MMODBUS_USART            USART3            
+#define _MMODBUS_RXSIZE           64  
+#define _MMODBUS_TXDMA            0   
+
+#define _MMODBUS_CTRL_GPIO        USART_485_DE_GPIO_PORT
+#define _MMODBUS_CTRL_PIN         USART_485_DE_PIN
+#define gettick( )                           ( xTaskGetTickCount() )
+
+#if (_MMODBUS_RTU == 1) && (_MMODBUS_ASCII == 1)
+#error please select _MMODBUS_RTU or _MMODBUS_ASCII
+#endif
+#endif

+ 600 - 0
app/MODBUS/modbus.c

@@ -0,0 +1,600 @@
+
+#include "mmodbus.h"
+#include "usart.h"
+#include "timer.h"
+#include "log.h"
+#include "led.h"
+
+MModBus_t mmodbus;
+
+// #####################################################################################################
+#if (_MMODBUS_RTU == 1)
+static const uint16_t wCRCTable[] =
+    {
+        0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
+        0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
+        0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
+        0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
+        0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
+        0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
+        0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
+        0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
+        0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
+        0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
+        0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
+        0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
+        0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
+        0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
+        0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
+        0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
+        0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
+        0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
+        0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
+        0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
+        0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
+        0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
+        0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
+        0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
+        0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
+        0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
+        0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
+        0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
+        0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
+        0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
+        0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
+        0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040};
+// crc校验
+uint16_t mmodbus_crc16(const uint8_t *nData, uint16_t wLength)
+{
+  uint8_t nTemp;
+  uint16_t wCRCWord = 0xFFFF;
+  while (wLength--)
+  {
+    nTemp = *nData++ ^ wCRCWord;
+    wCRCWord >>= 8;
+    wCRCWord ^= wCRCTable[nTemp];
+  }
+  return wCRCWord;
+}
+
+
+
+#endif
+void mmodbus_callback(UART_HandleTypeDef *husart)
+{ 
+  if(__HAL_UART_GET_FLAG(husart, UART_FLAG_RXNE) && __HAL_UART_GET_IT_SOURCE(husart, UART_IT_RXNE))
+	{
+			if (mmodbus.rxIndex < _MMODBUS_RXSIZE - 1)
+			{
+				mmodbus.rxBuf[mmodbus.rxIndex] = husart->Instance->DR;
+				mmodbus.rxIndex++;
+			}
+			else
+			{
+				uint8_t data = husart->Instance->DR;
+			}
+	}
+	if ((mmodbus.rxIndex > 0) && RESET != __HAL_UART_GET_FLAG(husart, USART_FLAG_IDLE) && __HAL_UART_GET_IT_SOURCE(husart, UART_IT_IDLE))
+	{	
+		uint8_t i;	
+		mmodbus.done = 1;	
+		i = husart->Instance->SR;
+		i = husart->Instance->DR;		
+		return;
+	}
+  mmodbus.rxTime = gettick();
+}
+
+
+// ##################################################################################################
+uint16_t mmodbus_receiveRaw(uint32_t timeout)
+{
+  uint32_t startTime = gettick();
+  while (1)
+  {
+    if (gettick() - startTime> timeout * 1000)
+      return 0;
+    if (mmodbus.done == 1)
+    {
+      return mmodbus.rxIndex;
+    }
+    mmodbus_delay(5);
+  }
+}
+// ##################################################################################################
+bool mmodbus_sendRaw(uint8_t *data, uint16_t size, uint32_t timeout)
+	{
+	while(mmodbus.txBusy == 1)
+	mmodbus_delay(1);
+	mmodbus.txBusy = 1;
+	memset(mmodbus.rxBuf, 0, _MMODBUS_RXSIZE);
+	mmodbus.rxIndex = 0;
+	mmodbus.done = 0;
+	uint32_t startTime = gettick();
+	portENTER_CRITICAL();
+	USART_485_Send(data,size);
+	portEXIT_CRITICAL();
+	mmodbus.done=0;
+	mmodbus.txBusy = 0;
+
+	return true;
+}
+
+
+// ##################################################################################################
+bool mmodbus_init(uint32_t timeout)
+{
+  // HAL_GPIO_WritePin(_MMODBUS_CTRL_GPIO, _MMODBUS_CTRL_PIN, GPIO_PIN_RESET); 此处初始化在485 init过
+	HAL_GPIO_WritePin(_MMODBUS_CTRL_GPIO, _MMODBUS_CTRL_PIN,0);
+  memset(&mmodbus, 0, sizeof(mmodbus));
+  mmodbus.timeout = timeout;
+  return true;
+}
+// ##################################################################################################
+void mmodbus_set16bitOrder(MModBus_16bitOrder_t MModBus_16bitOrder_)
+{
+  mmodbus.byteOrder16 = MModBus_16bitOrder_;
+}
+// ##################################################################################################
+void mmodbus_set32bitOrder(MModBus_32bitOrder_t MModBus_32bitOrder_)
+{
+  mmodbus.byteOrder32 = MModBus_32bitOrder_;
+}
+// ##################################################################################################
+bool mmodbus_readCoil(uint8_t slaveAddress, uint16_t number, uint8_t *data)
+{
+  return mmodbus_readCoils(slaveAddress, number, 1, data);
+}
+// ##################################################################################################
+// 读线圈
+bool mmodbus_readCoils(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data)
+{
+#if (_MMODBUS_RTU == 1)
+  uint8_t txData[8];
+  txData[0] = slaveAddress;
+  txData[1] = MModbusCMD_ReadCoilStatus;
+  txData[2] = (startnumber & 0xFF00) >> 8;
+  txData[3] = (startnumber & 0x00FF);
+  txData[4] = (length & 0xFF00) >> 8;
+  txData[5] = (length & 0x00FF);
+  static uint16_t crc;
+  crc = mmodbus_crc16(txData, 6);
+  txData[6] = (crc & 0x00FF);
+  txData[7] = (crc & 0xFF00) >> 8;
+  mmodbus_sendRaw(txData, 8, 100);
+  uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
+  if (recLen == 0)
+    return false;
+  if (mmodbus.rxBuf[0] != slaveAddress)
+    return false;
+  if (mmodbus.rxBuf[1] != MModbusCMD_ReadCoilStatus)
+    return false;
+  crc = mmodbus_crc16(mmodbus.rxBuf, mmodbus.rxBuf[2] + 3);
+  if (((crc & 0x00FF) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 3]) || (((crc & 0xFF00) >> 8) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 4]))
+    return false;
+  if (data != NULL)
+    memcpy(data, &mmodbus.rxBuf[3], mmodbus.rxBuf[2]);
+  return true;
+#endif
+#if (_MMODBUS_ASCII == 1)
+
+#endif
+}
+// ##################################################################################################
+bool mmodbus_readDiscreteInput(uint8_t slaveAddress, uint16_t number, uint8_t *data)
+{
+  return mmodbus_readDiscreteInputs(slaveAddress, number, 1, data);
+}
+// ##################################################################################################
+// 读取线圈功能码处理
+bool mmodbus_readDiscreteInputs(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data)
+{
+#if (_MMODBUS_RTU == 1)
+  uint8_t txData[8];
+  txData[0] = slaveAddress;
+  txData[1] = MModbusCMD_ReadDiscreteInputs;
+  txData[2] = (startnumber & 0xFF00) >> 8;
+  txData[3] = (startnumber & 0x00FF);
+  txData[4] = (length & 0xFF00) >> 8;
+  txData[5] = (length & 0x00FF);
+  static uint16_t crc;
+  crc = mmodbus_crc16(txData, 6);
+  txData[6] = (crc & 0x00FF);
+  txData[7] = (crc & 0xFF00) >> 8;
+  mmodbus_sendRaw(txData, 8, 100);
+  uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
+  if (recLen == 0)
+    return false;
+  if (mmodbus.rxBuf[0] != slaveAddress)
+    return false;
+  if (mmodbus.rxBuf[1] != MModbusCMD_ReadDiscreteInputs)
+    return false;
+  crc = mmodbus_crc16(mmodbus.rxBuf, mmodbus.rxBuf[2] + 3);
+  if (((crc & 0x00FF) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 3]) || (((crc & 0xFF00) >> 8) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 4]))
+    return false;
+  if (data != NULL)
+    memcpy(data, &mmodbus.rxBuf[3], mmodbus.rxBuf[2]);
+  return true;
+#endif
+}
+// ##################################################################################################
+
+bool mmodbus_readInputRegisters8i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data)
+{
+#if (_MMODBUS_RTU == 1)
+  uint8_t txData[8];
+  txData[0] = slaveAddress;
+  txData[1] = MModbusCMD_ReadInputRegisters;
+  txData[2] = (startnumber & 0xFF00) >> 8;
+  txData[3] = (startnumber & 0x00FF);
+  txData[4] = (length & 0xFF00) >> 8;
+  txData[5] = (length & 0x00FF);
+  static uint16_t crc;
+  crc = mmodbus_crc16(txData, 6);
+  txData[6] = (crc & 0x00FF);
+  txData[7] = (crc & 0xFF00) >> 8;
+  mmodbus_sendRaw(txData, 8, 100);
+  uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
+  if (recLen == 0)
+    return false;
+  if (mmodbus.rxBuf[0] != slaveAddress)
+    return false;
+  if (mmodbus.rxBuf[1] != MModbusCMD_ReadInputRegisters)
+    return false;
+  crc = mmodbus_crc16(mmodbus.rxBuf, mmodbus.rxBuf[2] + 3);
+  if (((crc & 0x00FF) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 3]) || (((crc & 0xFF00) >> 8) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 4]))
+    return false;
+  if (data != NULL)
+    memcpy(data, &mmodbus.rxBuf[3], mmodbus.rxBuf[2]);
+  return true;
+#endif
+}
+// ##################################################################################################
+bool mmodbus_readInputRegister32f(uint8_t slaveAddress, uint16_t number, float *data)
+{
+  return mmodbus_readInputRegisters32f(slaveAddress, number, 1, data);
+}
+// ##################################################################################################
+bool mmodbus_readInputRegisters32f(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, float *data)
+{
+  bool ret = mmodbus_readInputRegisters8i(slaveAddress, startnumber, length * 2, (uint8_t *)data);
+  if (ret == true)
+  {
+    for (uint16_t i = 0; i < length; i++)
+    {
+      uint8_t tmp1[4], tmp2[4];
+      switch (mmodbus.byteOrder32)
+      {
+      case MModBus_32bitOrder_DCBA:
+        memcpy(tmp1, &data[i], 4);
+        tmp2[0] = tmp1[3];
+        tmp2[1] = tmp1[2];
+        tmp2[2] = tmp1[1];
+        tmp2[3] = tmp1[0];
+        memcpy(&data[i], tmp2, 4);
+        break;
+      case MModBus_32bitOrder_BADC:
+        memcpy(tmp1, &data[i], 4);
+        tmp2[0] = tmp1[1];
+        tmp2[1] = tmp1[0];
+        tmp2[2] = tmp1[3];
+        tmp2[3] = tmp1[2];
+        memcpy(&data[i], tmp2, 4);
+        break;
+      case MModBus_32bitOrder_CDAB:
+        memcpy(tmp1, &data[i], 4);
+        tmp2[0] = tmp1[2];
+        tmp2[1] = tmp1[3];
+        tmp2[2] = tmp1[0];
+        tmp2[3] = tmp1[1];
+        memcpy(&data[i], tmp2, 4);
+        break;
+      default:
+
+        break;
+      }
+    }
+    return true;
+  }
+  else
+    return false;
+}
+// ##################################################################################################
+bool mmodbus_readInputRegister32i(uint8_t slaveAddress, uint16_t number, uint32_t *data)
+{
+  return mmodbus_readInputRegisters32i(slaveAddress, number, 1, data);
+}
+// ##################################################################################################
+bool mmodbus_readInputRegisters32i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint32_t *data)
+{
+  return mmodbus_readInputRegisters32f(slaveAddress, startnumber, length, (float *)data);
+}
+// ##################################################################################################
+bool mmodbus_readInputRegister16i(uint8_t slaveAddress, uint16_t number, uint16_t *data)
+{
+  return mmodbus_readInputRegisters16i(slaveAddress, number, 1, data);
+}
+// ##################################################################################################
+bool mmodbus_readInputRegisters16i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint16_t *data)
+{
+  bool ret = mmodbus_readInputRegisters8i(slaveAddress, startnumber, length * 1, (uint8_t *)data);
+  if (ret == true)
+  {
+    uint8_t tmp1[2], tmp2[2];
+    for (uint16_t i = 0; i < length; i++)
+    {
+      switch (mmodbus.byteOrder16)
+      {
+      case MModBus_16bitOrder_AB:
+        memcpy(tmp1, &data[i], 2);
+        tmp2[0] = tmp1[0];
+        tmp2[1] = tmp1[1];
+        memcpy(&data[i], tmp2, 2);
+        break;
+      default:
+        memcpy(tmp1, &data[i], 2);
+        tmp2[0] = tmp1[1];
+        tmp2[1] = tmp1[0];
+        memcpy(&data[i], tmp2, 2);
+        break;
+      }
+    }
+    return true;
+  }
+  else
+    return false;
+}
+// ##################################################################################################
+bool mmodbus_readHoldingRegisters8i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data)
+{
+#if (_MMODBUS_RTU == 1)
+  uint8_t txData[8];
+  txData[0] = slaveAddress;
+  txData[1] = MModbusCMD_ReadHoldingRegisters;
+  txData[2] = (startnumber & 0xFF00) >> 8;
+  txData[3] = (startnumber & 0x00FF);
+  txData[4] = (length & 0xFF00) >> 8;
+  txData[5] = (length & 0x00FF);
+  static uint16_t crc;
+  crc = mmodbus_crc16(txData, 6);
+  txData[6] = (crc & 0x00FF);
+  txData[7] = (crc & 0xFF00) >> 8;
+  mmodbus_sendRaw(txData, 8, 100);
+  uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
+  if (recLen == 0)
+    return false;
+  if (mmodbus.rxBuf[0] != slaveAddress)
+    return false;
+  if (mmodbus.rxBuf[1] != MModbusCMD_ReadHoldingRegisters)
+    return false;
+  crc = mmodbus_crc16(mmodbus.rxBuf, mmodbus.rxBuf[2] + 3);
+  if (((crc & 0x00FF) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 3]) || (((crc & 0xFF00) >> 8) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 4]))
+    return false;
+  if (data != NULL)
+  {
+    for (uint8_t i = 0; i < mmodbus.rxBuf[2]; i += 2)
+    {
+      uint8_t H = mmodbus.rxBuf[i + 3];
+      mmodbus.rxBuf[i + 3] = mmodbus.rxBuf[i + 3 + 1];
+      mmodbus.rxBuf[i + 3 + 1] = H;
+    }
+    memcpy(data, &mmodbus.rxBuf[3], mmodbus.rxBuf[2]);
+  }
+  return true;
+#endif
+}
+// ##################################################################################################
+bool mmodbus_readHoldingRegister32f(uint8_t slaveAddress, uint16_t number, float *data)
+{
+  return mmodbus_readHoldingRegisters32f(slaveAddress, number, 1, data);
+}
+// ##################################################################################################
+bool mmodbus_readHoldingRegisters32f(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, float *data)
+{
+  bool ret = mmodbus_readHoldingRegisters8i(slaveAddress, startnumber, length * 2, (uint8_t *)data);
+  if (ret == true)
+  {
+    for (uint16_t i = 0; i < length; i++)
+    {
+      uint8_t tmp1[4], tmp2[4];
+      switch (mmodbus.byteOrder32)
+      {
+      case MModBus_32bitOrder_DCBA:
+        memcpy(tmp1, &data[i], 4);
+        tmp2[0] = tmp1[3];
+        tmp2[1] = tmp1[2];
+        tmp2[2] = tmp1[1];
+        tmp2[3] = tmp1[0];
+        memcpy(&data[i], tmp2, 4);
+        break;
+      case MModBus_32bitOrder_BADC:
+        memcpy(tmp1, &data[i], 4);
+        tmp2[0] = tmp1[1];
+        tmp2[1] = tmp1[0];
+        tmp2[2] = tmp1[3];
+        tmp2[3] = tmp1[2];
+        memcpy(&data[i], tmp2, 4);
+        break;
+      case MModBus_32bitOrder_CDAB:
+        memcpy(tmp1, &data[i], 4);
+        tmp2[0] = tmp1[2];
+        tmp2[1] = tmp1[3];
+        tmp2[2] = tmp1[0];
+        tmp2[3] = tmp1[1];
+        memcpy(&data[i], tmp2, 4);
+        break;
+      default:
+
+        break;
+      }
+    }
+    return true;
+  }
+  else
+    return false;
+}
+// ##################################################################################################
+bool mmodbus_readHoldingRegister32i(uint8_t slaveAddress, uint16_t number, uint32_t *data)
+{
+  return mmodbus_readHoldingRegisters32i(slaveAddress, number, 1, data);
+}
+// ##################################################################################################
+bool mmodbus_readHoldingRegisters32i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint32_t *data)
+{
+  return mmodbus_readHoldingRegisters32f(slaveAddress, startnumber, length, (float *)data);
+}
+// ##################################################################################################
+bool mmodbus_readHoldingRegister16i(uint8_t slaveAddress, uint16_t number, uint16_t *data)
+{
+  return mmodbus_readHoldingRegisters16i(slaveAddress, number, 1, data);
+}
+// ##################################################################################################
+bool mmodbus_readHoldingRegisters16i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint16_t *data)
+{
+  bool ret = mmodbus_readHoldingRegisters8i(slaveAddress, startnumber, length * 1, (uint8_t *)data);
+  if (ret == true)
+  {
+    uint8_t tmp1[2], tmp2[2];
+    for (uint16_t i = 0; i < length; i++)
+    {
+      switch (mmodbus.byteOrder16)
+      {
+      case MModBus_16bitOrder_AB:
+        memcpy(tmp1, &data[i], 2);
+        tmp2[0] = tmp1[0];
+        tmp2[1] = tmp1[1];
+        memcpy(&data[i], tmp2, 2);
+        break;
+      default:
+        memcpy(tmp1, &data[i], 2);
+        tmp2[0] = tmp1[1];
+        tmp2[1] = tmp1[0];
+        memcpy(&data[i], tmp2, 2);
+        break;
+      }
+    }
+    return true;
+  }
+  else
+    return false;
+}
+// ##################################################################################################
+bool mmodbus_writeCoil(uint8_t slaveAddress, uint16_t number, uint8_t data)
+{
+#if (_MMODBUS_RTU == 1)
+  uint8_t txData[8];
+  txData[0] = slaveAddress;
+  txData[1] = MModbusCMD_WriteSingleCoil;
+  txData[2] = (number & 0xFF00) >> 8;
+  txData[3] = (number & 0x00FF);
+  if (data == 0)
+    txData[4] = 0;
+  else
+    txData[4] = 0xFF;
+  txData[5] = 0;
+  static uint16_t crc;
+  crc = mmodbus_crc16(txData, 6);
+  txData[6] = (crc & 0x00FF);
+  txData[7] = (crc & 0xFF00) >> 8;
+  mmodbus_sendRaw(txData, 8, 100);
+  uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
+  if (recLen == 0)
+    return false;
+  if (memcmp(txData, mmodbus.rxBuf, 8) == 0)
+    return true;
+  else
+    return false;
+#endif
+#if (_MMODBUS_ASCII == 1)
+
+#endif
+}
+
+// ##################################################################################################
+bool mmodbus_writeHoldingRegister16i(uint8_t slaveAddress, uint16_t number, uint16_t data)
+{
+#if (_MMODBUS_RTU == 1)
+  uint8_t txData[8];
+  txData[0] = slaveAddress;
+  txData[1] = MModbusCMD_WriteSingleRegister;
+  txData[2] = (number & 0xFF00) >> 8;
+  txData[3] = (number & 0x00FF);
+  txData[4] = (data & 0xFF00) >> 8;
+  txData[5] = data & 0x00FF;
+  static uint16_t crc;
+  crc = mmodbus_crc16(txData, 6);
+  txData[6] = (crc & 0x00FF);
+  txData[7] = (crc & 0xFF00) >> 8;
+  mmodbus_sendRaw(txData, 8, 100);
+  uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
+  if (recLen == 0)
+    return false;
+  if (memcmp(txData, mmodbus.rxBuf, 8) == 0)
+    return true;
+  else
+    return false;
+#endif
+#if (_MMODBUS_ASCII == 1)
+
+#endif
+}
+// ##################################################################################################
+bool mmodbus_writeHoldingRegisters16i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint16_t *data)
+{
+#if (_MMODBUS_RTU == 1)
+  if (length == 1)
+  {
+    return mmodbus_writeHoldingRegister16i(slaveAddress, startnumber, data[0]);
+  }
+  else
+  {
+    uint8_t txData[7 + length * 2 + 2];
+    txData[0] = slaveAddress;
+    txData[1] = MModbusCMD_WriteMultipleRegisters;
+    txData[2] = (startnumber & 0xFF00) >> 8;
+    txData[3] = (startnumber & 0x00FF);
+    txData[4] = (length & 0xFF00) >> 8;
+    txData[5] = (length & 0x00FF);
+    txData[6] = (length * 2);
+    uint8_t tmp1[2], tmp2[2];
+    for (uint16_t i = 0; i < length; i++)
+    {
+      switch (mmodbus.byteOrder16)
+      {
+      case MModBus_16bitOrder_AB:
+        memcpy(tmp1, &data[i], 2);
+        tmp2[0] = tmp1[1];
+        tmp2[1] = tmp1[0];
+        memcpy(&txData[7 + i * 2], tmp2, 2);
+        break;
+      default:
+        memcpy(tmp1, &data[i], 2);
+        tmp2[0] = tmp1[0];
+        tmp2[1] = tmp1[1];
+        memcpy(&txData[7 + i * 2], tmp2, 2);
+        break;
+      }
+    }
+    static uint16_t crc;
+    crc = mmodbus_crc16(txData, 7 + length * 2);
+    txData[7 + length * 2 + 0] = (crc & 0x00FF);
+    txData[7 + length * 2 + 1] = (crc & 0xFF00) >> 8;
+    mmodbus_sendRaw(txData, 7 + length * 2 + 2, 100);
+    uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
+    if (recLen == 0)
+      return false;
+    crc = mmodbus_crc16(txData, 6);
+    txData[6] = (crc & 0x00FF);
+    txData[7] = (crc & 0xFF00) >> 8;
+    if (memcmp(txData, mmodbus.rxBuf, 8) == 0)
+      return true;
+    else
+      return false;
+  }
+#endif
+#if (_MMODBUS_ASCII == 1)
+
+#endif
+}
+// ##################################################################################################
+

+ 0 - 0
app/MODBUS/modbus.h


+ 1 - 1
app/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c

@@ -61,7 +61,7 @@ task.h is included from an application file. */
 	heap - probably so it can be placed in a special segment or address. */
 	extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
 #else
-	static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__((at(0x68000000)));			//ʹÓÃÍⲿSRAM
+	static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; //__attribute__((at(0x68000000)));			//ʹÓÃÍⲿSRAM
 #endif /* configAPPLICATION_ALLOCATED_HEAP */
 
 /* Define the linked list structure.  This is used to link free blocks in order

+ 1 - 0
app/Middlewares/Third_Party/mqttclient/mqttclient/mqttclient.c

@@ -1219,6 +1219,7 @@ mqtt_client_t *mqtt_lease(void)
     mqtt_client_t* c;
 
     c = (mqtt_client_t *)platform_memory_alloc(sizeof(mqtt_client_t));
+//		c = (mqtt_client_t *)mymalloc(SRAMEX, sizeof(mqtt_client_t));
     if (NULL == c)
         return NULL;
 

+ 41 - 0
app/SYSTEM/include/data_task.h

@@ -0,0 +1,41 @@
+#ifndef __TASK_H
+#define	__TASK_H
+#include "stm32f2xx.h"
+#include "gateway_message.h"
+#include "mqttclient.h"
+#include "FreeRTOS.h"
+#include "task.h"
+
+
+uint32_t my_pow(int x,int y);
+
+//主要的数据处理线程
+#define DATA_TASK_PRIO    3 
+#define DATA_STK_SIZE  2*1024
+
+#define GetCurrentTime()  xTaskGetTickCount()
+
+extern void data_task(void const * argument);
+
+
+/* 写入modbus寄存器 */
+void write_modbus_data(char* cJSONstring);
+/* 发送至mqtt */
+void send_mqtt(char*buf);
+/* 读取设备数据 */
+int read_device_data(DEVICE_PARAMS *current_device,char* string);
+///* 读取设备数据 */
+//int read_device_data1(DEVICE_PARAMS *current_device,char* buf);
+//int read_device_data2(DEVICE_PARAMS *current_device,char* buf);
+
+typedef struct __JSON_CMD{
+	uint8_t deviceId[25];
+	uint8_t identifier[20];
+	uint8_t messageId[20];
+	uint8_t parameter;
+	uint8_t action[1];
+	
+}JSON_CMD;
+
+
+#endif

+ 123 - 0
app/SYSTEM/include/gateway_message.h

@@ -0,0 +1,123 @@
+#ifndef __GATEWAY_MESSAGE_H
+#define __GATEWAY_MESSAGE_H
+
+#include "stm32f2xx.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include "malloc.h"
+
+// 解析发过来的数据是modbus还是dlt645 
+#define	MODBUS_WRITE 4                //本机用于区分读写
+#define	MODBUS_READ 3
+#define	DLT645_07 1
+#define	DLT645_97 2
+extern uint8_t protocol_485;
+
+
+#define	MODBUS 3
+
+// 网关所存储的modbus写命令
+typedef struct _GATEWAY_WRITE_MODBUS_COMMAND
+{
+	uint16_t registerByteNum;
+	uint8_t slaveAddress;
+	uint8_t functionCode;
+	uint8_t dataType;          //数据类型
+	uint8_t keyword[20]; // 所写属性的名称
+	uint8_t bigLittleFormat;
+	uint16_t registerAddress;	// 寄存器地址
+	uint8_t write_command_flag; // 是否成功写入的标志
+	struct _GATEWAY_WRITE_MODBUS_COMMAND *nextParams;
+} GATEWAY_WRITE_MODBUS_COMMAND;
+
+// 网关所存储的modbus读命令
+typedef struct _GATEWAY_READ_MODBUS_COMMAND
+{
+	uint8_t slaveAddress;
+	uint8_t functionCode;
+	uint8_t keyword[20]; // 所读属性的名称
+	uint16_t registerAddress;  // 寄存器地址
+	uint8_t read_command_flag; // 是否成功读取到的标志
+	uint32_t value;          //读取到的数据值
+	uint16_t registerByteNum;
+	uint8_t decimalPoint;
+	struct _GATEWAY_READ_MODBUS_COMMAND *nextParams;
+} GATEWAY_READ_MODBUS_COMMAND;
+
+
+// 节点所存储都DLT645读指令
+typedef struct _GATEWAY_READ_DLT645_COMMAND
+{
+	uint8_t deviceID645[6];
+	uint8_t keyword[20];   // 所读属性的名称
+	uint32_t Identification; // 645数据标识
+	uint8_t data[9];	   // 读到的数据
+	uint8_t rxLen;		   // 从机应答值的长度
+	struct _GATEWAY_READ_DLT645_COMMAND *nextParams;
+} GATEWAY_READ_DLT645_COMMAND;
+
+typedef struct _PARAMS_PROTOCOL_COMMAND
+{
+	GATEWAY_READ_MODBUS_COMMAND   *gateway_read_modbus_command;
+	GATEWAY_WRITE_MODBUS_COMMAND  *gateway_write_modbus_command;
+	GATEWAY_READ_DLT645_COMMAND   *gateway_read_dlt645_command;
+}PARAMS_PROTOCOL_COMMAND;
+
+
+// 节点包含的设备信息
+typedef struct _DEVICE_PARAMS
+{
+	uint8_t aliveflag; // 存活证明(由轮询来进行保证,当有轮询回应是确定其存活,当链路变化时立即上报设备已经死去,当轮询有相应的相应值时去上报已经存活)
+	uint8_t deviceID[20];
+	uint8_t protocol;  // 所属协议类型   1:modbus read 2:modbus write 3:dlt97  4:dlt07    一个设备只能存在一个协议	
+	uint8_t MDBbigLittleFormat;
+	uint8_t MDBdataType;	
+	PARAMS_PROTOCOL_COMMAND	*params;
+	struct _DEVICE_PARAMS *nextDevice; // 指向下一个设备地址
+} DEVICE_PARAMS;
+
+
+// 网关包含的设备信息
+typedef struct _GATEWAY_PARAMS
+{
+	uint8_t data_valid_flag;  // 数据有效标志  0xF1:有效  其它:无效
+	uint8_t host[20];		  // MQTT服务器地址
+	uint16_t port;			  // MQTT服务器端口号
+	uint8_t messageTopic[50]; // MQTT消息主题
+	uint8_t commandTopic[50]; // MQTT指令主题
+	uint8_t username[20];			//MQTT用户名
+	uint8_t passwd[20];				// MQTT用户密码
+	uint8_t deviceId[25];	  // 设备ID
+	uint8_t dataSource;		  // 协议类型                 0 保留 1 表示645协议 2表示modbus协议
+	uint8_t dataType645;	  // 645协议数据类型          0 保留 1 表示07版本  2表示97版本
+	uint32_t pollTime;		  // 轮询时间
+	uint32_t inboundTime;
+	uint8_t state;			 // 检测是否上位机配置过当上位机配置过该状态位,则以后均不走http获取相应配置 置位值为0xF1
+	uint8_t gatewayId[10];	 // 固化信息
+	uint8_t gatewayMode[10]; // 工作模式、后续版本迭代使用
+		uint8_t gateName[10];		// 网关相关信息
+
+	// 包含的设备结构体
+	uint8_t deviceCount;
+	DEVICE_PARAMS *device_params;
+		// 外设的串口工作属性仅只有一个
+	uint32_t baudrate;	 // 波特率
+	uint8_t dataBits;	 // 数据位
+	uint8_t checkBit;	 // 校验位
+	uint8_t stopBit;	 // 停止位
+	uint8_t flowControl; // 流控制
+	uint8_t parity;				//校验位
+	uint8_t bandwidth;	
+} GATEWAY_PARAMS;
+
+void addGatewayParams(char *gatewayString);
+void addDevice(char *string);
+
+int parseIntField(const char *data, const char *field);
+void parseStringField(const char *data, const char *field, char *value);
+
+GATEWAY_PARAMS *get_gateway_config_params(void);
+int extract_substring(const char *input_string, const char *start_token, const char *end_token, char *result);
+
+
+#endif

+ 23 - 0
app/SYSTEM/include/http_client.h

@@ -0,0 +1,23 @@
+#ifndef HTTP_CLIENT_H
+#define HTTP_CLIENT_H
+
+#define HTTP_PRINTF printf 
+
+#include "stdint.h"
+
+
+int http_clientConnectToServer(char *host, int port, int hostIsIp);
+void http_clientClose(int sock);
+
+int http_clientPacketRequest_GET(int sock, char *host, char *url);
+int http_clientReadResponse_GET(int sock, uint8_t *pbuf, int *datlen);
+int http_clientGet(char *host, char *url, uint16_t port, uint8_t hostIsIp,uint8_t *pbuf, int *datalen);
+
+int http_clientPacketRequest_POST(int sock, char *host, char *url, int datalen);
+int http_clientPacketBody_POST(int sock, uint8_t *pbuf, int datalen);
+int http_clientReadResponse_POST(int sock, uint8_t *pbuf, int *datlen);
+int http_clientPost(char *host, char *url, uint16_t port, uint8_t hostIsIp, uint8_t *postbuf, int postlen, uint8_t *rtnbuf, int *rtnlen);
+
+#endif 
+
+

+ 1 - 1
app/SYSTEM/include/log.h

@@ -24,7 +24,7 @@ typedef enum LOG_LEVEL_U
 }logLevel_t;
 
  void LogPrint(logLevel_t logLevel,const char *file, const char *func, const int line, char * fmt, ...);
-void log_init();
+void log_init(void);
 int get_udp_sem(void);
 #define LOG_PRINT(logLevel, fmt, ...)  if(DEBUG_ON){LogPrint(logLevel,__FILE__,__FUNCTION__, __LINE__, fmt, ##__VA_ARGS__);}
 #endif /* INC_LOG_H_ */

+ 34 - 0
app/SYSTEM/include/lte.h

@@ -0,0 +1,34 @@
+#ifndef  __LTE_H
+#define  __LTE_H
+
+#include "usart.h"
+#include "string.h"
+#include "sys_mqtt.h"
+#include "LTE_MQTT.h"
+
+#include "stdint.h"
+#include "timer.h"
+#include "gateway_message.h"
+#if 0
+#include <ucos_ii.h>
+#define LTE_Delay(x)				OSTimeDly(x);
+#else
+#define LTE_Delay(x)				delay_ms(x)
+#endif
+
+#define SUCCESS  0
+#define ERROR  	 1
+#define TIMEOUT  2
+extern int socket;
+extern uint8_t config_flag;
+
+void EC800M_open(void);
+int LTE_HTTP_get(void); 
+void ec800_init(void);
+void ec800_TCP(void);
+void http_set_url(char *url);
+int Iot_SendCmd(char* cmd, char* reply, int wait);
+
+void EC800M_task(void);
+
+#endif

+ 40 - 0
app/SYSTEM/include/lte_mqtt.h

@@ -0,0 +1,40 @@
+#ifndef __LTE_MQTT_H
+#define __LTE_MQTT_H
+
+#include "sys_mqtt.h"
+#include "malloc.h"
+
+#define  MQTT_SENDBUF_LENGTH   10 * 1024
+#define  MQTT_RECVBUF_LENTH  	 512
+
+#define client_recv_idx  1 // MQTT 客户端标识符 0~5
+#define client_send_idx  0 // MQTT 客户端标识符 0~5
+#define keepalive   60 // 保活时间   范围:0~3600;默认值:120;单位:秒
+#define MQTT_3  3   // version 3.1
+#define MQTT_4  4   // version 3.1.1
+			  
+#define clientid1  "LTE_TEST_SEND"
+#define username1  "LTE"
+#define password1  "1234"
+
+#define clientid2  "LTE_TEST_RECV"
+#define username1  "LTE"
+#define password1  "1234"
+#define recv_id    1 //表示每条接收数据的序号。范围:0~4
+
+#define NETSUCCESS 0
+#define NETERR -1				//打开网络失败
+#define PARAMERR 1			//参数错误
+#define IDFERR 2				//MQTT 标识符被占用
+#define PDPERR 3				//激活 PDP 失败
+#define DNSERR 4				//域名解析失败
+#define DISCONERR 5  		//网络断开导致错误
+
+typedef struct _PAYLOAD_config
+{
+	int stringLength;
+	char* p;
+}PAYLOAD_config;
+
+void MQ_threadCreate(void);
+#endif

+ 1 - 0
app/SYSTEM/include/myFile.h

@@ -11,4 +11,5 @@ void write_file(const char* filename, const char* data, uint32_t length);
 void read_file(const char* filename, char* data);
 void ViewRootDir(void);
 void DeleteDirFile(const char* filename);
+
 #endif

+ 10 - 0
app/SYSTEM/include/sys_http.h

@@ -0,0 +1,10 @@
+#ifndef SYS_HTTP_H
+#define SYS_HTTP_H
+#include <stdint.h>
+extern uint8_t load_http_config;
+void http_getDemo(void);
+
+void http_postDemo(void);
+#endif 
+
+

+ 17 - 0
app/SYSTEM/include/sys_mqtt.h

@@ -0,0 +1,17 @@
+#ifndef SYS_MQTT_H
+#define SYS_MQTT_H
+#include <stdint.h>
+#include "mqttclient.h"
+
+extern int mqtt_connectFlag;
+extern	QueueHandle_t xQueue1;
+struct Pub_Queue
+{
+	uint16_t pubLength;
+	mqtt_qos_t qos;
+	char *pub_topic;
+	char *message;
+};
+void mqtt_task_creat(void);
+void mqtt_publish_data(char *payload,mqtt_qos_t qos,uint16_t pub_length,char *topic);
+#endif

+ 20 - 0
app/SYSTEM/include/sys_udp.h

@@ -0,0 +1,20 @@
+/*!
+    \file  udp_echo.h
+    \brief the header file of udp_echo 
+*/
+
+/*
+    Copyright (C) 2017 GigaDevice
+
+    2017-07-28, V1.0.0, demo for GD32F30x
+*/
+
+#ifndef UDP_ECHO_H
+#define UDP_ECHO_H
+
+/* function declarations */
+/* initialize the tcp_client application */
+int udp_log_start(void);
+void udp_log_close(void);
+int udp_send_printf(char *p);
+#endif /* UDP_ECHO_H */

+ 50 - 0
app/SYSTEM/include/tcp_server.h

@@ -0,0 +1,50 @@
+#ifndef TCP_SERVER_H
+#define TCP_SERVER_H
+
+#include "stdint.h"
+
+#define RECV_BUF_SIZE			1460
+
+#define WRITE_CONFIG	1
+#define WRITE_CONFIG_ADD	2
+#define READ_CONFIG	3
+#define FIND_DEVICE	4
+#define IP_CONFIG	5
+#define TOGGLE_MODE	6
+#define UPDATE	7
+#define REBOOT	8
+#define CMD_ERROR		9
+
+extern uint8_t tcp_config;
+extern uint8_t ProtocolsModeFlag;
+extern uint8_t TransparentModeFlag;
+void tcp_server_init(void);
+
+// 储存上位机下发的ip_config数据
+typedef struct _ip_config
+{
+		uint8_t host[20];	
+		uint8_t subnetMask[20];
+    uint8_t defaultGateway[20];	
+		uint16_t udpLogPort;  
+}ip_config;
+ip_config *get_ip_config(void);
+
+
+//// 储存上位机发送的config数据,并返回上位机操作结果
+//void save_config(int client_socket,char* dataBuf);
+
+//// 储存上位机发送的config_add数据,并返回上位机操作结果
+//void add_config(int client_socket, char* dataBuf);
+
+//// 发送设备当前的config数据
+//void send_config(int client_socket);
+
+//// 解析设备当前的硬件信息(结构体内的数据)
+//void get_device_params(char* device_params);
+
+//// 切换工作模式
+//void work_mode(char* buf);
+
+
+#endif

+ 11 - 0
app/SYSTEM/include/updata.h

@@ -0,0 +1,11 @@
+#ifndef UPDATA_H
+#define UPDATA_H
+#include "stdint.h"
+#include "gateway_message.h"
+
+void updata_task_creat(int client_socket);
+void updata_task(void const * argument);
+
+
+uint16_t Checkcrc16(const uint8_t *nData, uint16_t wLength);
+#endif

+ 495 - 0
app/SYSTEM/source/data_task.c

@@ -0,0 +1,495 @@
+#include "data_task.h"
+#include "usart.h"
+#include "sys_mqtt.h"
+#include "sys_http.h"
+#include "mmodbus.h"
+#include "gateway_message.h"
+#include "dlt645_port.h"
+#include "myFile.h"
+#include "timer.h"
+#include "led.h"
+#include "tcp_server.h"
+#include "log.h"
+#include "app_ethernet.h"
+
+void protocolsModeFunc(GATEWAY_PARAMS* current_device, char* string);
+void transparentModeFunc(DEVICE_PARAMS* current_device);
+//recv_state:读写标志位 	0:失败 		 1:成功
+//mode:读取数据的方式 	  0:全部数据 1:不同数据
+//def:检测mode = 1,string是否含有数据		
+//startFlag:读数据启动位
+uint8_t recv_state = 0, mode = 0, def = 0, startFlag = 0;
+int time1,time2;
+void data_task(void const * argument)
+{			
+		dlt645_init(10);	// 若读不到数据,则延时 参数 秒
+		mmodbus_init(10);// 若读不到数据,则延时 参数 秒
+	
+		GATEWAY_PARAMS *get;
+		
+		char *device_config_json = mymalloc(SRAMEX, 20 * 1024);
+		if(device_config_json == NULL)	
+			LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"device_config_json malloc fail");
+		memset(device_config_json,0,strlen(device_config_json));
+		read_file("device.txt", device_config_json);
+		addGatewayParams(device_config_json);
+		myfree(SRAMEX,device_config_json);
+
+	
+		get= get_gateway_config_params();
+		LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"device params not empty");
+		DEVICE_PARAMS *current_device=get->device_params;
+		
+		char *string = mymalloc(SRAMEX, 5 * 1024);	// 接收读取数据
+		if(string == NULL)
+			LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"string malloc fail");	
+		memset(string,0,strlen(string));
+		while (current_device!=NULL)
+		{
+			
+			if(ProtocolsModeFlag)
+			{		
+				protocolsModeFunc(get,string);	
+			}
+			else if(TransparentModeFlag)
+			{
+				transparentModeFunc(current_device);
+			}
+			current_device=get->device_params;	
+			HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_RESET);
+			vTaskDelay(500);
+		}	
+		vPortFree(string);
+		LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"data_task return");
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: int compareArrays(uint8_t arr1[], uint8_t arr2[], int size)
+*	功能说明: 比较两个数组是否相同
+*	形    参: arr1[] 数组1,arr2[] 数组2,size 比较数组的大小
+*	返 回 值: 1: 相同 0:不相同
+*********************************************************************************************************
+*/
+int compareArrays(uint8_t arr1[], uint8_t arr2[], int size) {
+    for (int i = 0; i < size; ++i) {
+        if (arr1[i] != arr2[i]) {
+            return 1; // 两个数组不相同,返回0
+        }
+    }   
+    return 0; // 两个数组相同,返回1
+}
+/*
+*********************************************************************************************************
+*	函 数 名: int READ_MODBUS_DATA(DEVICE_PARAMS *device)
+*	功能说明: 读取当前节点上的modbus数据
+*	形    参: DEVICE_PARAMS *device  当前设备
+*	返 回 值: 1: 成功 0:失败
+*********************************************************************************************************
+*/
+int read_device_data(DEVICE_PARAMS *device, char* string)
+{
+		DEVICE_PARAMS *current_device=device;	
+		GATEWAY_READ_MODBUS_COMMAND *currentModbusParams = current_device->params->gateway_read_modbus_command;
+		GATEWAY_READ_DLT645_COMMAND *currentDLT645Params = current_device->params->gateway_read_dlt645_command;	
+		while(current_device->params != NULL)
+		{	
+				if (current_device->protocol == MODBUS_READ)
+				{
+						uint16_t *data = mymalloc(SRAMEX,currentModbusParams->registerByteNum /2); // modbus寄存器长度					
+						mmodbus_set16bitOrder(current_device->MDBbigLittleFormat);
+						// 读单个寄存器
+						if (currentModbusParams->functionCode == 0x03)
+						{
+//  							bool success = mmodbus_readHoldingRegisters16i(0x17,0x00,0x02,data);
+								bool success = mmodbus_readHoldingRegisters16i(currentModbusParams->slaveAddress,
+																															 currentModbusParams->registerAddress,
+																															 currentModbusParams->registerByteNum /2,
+																															 data);
+								if (success)
+								{
+										uint32_t value;
+										if (currentModbusParams->registerByteNum == 4)
+										{
+												value = (uint32_t)data[0] | data[1];
+										}
+										else if (currentModbusParams->registerByteNum == 2)
+										{
+												value = data[0];
+										}
+										
+										if(mode == 0)// all
+										{
+											sprintf(string + strlen(string), "{\"deviceId\":\"%s\",\"%s\":%d},", 
+																									current_device->deviceID, currentModbusParams->keyword, value);
+										}
+										else if(mode == 1)// def
+										{
+											if((value - currentModbusParams->value) != 0)
+											{																
+													sprintf(string + strlen(string), "{\"deviceId\":\"%s\",\"%s\":%d},", 
+																										current_device->deviceID, currentModbusParams->keyword, value);
+													def = 1;
+											}
+										}
+										
+										if (currentModbusParams->decimalPoint == 0)
+										{
+												currentModbusParams->value = value;
+										}
+										else
+										{ 	
+												currentModbusParams->value = value / my_pow(10,currentModbusParams->decimalPoint);
+										}
+																	
+								}					
+								currentModbusParams = currentModbusParams->nextParams;
+								if (currentModbusParams == NULL)	
+								{
+										current_device = current_device->nextDevice;
+										currentModbusParams = current_device->params->gateway_read_modbus_command;
+										if(current_device == NULL)
+										{
+												sprintf(string + strlen(string) - 1, ""); 
+												return 1;
+										}
+								}												
+						}
+				}
+				else if (current_device->protocol == DLT645_2007 || current_device->protocol == DLT645_97)
+				{
+						uint8_t read_buf[10];
+						uint32_t dltValue;
+						
+						currentDLT645Params->rxLen = 0;
+						memset(read_buf, 0, 10);
+						memset(currentDLT645Params->data, 0, 10);
+
+						dlt645_set_addr(&dlt645, currentDLT645Params->deviceID645);
+						int8_t rs;
+						if (current_device->protocol == DLT645_2007)
+						{
+								rs = dlt645_read_data(&dlt645, currentDLT645Params->Identification, read_buf, DLT645_2007);
+						}
+						else if (current_device->protocol == DLT645_1997)
+						{
+								rs = dlt645_read_data(&dlt645, currentDLT645Params->Identification, read_buf, DLT645_1997);
+						}
+						if (rs != -1)
+						{
+							if(mode == 0)// all
+								{
+										if (rs <= 4)
+										{
+												memcpy(currentDLT645Params->data, read_buf, 4);
+												currentDLT645Params->rxLen = 4;
+										}
+										else if (rs == 5)
+										{
+												memcpy(currentDLT645Params->data, read_buf, 5);
+												currentDLT645Params->rxLen = 5;
+										}
+										else if (rs > 5)
+										{
+												memcpy(currentDLT645Params->data, read_buf, 9);
+												currentDLT645Params->rxLen = 9;
+										}
+										dltValue = currentDLT645Params->data[0] << 24 | currentDLT645Params->data[1] << 16|
+																				currentDLT645Params->data[2] << 8  | currentDLT645Params->data[3];
+										
+										sprintf(string + strlen(string), "{\"identifier\":\"%s\",\"deviceID645\":\"%02x%02x%02x%02x%02x%02x\",\"identifier645\":%d,\"value\":%X}",
+																										currentDLT645Params->keyword, currentDLT645Params->deviceID645[0],
+																										currentDLT645Params->deviceID645[1],currentDLT645Params->deviceID645[2],
+																										currentDLT645Params->deviceID645[3],currentDLT645Params->deviceID645[4],
+																										currentDLT645Params->deviceID645[5],currentDLT645Params->Identification,dltValue);
+								}
+								else if(mode == 1)//def
+								{
+									if(compareArrays(read_buf,currentDLT645Params->data,10))// 不相同1,相同0
+									{
+										if (rs <= 4)
+										{
+												memcpy(currentDLT645Params->data, read_buf, 4);
+												currentDLT645Params->rxLen = 4;
+										}
+										else if (rs == 5)
+										{
+												memcpy(currentDLT645Params->data, read_buf, 5);
+												currentDLT645Params->rxLen = 5;
+										}
+										else if (rs > 5)
+										{
+												memcpy(currentDLT645Params->data, read_buf, 9);
+												currentDLT645Params->rxLen = 9;
+										}
+										dltValue = currentDLT645Params->data[0] << 24 | currentDLT645Params->data[1] << 16|
+																				currentDLT645Params->data[2] << 8  | currentDLT645Params->data[3];
+										
+										sprintf(string + strlen(string), "{\"identifier\":\"%s\",\"deviceID645\":\"%02x%02x%02x%02x%02x%02x\",\"identifier645\":%d,\"value\":%X}",
+																								currentDLT645Params->keyword, currentDLT645Params->deviceID645[0],
+																								currentDLT645Params->deviceID645[1],currentDLT645Params->deviceID645[2],
+																								currentDLT645Params->deviceID645[3],currentDLT645Params->deviceID645[4],
+																								currentDLT645Params->deviceID645[5],currentDLT645Params->Identification,dltValue);
+										def = 1;
+									}
+							}
+						}
+		
+								currentDLT645Params = currentDLT645Params->nextParams;		
+								if (currentDLT645Params == NULL)	
+								{
+										current_device = current_device->nextDevice;
+										currentDLT645Params = current_device->params->gateway_read_dlt645_command;
+										if(current_device == NULL)
+										{
+												sprintf(string + strlen(string) - 1, ""); 
+												return 1;
+										}
+								}										
+				}
+			}	
+		return 1;
+	
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名:void WRITE_MODBUS_DATA(char* cJSONstring)
+*	功能说明: 接收mqtt数据并写入modbus寄存器
+*	形    参:char* cJSONstring mqtt接收到的数据
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void write_modbus_data(char* JSON_STRING)
+{	
+		JSON_CMD jsonMsg;
+		GATEWAY_PARAMS* get;
+		get = get_gateway_config_params();
+		DEVICE_PARAMS* current_device = get->device_params;
+
+		jsonMsg.parameter =parseIntField(JSON_STRING, "\"parameter\":");
+		parseStringField(JSON_STRING, "\"deviceId\":\"", (char*)&jsonMsg.deviceId);
+		parseStringField(JSON_STRING, "\"identifier\":\"", (char*)&jsonMsg.identifier);
+		parseStringField(JSON_STRING, "\"messageId\":\"", (char*)&jsonMsg.messageId);
+		parseStringField(JSON_STRING, "\"action\":\"", (char*)&jsonMsg.action);
+
+		LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"write to mqtt");
+		while(current_device)
+		{
+			char* device_ID = (char*)current_device->deviceID;
+			GATEWAY_WRITE_MODBUS_COMMAND *currentModbusWriteParams = current_device->params->gateway_write_modbus_command;
+			GATEWAY_READ_MODBUS_COMMAND *currentModbusReadParams = current_device->params->gateway_read_modbus_command;
+			char* pubJsonString = mymalloc(SRAMEX,150);
+			switch(atoi((char*)&jsonMsg.action))
+			{
+				case 0:/* write */
+					if(!strcmp(device_ID,(char*)&jsonMsg.deviceId))
+					{
+						while(currentModbusWriteParams != NULL)
+						{
+							if(!strcmp((char*)&currentModbusWriteParams->keyword,(char*)&jsonMsg.identifier)) //匹配ID和属性
+							{
+								recv_state = 0;
+								delay_ms(100);	
+								while(mmodbus.done != 1) 	delay_ms(100); 							
+								mmodbus_writeHoldingRegister16i(currentModbusWriteParams->slaveAddress, currentModbusWriteParams->registerAddress, jsonMsg.parameter);
+								sprintf(pubJsonString,"{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d}",
+													jsonMsg.action,jsonMsg.identifier,jsonMsg.deviceId,jsonMsg.messageId,recv_state);	// 组成要发送的json语句
+								mqtt_publish_data(pubJsonString, QOS0, strlen(pubJsonString), (char*)&get->messageTopic);	
+								delay_ms(100);
+							}
+							currentModbusWriteParams = currentModbusWriteParams->nextParams;
+						}
+					}
+					break;
+				case 1:/* read  */
+					if(!strcmp(device_ID,(char*)&jsonMsg.deviceId)) 
+					{
+						while(currentModbusReadParams != NULL)
+						{
+							if(!strcmp((char*)&currentModbusReadParams->keyword,(char*)&jsonMsg.identifier)) //匹配ID和属性
+							{
+								delay_ms(100);
+								recv_state = 0;
+								uint16_t* data = mymalloc(SRAMEX, currentModbusReadParams->registerByteNum /2); // modbus寄存器长度
+								while(mmodbus.done != 1) 	delay_ms(100); 
+								bool success = mmodbus_readHoldingRegisters16i(currentModbusReadParams->slaveAddress,currentModbusReadParams->registerAddress,
+																																	currentModbusReadParams->registerByteNum /2,data);
+
+									if (success)
+									{
+											recv_state = 1;
+											uint32_t value;
+											if (currentModbusReadParams->registerByteNum == 4)
+											{
+													value = (uint32_t)data[0] | data[1];
+											}
+											else if (currentModbusReadParams->registerByteNum == 2)
+											{
+													value = data[0];
+											}
+											sprintf(pubJsonString,"{\"action\":\"%s\",\"identifier\":\"%s\",\"deviceId\":\"%s\",\"messageId\":\"%s\",\"state\":%d,\"parameter\":%d}",
+														jsonMsg.action,jsonMsg.identifier,jsonMsg.deviceId,jsonMsg.messageId,recv_state,value);	// 组成要发送的json语句
+											mqtt_publish_data(pubJsonString, QOS0, strlen(pubJsonString), (char*)&get->messageTopic);	
+											delay_ms(100);
+									}
+									myfree(SRAMEX, data);
+								}
+							currentModbusReadParams = currentModbusReadParams->nextParams;
+						}
+					}
+					break;
+				case 3:/* reboot */
+					__set_PRIMASK(1);
+					NVIC_SystemReset();
+					break;
+			}
+				current_device = current_device->nextDevice;
+				myfree(SRAMEX, pubJsonString);
+		}
+}
+// 重定义pow函数
+uint32_t my_pow(int base, int exponent) {
+    uint32_t result = 1;
+    for(int i = 0; i < exponent; i++) {
+        result *= base;
+    }
+    return result;
+}
+
+void protocolsModeFunc(GATEWAY_PARAMS* get, char* string)
+{
+		if(mqtt_connectFlag)
+		{
+				HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_SET);
+				time1 = GetCurrentTime();
+				sprintf(string,"{\"deviceId\":\"%s\",\"data\":[",get->deviceId);	// 组成要发送的json语句	
+				if(startFlag && time2  <= time1 - ( 10 * 1000))// 10s进行一次全数据发送
+				{
+						mode = 0;//all
+						LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"protocolsMode:All data");
+						read_device_data(get->device_params,string);
+						sprintf(string + strlen(string),"]}");
+						mqtt_publish_data(string, QOS0, strlen(string), (char*)&get->messageTopic);					
+						time2 = GetCurrentTime();
+				}
+				else
+				{
+						mode = 1;// def
+						read_device_data(get->device_params, string);
+						if(def)// 检测string是否含有数据
+						{
+							def = 0;
+							LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"protocolsMode:Different data");
+							sprintf(string + strlen(string),"]}");
+							mqtt_publish_data(string, QOS0, strlen(string), (char*)&get->messageTopic);			
+							time2 = GetCurrentTime();		
+						}					
+				}
+				startFlag = 1;				
+				memset(string,0,strlen(string));	
+				
+		}				
+}
+
+
+
+int transparent_data(DEVICE_PARAMS *device)
+{
+		DEVICE_PARAMS *current_device=device;	
+		GATEWAY_READ_MODBUS_COMMAND *currentModbusParams = current_device->params->gateway_read_modbus_command;
+		GATEWAY_READ_DLT645_COMMAND *currentDLT645Params = current_device->params->gateway_read_dlt645_command;	
+		while(current_device->params != NULL)
+		{	
+
+				if (current_device->protocol == MODBUS_READ)
+				{
+//						uint16_t data[currentModbusParams->registerByteNum /2]; // modbus寄存器长度	
+						uint16_t *data = mymalloc(SRAMEX,currentModbusParams->registerByteNum /2); 
+						mmodbus_set16bitOrder(current_device->MDBbigLittleFormat);
+						// 读单个寄存器
+						if (currentModbusParams->functionCode == 0x03)
+						{
+//								bool success = mmodbus_readHoldingRegisters16i(0x17,0x00,0x02,data);
+  							bool success = mmodbus_readHoldingRegisters16i(currentModbusParams->slaveAddress,
+																															 currentModbusParams->registerAddress,
+																															 currentModbusParams->registerByteNum /2,
+																															 data);
+								if (success)
+								{
+										uint32_t value;		
+										if((value - currentModbusParams->value) != 0)
+										{
+											for (uint8_t i = 0; i < mmodbus.rxBuf[2]; i += 2)
+											{
+												uint8_t H = mmodbus.rxBuf[i + 3];
+												mmodbus.rxBuf[i + 3] = mmodbus.rxBuf[i + 3 + 1];
+												mmodbus.rxBuf[i + 3 + 1] = H;
+											}
+											USART_485_Send(mmodbus.rxBuf,mmodbus.rxIndex);
+											vTaskDelay(100);
+										}									
+								}					
+								currentModbusParams = currentModbusParams->nextParams;
+								if (currentModbusParams == NULL)	
+								{
+										current_device = current_device->nextDevice;
+										currentModbusParams = current_device->params->gateway_read_modbus_command;
+										if(current_device == NULL)
+										{
+												return 1;
+										}
+								}												
+						}
+						myfree(SRAMEX, data);
+				}
+				 else if (current_device->protocol == DLT645_2007 || current_device->protocol == DLT645_97)
+				{
+						uint8_t read_buf[10];
+										
+						memset(read_buf, 0, 10);
+						memset(currentDLT645Params->data, 0, 10);
+
+						dlt645_set_addr(&dlt645, currentDLT645Params->deviceID645);
+						int8_t rs;
+						if (current_device->protocol == DLT645_2007)
+						{
+								rs = dlt645_read_data(&dlt645, currentDLT645Params->Identification, read_buf, DLT645_2007);
+						}
+						else if (current_device->protocol == DLT645_1997)
+						{
+								rs = dlt645_read_data(&dlt645, currentDLT645Params->Identification, read_buf, DLT645_1997);
+						}
+						if (rs != -1)
+						{
+								if(compareArrays(read_buf,currentDLT645Params->data,10))// 不相同1,相同0
+								{
+									portENTER_CRITICAL();
+									USART_485_Send(mmodbus.rxBuf,mmodbus.rxIndex);
+									portEXIT_CRITICAL();
+									vTaskDelay(100);
+								}
+						}
+							currentDLT645Params = currentDLT645Params->nextParams;		
+							if (currentDLT645Params == NULL)	
+							{
+									current_device = current_device->nextDevice;
+									currentDLT645Params = current_device->params->gateway_read_dlt645_command;
+									if(current_device == NULL)
+									{
+											return 1;
+									}
+							}										
+				}					
+		}		
+		return 1;
+	
+}
+void transparentModeFunc(DEVICE_PARAMS* current_device)
+{
+			HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_SET);
+			LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"transparentMode:All data");
+			printf("transparentMode:All data\n");
+			transparent_data(current_device);		
+}
+

+ 313 - 0
app/SYSTEM/source/gateway_message.c

@@ -0,0 +1,313 @@
+
+#include "string.h"
+#include <stdlib.h>
+#include <stdio.h>   
+#include "gateway_message.h"
+
+
+GATEWAY_PARAMS gateway_config_params = {0};
+
+GATEWAY_PARAMS *get_gateway_config_params()
+{
+    return &gateway_config_params;
+}
+
+void parseStringField(const char *data, const char *field, char *value);
+int parseIntField(const char *data, const char *field);
+int extract_substring(const char *input_string, const char *start_token, const char *end_token, char *result);
+void addSensorListParams(char *paramString, DEVICE_PARAMS *device);
+void addCommandListParams(char *paramString, DEVICE_PARAMS *device);
+/**
+ * @brief  解析输入字符串网关结构体信息,将数据保存
+ * @param  char *gatewayString 输入字符串的数据
+ * @retval 无
+ */
+void addGatewayParams(char *gatewayString)
+{
+		//gateway_config_params.device_params = NULL;
+		gateway_config_params.port = parseIntField(gatewayString, "\"port\":");
+		gateway_config_params.stopBit = parseIntField(gatewayString, "\"stopBit\":");
+		gateway_config_params.dataBits = parseIntField(gatewayString, "\"dataBit\":");
+		gateway_config_params.baudrate = parseIntField(gatewayString, "\"baudrate\":");
+		gateway_config_params.checkBit = parseIntField(gatewayString, "\"checkBit\":");
+		gateway_config_params.inboundTime= parseIntField(gatewayString, "\"inboundTime\":");
+		
+		parseStringField(gatewayString, "\"host\":\"", (char *)&gateway_config_params.host);
+		parseStringField(gatewayString, "\"deviceId\":\"", (char *)&gateway_config_params.deviceId);
+		parseStringField(gatewayString, "\"commandTopic\":\"", (char *)&gateway_config_params.commandTopic);
+		parseStringField(gatewayString, "\"messageTopic\":\"", (char *)&gateway_config_params.messageTopic);
+		parseStringField(gatewayString, "\"username\":\"", (char *)&gateway_config_params.username);
+		parseStringField(gatewayString, "\"password\":\"", (char *)&gateway_config_params.passwd);
+	
+		char *deviceString = strstr(gatewayString,"deviceList");  //移位置到节点数据开始处
+		
+		
+		while (1)
+    {
+        if (deviceString)
+        {
+           addDevice(deviceString); // 往此地址下挂载设备信息
+           deviceString=deviceString;//重新获取设备字符串的位置
+					 deviceString = strstr(deviceString, "}"); 
+					 deviceString[0]='A';
+					 deviceString++;
+					 if(deviceString[0]==']')
+					 {
+					 break;
+					 }
+        }
+        else
+        {
+            return;
+        }
+    }
+}
+
+/**
+ * @brief  解析输入字段的字符串,解析出属于该节点下的设备信息
+ * @param  uint8_t *string输入的字符串数据,NODE_PARAMS *node节点信息
+ * @retval 无
+ */
+
+void addDevice(char *deviceString)
+{
+    char *paramString = (char *)deviceString; // 属性指针
+		DEVICE_PARAMS *newDevicePage = (DEVICE_PARAMS *)mymalloc(SRAMEX, sizeof(DEVICE_PARAMS));    // 创建新设备页
+    newDevicePage->nextDevice = NULL;
+    newDevicePage->protocol = parseIntField(deviceString, "\"protocol\":");
+		newDevicePage->MDBdataType = parseIntField(deviceString, "\"dataType\":");
+		newDevicePage->MDBbigLittleFormat = parseIntField(deviceString, "\"bigLittleFormat\":");
+		
+		parseStringField(deviceString, "\"deviceId\":\"", (char *)&newDevicePage->deviceID);
+		
+    newDevicePage->params = (PARAMS_PROTOCOL_COMMAND *)mymalloc(SRAMEX,sizeof(PARAMS_PROTOCOL_COMMAND));
+		memset(newDevicePage->params, 0, sizeof(PARAMS_PROTOCOL_COMMAND));
+    paramString = strstr(paramString, "\"sensorData\":["); // 找到该节点的轮询上发属性
+    while (1)                                              // 此处数据是以数组形式存储所以解析方法和上面不一样
+    {
+        addSensorListParams(paramString, newDevicePage); // 解析一个属性并挂载该属性于该属性下
+				paramString=paramString;
+        paramString = strstr(paramString, "}");          // 移动到下一条属性
+				paramString[0]='A';
+        paramString++;
+        if (paramString[0] == ']')
+        {
+            paramString = (char *)deviceString; // 复原指针位置
+						break;                              // 找到了结束符,跳出循环
+        }
+    }
+		if(newDevicePage->protocol==MODBUS)  //如果为modbus的话解析写指令
+		{
+			paramString=deviceString;                                //移动到最开始的地方
+			newDevicePage->MDBbigLittleFormat = parseIntField(paramString, "\"bigLittleFormat\":");
+      newDevicePage->MDBdataType= parseIntField(paramString, "\"dataType\":");
+		  paramString = strstr(paramString, "\"commandData\":["); // 找到其轮询的写命令
+			if(paramString!=NULL)
+			{
+				while(1)
+				{
+					addCommandListParams(paramString, newDevicePage);
+					paramString = strstr(paramString, "}");
+				  paramString[0]='A';
+					paramString++;
+					if (paramString[0] == ']')
+					{
+						paramString = (char *)deviceString;// 复原指针位置
+						break;														 // 找到了结束符,跳出循环
+					}
+				}
+			}
+		}
+    // 解析下发的mqtt存储信息下发控制指令
+		
+    // 添加设备页到链表末尾
+    if (gateway_config_params.device_params == NULL)
+    {
+        gateway_config_params.device_params = newDevicePage;
+    }
+    else
+    {
+        DEVICE_PARAMS *current = gateway_config_params.device_params;
+        while (current->nextDevice != NULL)
+        {
+            current = current->nextDevice;
+        }
+        current->nextDevice = newDevicePage;
+    }
+		//解析modbus command指令将其加载到设备链表中
+		
+}
+/**
+ * @brief  解析输入字符串的paramString数据,将数据保存到至该设备结构体下,此处解析sensorList
+ * @param  uint8_t *paramString输入的字符串数据,DEVICE_PARAMS *device节点信息
+ * @retval 无
+ */
+void addSensorListParams(char *paramString, DEVICE_PARAMS *device)
+{
+    switch (device->protocol)
+    {
+    case DLT645_97:
+    case DLT645_07:
+		{
+        GATEWAY_READ_DLT645_COMMAND *read_dlt645_command = mymalloc(SRAMEX,sizeof(GATEWAY_READ_DLT645_COMMAND));
+        read_dlt645_command->Identification = parseIntField(paramString, "\"identifier645\":");
+        parseStringField(paramString, "\"identifier\":\"", (char *)&read_dlt645_command->keyword);
+        char *string = mymalloc(SRAMEX,13);
+        parseStringField(paramString, "\"deviceID645\":\"", string);
+        for (int j = 0; j < 6; j++)
+        {
+          uint8_t byte;
+          sscanf((const char *)&string[j * 2], "%2hhx", &byte);
+          read_dlt645_command->deviceID645[j]=byte;
+        }				
+        myfree(SRAMEX, string);
+				string = NULL;
+        if (device->params->gateway_read_dlt645_command == NULL)
+        {
+            device->params->gateway_read_dlt645_command = read_dlt645_command;
+        }
+        else
+        {
+            GATEWAY_READ_DLT645_COMMAND *current = device->params->gateway_read_dlt645_command;
+            while (current->nextParams != NULL)
+            {
+                current = current->nextParams;
+            }
+            current->nextParams = read_dlt645_command;
+        }
+			}
+				
+        break;
+    case MODBUS:
+		{
+        GATEWAY_READ_MODBUS_COMMAND *read_modbus_command = mymalloc(SRAMEX,sizeof(GATEWAY_READ_MODBUS_COMMAND));
+				memset(read_modbus_command, 0, sizeof(GATEWAY_READ_MODBUS_COMMAND));
+				parseStringField(paramString,"\"identifier\":\"",(char *)&read_modbus_command->keyword);
+        read_modbus_command->decimalPoint = parseIntField(paramString, "\"precise\":");
+        read_modbus_command->functionCode = parseIntField(paramString, "\"rFunctionCode\":");
+        read_modbus_command->slaveAddress = parseIntField(paramString, "\"slaveAddress\":");
+        read_modbus_command->registerAddress = parseIntField(paramString, "\"registerAddress\":");
+        read_modbus_command->registerByteNum = parseIntField(paramString, "\"registerByteNum\":");
+        
+			if (device->params->gateway_read_modbus_command== NULL)
+        {
+            device->params->gateway_read_modbus_command = read_modbus_command;
+        }
+        else
+        {
+            GATEWAY_READ_MODBUS_COMMAND *current = device->params->gateway_read_modbus_command;
+            while (current->nextParams != NULL)
+            {
+                current = current->nextParams;
+            }
+            current->nextParams = read_modbus_command;
+        }
+			}
+        break;
+    default:
+        break;
+    }
+}
+/**
+ * @brief  解析输入字符串的paramString数据,将数据保存到至该设备结构体下,此处解析commandList
+ * @param  uint8_t *paramString输入的字符串数据,DEVICE_PARAMS *device节点信息
+ * @retval 无
+ */
+void addCommandListParams(char *paramString, DEVICE_PARAMS *device)
+{
+	
+ 	GATEWAY_WRITE_MODBUS_COMMAND *write_modbus_command=mymalloc(SRAMEX,sizeof(GATEWAY_WRITE_MODBUS_COMMAND));
+	memset(write_modbus_command, 0, sizeof(GATEWAY_WRITE_MODBUS_COMMAND));
+	parseStringField(paramString,"\"identifier\":\"",(char *)&write_modbus_command->keyword);
+	write_modbus_command->functionCode=parseIntField(paramString, "\"wFunctionCode\":");
+	write_modbus_command->slaveAddress=parseIntField(paramString, "\"slaveAddress\":");
+	write_modbus_command->registerAddress = parseIntField(paramString, "\"registerAddress\":");
+	write_modbus_command->registerByteNum = parseIntField(paramString, "\"registerByteNum\":");
+	if(device->params->gateway_write_modbus_command == NULL)
+	{
+		device->params->gateway_write_modbus_command=write_modbus_command;
+	}
+	else
+	{
+		GATEWAY_WRITE_MODBUS_COMMAND *current=device->params->gateway_write_modbus_command;
+    while (current->nextParams != NULL)
+    {
+      current = current->nextParams;
+    }
+    current->nextParams = write_modbus_command;		
+	}
+}
+// 提取int数据
+int parseIntField(const char *data, const char *field)
+{
+
+    char *ptr = strstr(data, field) + strlen(field);
+    int value;
+    value = strtol(ptr, &ptr, 10);
+    return value;
+}
+
+// 提取string字符串
+void parseStringField(const char *data, const char *field, char *value)
+{
+    char *ptr = strstr(data, field) + strlen(field);
+    sscanf(ptr, "%[^\"],", value);
+}
+
+// 不采用json解析硬解json数据
+void processStringJson(uint8_t *data)
+{
+    GATEWAY_PARAMS *gateway;
+    gateway = get_gateway_config_params();
+    uint8_t *ptr = (uint8_t *)data;
+    parseStringField((char *)&ptr, "\"messageTopic\":\"", (char *)&gateway->messageTopic);
+    parseStringField((char *)&ptr, "\"commandTopic\":\"", (char *)&gateway->commandTopic);
+    gateway->port = parseIntField((char *)&ptr, "\"port\":\"");
+    parseStringField((char *)&ptr, "\"host\":\"", (char *)&gateway->host);
+    parseStringField((char *)&ptr, "\"deviceId\":\"", (char *)&gateway->deviceId);
+    // 解析最外层数据完成,申请空间存储节点信息
+
+    int nodeNum = 1;
+    char *node_index = mymalloc(SRAMEX,10);
+    sprintf(node_index, "node_%d", nodeNum);
+    strstr(ptr, node_index); // 将指针指向第一个节点
+    while (*ptr == NULL)
+    {
+
+    }
+    myfree(SRAMEX, node_index);
+}
+/**
+ * @brief  从输入的input_string中寻找开始到结束位置的字符串数据,并将数据截取出来,传给result;
+ * @param  input_string输入字符串,start_token字符串起始位置,end_token字符串结束位置,result截取出的字符串
+ * @retval 0:没有被截取到的字符串。1:有被截取到的字符串。
+ */
+int extract_substring(const char *input_string, const char *start_token, const char *end_token, char *result)
+{
+    const char *start_ptr = strstr(input_string, start_token);
+
+    if (start_ptr == NULL)
+    {
+        return 0; // 未找到起始标记
+    }
+
+    start_ptr += strlen(start_token); // 移动指针到起始标记之后
+
+    const char *end_ptr = strstr(start_ptr, end_token);
+
+    if (end_ptr == NULL)
+    {
+        // 如果未找到结束标记,将从起始标记开始的字符串一直复制到 \0 结束
+        strcpy(result, start_ptr);
+    }
+    else
+    {
+        // 找到结束标记,计算截取的长度并复制
+        size_t length = end_ptr - start_ptr;
+        strncpy(result, start_ptr, length);
+        result[length] = '\0'; // 添加字符串结束符
+    }
+    return 1;
+}
+
+

+ 455 - 0
app/SYSTEM/source/http_clinet.c

@@ -0,0 +1,455 @@
+#include "stdint.h"
+#include "stdio.h"
+#include "string.h"
+#include "lwip/opt.h"
+#include "lwip/arch.h"
+#include "lwip/api.h"
+#include "lwip/inet.h"
+#include "lwip/sockets.h"
+#include "lwip/dns.h"
+#include "http_client.h"
+#include "malloc.h"
+
+uint8_t httpSendBuffer[1024];
+uint8_t httpRecvBuffer[512];
+
+#define sendBufSize  1024
+#define recvBufSize  512
+
+/**
+  * @brief  从socket缓存中读取一行http数据
+	* @param  sock:    已经连接到服务器的sock编号
+	* @param  buf:     保存数据的buffer
+	* @param  size:    buf的最大可用长度
+	* @retval 读取到的数据的长度,包括两个字节的换行符
+  */
+int http_getLine(int sock, uint8_t *buf, int size)
+{
+	 int i = 0;
+	 char c = '\0';
+	 int n;
+	
+	 while((i < (size - 1)) && (c != '\n'))
+	 {
+			n = recv(sock, &c, 1, 0);
+		  if(n <= 0) c = '\n';
+			buf[i++] = c;
+	 }
+	 buf[i] = '\0';
+ 
+	 return i;  //返回读取的到的数据长度
+}
+
+/**
+  * @brief  解析http响应行
+	* @param  pbuf:  响应行的数据
+* @retval 其他值: 返回http请求状态   -1: 解析失败
+  */
+int http_parseRequestLine(uint8_t *pbuf)
+{
+	int b, s, g;
+	
+	if((strncmp((char *)pbuf, "HTTP/1.1 ", strlen("HTTP/1.1 ")) == 0) || (strncmp((char *)pbuf, "http/1.1 ", strlen("http/1.1 ")) == 0))
+	{
+		pbuf += strlen("HTTP/1.1 ");
+		b = pbuf[0] - '0';
+		s = pbuf[1] - '0';
+		g = pbuf[2] - '0';	
+
+		return (b * 100 + s * 10 + g);
+	}
+	
+	return -1;
+}
+
+/**
+  * @brief  DNS解析回调函数
+  * @note   在解析域名成功后,会调用这个函数,然后可以读取到对应的IP地址
+  * @param  name:         域名
+  * @param  host_ip:      域名对应的ip地址
+  * @param  callback_arg: 传递的参数
+  * @retval None
+  */
+void http_dns_found(const char *name, ip_addr_t *host_ip, void *callback_arg)
+{
+	*(ip_addr_t *)callback_arg = *host_ip;
+	HTTP_PRINTF("%s:%s\r\n",name, ipaddr_ntoa(host_ip));
+}
+
+/**
+  * @brief  连接到http服务器的函数
+	* @note   连接到http服务器
+  * @param  host:     服务器的域名或者ip地址
+	* @param  port:     服务器端口号
+	* @param  hostIsIp: host代表的是 域名,还是ip地址  0: host为域名  1: host为ip地址
+	* @retval -1:连接服务器失败  -2: 域名解析失败  >=0: 连接成功,返回值为 sock编号
+  */
+int http_clientConnectToServer(char *host, int port, int hostIsIp)
+{
+	int timeout;
+	struct sockaddr_in serverAddr;
+	int sock = socket(AF_INET, SOCK_STREAM, 0);
+	if(sock < 0) return -2;	
+
+	//如果传入的host参数是域名,解析域名
+	if(hostIsIp == 0)
+	{
+		ip_addr_t addr;	
+		
+    addr.addr = 0;
+		dns_gethostbyname(host, &addr, http_dns_found, &addr);
+		//等待dns解析完成
+		timeout = 0;
+		while((addr.addr == 0) && (timeout < 2000)) 
+		{
+			timeout += 10;
+			vTaskDelay(100);  
+			
+		}
+		if(timeout >= 2000) 
+		{
+			HTTP_PRINTF(("dns get failure \n"));
+			return -2;
+		}
+		serverAddr.sin_addr.s_addr = inet_addr(inet_ntoa(addr));
+	}
+	else serverAddr.sin_addr.s_addr = inet_addr((char*)host);
+	serverAddr.sin_len = sizeof(serverAddr);
+	serverAddr.sin_family = AF_INET;
+	serverAddr.sin_port = htons(port);	
+  memset(&serverAddr.sin_zero, 0, sizeof(serverAddr.sin_zero));
+	
+	//连接服务器
+	if(connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) != 0)
+	{
+		HTTP_PRINTF("connect server error \r\n");
+		return -1;
+	}
+	
+	//设置接收数据超时时间
+	timeout = 3000;
+	setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(int));	
+	
+	HTTP_PRINTF("connect server success \r\n");
+	
+	return sock;
+}
+
+/**
+  * @brief  关闭socket端口
+	* @param  sock:    已经连接到服务器的sock编号
+  */
+void http_clientClose(int sock)
+{
+	close(sock);
+}
+
+
+/**
+  * @brief  连接到发送GET请求
+	* @note   组装GET数据包,并将GET请求发送出去
+	* @param  sock:    已经连接到服务器的sock编号
+  * @param  host:    服务器的域名或者ip地址
+	* @param  url:     请求资源的地址
+	* @retval -1: 发送请求失败 1:发送成功
+  */
+int http_clientPacketRequest_GET(int sock, char *host, char *url)
+{
+	int len;
+	uint8_t* httpSendBuffer = mymalloc(SRAMEX, sendBufSize);
+	memset(httpSendBuffer, 0, sendBufSize);
+	//组建请求行
+	sprintf((char *)httpSendBuffer, "GET ");
+	if(url == NULL) strcat((char *)httpSendBuffer, "/");
+	else            strcat((char *)httpSendBuffer, url); 
+	strcat((char *)httpSendBuffer, " HTTP/1.1\r\n");
+	//组建请求头部 
+	strcat((char *)httpSendBuffer, "Host: ");
+	strcat((char *)httpSendBuffer, host);	
+	strcat((char *)httpSendBuffer, "\r\n");
+	strcat((char *)httpSendBuffer, "Connection: close\r\n");	
+	strcat((char *)httpSendBuffer, "Accept: application/json\r\n");
+	strcat((char *)httpSendBuffer, "User-Agent: stm32f207\r\n");		
+	strcat((char *)httpSendBuffer, "Cache-Control: no-cache\r\n");	
+	//添加一个空白行
+	strcat((char *)httpSendBuffer, "\r\n"); 
+	len = strlen((char *)httpSendBuffer);
+	HTTP_PRINTF("%s", (char *)httpSendBuffer);	 //
+	
+	//发送请求报文
+	len = write(sock, httpSendBuffer, len);  
+	if(len <= 0) 
+	{
+		myfree(SRAMEX, httpSendBuffer);
+		return -1;
+	}
+	myfree(SRAMEX, httpSendBuffer);
+	return 1;
+}
+
+/**
+  * @brief  http_clientReadResponse_GET
+	* @note   等待服务器返回GET响应
+	* @param  sock:    已经连接到服务器的sock编号
+	* @retval -1: 发送请求失败 1:发送成功
+  */
+int http_clientReadResponse_GET(int sock, uint8_t *pbuf, int *datlen)
+{
+	int len, ret;
+	int length = 0;
+	uint8_t* httpRecvBuffer = mymalloc(SRAMEX, recvBufSize);
+	//读取响应行
+	len = http_getLine(sock, httpRecvBuffer, recvBufSize);	
+	if(len <= 0) 
+	{
+		myfree(SRAMEX, httpRecvBuffer);
+		return -1;
+	}
+	HTTP_PRINTF("%s", (char *)httpRecvBuffer);
+	
+	ret = http_parseRequestLine(httpRecvBuffer);
+	
+	//读取响应头
+	do
+	{
+		len = http_getLine(sock, httpRecvBuffer, recvBufSize);		
+		HTTP_PRINTF("%s", (char *)httpRecvBuffer);
+		if(len <= 2) 
+		{
+			if(len == 2) break;     //读取到了空行
+			else         
+			{
+				myfree(SRAMEX, httpRecvBuffer);
+				return -1;
+			}
+		}
+	}while(len > 0);
+	
+	//读取响应主体内容
+	length = 0;
+	do
+	{
+		 len = recv(sock, httpRecvBuffer, recvBufSize, 0);
+		 if(len > 0) 
+		 {
+			 memcpy(pbuf + length, httpRecvBuffer, len);
+			 length += len;
+		 }
+	}while(len > 0);
+	
+	*datlen = length;
+	myfree(SRAMEX, httpRecvBuffer);
+	return ret;
+}
+
+/*
+* @brief  http_clientPacketRequest_POST
+* @note   组建和发送POST请求头数据包
+* @param  sock:     已经连接到服务器的sock编号
+* @param  host:     服务器域名或者IP地址
+* @param  url:      请求的资源位置 
+* @param  pbuf:     需要post的数据缓存
+* @param  datalen   需要post的数据长度
+* @retval           -1: 发送失败 1:发送成功
+*/
+
+char httpTmpBuffer[64];
+int http_clientPacketRequest_POST(int sock, char *host, char *url, int datalen)
+{
+	int len;
+	uint8_t* httpSendBuffer = mymalloc(SRAMEX,sendBufSize);
+	memset(httpSendBuffer, 0, sendBufSize);
+	//组建请求行
+	sprintf((char *)httpSendBuffer, "POST ");
+	if(url == NULL) strcat((char *)httpSendBuffer, "/");
+	else            strcat((char *)httpSendBuffer, url); 
+	strcat((char *)httpSendBuffer, " HTTP/1.1\r\n");
+	
+	//组建请求头部
+	memset(httpTmpBuffer, 0, sizeof(httpTmpBuffer));
+	sprintf(httpTmpBuffer, "Host: %s\r\n", host);
+	strcat((char *)httpSendBuffer, httpTmpBuffer);
+	strcat((char *)httpSendBuffer, "Connection: close\r\n");	
+	strcat((char *)httpSendBuffer, "Accept: application/json\r\n");		 //
+	strcat((char *)httpSendBuffer, "User-Agent: stm32f207\r\n");			
+	strcat((char *)httpSendBuffer, "Cache-Control: no-cache\r\n");	
+	strcat((char *)httpSendBuffer, "Content-Type: application/json\r\n");
+	memset(httpTmpBuffer, 0, sizeof(httpTmpBuffer));
+	sprintf(httpTmpBuffer, "Content-Length: %d\r\n", datalen);   
+	strcat((char *)httpSendBuffer, httpTmpBuffer);
+	//添加一个空白行
+	strcat((char *)httpSendBuffer, "\r\n"); 
+	
+	len = strlen((char *)httpSendBuffer);
+	HTTP_PRINTF("%s", (char *)httpSendBuffer);	
+
+	//发送请求报文
+	len = write(sock, httpSendBuffer, len);  
+	if(len <= 0) 
+	{
+		myfree(SRAMEX, httpSendBuffer);
+		return -1;
+	}
+	myfree(SRAMEX, httpSendBuffer);
+	return 1;
+}
+
+
+/*
+* @brief  http_clientPacketBody_POST
+* @note   发送post数据
+* @param  sock:     已经连接到服务器的sock编号
+* @param  pbuf:     需要post的数据缓存
+* @param  datalen   需要post的数据长度
+* @retval           -1: 发送失败 1:发送成功
+*/
+int http_clientPacketBody_POST(int sock, uint8_t *pbuf, int datalen)
+{
+	int len;
+	
+	while(datalen > 1000)
+	{
+		len = write(sock, pbuf, 1000);  
+		if(len <= 0) 
+		{
+			return -1;
+		}
+		
+	  datalen -= 1000;
+		pbuf += 1000;
+	}
+	
+	if(datalen > 0)
+	{
+		len = write(sock, pbuf, datalen);  
+		if(len <= 0) 
+		{
+			return -1;
+		}
+	}	
+	
+	return 1;
+}
+
+/*
+* @brief  http_clientReadResponse_POST
+* @note   读取和解析POST返回的响应
+* @param  sock:     已经连接到服务器的sock编号
+* @retval 响应的返回值
+*/
+int http_clientReadResponse_POST(int sock, uint8_t *pbuf, int *datlen)
+{
+	int len, ret;
+	int length = 0;
+	uint8_t* httpRecvBuffer = mymalloc(SRAMEX, recvBufSize);
+	//读取响应行
+	len = http_getLine(sock, httpRecvBuffer, recvBufSize);	
+	if(len <= 0) 
+	{
+		myfree(SRAMEX, httpRecvBuffer);
+		return -1;
+	}
+	HTTP_PRINTF("%s", (char *)httpRecvBuffer);
+	
+	ret = http_parseRequestLine(httpRecvBuffer);
+	
+	//读取响应头
+	do
+	{
+		len = http_getLine(sock, httpRecvBuffer, recvBufSize);		
+		HTTP_PRINTF("%s", (char *)httpRecvBuffer);
+		if(len <= 2) 
+		{
+			if(len == 2) break;     //读取到了空行
+			else 
+			{		
+				myfree(SRAMEX, httpRecvBuffer);	
+				return -1;
+			}
+		}
+	}while(len > 0);	
+	
+	//读取响应主体内容
+	length = 0;
+	do
+	{
+		 len = recv(sock, httpRecvBuffer, recvBufSize, 0);
+		 if(len > 0) 
+		 {
+			 memcpy(pbuf + length, httpRecvBuffer, len);
+			 length += len;
+		 }
+	}while(len > 0);
+	
+	*datlen = length;
+	myfree(SRAMEX, httpRecvBuffer);	
+	return ret;	
+}
+
+
+/*
+* @brief  http_clientGet
+* @note   客户端发送GET请求
+* @param  host:     服务器的域名或者IP地址
+* @param  url:      访问服务器资源的位置
+* @param  port:     服务器的端口号
+* @param  hostIsIp: 第一个参数是域名还是ip地址   0:域名  1: ip地址
+* @param  pbuf:     接收服务器响应的数据
+* @param  datalen:  服务器响应数据的长度
+* @retval 负值: GET请求异常, 正值: http协议的返回码
+*/
+int http_clientGet(char *host, char *url, uint16_t port, uint8_t hostIsIp, uint8_t *pbuf, int *datalen)
+{
+	int sock = -1, ret;
+	
+	sock = http_clientConnectToServer(host, port, hostIsIp);
+	if(sock < 0) goto __httpError;
+	
+	ret = http_clientPacketRequest_GET(sock, host, url);
+	if(sock < 0) goto __httpError;
+	
+	ret = http_clientReadResponse_GET(sock, pbuf, datalen);
+	if(sock < 0) goto __httpError;
+
+__httpError:	
+	if(sock >= 0)
+		http_clientClose(sock);
+
+	return ret;
+}
+
+/*
+* @brief  http_clientGet
+* @note   客户端发送GET请求
+* @param  host:     服务器的域名或者IP地址
+* @param  url:      访问服务器资源的位置
+* @param  port:     服务器的端口号
+* @param  hostIsIp: 第一个参数是域名还是ip地址   0:域名  1: ip地址
+* @param  postbuf:  需要发往服务器的数据
+* @param  postlen:  发送数据的长度
+* @param  rtnbuf:     接收服务器响应的数据
+* @param  rtnlen:  服务器响应数据的长度
+* @retval 负值: GET请求异常, 正值: http协议的返回码
+*/
+int http_clientPost(char *host, char *url, uint16_t port, uint8_t hostIsIp, uint8_t *postbuf, int postlen, uint8_t *rtnbuf, int *rtnlen)
+{
+	int sock, ret;
+	
+	sock = http_clientConnectToServer(host, port, hostIsIp);
+	if(sock < 0) goto __httpError;
+
+	ret = http_clientPacketRequest_POST(sock, host, url, postlen);
+	if(ret < 0) goto __httpError;
+	
+	ret = http_clientPacketBody_POST(sock, postbuf, postlen);
+  if(ret < 0) goto __httpError;
+	
+	ret = http_clientReadResponse_POST(sock, rtnbuf, rtnlen);
+
+__httpError:	
+	if(sock >= 0)
+		http_clientClose(sock);
+	
+	return ret;
+}
+

+ 3 - 3
app/SYSTEM/source/log.c

@@ -10,7 +10,7 @@
 #include "app_ethernet.h"
 
 SemaphoreHandle_t logMutex;
- void LogPrint(logLevel_t logLevel,const char *file, const char *func, const int line, char * fmt, ...)
+void LogPrint(logLevel_t logLevel,const char *file, const char *func, const int line, char * fmt, ...)
 {
 	if(dhcp_done!=1)return;
 	if (xSemaphoreTake(logMutex, 1000))
@@ -21,7 +21,7 @@ SemaphoreHandle_t logMutex;
 		char buf[LOG_LEN_MAX];
 		vsnprintf(buf, sizeof(buf), fmt, args);
 		va_end(args);
-		char *p=pvPortMalloc(1024);
+		char *p=mymalloc(SRAMEX,1024);
 			switch (logLevel)
 			{
 		#ifdef _LOG_INFO
@@ -46,7 +46,7 @@ SemaphoreHandle_t logMutex;
 					break;
 			}
 			udp_send_printf(p);
-			vPortFree(p);
+			myfree(SRAMEX, p);
 			udp_log_close();
 			xSemaphoreGive(logMutex);
 		}

+ 411 - 0
app/SYSTEM/source/lte.c

@@ -0,0 +1,411 @@
+#include "main.h"
+#include "lte.h"
+#include "myFIle.h"
+#include "malloc.h"
+#include "LTE_MQTT.h"
+#include "usart.h"
+
+uint8_t config_flag = 0;
+uint8_t UART6_RxCounter = 0;
+int socket;
+
+//PG6 初始化、拉低
+void SIM_CD_config()
+{
+		 GPIO_InitTypeDef GPIO_InitStruct = {0};
+		__HAL_RCC_GPIOG_CLK_ENABLE();												   
+		GPIO_InitStruct.Pin = GPIO_PIN_6;	
+		GPIO_InitStruct.Mode = GPIO_MODE_INPUT;   
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+		HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);	
+		HAL_GPIO_WritePin(GPIOG,GPIO_PIN_6,GPIO_PIN_RESET);
+}
+
+// 模块上电  
+// 拉高PA4,给EC800M上电
+void VBAT_config()
+{
+		GPIO_InitTypeDef GPIO_InitStructure;
+		__HAL_RCC_GPIOA_CLK_ENABLE();												   
+		GPIO_InitStructure.Pin = GPIO_PIN_4;	
+		GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;        
+    GPIO_InitStructure.Pull = GPIO_PULLUP;
+		GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; 
+		HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);	
+		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
+}
+
+// 拉高PB12脚
+// 开机:需要在稳定的高电平时,拉低一段时间,再拉高
+// 本机因为初始化前为高电平,只需要拉低后即可开机 
+//PWRKEY1电平与GPIOB12电平同步
+void EC800M_open()
+{	
+		VBAT_config();  // 模块上电
+	
+		GPIO_InitTypeDef GPIO_InitStructure;
+		__HAL_RCC_GPIOB_CLK_ENABLE();
+		GPIO_InitStructure.Pin = GPIO_PIN_12 ;	
+		GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;   
+    GPIO_InitStructure.Pull = GPIO_PULLDOWN;   
+		GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; 
+		HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);	
+		//当GPIO引脚初始化前为低电平时,需要进行下列步骤		
+//		delay_ms(35);
+//		GPIO_WriteBit(GPIOB,GPIO_Pin_12,1);
+//  	GPIO_WriteBit(GPIOB,GPIO_Pin_13,1);
+//		delay_ms(500);
+//		 
+//		GPIO_WriteBit(GPIOB,GPIO_Pin_12,0);
+//		GPIO_WriteBit(GPIOB,GPIO_Pin_13,0);
+
+		delay_ms(1000);  // 延时一段时间
+		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET);
+}
+
+// 发送AT指令并对RX数据进行匹配
+int Iot_SendCmd(char* cmd, char* reply, int wait)
+{
+		uint8_t i=0;
+		int time = wait * 100;
+    int rssi,res;
+    memset(UART6_RX_BUF, 0, BUFF_SIZE); 
+		HAL_UART_Transmit(&USART_InitStruct_DEBUG, (uint8_t*)cmd, strlen(cmd), HAL_MAX_DELAY);
+		
+    LTE_Delay(time);
+    while(UART6_RX_STAT != 1) // 判断是否接收数据
+    {
+        LTE_Delay(1);
+        i++;
+        if(i >= wait){
+            printf("cat1 check out\r\n");
+            return -1;   
+        }
+    }
+    UART6_RX_STAT = 0;
+		
+    if (!strcmp(reply,"+CSQ"))
+    {
+				char* rss_str = strstr((char*)UART6_RX_BUF, "+CSQ:");
+        if (!rss_str)		return 1;
+       	
+        sscanf(rss_str, "+CSQ:%d,%d", &rssi, &res);
+        if (rssi != 99)		return 0;
+       
+    }
+    else if (!strcmp(reply,"+QMTPUBEX"))
+    {
+				char	MQ_str[64] = {0};
+				sprintf(MQ_str,"%s",UART6_RX_BUF);
+				char* MQ_send = strstr(MQ_str + 5, ">");
+        if (MQ_send){	
+//					HAL_UART_Transmit(&USART_InitStruct_DEBUG, (uint8_t*)pubJsonString, strlen(pubJsonString), HAL_MAX_DELAY);				
+					return 0;
+				}
+    }
+    if (strstr((char*)UART6_RX_BUF, reply))		
+		{
+			return 0;
+		}
+    return 1;  
+}
+
+// EC800M 的初始化
+void ec800_init()
+{
+    uint16_t cat1_timeout = 0;
+    while(Iot_SendCmd("AT\r\n","OK", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+		cat1_timeout = 0;
+		while(Iot_SendCmd("AT+CFUN?\r\n","OK", 1)){
+				LTE_Delay(1);
+				cat1_timeout ++;
+				if(cat1_timeout >= 2000){
+						printf(" uart false\r\n");
+						return;   
+				}
+		}
+		cat1_timeout = 0;
+		Iot_SendCmd("AT+QCFG=\"nat\",0\r\n","OK", 1);
+		while(Iot_SendCmd("AT+QCFG=\"nat\"\r\n","OK", 1)){
+				LTE_Delay(1);
+				cat1_timeout ++;
+				if(cat1_timeout >= 2000){
+						printf(" uart false\r\n");
+						return;   
+				}
+		}
+
+    cat1_timeout = 0;
+    printf("uart ok\r\n");
+    while(Iot_SendCmd("AT+CPIN?\r\n","READY", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+    cat1_timeout = 0;
+    printf("simcard ok\r\n");
+    while(Iot_SendCmd("AT+CSQ\r\n","+CSQ", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+//		cat1_timeout = 0;
+//    while(Iot_SendCmd("AT+COPS?\r\n","0,0", 1)){
+//        LTE_Delay(1);
+//        cat1_timeout ++;
+//        if(cat1_timeout >= 2000){
+//            return;   
+//        }
+//    }
+		
+		cat1_timeout = 0;
+    while(Iot_SendCmd("AT+COPS=0,0,\"CHN-CT\",7\r\n","0,0", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+		
+    cat1_timeout = 0;
+    while(Iot_SendCmd("AT+CEREG?\r\n","0,1", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+    printf("网络注册 ok\r\n");
+    cat1_timeout = 0;
+    while(Iot_SendCmd("AT+CGATT?\r\n","+CGATT: 1", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+    printf(" 网络附着 ok\r\n");
+}
+
+// TCP初始化
+void ec800_TCP(){
+    uint16_t cat1_timeout = 0;
+    while(Iot_SendCmd("AT+QHTTPCFG=\"contextid\",1\r\n","OK", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+  
+		cat1_timeout = 0;    
+    while(Iot_SendCmd("AT+QHTTPCFG=\"contenttype\",1\r\n","OK", 3)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+		
+    // APN 联通:UNINET   移动:CMNET   电信:CTNET
+		cat1_timeout = 0;
+    while(Iot_SendCmd("AT+QICSGP=1,1,\"CTNET\",\"\",\"\",1\r\n","OK", 3)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+		
+    cat1_timeout = 0;
+    while(Iot_SendCmd("AT+QIACT?\r\n","+QIACT", 3)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+		
+    cat1_timeout = 0;
+     while(Iot_SendCmd("AT+QIACT=1\r\n","OK", 1)){
+         LTE_Delay(1);
+         cat1_timeout ++;
+         if(cat1_timeout >= 2000){
+             return;   
+         }
+     }
+		 
+		cat1_timeout = 0;
+    while(Iot_SendCmd("AT+QIACT?\r\n","OK", 3)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+		// 周期性发送心跳包
+//			cat1_timeout = 0;
+//			char message[64];
+//			memset(message, 0, sizeof(message));
+//			snprintf(message, sizeof(message), "AT+QICFG=\"send/auto\",1,120,\"C000\"\r\n");
+//			while(Iot_SendCmd(message,"OK",2)){
+//					LTE_Delay(1);
+//					cat1_timeout ++;
+//					if(cat1_timeout >= 2000){
+//						 return;
+//					}
+//			}
+}
+
+// 连接网址
+void http_set_url(char *url)
+{
+    uint16_t cat1_timeout = 0;
+    char message[32];
+    snprintf(message, sizeof(message), "AT+QHTTPURL=%d,%d\r\n", strlen(url), 5);
+    while(Iot_SendCmd(message,"CONNECT", 2)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+    cat1_timeout = 0;
+    printf("ready to send url\r\n");
+    while(Iot_SendCmd(url,"OK", 5)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return;   
+        }
+    }
+    cat1_timeout = 0;
+    printf("url set OK\r\n");
+}
+
+
+
+//定义通过串口6发送AT指令命令
+int LTE_SendCmd(char *cmd, char* reply) 
+{
+	UART6_RxCounter = 0; 
+	int timeout = 10;
+	memset(UART6_RX_BUF, 0, BUFF_SIZE);
+	HAL_UART_Transmit(&USART_InitStruct_DEBUG, (uint8_t*)cmd, strlen(cmd), HAL_MAX_DELAY);
+	while(timeout--) {
+		LTE_Delay(1);
+		if(strstr((char*)&UART6_RX_BUF, reply))
+			break;
+		printf("time = %d ", timeout);
+	}
+	printf("\r\n");
+	if(timeout <= 0)
+		return 1; 
+	return 0; 
+}
+
+// HTTP获取数据
+int LTE_HTTP_get()
+{
+	uint16_t cat1_timeout;
+	int err,httprspcode,content_length,fd;
+__start:
+	 //发送 HTTP GET 请求,最大响应时间为 80 秒
+	cat1_timeout = 0;
+   while(Iot_SendCmd("AT+QHTTPGET=80\r\n","OK",1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            goto __start;   
+        }
+    }
+	 LTE_Delay(500);
+	 char* getStr = mymalloc(SRAMEX, 64); 
+	 getStr = strstr((char*)&UART6_RX_BUF,"+QHTTPGET:");
+   if (!getStr) {
+			myfree(SRAMEX, getStr);
+      goto __start;
+    }
+	 sscanf(getStr, "+QHTTPGET: %d,%d,%d ", &err, &httprspcode, &content_length);
+	 if(200 == httprspcode)
+	 {
+		 printf("connect OK\r\n");
+		 myfree(SRAMEX, getStr);		 
+	 }
+	 else
+	 {
+		 myfree(SRAMEX, getStr);
+		 goto __start;
+	 }
+
+	 // 读取 HTTP 响应信息并将其储存到 UFS 文件中
+		cat1_timeout = 0;
+		while(Iot_SendCmd("AT+QHTTPREADFILE=\"UFS:test.txt\",80 \r\n","OK",20)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return TIMEOUT;   
+        }
+    }
+		
+		cat1_timeout = 0;
+		// 打开文件
+		while(Iot_SendCmd("AT+QFOPEN=\"test.txt\",2\r\n","OK",5)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return TIMEOUT;   
+        }
+    }
+		char* readStr = mymalloc(SRAMEX, 128); 
+	  readStr = strstr((char*)&UART6_RX_BUF,"+QFOPEN:");
+		if(!readStr)
+		{
+			myfree(SRAMEX, readStr);	
+			goto __start;
+		}
+		sscanf(readStr, "+QFOPEN:%d ", &fd);// 获取文件指针
+		myfree(SRAMEX, readStr);
+		
+		// 读取文件
+		char* readMessage = mymalloc(SRAMEX, 32); 
+    sprintf(readMessage,"AT+QFREAD=%d\r\n", fd);
+		while(Iot_SendCmd(readMessage,"OK",40)){
+      printf("%s\n",UART6_RX_BUF);  
+			LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+						myfree(SRAMEX, readMessage);
+            goto __start;   
+        }
+    }
+		myfree(SRAMEX, readMessage);
+		DeleteDirFile("device.txt");
+		write_file("device.txt",(char*)&UART6_RX_BUF,strlen((char*)&UART6_RX_BUF));
+		config_flag = 1;
+		
+		cat1_timeout = 0;
+		// 关闭文件
+		char closeCMD[32]; 
+		sprintf(closeCMD,"AT+QFCLOSE=%d\r\n", fd);
+		while(Iot_SendCmd(closeCMD,"OK",1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+						myfree(SRAMEX, closeCMD);
+            return TIMEOUT;   
+        }
+    }
+		return SUCCESS;
+}

+ 328 - 0
app/SYSTEM/source/lte_mqtt.c

@@ -0,0 +1,328 @@
+#include "LTE_MQTT.h"
+#include "lte.h"
+#include "stdint.h"
+#include "data_task.h"
+
+// 配置mqtt参数
+int MQTT_config()
+{
+		uint16_t cat1_timeout = 0;
+		char configMessage[64];
+    snprintf(configMessage, sizeof(configMessage), "AT+QMTCFG=\"version\",%d,%d \r\n",client_send_idx, MQTT_4);
+    while(Iot_SendCmd(configMessage,"OK", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return TIMEOUT;   
+        }
+    }
+		
+		cat1_timeout = 0;
+		memset(configMessage, 0, sizeof(configMessage));
+		snprintf(configMessage, sizeof(configMessage), "AT+QMTCFG=\"keepalive\",%d,120 \r\n",client_send_idx);
+    while(Iot_SendCmd(configMessage,"OK", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return TIMEOUT;   
+        }
+    }
+		// 配置需求参数
+		cat1_timeout = 0;
+		memset(configMessage, 0, sizeof(configMessage));
+		snprintf(configMessage, sizeof(configMessage), "AT+QMTCFG=\"session\",%d,1 \r\n",client_send_idx);
+    while(Iot_SendCmd(configMessage,"OK", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return TIMEOUT;   
+        }
+    }
+		
+		cat1_timeout = 0;
+		memset(configMessage, 0, sizeof(configMessage));
+		snprintf(configMessage, sizeof(configMessage), "AT+QMTCFG=\"timeout\",%d,10,3,1 \r\n",client_send_idx);
+    while(Iot_SendCmd(configMessage,"OK", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return TIMEOUT;   
+        }
+    }
+		
+		cat1_timeout = 0;
+		memset(configMessage, 0, sizeof(configMessage));
+		snprintf(configMessage, sizeof(configMessage), "AT+QMTCFG=\"will\",%d \r\n",client_send_idx);
+    while(Iot_SendCmd(configMessage,"OK", 1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            return TIMEOUT;   
+        }
+    }
+	return SUCCESS;	
+}
+
+
+uint8_t  mqtt_pulish(char* message, void* buf )
+{
+	uint8_t i;
+	HAL_UART_Transmit(&USART_InitStruct_DEBUG, (uint8_t*)message, strlen(message), HAL_MAX_DELAY);
+	while(strstr((char*)&UART6_RX_BUF,">") == NULL){
+		i++;
+		delay_ms(100);
+		if(i > 20)
+			return 0;// 失败
+	}
+	HAL_UART_Transmit(&USART_InitStruct_DEBUG, (uint8_t*)buf, strlen(buf), HAL_MAX_DELAY);
+	return 1;// 成功
+}
+// 连接MQTT- 发送模式
+void MQTT_send_connect(void const* arg)
+{
+//		MQTT_config(); 
+		uint16_t cat1_timeout = 0;
+__Start:
+		// 选择模式
+    while(Iot_SendCmd("AT+QMTCFG=\"send/mode\",0,0 \r\n","OK",1)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            goto __Start;  
+        }
+    }
+		
+		GATEWAY_PARAMS *get;
+		get= get_gateway_config_params();
+		// 打开mqtt
+		cat1_timeout = 0;
+		char message[64];
+    snprintf(message, sizeof(message),"AT+QMTOPEN=%d,%s,%d \r\n",client_send_idx,get->host,get->port);
+    while(Iot_SendCmd(message,"OK",20)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+           goto __Start;  
+        }
+    }
+			
+		// 连接服务器
+		mqtt_connectFlag = 0;
+		cat1_timeout = 0;
+		memset(message, 0, sizeof(message));
+    snprintf(message, sizeof(message), "AT+QMTCONN=%d,%s,%s,%s\r\n",
+															client_send_idx,(char*)&clientid1,get->username, get->passwd);
+    while(Iot_SendCmd(message,"OK",10)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            goto __Start;  
+        }
+    }
+
+		int result,index;
+		char* mqttStr = strstr((char*)&UART6_RX_BUF,"+QMTCONN:");
+		sscanf(mqttStr, "+QMTCONN:  %d,%d, ", &index, &result);
+
+#if 0
+		// 拿返回的result做判断
+		switch(result){
+			case NETSUCCESS:
+				break;
+			case NETERR:
+				goto __Start;
+			case 1:
+				goto __Start;
+			
+		}		
+#endif
+
+		
+		// 订阅主题
+		cat1_timeout = 0;
+		memset(message, 0, sizeof(message));
+    snprintf(message, sizeof(message), "AT+QMTSUB=%d,1,%s,0 \r\n",client_send_idx,get->commandTopic);
+    while(Iot_SendCmd(message,"OK", 5)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            goto __Start;  
+        }
+    }
+		mqtt_connectFlag = 1;
+		mqtt_message_t msg;
+		memset(&msg, 0, sizeof(msg));
+		struct Pub_Queue *pxMessage;
+		//发布消息
+		while(1)
+		{
+			if(xQueue1 != 0)
+			{		
+				if(xQueueReceive(xQueue1, &(pxMessage), (TickType_t)10))
+				{
+						// 处理队列内部数据并上传
+						msg.payloadlen = pxMessage->pubLength;
+						msg.qos = pxMessage->qos;
+						msg.payload = (void *)pxMessage->message;
+					
+						cat1_timeout = 0;
+						memset(message, 0, sizeof(message));
+						snprintf(message, sizeof(message), "AT+QMTPUBEX=%d,0,0,0,%s,%d\r\n",
+																				client_send_idx, get->messageTopic, strlen(msg.payload));		
+		
+						mqtt_pulish(message, msg.payload);
+						
+						memset(UART6_RX_BUF, 0, BUFF_SIZE);
+						myfree(SRAMEX, pxMessage->pub_topic);
+						myfree(SRAMEX, pxMessage->message);
+						myfree(SRAMEX, pxMessage);
+			
+			}
+//		watchdog_feed();
+			LTE_Delay(100);
+		}
+	}
+}
+
+// 连接MQTT- 接收模式
+void MQTT_recv_connect(void const* arg)
+{
+		uint16_t cat1_timeout = 0;
+		char message[64];
+		while(1)
+		{
+			if(mqtt_connectFlag == 1)
+			{
+				// 选择模式
+				memset(message, 0, sizeof(message));
+				snprintf(message, sizeof(message), "AT+QMTCFG=\"recv/mode\",1,0,1 \r\n");
+				while(Iot_SendCmd(message,"OK", 1)){
+						LTE_Delay(1);
+						cat1_timeout ++;
+						if(cat1_timeout >= 2000){
+								break;
+						}
+				}		
+				//接收消息
+					memset(UART6_RX_BUF, 0, BUFF_SIZE); 
+					char* cmd = "AT+QMTRECV=0,1\r\n";
+					HAL_UART_Transmit(&USART_InitStruct_DEBUG, (uint8_t*)cmd, strlen(cmd), HAL_MAX_DELAY);
+					while(1){
+						char* payloadstr = mymalloc(SRAMEX, 1024);
+						payloadstr = strstr((char*)UART6_RX_BUF, "+QMTRECV:");
+						if (!payloadstr)
+						{
+							myfree(SRAMEX, payloadstr);
+						}
+						else
+						{
+							payloadstr = strstr((char*)UART6_RX_BUF, "{");
+							sprintf(payloadstr + strlen(payloadstr) - 3 , " ");
+							write_modbus_data(payloadstr);
+						}
+					memset(UART6_RX_BUF, 0, BUFF_SIZE); 
+					LTE_Delay(100);						
+				}
+			}
+//			watchdog_feed();
+			LTE_Delay(100);
+		}
+}
+#if 0
+void MQTT_send_connect(void* arg)
+{
+		uint16_t cat1_timeout = 0;
+		void *mboxMsg;
+		uint8_t err;
+		char message[64];
+__Start:
+		memset(message, 0, sizeof(message));
+    snprintf(message, sizeof(message), "AT+QMTCFG=\"recv/mode\",%d,0,1 \r\n",client_recv_idx);
+    while(Iot_SendCmd(message,"OK", 5)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            goto __Start;  
+        }
+    }
+		// 打开mqtt
+		cat1_timeout = 0;
+    snprintf(message, sizeof(message),"AT+QMTOPEN=%d,\"36.134.23.11\",1883 \r\n",client_recv_idx);
+    while(Iot_SendCmd(message,"OK",20)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            goto __Start; 
+        }
+    }
+		// 连接服务器
+		mqtt_connectFlag = 0;
+		cat1_timeout = 0;
+		memset(message, 0, sizeof(message));
+    snprintf(message, sizeof(message), "AT+QMTCONN=%d,%s\r\n",client_send_idx,(char*)&clientid1);
+    while(Iot_SendCmd(message,"OK",10)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            goto __Start;  
+        }
+    }
+		// 订阅主题
+		cat1_timeout = 0;
+		memset(message, 0, sizeof(message));
+    snprintf(message, sizeof(message), "AT+QMTSUB=%d,1,\"test0003/command\",0 \r\n",client_send_idx);
+    while(Iot_SendCmd(message,"OK",10)){
+        LTE_Delay(1);
+        cat1_timeout ++;
+        if(cat1_timeout >= 2000){
+            goto __Start;  
+        }
+    }
+		while(1)
+		{
+			
+			mboxMsg = OSMboxPend(mqtt_sendMseeageMbox, 1000, &err);
+			if(OS_ERR_NONE == err)
+			{
+				if((*(unsigned int *)mboxMsg) == MBOX_NETWORK_ERROR) goto __Start;
+				else
+				{
+						cat1_timeout = 0;
+						memset(message, 0, sizeof(message));
+						snprintf(message, sizeof(message), "AT+QMTPUBEX=%d,0,0,0,\"test0003\",%d\r\n",client_send_idx,strlen(pubJsonString));
+						while(Iot_SendCmd(message,">",2)){
+								LTE_Delay(1);
+								cat1_timeout ++;
+								if(cat1_timeout >= 2000){
+										goto __Start;
+								}
+						}
+						cat1_timeout = 0;
+						while(Iot_SendCmd(pubJsonString,"+QMTPUBEX", 5)){
+								LTE_Delay(1);
+								cat1_timeout ++;
+								if(cat1_timeout >= 2000){
+										goto __Start;
+								}
+						}		
+						memset(pubJsonString, 0, strlen(pubJsonString));
+			}	
+		}
+			LTE_Delay(100);
+		}
+	
+}
+#endif
+
+void MQ_threadCreate()
+{
+//	mqtt_client_t *client = NULL; // 创建一个客户端
+	mqtt_log_init();
+	printf("\nwelcome to mqttclient test...\n");
+	xQueue1 = xQueueCreate(10, sizeof(struct Pub_Queue *)); // 创建一个mqtt上传的队列
+	osThreadDef(MQTT_send_task, MQTT_send_connect, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 8);
+	osThreadCreate (osThread(MQTT_send_task), NULL);
+	osThreadDef(MQTT_recv_task, MQTT_recv_connect, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 8);
+  osThreadCreate (osThread(MQTT_recv_task), NULL);
+}
+

+ 48 - 24
app/SYSTEM/source/myFile.c

@@ -19,7 +19,9 @@ void write_file(const char* filename, const char* data, uint32_t length)
 	result = f_mount(&fs, FS_VOLUME_NAND, 0);			/* Mount a logical drive */
 	if (result != FR_OK)
 	{
-		LOG_PRINT(LOG_ERROR,"(%d)\r\n", result);
+//		LOG_PRINT(LOG_ERROR,"(%d)\r\n", result);
+		printf("挂载文件系统失败 (%d)\r\n", result);
+		
 	}
 
 	/* 打开根文件夹 */
@@ -30,7 +32,8 @@ void write_file(const char* filename, const char* data, uint32_t length)
 	}
 	if (result != FR_OK)
 	{	
-		LOG_PRINT(LOG_ERROR,"打开根目录失败 (%d)\r\n", result);
+//		LOG_PRINT(LOG_ERROR,"打开根目录失败 (%d)\r\n", result);
+		printf("打开根目录失败 (%d)\r\n", result);
 		return ;
 	}
   char filepath[30];
@@ -43,12 +46,13 @@ void write_file(const char* filename, const char* data, uint32_t length)
 	result = f_write(&file,data, length, &bw);
 	if (result == FR_OK)
 	{
-		LOG_PRINT(LOG_INFO,"文件写入成功\r\n");
-		
+//		LOG_PRINT(LOG_INFO,"文件写入成功\r\n");
+		printf("文件写入成功\r\n");
 	}
 	else
 	{
-		LOG_PRINT(LOG_ERROR,"文件写入失败\r\n");
+//		LOG_PRINT(LOG_ERROR,"文件写入失败\r\n");
+		printf("文件写入失败\r\n");
 	}
 	/* 关闭文件*/
 	f_close(&file);
@@ -78,7 +82,8 @@ void read_file(const char* filename, char* data)
 	
 	if (result != FR_OK)
 	{
-		LOG_PRINT(LOG_ERROR,"挂载文件系统失败(%d)\r\n", result);
+//		LOG_PRINT(LOG_ERROR,"挂载文件系统失败(%d)\r\n", result);
+		printf("挂载文件系统失败(%d)\r\n", result);
 	}
 
 	/* 打开根文件夹 */
@@ -89,7 +94,8 @@ void read_file(const char* filename, char* data)
 	}
 	if (result != FR_OK)
 	{
-		LOG_PRINT(LOG_ERROR,"打开根目录失败(%d)\r\n", result);		
+//		LOG_PRINT(LOG_ERROR,"打开根目录失败(%d)\r\n", result);		
+		printf("打开根目录失败(%d)\r\n", result);
 		goto _exit_file;
 	}
 	char filepath[30];
@@ -98,7 +104,8 @@ void read_file(const char* filename, char* data)
 	result = f_open(&file, filepath, FA_OPEN_EXISTING | FA_READ);
 	if (result !=  FR_OK)
 	{
-		LOG_PRINT(LOG_ERROR,"Don't Find File \r\n");			
+//		LOG_PRINT(LOG_ERROR,"Don't Find File \r\n");		
+		printf("Don't Find File \r\n");		
 		goto _exit_file;
 	}
 
@@ -107,11 +114,13 @@ void read_file(const char* filename, char* data)
 	result= f_read(&file, data, f_size(&file), &bw);
 	if (bw > 0)
 	{
-		LOG_PRINT(LOG_INFO,"\r\%s 文件内容 : \r\n%s\r\n", filename,data);			
+		//LOG_PRINT(LOG_INFO,"\r\%s 文件内容 : \r\n%s\r\n", filename,data);		
+		printf("\r\%s 文件内容 : \r\n%s\r\n", filename,data);		
 	}
 	else
 	{
-		LOG_PRINT(LOG_INFO,"\r\%s 文件内容 : \r\n%s\r\n", filename);			
+		//LOG_PRINT(LOG_INFO,"\r\%s 文件内容 : \r\n%s\r\n", filename);	
+		printf("\r\%s 文件内容 : \r\n",filename);
 	}
 	_exit_file:
 	/* 关闭文件*/
@@ -142,20 +151,23 @@ void ViewRootDir(void)
 	result = f_mount(&fs, FS_VOLUME_NAND, 0);	/* Mount a logical drive */	
 	if (result != FR_OK)
 	{
-		LOG_PRINT(LOG_ERROR,"挂载文件系统失败(%d)\r\n", result);
+//		LOG_PRINT(LOG_ERROR,"挂载文件系统失败(%d)\r\n", result);
+		printf("挂载文件系统失败 (%d)\r\n", result);
 	}
 	/* 打开根文件夹 */
 	result = f_opendir(&DirInf, "0:/"); /* 0: 表示盘符 */
 	if (result != FR_OK)
 	{
-		LOG_PRINT(LOG_ERROR,"打开根目录失败(%d)\r\n", result);
+//		LOG_PRINT(LOG_ERROR,"打开根目录失败(%d)\r\n", result);
+		printf("打开根目录失败 (%d)\r\n", result);
 		return;
 	}
 
 	/* 读取当前文件夹下的文件和目录 */
 	FileInf.lfname = lfname;
 	FileInf.lfsize = 256;
-	LOG_PRINT(LOG_INFO,"属性 |  文件大小 | 短文件名 | 长文件名\r\n");
+//	LOG_PRINT(LOG_INFO,"属性 |  文件大小 | 短文件名 | 长文件名\r\n");
+	printf("属性 |  文件大小 | 短文件名 | 长文件名\r\n");
 	for (cnt = 0; ;cnt++)
 	{
 		result = f_readdir(&DirInf,&FileInf); 		/* 读取目录项,索引会自动下移 */
@@ -172,18 +184,25 @@ void ViewRootDir(void)
 		/* 判断是文件还是子目录 */
 		if (FileInf.fattrib & AM_DIR)
 		{
-			LOG_PRINT(LOG_INFO,"(0x%02d)目录  ", FileInf.fattrib);			
+//			LOG_PRINT(LOG_INFO,"(0x%02d)目录  ", FileInf.fattrib);
+			printf("(0x%02d)目录  ", FileInf.fattrib);			
 		}
 		else
 		{
-			LOG_PRINT(LOG_INFO,"(0x%02d)文件  ", FileInf.fattrib);			
+//			LOG_PRINT(LOG_INFO,"(0x%02d)文件  ", FileInf.fattrib);	
+			printf("(0x%02d)文件  ", FileInf.fattrib);			
 		}
 
-		/* 打印文件大小, 最大4G */
-		LOG_PRINT(LOG_INFO," %10d", FileInf.fsize);		
-		LOG_PRINT(LOG_INFO,"  %s |", FileInf.fname);
+//		/* 打印文件大小, 最大4G */
+//		LOG_PRINT(LOG_INFO," %10d", FileInf.fsize);		
+//		LOG_PRINT(LOG_INFO,"  %s |", FileInf.fname);
+
+//		LOG_PRINT(LOG_INFO,"  %s\r\n", (char *)FileInf.lfname);
+				/* 打印文件大小, 最大4G */
+		printf(" %10d", FileInf.fsize);
+		printf("  %s |", FileInf.fname);	/* 短文件名 */
 
-		LOG_PRINT(LOG_INFO,"  %s\r\n", (char *)FileInf.lfname);
+		printf("  %s\r\n", (char *)FileInf.lfname);	/* 长文件名 */
 	}
 
 	/* 卸载文件系统 */
@@ -210,7 +229,8 @@ void DeleteDirFile(const char* filename)
 	result = f_mount(&fs, FS_VOLUME_NAND, 0);			/* Mount a logical drive */
 	if (result != FR_OK)
 	{
-		LOG_PRINT(LOG_ERROR,"挂载文件系统失败(%d)\r\n", result);
+//		LOG_PRINT(LOG_ERROR,"挂载文件系统失败(%d)\r\n", result);
+		printf("挂载文件系统失败 (%d)\r\n", result);
 	}
 
 	#if 0
@@ -218,7 +238,8 @@ void DeleteDirFile(const char* filename)
 	result = f_opendir(&DirInf, "0:/"); /* 如果不带参数,则从当前目录开始 */
 	if (result != FR_OK)
 	{
-		LOG_PRINT(LOG_ERROR,"挂载文件系统失败(%d)\r\n", result);
+//		LOG_PRINT(LOG_ERROR,"挂载文件系统失败(%d)\r\n", result);
+		printf("打开根目录失败(%d)\r\n", result);
 		return;
 	}
 	#endif
@@ -226,15 +247,18 @@ void DeleteDirFile(const char* filename)
 	result = f_unlink(FileName);
 	if (result == FR_OK)
 	{
-		LOG_PRINT(LOG_ERROR,"删除文件 %s 成功\r\n",filename);		
+//		LOG_PRINT(LOG_ERROR,"删除文件 %s 成功\r\n",filename);
+		printf("删除文件 %s 成功\r\n",filename);		
 	}
 	else if (result == FR_NO_FILE)
 	{
-		LOG_PRINT(LOG_ERROR,"没有发现文件或目录 :%s\r\n", filename);			
+//		LOG_PRINT(LOG_ERROR,"没有发现文件或目录 :%s\r\n", filename);	
+		printf("没有发现文件或目录 :%s\r\n", filename);
 	}
 	else
 	{
-		LOG_PRINT(LOG_ERROR,"删除%s失败(错误代码 = %d) 文件只读或目录非空\r\n",filename,result);		
+//		LOG_PRINT(LOG_ERROR,"删除%s失败(错误代码 = %d) 文件只读或目录非空\r\n",filename,result);	
+		printf("删除%s失败(错误代码 = %d) 文件只读或目录非空\r\n",filename,result);
 	}
 	/* 卸载文件系统 */
 	f_mount(NULL, FS_VOLUME_NAND, 0);

+ 72 - 0
app/SYSTEM/source/sys_http.c

@@ -0,0 +1,72 @@
+#include "http_client.h"
+#include "string.h"
+#include "stdio.h"
+#include "main.h"
+#include "myFIle.h"
+#include "sys_http.h"
+#include "log.h"
+#include "main.h"
+  
+uint8_t load_http_config=0;
+//get请求  http://gpu.ringzle.com:8082/iot/transmit/getTransmitConfig/DT8pd3ac6h 端口8082
+//目前为此处去控制http一次性读入数据大小,应为该处为读入函数
+void http_getDemo(void)
+{
+	int datalen;
+	int ret;
+	char* device_config = mymalloc(SRAMEX, 10);
+	memset(device_config, 0,10);
+	read_file("device.txt", device_config);
+	if((strstr(device_config,"tcp_config")) == NULL)
+	{
+			myfree(SRAMEX, device_config);
+			char *http_data=mymalloc(SRAMEX, 20 * 1024);
+			char *http=mymalloc(SRAMEX,50);
+			sprintf(http,"/iot/transmit/getTransmitConfig/%s",gatewayId);
+			ret = http_clientGet("gpu.ringzle.com", http, 8082, 0, (uint8_t*)http_data, &datalen);
+			if(ret==200) //获取成功
+			{
+				DeleteDirFile("device.txt");	
+				write_file("device.txt",http_data,strlen(http_data));
+				load_http_config=1;
+				printf("http get demo success\n");
+			}
+			HTTP_PRINTF("%s", (char *)http_data);
+			HTTP_PRINTF("\r\n ret=%d datalen=%d\r\n", ret, datalen);
+			myfree(SRAMEX,http_data);
+			myfree(SRAMEX,http);
+			return;
+	}
+	myfree(SRAMEX, device_config);
+}
+
+
+char *postData = "{\"bandwidth\":250,\"codeRate\":4700}";
+
+uint8_t postResult[512];
+
+//POST请求 http://gpu.ringzle.com/iot/test/httpTest  端口号8082
+void http_postDemo(void)
+{
+	int datalen, ret;
+	
+	memset(postResult, 0, sizeof(postResult));
+	
+//	ret = http_clientPost("gpu.ringzle.com", "/iot/test/httpTest", 8082, 0, http_data, 5837, postResult, &datalen);
+	ret = http_clientPost("gpu.ringzle.com", "/iot/test/httpTest", 8082, 0, (uint8_t *)postData, strlen(postData), postResult, &datalen);
+	
+	HTTP_PRINTF("%s", (char *)postResult);
+	HTTP_PRINTF("\r\n ret=%d datalen=%d\r\n", ret, datalen);	
+}
+/*
+*********************************************************************************************************
+*	函 数 名: int get_http_config(void)
+*	功能说明: 获取http配置的相关参数
+*	形    参:无
+*	返 回 值: 返回http是否配置 0:没有配置过,1:配置过
+*********************************************************************************************************
+*/
+int get_http_config(void)
+{
+	return load_http_config;
+}

+ 146 - 0
app/SYSTEM/source/sys_mqtt.c

@@ -0,0 +1,146 @@
+/*
+ * @Author: jiejie
+ * @Github: https://github.com/jiejieTop
+ * @Date: 2019-12-11 21:53:07
+ * @LastEditTime : 2022-06-15 23:03:30
+ * @Description: the code belongs to jiejie, please keep the author information and source code according to the license.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "mqtt_config.h"
+#include "mqtt_log.h"
+#include "sys_mqtt.h"
+#include "sys_http.h"
+#include "gateway_message.h"
+#include "data_task.h"
+#include "app_ethernet.h"
+#include "tcp_server.h"
+#include "main.h"
+
+
+
+int mqtt_connectFlag;
+static void mqtt_publish_task(void const *arg);
+/*
+ *接收并处理mqtt订阅消息
+ */
+static void topic1_handler(void *client, message_data_t *msg)
+{
+	(void)client;
+	MQTT_LOG_I("topic: %s\nmessage:%s", msg->topic_name, (char *)msg->message->payload);
+	LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"Write Modbus Data");
+	// json 解析数据
+	write_modbus_data((char*)msg->message->payload);
+}
+/*
+ *初始化mqtt连接
+ */
+int8_t mqtt_init(mqtt_client_t *client, char *clientId, char *user_name, char *password, char *ip, char* port, uint16_t keepAlive)
+{
+	mqtt_set_client_id(client, clientId);
+	mqtt_set_port(client, port);
+	mqtt_set_host(client, ip);
+	mqtt_set_user_name(client, user_name);
+	mqtt_set_password(client, password);
+	mqtt_set_clean_session(client, 1);
+	mqtt_set_keep_alive_interval(client, keepAlive);
+	return mqtt_connect(client);
+}
+// 发送数据队列句柄
+QueueHandle_t xQueue1;
+void mqtt_task_creat()
+{
+//	mqtt_client_t *client = NULL; // 创建一个客户端
+	mqtt_log_init();
+	printf("\nwelcome to mqttclient test...\n");
+	xQueue1 = xQueueCreate(10, sizeof(struct Pub_Queue *)); // 创建一个mqtt上传的队列
+	osThreadDef(MQTT_task, mqtt_publish_task, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 8);
+  osThreadCreate (osThread(MQTT_task), NULL);
+}
+
+static void mqtt_publish_task(void const *arg)
+{
+	mqtt_client_t *client = NULL; // 创建一个客户端
+	client = mqtt_lease();
+	
+	GATEWAY_PARAMS *get;
+	get= get_gateway_config_params();	
+	int rc;
+	char port[6];
+
+__MQTT_START:
+	rc = -1;
+
+	while (rc != 0)
+	{
+		vTaskDelay(500);
+		sprintf(port, "%hu", get->port);
+	  rc = mqtt_init(client, "client_id_002", (char*)&get->username,(char*)&get->passwd,(char*)&get->host,port, 120);				
+//	  rc = mqtt_init(client, "client_id_002", "device","Dev&*(789","183.162.218.20","1883", 120);	
+	}
+	LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"MQTT Connect success");
+	mqtt_connectFlag = 1;
+	if(mqtt_subscribe(client, (char*)&get->commandTopic, QOS0, topic1_handler) != 0)
+	{
+		LogPrint(LOG_WARN,__FILE__,__FUNCTION__,__LINE__,"MQTT Subscribe fail");
+	}
+	mqtt_message_t msg;
+	memset(&msg, 0, sizeof(msg));
+	mqtt_list_subscribe_topic(client);
+	struct Pub_Queue *pxMessage;
+	while (1)
+	{
+		if (xQueue1 != 0)
+		{
+			if (xQueueReceive(xQueue1, &(pxMessage), (TickType_t)10))
+			{
+				// 处理队列内部数据并上传
+				msg.payloadlen = pxMessage->pubLength;
+				msg.qos = pxMessage->qos;
+				msg.payload = (void *)pxMessage->message;
+				if(mqtt_publish(client, pxMessage->pub_topic, &msg) != 0)// 0:成功
+				{
+					
+					LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"MQTT Publish Failed");
+					mqtt_unsubscribe(client,(char*)&get->commandTopic);
+					mqtt_disconnect(client);
+					platform_thread_destroy(client->mqtt_thread);
+					client->mqtt_thread = NULL;
+					goto __MQTT_START;
+				}
+				LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"MQTT Publish Message");
+				myfree(SRAMEX, pxMessage->pub_topic);
+				myfree(SRAMEX, pxMessage->message);
+				myfree(SRAMEX, pxMessage);
+			}
+		}
+		vTaskDelay(500);
+	}	
+}
+/*
+ *  函数名:void mqtt_publish_data(uint8_t *payload,mqtt_qos_t qos,uint16_t pub_length,char *topic)
+ *  输入参数:payload上传的数据包,qos以什么等级去发布数据,pub_length上传的数据包长度,topic上传的topic
+ *  输出参数:无
+ *  返回值:无
+ *  函数作用:向队列中写入mqtt上传的消息
+ *  TODO:队列满无法写入的情况处理
+ */
+
+void mqtt_publish_data(char *payload, mqtt_qos_t qos, uint16_t pub_length, char *topic)
+{
+	struct Pub_Queue *pxMessage = mymalloc(SRAMEX, sizeof(struct Pub_Queue));
+	pxMessage->message = mymalloc(SRAMEX, pub_length + 1);
+	memset(pxMessage->message, 0, (pub_length + 1));
+	memcpy(pxMessage->message, payload, pub_length);
+	pxMessage->pub_topic = mymalloc(SRAMEX,strlen(topic) + 1);
+	memset(pxMessage->pub_topic, 0, (strlen(topic) + 1));
+	strcpy(pxMessage->pub_topic, topic);
+	
+	pxMessage->pubLength = pub_length;
+	pxMessage->qos = qos;
+	
+	if(pxMessage->message == NULL)
+		LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"queue message malloc fail");
+	
+	xQueueSend(xQueue1, (void *)&pxMessage, (TickType_t)0);
+}

+ 113 - 0
app/SYSTEM/source/sys_udp.c

@@ -0,0 +1,113 @@
+/*!
+    \file  udp_echo.c
+    \brief UDP demo program  
+
+    \version 2017-02-10, V1.0.0, firmware for GD32F30x
+    \version 2018-10-10, V1.1.0, firmware for GD32F30x
+    \version 2018-12-25, V2.0.0, firmware for GD32F30x
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "lwip/opt.h"
+#include "lwip/tcp.h"
+#include "lwip/sys.h"
+#include "sys_udp.h"  
+#include <string.h>
+#include <stdio.h>
+#include "stm32f2xx.h"
+#include "lwip/memp.h"
+#include "main.h"
+#include "lwip/api.h"
+
+
+#define UDP_TASK_PRIO       ( tskIDLE_PRIORITY + 5)
+#define MAX_BUF_SIZE        50
+
+
+#include "lwip/sockets.h"
+
+/*!
+    \brief      udp echo task 
+    \param[in]  arg: user supplied argument
+    \param[out] none
+    \retval     none
+*/
+volatile int8_t sockfd=-1;
+#define UDP_LOCAL_PORT 12345
+#define UDP_REMOTE_PORT 54321
+#define SERCER_IP_ADDRESS "192.168.2.22"       //接收服务器ip
+struct sockaddr_in remote_addr;
+int udp_log_start()
+{
+	int ret;
+	struct sockaddr_in local_addr;
+	// 创建UDP套接字
+  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+  if (sockfd < -1) {
+    perror("Error creating socket");
+		goto exit;
+  }
+	local_addr.sin_family=AF_INET;
+	local_addr.sin_port=htons(UDP_LOCAL_PORT);
+	local_addr.sin_addr.s_addr=INADDR_ANY;
+	ret = bind(sockfd, (struct sockaddr *)&local_addr, sizeof(local_addr));
+  if(ret < 0)
+	{ 
+    lwip_close(sockfd);
+    sockfd = -1;
+    goto exit;
+  }
+	//设置远程服务器地址 TODO:服务器地址配置后自动获取
+	remote_addr.sin_family=AF_INET;
+	remote_addr.sin_port=htons(UDP_REMOTE_PORT);
+	inet_aton(SERCER_IP_ADDRESS,&(remote_addr.sin_addr));
+	return 1;
+	
+exit:
+			return -1;
+}
+
+
+void udp_log_close()
+{
+	lwip_close(sockfd);
+	sockfd=-1;
+}
+
+
+int udp_send_printf(char *p)
+{
+	if(sockfd>=0)
+	{
+		sendto(sockfd, p, strlen(p), 0, (struct sockaddr *)&remote_addr,sizeof(remote_addr));
+	}
+	return 1;
+}

+ 393 - 0
app/SYSTEM/source/tcp_server.c

@@ -0,0 +1,393 @@
+#include "lwip/opt.h"
+#include "lwip/sys.h"
+#include "tcp_server.h"
+#include <string.h>
+#include <stdio.h>
+#include "stm32f2xx.h"
+#include "main.h"
+#include "lwip/tcp.h"
+#include "lwip/memp.h"
+#include "lwip/api.h"
+#include "lwip/sockets.h"
+#include "log.h"
+#include "app_ethernet.h"
+#include "gateway_message.h"
+#include "stdlib.h"
+#include "timer.h"
+#include "sys_mqtt.h"
+#include "updata.h"
+#include "app_ethernet.h"
+#include "stm32f2xx_hal.h"
+#include "myFile.h"
+
+
+uint8_t closeFlag = 0;				// DHCP关闭标志位
+uint8_t ProtocolsModeFlag = 1;// 开启内置协议模式
+
+ip_config load_ip_config = {0};
+ip_config *get_ip_config()
+{
+    return &load_ip_config;
+}
+uint8_t TransparentModeFlag = 0;	// 表示用串口透传 将数据原封不动的发给客户端
+#if 1
+// 解析设备当前的硬件信息(结构体内的数据)
+void get_device_params(char* device_params)
+{
+	GATEWAY_PARAMS *get;
+	get= get_gateway_config_params();
+	DEVICE_PARAMS *current_device=get->device_params;
+	sprintf(device_params, "{\"read_config\":\"success\",\"baudrate\":%d,\"checkBit\":%d,\"commandTopic\":\"%s\",\"dataBit\":%d,\
+\"deviceId\":\"%s\",\"host\":\"%s\",\"inboundTime\":%d,\"messageTopic\":\"%s\",\"port\":%d,\"stopBit\":%d,\"deviceList\":[",get->baudrate,
+			get->checkBit,get->commandTopic,get->dataBits,get->deviceId,get->host,get->inboundTime,get->messageTopic,get->port,get->stopBit);
+	while(current_device != NULL)
+	{	
+		sprintf(device_params + strlen(device_params),"{\"protocol\":%d,\"bigLittleFormat\":%d,\"deviceId\":\"%s\",\"sensorData\":[",
+												current_device->protocol,current_device->MDBbigLittleFormat,current_device->deviceID);
+			GATEWAY_READ_DLT645_COMMAND *read_dlt645_command = current_device->params->gateway_read_dlt645_command;
+			GATEWAY_READ_MODBUS_COMMAND *read_modbus_command = current_device->params->gateway_read_modbus_command;
+			GATEWAY_WRITE_MODBUS_COMMAND *write_modbus_command = current_device->params->gateway_write_modbus_command;
+			
+			// dlt645 read
+			while(read_dlt645_command != NULL)
+			{	
+				sprintf(device_params + strlen(device_params),"{\"identifier645\":%d,\"identifier\":\"%s\",\"deviceID645\":\"%s\"},",
+											read_dlt645_command->Identification,read_dlt645_command->keyword,read_dlt645_command->deviceID645);
+				read_dlt645_command = read_dlt645_command->nextParams;
+			}
+		
+			// modbus read
+			while(read_modbus_command != NULL)
+			{
+				sprintf(device_params + strlen(device_params),"{\"rFunctionCode\":%d,\"registerAddress\":%d,\"slaveAddress\":%d,\"registerByteNum\":%d,\"identifier\":\"%s\",\"precise\":%d},",
+																											read_modbus_command->functionCode, read_modbus_command->registerAddress,read_modbus_command->slaveAddress,
+																											read_modbus_command->registerByteNum,read_modbus_command->keyword,read_modbus_command->decimalPoint);
+				read_modbus_command = read_modbus_command->nextParams;
+			}
+			
+			// modbus write
+			sprintf(device_params + strlen(device_params)-1,"], \"commandData\":[");//sensorData:[ 
+			while(write_modbus_command != NULL)
+			{
+				sprintf(device_params + strlen(device_params),"{\"registerAddress\":%d,\"slaveAddress\":%d,\"wFunctionCode\":%d,\"registerByteNum\":%d},",
+								write_modbus_command->registerAddress,write_modbus_command->slaveAddress,write_modbus_command->functionCode,write_modbus_command->registerByteNum);
+				write_modbus_command = write_modbus_command->nextParams;
+			}		
+			sprintf(device_params + strlen(device_params)-1,"]},");// commandData:[
+			current_device = current_device->nextDevice;	
+	}
+	sprintf(device_params + strlen(device_params) -1 ,"]}");
+}
+
+// 储存上位机发送的config数据,并返回上位机操作结果
+void save_config(int client_socket,char* buf)
+{
+		char* saveData = mymalloc(SRAMEX,20 * 1024);//(RECV_BUF_SIZE);// 存储config数据			最大20K
+		if(saveData == NULL) 
+			LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"recv buf malloc fail");
+		memset(saveData,0,strlen(saveData));	
+		// 插入tcp_config标志位,后续不通过http获取默认配置数据
+		sprintf(saveData, "tcp_config");
+		sprintf(saveData + strlen(saveData),"%s",buf);
+		// 	获取上位机发送的数据
+		do{
+				memset(buf, 0, strlen(buf));
+				recv(client_socket,buf,1460,0);	
+				memcpy(saveData + strlen(saveData), buf, strlen(buf));
+			}while(buf[1] != 0 && buf[1459] != 0);
+		
+		DeleteDirFile("device.txt");
+		write_file("device.txt",saveData,strlen(saveData));// 储存到flash 不用判断失败
+		myfree(SRAMEX, saveData);
+		
+		char* retMsg = mymalloc(SRAMEX,32);
+		memset(retMsg, 0, strlen(retMsg));
+		retMsg = "{\"write_config\":\"success\"}";
+		send(client_socket, retMsg, strlen(retMsg), 0);	
+		myfree(SRAMEX ,retMsg);
+}
+// 储存上位机发送的config_add数据,并返回上位机操作结果
+void add_config(int client_socket, char* dataBuf)
+{	
+	GATEWAY_PARAMS *get;
+	get= get_gateway_config_params();
+	DEVICE_PARAMS *device=get->device_params;
+	char* retMsg = mymalloc(SRAMEX,32);
+	memset(retMsg, 0, strlen(retMsg));
+	while(device != NULL)// 一直轮询到当前为NULL
+	{
+		device = device->nextDevice;
+	}
+	addDevice(dataBuf);
+	// 再检查更新后的deviceId是否为NULL
+	if(device == NULL)// error
+	{	
+		retMsg = "{\"write_config\":\"error\"}";
+		send(client_socket, retMsg, strlen(retMsg), 0);	
+	}
+	else// success
+	{
+		retMsg = "{\"write_config\":\"success\"}";
+		send(client_socket, retMsg, strlen(retMsg), 0);	
+	}
+		myfree(SRAMEX, retMsg);
+}
+// 设备嗅探
+void find_device(int client_socket)
+{
+	char deviceId[50];// 发送设备名
+	GATEWAY_PARAMS *get;
+	get= get_gateway_config_params();
+	if(get->device_params == NULL)
+	{	
+		sprintf(deviceId, "{\"find_device\":\"%s\"}", gatewayId);		
+		send(client_socket, deviceId, strlen(deviceId), 0);
+	}
+	else
+	{
+		sprintf(deviceId, "{\"find_device\":\"%s\"}", get->deviceId);		
+		send(client_socket, deviceId, strlen(deviceId), 0);
+	}
+	memset(deviceId, 0, 50);
+}
+
+// 发送设备当前的config数据
+void send_config(int client_socket)
+{
+	GATEWAY_PARAMS *get;
+	get= get_gateway_config_params();
+	char* device_params = mymalloc(SRAMEX, 3 * 1024);
+	memset(device_params,0,3 * 1024);
+	if(get->device_params == NULL)
+	{
+		sprintf(device_params, "{\"read_config\":\"error\"}");
+		send(client_socket, device_params, strlen(device_params), 0);
+	}
+	else
+	{
+		get_device_params(device_params);
+		send(client_socket, device_params, strlen(device_params), 0);
+	}
+	myfree(SRAMEX, device_params);
+}
+
+// 解析上位机发送的ip_config数据
+void analysis_ip_config(int client_socket, int sockfd,struct sockaddr_in tcpServerSock, char* buf)
+{
+		// 打开DHCP
+		if (strstr(buf, "\"dhcpMode\":\"open\"") != NULL)
+		{
+			DHCP_open();			
+			char* retMsg = mymalloc(SRAMEX,32);
+			retMsg = "{\"ip_config\":\"success\"}";
+			send(client_socket,retMsg,strlen(retMsg),0);
+			myfree(SRAMEX, retMsg);
+		}
+		// 关闭DHCP
+		else if (strstr(buf, "\"dhcpMode\":\"close\"") != NULL)
+		{		
+			uint8_t prot[6];
+			// 设置静态IP地址,并关闭DHCP
+			set_ipaddr(buf);
+			// 解析buf内的数据,保存到load_ip_config结构体
+			parseStringField(buf, "\"ipv4\":\"", (char *)&load_ip_config.host);// eg:192.168.1.100
+			parseStringField(buf, "\"subnetMask\":\"", (char *)&load_ip_config.subnetMask);// eg:255.255.255.0
+			parseStringField(buf, "\"defaultGateway\":\"", (char *)&load_ip_config.defaultGateway);// eg:192.168.1.1
+			parseStringField(buf, "\"udpLogPort\":\"", (char *)&prot);
+			load_ip_config.udpLogPort = atoi((char *)&prot);
+			// 关闭服务端和客户端
+			lwip_close(sockfd);	
+			lwip_close(client_socket);
+			// DHCP关闭标志位置 1 
+			closeFlag = 1;
+		}
+}
+
+// 切换工作模式
+void work_mode(char* buf)
+{
+	/* 用标志位开关data_task任务中,发送数据的方式 */
+		// 内置协议模式
+		if(strstr(buf,"protocolsMode") != NULL)
+		{
+			ProtocolsModeFlag = 1;// 开启内置协议模式
+			TransparentModeFlag = 0; // 关闭透明传输模式
+			LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"ProtocolsMode");	
+		}
+		// 透明传输模式
+		if(strstr(buf,"TransparentMode") != NULL)
+		{
+			ProtocolsModeFlag = 0;// 关闭内置协议模式
+			TransparentModeFlag = 1; // 开启透明传输模式
+			LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"TransparentModeFlag");	
+		}
+}
+#endif
+void tcp_server_task(void const * argument)
+{
+    int ret,sockfd;
+		int recv_size;
+    struct sockaddr_in tcpServerSock;
+    struct sockaddr_in client_sock;
+		// 命令集
+		char* recv_cmd[] = {"\"cmd\":\"write_config\"","\"cmd\":\"write_config_add\"",
+												"\"cmd\":\"read_config\"","\"cmd\":\"find_device\"",
+												"\"cmd\":\"ip_config\"","\"cmd\":\"toggle_work_mode\"",
+												"\"cmd\":\"software_update\"","\"cmd\":\"reboot\""};
+		
+		while(dhcp_done!=1)	{vTaskDelay(100);}
+
+    tcpServerSock.sin_family = AF_INET;
+		inet_aton("192.168.0.100",&(tcpServerSock.sin_addr));
+//    tcpServerSock.sin_addr.s_addr = htonl(IPADDR_ANY);
+    tcpServerSock.sin_port = htons(8080);
+tcp_server_begin:
+    sockfd = socket(AF_INET, SOCK_STREAM, 0);
+    if (sockfd < 0)
+    {
+        goto tcp_server_begin;
+    }
+    ret = bind(sockfd, (struct sockaddr *)&tcpServerSock, sizeof(tcpServerSock));
+    if (ret < 0)
+    {
+        lwip_close(sockfd);
+        sockfd = -1;
+        goto tcp_server_begin;
+    }
+    ret = listen(sockfd, 10);
+    if (ret < 0)
+    {
+        lwip_close(sockfd);
+        sockfd = -1;
+        goto tcp_server_begin;
+    }
+		socklen_t len = sizeof(client_sock);
+    int client_socket = accept(sockfd, (struct sockaddr*)&client_sock,&len);
+		if (client_socket<0)
+    {
+      printf("error");
+    }
+		LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"PC connect success");	
+    while (1)
+    {		
+				vTaskDelay(100);
+
+				char *dataBuf= mymalloc(SRAMEX,RECV_BUF_SIZE);// 存储上位机下发数据			
+				
+				memset(dataBuf,0,RECV_BUF_SIZE);
+				// 	获取上位机发送的数据
+				recv_size=recv(client_socket,dataBuf,RECV_BUF_SIZE,0);
+
+					// 接收到消息
+					// 解析上位机发送的CMD命令	
+					if(recv_size>0)
+					{
+						int j = 0;
+						for(int i = 0; i < sizeof(recv_cmd)/sizeof(recv_cmd[0]); i++)
+						{
+							if(strstr(dataBuf,recv_cmd[i]) != NULL)
+							{
+								i = sizeof(recv_cmd)/sizeof(recv_cmd[0]);
+							}
+							j++;
+						}
+						
+						if (ProtocolsModeFlag) {
+								switch (j) {
+									case WRITE_CONFIG:
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "write config");
+											save_config(client_socket, dataBuf);
+											__set_PRIMASK(1);
+											NVIC_SystemReset();
+											break;
+									case WRITE_CONFIG_ADD:
+											add_config(client_socket, dataBuf);
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "write config add");
+											break;
+									case READ_CONFIG:
+											send_config(client_socket);
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "read config");
+											break;
+									case FIND_DEVICE:
+											find_device(client_socket);
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "find device");
+											break;
+									case IP_CONFIG:
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "ipconfig");
+											analysis_ip_config(client_socket, sockfd, tcpServerSock, dataBuf);
+											if (closeFlag == 1) {
+													// 更新新的地址
+													inet_aton((char*)&load_ip_config.host, &(tcpServerSock.sin_addr));
+													closeFlag = 0;
+													goto tcp_server_begin;
+											}
+											break;
+									case TOGGLE_MODE:
+											work_mode(dataBuf);
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "toggle work mode");
+											break;
+									case UPDATE:
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "update");
+											updata_task_creat(client_socket);
+											break;
+									case REBOOT:
+											send(client_socket,"{\"reboot\":\"success\"}", 20, 0);
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "reboot");
+											__set_PRIMASK(1);
+											NVIC_SystemReset();
+											break;
+								}
+							} else {
+								switch (j) {
+									case FIND_DEVICE:
+											find_device(client_socket);
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "find device");
+											break;
+									case IP_CONFIG:
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "ip config");
+											analysis_ip_config(client_socket, sockfd, tcpServerSock, dataBuf);
+											if (closeFlag == 1) {
+													// 更新新的地址
+													inet_aton((char*)&load_ip_config.host, &(tcpServerSock.sin_addr));
+													closeFlag = 0;
+													goto tcp_server_begin;
+											}
+											break;
+									case TOGGLE_MODE:
+											work_mode(dataBuf);
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "toggle work mode");
+											break;
+									case UPDATE:
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "update");
+											updata_task_creat(client_socket);
+											break;
+									case REBOOT:
+											send(client_socket,"{\"reboot\":\"success\"}", 20, 0);
+											LogPrint(LOG_INFO, __FILE__, __FUNCTION__, __LINE__, "reboot");
+											__set_PRIMASK(1);
+											NVIC_SystemReset();	
+											break;
+							}
+						}
+					}
+					// 没接收到消息
+					else if(recv_size==0)
+					{
+						lwip_close(client_socket);
+						LOG_PRINT(LOG_ERROR,"PC disconnect,wait reconnect");
+						client_socket= accept(sockfd, (struct sockaddr*)&client_sock,&len);
+					}
+					myfree(SRAMEX, dataBuf);
+			}
+}
+/*!
+    \brief      initialize the tcp_client application
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void tcp_server_init(void)
+{
+  osThreadDef(SERVER, tcp_server_task, osPriorityNormal, 0, configMINIMAL_STACK_SIZE*8);
+  osThreadCreate(osThread(SERVER), NULL);
+}

+ 1 - 1
app/SYSTEM/source/udp.c

@@ -63,7 +63,7 @@ OF SUCH DAMAGE.
 volatile int8_t sockfd=-1;
 #define UDP_LOCAL_PORT 12345
 #define UDP_REMOTE_PORT 54321
-#define SERCER_IP_ADDRESS "192.168.2.22"       //½ÓÊÕ·þÎñÆ÷ip
+#define SERCER_IP_ADDRESS "192.168.0.101"       //½ÓÊÕ·þÎñÆ÷ip
 struct sockaddr_in remote_addr;
 int udp_log_start()
 {

+ 150 - 0
app/SYSTEM/source/updata.c

@@ -0,0 +1,150 @@
+#include "updata.h"
+#include "FREERTOS.h"
+#include "task.h"
+#include "timer.h"
+#include "lwip/sockets.h"
+#include "string.h"
+#include "main.h"
+
+static const uint16_t wCRCTable[] =
+    {
+        0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
+        0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
+        0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
+        0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
+        0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
+        0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
+        0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
+        0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
+        0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
+        0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
+        0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
+        0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
+        0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
+        0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
+        0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
+        0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
+        0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
+        0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
+        0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
+        0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
+        0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
+        0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
+        0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
+        0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
+        0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
+        0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
+        0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
+        0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
+        0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
+        0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
+        0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
+        0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040};
+// crc校验
+uint16_t Checkcrc16(const uint8_t *nData, uint16_t wLength)
+{
+  uint8_t nTemp;
+  uint16_t wCRCWord = 0xFFFF;
+  while (wLength--)
+  {
+    nTemp = *nData++ ^ wCRCWord;
+    wCRCWord >>= 8;
+    wCRCWord ^= wCRCTable[nTemp];
+  }
+  return wCRCWord;
+}
+int i=0;
+
+// 更新OTA数据
+void updata_task(void const * argument)
+{
+	int recv_size;
+	uint16_t crc;	
+	uint8_t buf[1029];// 接收的一包数据(包括头标志、包序列、包序列反码、包数据、校验位)
+	uint8_t databuf[1024];// 保存包数据
+	
+	int const client_socket = *(int const *)argument;
+	uint16_t packId = 0x01;
+	uint8_t stx = 0x02,eot = 0x04,ack = 0x06,nak = 0x15,C = 0x43;
+
+	char* retMsg = mymalloc(SRAMEX,32);
+	memset(retMsg, 0, strlen(retMsg));
+	retMsg = "{\"software_update\":\"ready\"}";
+	send(client_socket, retMsg, strlen(retMsg), 0);	
+	myfree(SRAMEX, retMsg);
+	
+	// 发送第一个C
+	send(client_socket, &C, 1, 0);
+__start:
+	memset(buf, 0, sizeof(buf));
+	recv_size = recv(client_socket, buf, sizeof(buf), 0);
+	if(recv_size == 0)
+	{
+		//等待3S
+		delay_ms(3000);
+		//3s再发送C
+		send(client_socket, &C, 1, 0);
+		recv_size = recv(client_socket,buf,sizeof(buf),0);
+	}
+	do{
+			// 接收到结束信号,反馈ack
+			if(buf[0] == eot)
+			{
+				send(client_socket, &ack, 1, 0);
+				break;
+			}
+			// 检测头标志
+			if(buf[0] != stx)
+			{
+				send(client_socket, &nak, 1, 0);
+				goto __start;
+			}
+			// 检测包序列
+			if(buf[1] != packId)
+			{
+				send(client_socket, &nak, 1, 0);
+				goto __start;
+			}
+			// 检测包号反码
+			if(buf[2] !=(~packId & 0xff))
+			{
+				send(client_socket, &nak, 1, 0);
+				goto __start;
+			}
+			// 提取数据包
+			for(int i = 0; i < 1024; i++)
+			{
+				databuf[i] = buf[3 + i];
+			}
+			crc = Checkcrc16(databuf, 1024);
+			// 检测数据包的校验码
+			if (((crc & 0x00FF) != buf[1028]) || (((crc & 0xFF00) >> 8) != buf[1027]))
+			{	
+				send(client_socket, &nak, 1, 0);
+				goto __start;
+			}
+			// 对数据包进行操作
+			/*                */
+			memset(databuf, 0, sizeof(databuf));
+			
+			// 准备接收下一包数据
+			send(client_socket, &ack, 1, 0);
+			packId += 1;
+			
+			memset(buf, 0, 1029);
+			delay_ms(100);
+	}while(recv(client_socket,buf,sizeof(buf),0));
+
+		// 所有数据包接受完成,准备重启
+		__set_PRIMASK(1);
+		NVIC_SystemReset();
+}
+
+
+
+void updata_task_creat(int client_socket)
+{
+	osThreadDef(UPDATA, updata_task, osPriorityHigh, 0, configMINIMAL_STACK_SIZE * 4);
+  osThreadCreate (osThread(UPDATA), (void*)&client_socket);
+}
+

+ 1 - 1
app/USER/include/FreeRTOSConfig.h

@@ -55,7 +55,7 @@
 #define configTICK_RATE_HZ			( ( TickType_t ) 1000 )
 #define configMAX_PRIORITIES			(  7)
 #define configMINIMAL_STACK_SIZE		( ( uint16_t ) 128 )
-#define configTOTAL_HEAP_SIZE			( ( size_t ) ( 30 * 1024 ) )//使用的为外部sramIS61LV25616空间最大为256k*16
+#define configTOTAL_HEAP_SIZE			( ( size_t ) ( 40 * 1024 ) )//使用的为外部sramIS61LV25616空间最大为256k*16
 #define configMAX_TASK_NAME_LEN			( 16 )
 #define configUSE_TRACE_FACILITY		1
 #define configUSE_16_BIT_TICKS			0

+ 3 - 0
app/USER/include/app_ethernet.h

@@ -26,6 +26,7 @@
 
 /* Includes ------------------------------------------------------------------*/
 #include "lwip/netif.h"
+#include "main.h"
 
 /* Exported types ------------------------------------------------------------*/
 /* Exported constants --------------------------------------------------------*/
@@ -43,6 +44,8 @@ void User_notification(struct netif *netif);
 #ifdef USE_DHCP
 void DHCP_thread(void const * argument);
 extern volatile uint32_t dhcp_done;
+void DHCP_open(void);
+void DHCP_close(void);
 #endif 
 
 #ifdef __cplusplus

+ 4 - 1
app/USER/include/main.h

@@ -9,6 +9,8 @@
 /* Includes ------------------------------------------------------------------*/
 #include "stm32f2xx_hal.h"
 #include "log.h"
+#include "malloc.h"
+#include "stdio.h"
 
 #include "cmsis_os.h"
 
@@ -39,7 +41,8 @@
 /* Exported macro ------------------------------------------------------------*/
 /* Exported functions ------------------------------------------------------- */  
 void Error_Handler(void);
-
+void set_ipaddr(char* buf);
+extern char  gatewayId[11];
 
 #ifdef __cplusplus
 }

+ 13 - 0
app/USER/source/app_ethernet.c

@@ -19,6 +19,7 @@
 /* Includes ------------------------------------------------------------------*/
 #include "main.h"
 #include "lwip/dhcp.h"
+#include "lwip/inet.h"
 #include "app_ethernet.h"
 
 /* Private typedef -----------------------------------------------------------*/
@@ -94,6 +95,7 @@ void DHCP_thread(void const * argument)
         {
           DHCP_state = DHCP_ADDRESS_ASSIGNED;
           dhcp_done=1;
+					printf("dhcp ip_addr is %s \r\n", inet_ntoa(netif->ip_addr));
         }
         else
         {
@@ -132,7 +134,18 @@ void DHCP_thread(void const * argument)
     osDelay(250);
   }
 }
+
+void DHCP_open()
+{
+	DHCP_state = DHCP_START;
+}
+
+void DHCP_close()
+{
+	DHCP_state = DHCP_LINK_DOWN;
+}
 #endif  /* USE_DHCP */
 
 
+
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 13 - 1
app/USER/source/ethernetif.c

@@ -22,6 +22,7 @@
 #include "netif/etharp.h"
 #include "ethernetif.h"
 #include <string.h>
+#include "myFile.h"
 
 /* Private typedef -----------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
@@ -524,7 +525,8 @@ err_t ethernetif_init(struct netif *netif)
   */
 void ethernetif_set_link(void const *argument)
 {
-  uint32_t regvalue = 0;
+	char flag; // ÍøÂç±ê־λ
+  uint32_t regvalue = 0;	
   struct link_str *link_arg = (struct link_str *)argument;
   
   for(;;)
@@ -543,11 +545,21 @@ void ethernetif_set_link(void const *argument)
         /* Check whether the link is up or down*/
         if((regvalue & PHY_LINK_STATUS)!= (uint16_t)RESET)
         {
+					flag = 1;
+					write_file("ETH.txt",&flag,1);
           netif_set_link_up(link_arg->netif);
+					__set_PRIMASK(1);
+					NVIC_SystemReset();
         }
         else
         {
+					flag = 0;
+					portENTER_CRITICAL();
+					write_file("ETH.txt",&flag,1);
+					portEXIT_CRITICAL();
           netif_set_link_down(link_arg->netif);
+					__set_PRIMASK(1);
+					NVIC_SystemReset();
         }
       }
 //    }

+ 182 - 21
app/USER/source/main.c

@@ -9,6 +9,16 @@
 #include "nandflash.h"
 #include "myFile.h"
 #include "string.h"
+#include "data_task.h"
+#include "tcp_server.h"
+#include "timer.h"
+#include "usart.h"
+#include "sys_http.h"
+#include "sys_mqtt.h"
+#include "data_task.h"
+#include "mmodbus.h"
+#include "led.h"
+#include "lte.h"
 
 /* Private typedef -----------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
@@ -26,10 +36,14 @@ static void StartThread(void const * argument);
 static void ToggleLed4(void const * argument);
 static void BSP_Config(void);
 static void Netif_Config(void);
+void EC800M_taskFuntcion(void const*arg);
 
+void load_unique(void);
 
 /* Private functions ---------------------------------------------------------*/
-
+char gatewayId[11];
+char ETH_flag = 1; //  1,启用网线,0 启用LTE
+uint16_t data[2];
 /**
   * @brief  Main program
   * @param  None
@@ -37,6 +51,7 @@ static void Netif_Config(void);
   */
 int main(void)
 {
+	int status;
   /* STM32F2xx HAL library initialization:
        - Configure the Flash prefetch, instruction and Data caches
        - Configure the Systick to generate an interrupt each 1 msec
@@ -44,18 +59,43 @@ int main(void)
        - Global MSP (MCU Support Package) initialization
      */
   HAL_Init();  
+	load_unique();	
+	sprintf(gatewayId,"DTtest0001");//DT8pd3ac6h  DTbma5ac6h  DTtest0001  DTrzts0001
   /* Configure the system clock to 120 MHz */
   SystemClock_Config();
 	MX_FSMC_SRAM_Init();
-	NAND_Init();
-	
-	
-  /* Init task */
-  osThreadDef(Start, StartThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 4);
+	status = NAND_Init();
+	while(status){
+		NAND_Format();
+		status = NAND_Init();
+	}
 
-  osThreadCreate (osThread(Start), NULL);
+	TIMER_config();
+	my_mem_init(SRAMEX);
+	my_mem_init(SRAMIN);
+
+	USART_232_config();
+	USART_485_config();
+	
+	LED_GPIO_Config();
 	
+	read_file("ETH.txt", &ETH_flag);
+	DeleteDirFile("ETH.txt");
 
+	if(ETH_flag == 1)// 网线启动
+	{
+		/* Init task */
+		osThreadDef(Start, StartThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 4);
+		osThreadCreate (osThread(Start), NULL);
+	}
+	else // LTE启动
+	{
+		DEBUG_USART_Config();
+		USART_DMA_Config();	
+		/* LTE task */
+		osThreadDef(LTE_task, EC800M_taskFuntcion, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 4);
+		osThreadCreate (osThread(LTE_task), NULL);
+	}
   
   /* Start scheduler */
   osKernelStart();
@@ -79,12 +119,13 @@ static void StartThread(void const * argument)
   
   /* Initialize the LwIP stack */
   Netif_Config();
-  
-
-  
+   
   /* Notify user about the network interface config */
   User_notification(&gnetif);
-  
+	
+	tcp_server_init();
+	USART_232_task_creat();
+
 #ifdef USE_DHCP
   /* Start DHCPClient */
   osThreadDef(DHCP, DHCP_thread, osPriorityBelowNormal, 0, configMINIMAL_STACK_SIZE * 2);
@@ -95,12 +136,19 @@ static void StartThread(void const * argument)
 //  osThreadDef(LED4, ToggleLed4, osPriorityNormal, 0, configMINIMAL_STACK_SIZE*8);
 //  osThreadCreate(osThread(LED4), NULL);
 
-	   
-  for( ;; )
-  {
-    /* Delete the Init Thread */ 
-    osThreadTerminate(NULL);
-  }
+	// 确保dhcp配置完成
+	while(dhcp_done != 1)		vTaskDelay(100);
+
+	http_getDemo();
+	mqtt_task_creat();
+	
+	osThreadDef(DataTask, data_task, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 8);
+	osThreadCreate (osThread(DataTask), NULL);
+	for( ;; )
+	{
+		/* Delete the Init Thread */ 
+		osThreadTerminate(NULL);
+	}
 }
 
 /**
@@ -153,7 +201,48 @@ static void Netif_Config(void)
 	
 }
 
+void set_ipaddr(char* buf)
+{
+		ip_addr_t ipaddr;
+		ip_addr_t netmask;
+		ip_addr_t gw;
+	
+		int ipaddr0,ipaddr1,ipaddr2,ipaddr3;
+		int maskaddr0,maskaddr1,maskaddr2,maskaddr3;
+		int gwaddr0,gwaddr1,gwaddr2,gwaddr3;
+	
+		ipaddr0 = parseIntField(buf,"\"ipv4\":\"" );
+		ipaddr1 = parseIntField(strstr(buf,"\"ipv4\":\"") + 1,"." );
+		ipaddr2 = parseIntField(strstr(strstr(buf,"\"ipv4\":\"") + 1,"." ) + 1,".");
+		ipaddr3 = parseIntField(strstr(strstr(strstr(buf,"\"ipv4\":\"") + 1,"." ) + 1,".") + 1 ,".");
+
+		maskaddr0 = parseIntField(buf,"\"subnetMask\":\"" );
+		maskaddr1 = parseIntField(strstr(buf,"\"subnetMask\":\"") + 1,"." );
+		maskaddr2 = parseIntField(strstr(strstr(buf,"\"subnetMask\":\"") + 1,"." ) + 1,".");
+		maskaddr3 = parseIntField(strstr(strstr(strstr(buf,"\"subnetMask\":\"") + 1,"." ) + 1,".") + 1 ,".");
+		
+		gwaddr0 = parseIntField(buf,"\"defaultGateway\":\"" );
+		gwaddr1 = parseIntField(strstr(buf,"\"defaultGateway\":\"") + 1,"." );
+		gwaddr2 = parseIntField(strstr(strstr(buf,"\"defaultGateway\":\"") + 1,"." ) + 1,".");
+		gwaddr3 = parseIntField(strstr(strstr(strstr(buf,"\"defaultGateway\":\"") + 1,"." ) + 1,".") + 1 ,".");	
+	
+		IP4_ADDR(&ipaddr, ipaddr0 ,ipaddr1 , ipaddr2 , ipaddr3 );
+    IP4_ADDR(&netmask, maskaddr0, maskaddr1, maskaddr2, maskaddr3);
+    IP4_ADDR(&gw, gwaddr0, gwaddr1, gwaddr2,gwaddr3);
+		// 停止DHCP客户端
+		DHCP_close();
+		// 禁用网口
+		 netif_set_down(&gnetif);
+		// 设置网络接口的IP地址
+//		netif_set_gw(&gnetif, &gw);
+//		netif_set_netmask(&gnetif, &netmask);
+//		netif_set_ipaddr(&gnetif, &ipaddr);
+    netif_set_addr(&gnetif, &ipaddr , &netmask, &gw);
+
+		// 重启网络接口以使更改生效
+    netif_set_up(&gnetif);
 
+}
 /**
   * @brief  Initializes the LCD and LEDs resources.
   * @param  None
@@ -269,10 +358,10 @@ void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
 }
 
 
-int fputc(int ch, FILE *stream)
-{
- return ch;
-}
+//int fputc(int ch, FILE *stream)
+//{
+// return ch;
+//}
 
 #ifdef  USE_FULL_ASSERT
 /**
@@ -307,5 +396,77 @@ void ethernetif_notify_conn_changed(struct netif *netif)
   
 }
 
+void load_unique(void)
+{
+	char *hex_table = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN";
+	uint32_t CpuID1, CpuID2, CpuID3;
+	HAL_GetUIDw0();
+	CpuID1 = *(volatile uint32_t *)(UID_BASE);
+	CpuID2 = *(volatile uint32_t *)(UID_BASE+8);
+	CpuID3 = *(volatile uint32_t *)(UID_BASE+16);
+	char strId[11];
+
+	for (uint8_t i = 0, j = 0; i < 8; i += 2)
+	{
+		uint32_t sum1 = (CpuID1 >> ((j % 4) * 8)) & 0xFF; // 按字节取出
+		uint8_t index1 = sum1 / 16;
+		uint8_t remainder1 = sum1 % 16;
+
+		uint32_t sum2 = (CpuID2 >> ((j % 4) * 8)) & 0xFF; // 按字节取出
+		uint8_t index2 = sum2 / 16;
+		uint8_t remainder2 = sum2 % 16;
+
+		uint32_t sum3 = (CpuID3 >> ((j % 4) * 8)) & 0xFF; // 按字节取出
+		uint8_t index3 = sum3 / 16;
+		uint8_t remainder3 = sum3 % 16;
+
+		strId[i + 2] = hex_table[index1 + index2 + index3];
+		strId[i + 1 + 2] = hex_table[remainder1 + remainder2 + remainder3];
+
+		j++;
+	}
+	strId[10] = '\0';
+	strId[0]='L';
+	strId[1]='R';
+	strcpy(gatewayId,strId);
+}
+
+/*
+ *  函数名:void EC800M_taskFuntcion(void *arg)
+ *  输入参数:无
+ *  输出参数:无
+ *  返回值:无
+ *  函数作用:开启EC800M模块任务
+ */
+void EC800M_taskFuntcion(void const*arg)
+{
+	
+//	 /* Create tcp_ip stack thread */
+//  tcpip_init(NULL, NULL);
+//  
+//  /* Initialize the LwIP stack */
+//  Netif_Config();
+	
+	EC800M_open();
+	ec800_init();
+	
+	ec800_TCP();
+	char *http=mymalloc(SRAMEX,80); // 根据要访问的 URL修改分配的大小
+	sprintf(http,"http://gpu.ringzle.com:8082/iot/transmit/getTransmitConfig/%s",gatewayId);
+//	sprintf(http,"http://gpu.ringzle.com:8082/witcarbon-admin/profile/2024/03/25/7935dfd8-b398-41ba-85a3-8f04a6f1625e.bin");
+	http_set_url(http);
+	myfree(SRAMEX,http);
+	LTE_HTTP_get();
+	MQ_threadCreate();
+	
+	osThreadDef(DataTask, data_task, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 8);
+	osThreadCreate (osThread(DataTask), NULL);
+	
+	for( ;; )
+  {
+    /* Delete the LTE Thread */ 
+    osThreadTerminate(NULL);
+  }
+}
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 1 - 0
app/USER/source/stm32f2xx_it.c

@@ -54,6 +54,7 @@ void HardFault_Handler(void)
   /* Go to infinite loop when Hard Fault exception occurs */
   while (1)
   {
+		HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_SET);
   }
 }