#include #include #include "FreeRTOS.h" #include "freerotsTask.h" #include "task.h" #include "pDebug.h" #include "upUartParse.h" #include "FM_GPIO.h" #include "FM_ADC.h" #include "queueUart.h" #include "parameter.h" /* 读取寄存器,最大起始位 */ #define maxStartReadResAddr 10 /* 读取寄存器,最大长度 */ #define maxReadResAddrLen 20 /* 写入寄存器,最大起始位 */ #define maxStartWriteResAddr 10 /* 写入寄存器,最大长度 */ #define maxWriteResAddrLen 20 /* 单次读取配置文件最大个数 */ #define maxReadCfgLen 80 /* 单次写入配置文件最大字节 */ #define maxDistributionCfgLen 230 /* 2秒的节拍数 */ #define tick_2S (configTICK_RATE_HZ * 2) /* 1分钟的节拍数 */ #define tick_1M (configTICK_RATE_HZ * 60) /* 配置文件数据类型表 */ typedef enum { /* (1字节)对智能模块通信波特率(00H:不使用该串口,01H:4800;02H:9600;03H:19200;04H:38400;05H:57600;06H:115200) */ Upward_UART_Communication_Baud_Rate = 0x0001, J1_485_Communication_Baud_Rate = 0x0002, J2_485_Communication_Baud_Rate = 0x0003, J3_485_Communication_Baud_Rate = 0x0004, J4_485_Communication_Baud_Rate = 0x0005, J5_0_485_Communication_Baud_Rate = 0x0006, }gateWayCfgFileType; /* 状态机 */ typedef enum { wait = 0, /* 串口状态机初始状态 */ startFlagGW, /* 接收到帧头 */ functionCodeGW, /* 接收到功能码 */ readRegStartAddressGW, /* 接收到读取寄存器起始地址 */ readRegStartNumberGW, /* 接收到读取寄存器个数 */ crcCheckBitGW, /* 接收到校验位 */ endFlagGW, /* 接收到帧尾 */ writeRegStartAddressGW, /* 接收到写入寄存器起始地址 */ writeRegStartNumberGW, /* 接收到写入寄存器个数 */ cfgFramesNumGW, /* 接收到配置文件帧数 */ cfgLengthGW, /* 接收到配置文件长度 */ readCfgLengthGW, /* 接收到读取配置文件长度 */ startFlagSL, /* 接收到帧头 */ portSL, /* 接收到端口号 */ lengthSL, /* 接收到数据包的长度 */ endFlagSL, /* 接收到帧尾 */ } uartStateMachine; // /* 计时参数,1min后没解析整个配置文件,丢掉当前数据 */ // static uint32_t gw485CfgTime = 0; /* 计时参数,2秒后没解析出一帧数据,丢掉当前数据 */ static uint32_t gw485RxTime = 0; /* 储存gw485数据 */ static uint8_t gw485RxBuffer[1100]; static uint16_t gw485RxBufferIndex = 0; /* 状态机状态机变量 */ static uartStateMachine state = wait; /* 帧长度 */ static uint16_t frameLength = 0; static void stateMachine(device_handle device); /* 状态机函数 */ static uint8_t analysisWait(void); static uint8_t analysisStartFlagGW(void); static uint8_t analysisFunctionCodeGW(void); static uint8_t analysisReadRegStartAddressGW(void); static uint8_t analysisReadRegStartNumberGW(void); static uint8_t analysisCrcCheckBitGW(void); static uint8_t analysisEndFlagGW(device_handle device); static uint8_t analysisWriteRegStartAddressGW(void); static uint8_t analysisWriteRegStartNumberGW(void); static uint8_t analysisCfgFramesNumGW(void); static uint8_t analysisCfgLengthGW(void); static uint8_t analysisReadCfgLengthGW(void); static uint8_t analysisStartFlagSL(void); static uint8_t analysisPortSL(void); static uint8_t analysisLengthSL(void); static uint8_t analysisEndFlagSL(void); static void GW_MsgProcFunc_Read_Register(device_handle device,uint8_t *buff, uint16_t buffLen); static void GW_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen); static void GW_MsgProcFunc_Distribution_Profile(device_handle device, void *pMsg, uint32_t MsgLen); static void GW_MsgProcFunc_Read_Profile(device_handle device, void *pMsg, uint32_t MsgLen); /* 寄存器处理表 */ typedef uint16_t (*RegProcFunc)(void*); typedef struct _SL_RegProcTable{ uint32_t regId; RegProcFunc pRegProc; }SL_RegProcTable; /* 寄存器解析 */ static uint16_t ReadRegisterWorkCurrent(void *pMsg); static uint16_t ReadRegisterWorkVoltage(void *pMsg); static uint16_t ReadRegisterTemperature(void *pMsg); static uint16_t ReadRegisterPort1_Power(void *pMsg); static uint16_t ReadRegisterPort2_Power(void *pMsg); static uint16_t ReadRegisterPort3_Power(void *pMsg); static uint16_t ReadRegisterPort4_Power(void *pMsg); static uint16_t ReadRegisterPort5_Power(void *pMsg); static uint16_t ReadRegisterPort6_Power(void *pMsg); static uint16_t ReadRegisterPort7_Power(void *pMsg); static uint16_t ReadRegisterPort8_Power(void *pMsg); static uint16_t ReadRegisterPort9_Power(void *pMsg); static uint16_t WriteRegisterPort1_Power(void *pMsg); static uint16_t WriteRegisterPort2_Power(void *pMsg); static uint16_t WriteRegisterPort3_Power(void *pMsg); static uint16_t WriteRegisterPort4_Power(void *pMsg); static uint16_t WriteRegisterPort5_Power(void *pMsg); static uint16_t WriteRegisterPort6_Power(void *pMsg); static uint16_t WriteRegisterPort7_Power(void *pMsg); static uint16_t WriteRegisterPort8_Power(void *pMsg); static uint16_t WriteRegisterPort9_Power(void *pMsg); /* 读取寄存器处理表 */ SL_RegProcTable g_RegTblR[] = { {GW_Register_WorkCurrent, ReadRegisterWorkCurrent}, {GW_Register_WorkVoltage, ReadRegisterWorkVoltage}, {GW_Register_Temperature, ReadRegisterTemperature}, {GW_Register_Port1_Power, ReadRegisterPort1_Power}, {GW_Register_Port2_Power, ReadRegisterPort2_Power}, {GW_Register_Port3_Power, ReadRegisterPort3_Power}, {GW_Register_Port4_Power, ReadRegisterPort4_Power}, {GW_Register_Port5_Power, ReadRegisterPort5_Power}, {GW_Register_Port6_Power, ReadRegisterPort6_Power}, {GW_Register_Port7_Power, ReadRegisterPort7_Power}, {GW_Register_Port8_Power, ReadRegisterPort8_Power}, {GW_Register_Port9_Power, ReadRegisterPort9_Power}, }; /* 写入寄存器处理表 */ SL_RegProcTable g_RegTblW[] = { {GW_Register_Port1_Power, WriteRegisterPort1_Power}, {GW_Register_Port2_Power, WriteRegisterPort2_Power}, {GW_Register_Port3_Power, WriteRegisterPort3_Power}, {GW_Register_Port4_Power, WriteRegisterPort4_Power}, {GW_Register_Port5_Power, WriteRegisterPort5_Power}, {GW_Register_Port6_Power, WriteRegisterPort6_Power}, {GW_Register_Port7_Power, WriteRegisterPort7_Power}, {GW_Register_Port8_Power, WriteRegisterPort8_Power}, {GW_Register_Port9_Power, WriteRegisterPort9_Power}, }; /** * @brief 读取工作电流寄存器 * @param * @retval */ uint16_t ReadRegisterWorkCurrent(void *pMsg) { return (uint16_t)(getWorkCurrent() * 10); } /** * @brief 读取工作电压寄存器 * @param * @retval */ uint16_t ReadRegisterWorkVoltage(void *pMsg) { return (uint16_t)(getWorkVoltage() * 10); } /** * @brief 读取温度寄存器 * @param * @retval */ uint16_t ReadRegisterTemperature(void *pMsg) { return (uint16_t)(getTemperature() * 10); } /** * @brief 读取端口1电源状态 * @param * @retval */ uint16_t ReadRegisterPort1_Power(void *pMsg) { return readPwrCtrlState(J1_PwrCtrl); } /** * @brief 读取端口2电源状态 * @param * @retval */ uint16_t ReadRegisterPort2_Power(void *pMsg) { return readPwrCtrlState(J2_PwrCtrl); } /** * @brief 读取端口3电源状态 * @param * @retval */ uint16_t ReadRegisterPort3_Power(void *pMsg) { return readPwrCtrlState(J3_PwrCtrl); } /** * @brief 读取端口4电源状态 * @param * @retval */ uint16_t ReadRegisterPort4_Power(void *pMsg) { return readPwrCtrlState(J4_PwrCtrl); } /** * @brief 读取端口5电源状态 * @param * @retval */ uint16_t ReadRegisterPort5_Power(void *pMsg) { return readPwrCtrlState(J5_PwrCtrl); } /** * @brief 读取端口6电源状态 * @param * @retval */ uint16_t ReadRegisterPort6_Power(void *pMsg) { return readPwrCtrlState(J6_PwrCtrl); } /** * @brief 读取端口7电源状态 * @param * @retval */ uint16_t ReadRegisterPort7_Power(void *pMsg) { return readPwrCtrlState(J7_PwrCtrl); } /** * @brief 读取端口8电源状态 * @param * @retval */ uint16_t ReadRegisterPort8_Power(void *pMsg) { return readPwrCtrlState(J8_PwrCtrl); } /** * @brief 读取端口9电源状态 * @param * @retval */ uint16_t ReadRegisterPort9_Power(void *pMsg) { return readPwrCtrlState(J9_PwrCtrl); } /** * @brief 设置端口1电源状态 * @param * @retval */ uint16_t WriteRegisterPort1_Power(void *pMsg) { writePwrCtrlState(J1_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg)); return 0; } /** * @brief 设置端口2电源状态 * @param * @retval */ uint16_t WriteRegisterPort2_Power(void *pMsg) { writePwrCtrlState(J2_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg)); return 0; } /** * @brief 设置端口3电源状态 * @param * @retval */ uint16_t WriteRegisterPort3_Power(void *pMsg) { writePwrCtrlState(J3_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg)); return 0; } /** * @brief 设置端口4电源状态 * @param * @retval */ uint16_t WriteRegisterPort4_Power(void *pMsg) { writePwrCtrlState(J4_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg)); return 0; } /** * @brief 设置端口5电源状态 * @param * @retval */ uint16_t WriteRegisterPort5_Power(void *pMsg) { writePwrCtrlState(J5_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg)); return 0; } /** * @brief 设置端口6电源状态 * @param * @retval */ uint16_t WriteRegisterPort6_Power(void *pMsg) { writePwrCtrlState(J6_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg)); return 0; } /** * @brief 设置端口7电源状态 * @param * @retval */ uint16_t WriteRegisterPort7_Power(void *pMsg) { writePwrCtrlState(J7_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg)); return 0; } /** * @brief 设置端口8电源状态 * @param * @retval */ uint16_t WriteRegisterPort8_Power(void *pMsg) { writePwrCtrlState(J8_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg)); return 0; } /** * @brief 设置端口9电源状态 * @param * @retval */ uint16_t WriteRegisterPort9_Power(void *pMsg) { writePwrCtrlState(J9_PwrCtrl, (uint8_t)(*(uint16_t *)pMsg)); return 0; } /** * @brief 状态 wait * @param * @retval 0:解析失败 1:解析成功 */ #define waitMaxLen 2 uint8_t analysisWait(void) { if (gw485RxBufferIndex >= 2) { /* 透传数据帧包头 */ if (gw485RxBuffer[0] == 'S' && gw485RxBuffer[1] == 'L') { // log_info("startFlagSL\n"); state = startFlagSL; return TRUE; } /* 数据帧包头 */ else if (gw485RxBuffer[0] == 'G' && gw485RxBuffer[1] == 'W') { state = startFlagGW; return TRUE; } } if (gw485RxBufferIndex < waitMaxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 startFlagGW * @param * @retval 0:解析失败 1:解析成功 */ uint8_t analysisStartFlagGW(void) { if (gw485RxBuffer[2] == SL_Function_Code_Read_Register || gw485RxBuffer[2] == SL_Function_Code_Write_Register || gw485RxBuffer[2] == SL_Function_Code_Distribution_Profile || gw485RxBuffer[2] == SL_Function_Code_Read_Profile) { state = functionCodeGW; return TRUE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 functionCodeGW * @param * @retval 0:解析失败 1:解析成功 */ #define functionCodeGWMaxLen 5 uint8_t analysisFunctionCodeGW(void) { if (gw485RxBufferIndex >= 5 && gw485RxBuffer[2] == SL_Function_Code_Read_Register) { /* 读取寄存器起始地址 */ uint16_t startResAddr = ((gw485RxBuffer[3] << 8) | gw485RxBuffer[4]); if (startResAddr < maxStartReadResAddr) { frameLength = 10; state = readRegStartAddressGW; return TRUE; } } if (gw485RxBufferIndex >= 5 && gw485RxBuffer[2] == SL_Function_Code_Write_Register) { /* 写入寄存器起始地址 */ uint16_t startResAddr = ((gw485RxBuffer[3] << 8) | gw485RxBuffer[4]); if (startResAddr < maxStartWriteResAddr) { state = writeRegStartAddressGW; return TRUE; } } if (gw485RxBufferIndex >= 5 && gw485RxBuffer[2] == SL_Function_Code_Write_Register) { /* 写入寄存器起始地址 */ uint16_t startResAddr = ((gw485RxBuffer[3] << 8) | gw485RxBuffer[4]); if (startResAddr < maxStartWriteResAddr) { state = writeRegStartAddressGW; return TRUE; } } /* 解析配置文件下发帧数 */ if ((gw485RxBufferIndex >= 5) && (gw485RxBuffer[2] == SL_Function_Code_Distribution_Profile)) { if (gw485RxBuffer[3] <= gw485RxBuffer[4]) { state = cfgFramesNumGW; return TRUE; } } /* 解析配置文件读取内容的长度 */ if ((gw485RxBufferIndex >= 5) && (gw485RxBuffer[2] == SL_Function_Code_Read_Profile)) { uint32_t tempCfgLen = 0; tempCfgLen = (gw485RxBuffer[3] << 8) | gw485RxBuffer[4]; if (tempCfgLen < maxReadCfgLen && tempCfgLen > 0) { state = readCfgLengthGW; frameLength = 8 + tempCfgLen; return TRUE; } } if (gw485RxBufferIndex < functionCodeGWMaxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 readRegStartAddressGW * @param * @retval 0:解析失败 1:解析成功 */ #define ReadRegStartAddressGWMaxLen 7 uint8_t analysisReadRegStartAddressGW(void) { if (gw485RxBufferIndex >= 7) { /* 读取寄存器起始地址 */ uint16_t resAddrLen = ((gw485RxBuffer[5] << 8) | gw485RxBuffer[6]); if (resAddrLen < maxReadResAddrLen) { state = readRegStartNumberGW; return TRUE; } } if (gw485RxBufferIndex < functionCodeGWMaxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 readRegStartNumberGW * @param * @retval 0:解析失败 1:解析成功 */ #define ReadRegStartNumberMaxLen 9 uint8_t analysisReadRegStartNumberGW(void) { /* crc校验 */ if (gw485RxBufferIndex >= ReadRegStartNumberMaxLen) { uint16_t tempCrc = 0; tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2]; if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) { state = crcCheckBitGW; return TRUE; } } if (gw485RxBufferIndex < ReadRegStartNumberMaxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 crcCheckBitGW * @param * @retval 0:解析失败 1:解析成功 */ uint8_t analysisCrcCheckBitGW(void) { /* 结束标志校验校验 */ if (gw485RxBufferIndex == frameLength) { if (gw485RxBuffer[frameLength - 1] == 0x16) { state = endFlagSL; return TRUE; } } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 endFlagGW * @param * @retval 0:解析失败 1:解析成功 */ uint8_t analysisEndFlagGW(device_handle device) { /* 数据为读取寄存器 */ if (gw485RxBuffer[2] == SL_Function_Code_Read_Register) { GW_MsgProcFunc_Read_Register(device, gw485RxBuffer, frameLength); } /* 数据为写入寄存器 */ if (gw485RxBuffer[2] == SL_Function_Code_Write_Register) { GW_MsgProcFunc_Write_Register(device, gw485RxBuffer, frameLength); } /* 数据为下发配置文件 */ else if (gw485RxBuffer[9] == SL_Function_Code_Distribution_Profile) { GW_MsgProcFunc_Distribution_Profile(device, gw485RxBuffer, frameLength); } /* 数据为读取配置文件 */ else if (gw485RxBuffer[9] == SL_Function_Code_Read_Profile) { GW_MsgProcFunc_Read_Profile(device, gw485RxBuffer, frameLength); } //清零buff state = wait; gw485RxBufferIndex = 0; return 1; } /** * @brief 状态 writeRegStartAddressGW * @param * @retval 0:解析失败 1:解析成功 */ #define WriteRegStartAddressGWMaxLen 7 uint8_t analysisWriteRegStartAddressGW(void) { if (gw485RxBufferIndex >= 7) { /* 写入寄存器起始地址 */ uint16_t resAddrLen = ((gw485RxBuffer[5] << 8) | gw485RxBuffer[6]); if (resAddrLen < maxReadResAddrLen) { frameLength = 10 + 2 * resAddrLen; state = readRegStartNumberGW; return TRUE; } } if (gw485RxBufferIndex < WriteRegStartAddressGWMaxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 writeRegStartNumberGW * @param * @retval 0:解析失败 1:解析成功 */ #define WriteRegStartNumberGWMaxLen (frameLength - 1) uint8_t analysisWriteRegStartNumberGW(void) { /* crc校验 */ if (gw485RxBufferIndex >= WriteRegStartNumberGWMaxLen) { uint16_t tempCrc = 0; tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2]; if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) { state = crcCheckBitGW; return TRUE; } } if (gw485RxBufferIndex < WriteRegStartNumberGWMaxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 cfgFramesNumGW * @param * @retval 0:解析失败 1:解析成功 */ #define CfgFramesNumGWMaxLen 7 uint8_t analysisCfgFramesNumGW(void) { /* 解析下发配置文件数据内容长度 */ if (gw485RxBufferIndex >= CfgFramesNumGWMaxLen) { uint32_t tempLen = 0; tempLen = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13]; if (tempLen > 0 && tempLen <= maxDistributionCfgLen) { state = cfgLengthGW; frameLength = 10 + tempLen; // log_error("cfgFramesNumSL error : tempLen = %d \n", tempLen); return TRUE; } } if (gw485RxBufferIndex < CfgFramesNumGWMaxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 cfgLengthGW * @param * @retval 0:解析失败 1:解析成功 */ #define CfgLengthGWMaxLen (frameLength - 1) uint8_t analysisCfgLengthGW(void) { /* crc校验 */ if (gw485RxBufferIndex >= CfgLengthGWMaxLen) { uint16_t tempCrc = 0; tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2]; if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) { state = crcCheckBitGW; return TRUE; } } if (gw485RxBufferIndex < CfgLengthGWMaxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 * @param * @retval 0:解析失败 1:解析成功 */ #define ReadCfgLengthGWMaxLen (frameLength - 1) uint8_t analysisReadCfgLengthGW(void) { /* crc校验 */ if (gw485RxBufferIndex >= ReadCfgLengthGWMaxLen) { uint16_t tempCrc = 0; tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2]; if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) { state = crcCheckBitGW; return TRUE; } } if (gw485RxBufferIndex < ReadCfgLengthGWMaxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 startFlagSL * @param * @retval 0:解析失败 1:解析成功 */ uint8_t analysisStartFlagSL(void) { /* 校验端口号 */ if (gw485RxBuffer[2] < 10 && gw485RxBuffer[2] >= 0) { // log_info("portSL\n"); state = portSL; return TRUE; } // log_error("portSL %d \n", gw485RxBuffer[2]); state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 portSL * @param * @retval 0:解析失败 1:解析成功 */ #define PortSLMaxLen 5 uint8_t analysisPortSL(void) { /* 解析数据包的度 */ if (gw485RxBufferIndex >= PortSLMaxLen) { uint32_t tempLen = 0; tempLen = (gw485RxBuffer[3] << 8) | gw485RxBuffer[4]; if (tempLen > 0 && tempLen <= 1024) { // log_info("lengthSL\n"); state = lengthSL; frameLength = 6 + tempLen; return TRUE; } } if (gw485RxBufferIndex < PortSLMaxLen) { return FALSE; } // log_error("lengthSL %d \n", (gw485RxBuffer[3] << 8) | gw485RxBuffer[4]); state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 lengthSL * @param * @retval 0:解析失败 1:解析成功 */ #define LengthSLMaxLen frameLength uint8_t analysisLengthSL(void) { /* 解析帧尾 */ if (gw485RxBufferIndex >= LengthSLMaxLen) { if (gw485RxBuffer[LengthSLMaxLen - 1] == 0x17) { // log_info("endFlagSL\n"); state = endFlagSL; return TRUE; } } if (gw485RxBufferIndex < LengthSLMaxLen) { return FALSE; } // log_info("endFlagSL %d\n", gw485RxBuffer[LengthSLMaxLen - 1]); state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 endFlagSL * @param * @retval 0:解析失败 1:解析成功 */ uint8_t analysisEndFlagSL(void) { uint32_t tempLen = 0; tempLen = (gw485RxBuffer[3] << 8) | gw485RxBuffer[4]; //系统内存不足,丢去当前包 if (xPortGetFreeHeapSize() < tempLen + 1024) { goto err; } /* 对于不同通端口,传输的结构体不同 */ uint8_t *Buff; if (gw485RxBuffer[2] > 0 && gw485RxBuffer[2] < 5) { Buff = (uint8_t *)pvPortMalloc(tempLen + queueUartSendInfoSize); queueUartSendInfo *sendBuff = (queueUartSendInfo *)Buff; sendBuff->length = tempLen + 1; sendBuff->data = Buff + queueUartSendInfoSize; strlcpy((char *)sendBuff->data, (char *)&gw485RxBuffer[5], tempLen + 1); } else { Buff = (uint8_t *)pvPortMalloc(tempLen + queueTimeShareSendInfoSize); queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff; sendBuff->length = tempLen + 1; sendBuff->data = Buff + queueTimeShareSendInfoSize; strlcpy((char *)sendBuff->data, (char *)&gw485RxBuffer[5], tempLen + 1); } /* 通过不同的端口将数据发送到不同的地方 */ if (gw485RxBuffer[2] == 1) { if (uxQueueSpacesAvailable(J1_485_Queue)) { xQueueSend(J1_485_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } } else if (gw485RxBuffer[2] == 2) { if (uxQueueSpacesAvailable(J2_485_Queue)) { xQueueSend(J2_485_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } } else if (gw485RxBuffer[2] == 3) { if (uxQueueSpacesAvailable(J3_485_Queue)) { xQueueSend(J3_485_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } } else if (gw485RxBuffer[2] == 4) { if (uxQueueSpacesAvailable(J4_485_Queue)) { xQueueSend(J4_485_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } } else if (gw485RxBuffer[2] == 5) { queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff; sendBuff->connectPort = connectJ5; if (uxQueueSpacesAvailable(J5_0_485_Queue)) { xQueueSend(J5_0_485_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } } else if (gw485RxBuffer[2] == 6) { queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff; sendBuff->connectPort = connectJ6; if (uxQueueSpacesAvailable(J5_0_485_Queue)) { xQueueSend(J5_0_485_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } } else if (gw485RxBuffer[2] == 7) { queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff; sendBuff->connectPort = connectJ7; if (uxQueueSpacesAvailable(J5_0_485_Queue)) { xQueueSend(J5_0_485_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } } else if (gw485RxBuffer[2] == 8) { queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff; sendBuff->connectPort = connectJ8; if (uxQueueSpacesAvailable(J5_0_485_Queue)) { xQueueSend(J5_0_485_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } } else if (gw485RxBuffer[2] == 9) { queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff; sendBuff->connectPort = connectJ9; if (uxQueueSpacesAvailable(J5_0_485_Queue)) { xQueueSend(J5_0_485_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } } else if (gw485RxBuffer[2] == 0) { queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff; sendBuff->connectPort = connectJ0; if (uxQueueSpacesAvailable(J5_0_485_Queue)) { xQueueSend(J5_0_485_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } } err: //清零buff state = wait; gw485RxBufferIndex = 0; return 1; } /** * @brief 读取寄存器 * @param * @retval */ void GW_MsgProcFunc_Read_Register(device_handle device,uint8_t *buff, uint16_t buffLen) { uint16_t Start_Address_16 = (gw485RxBuffer[3] << 8) | gw485RxBuffer[4]; uint16_t Register_Number_16 = (gw485RxBuffer[5] << 8) | gw485RxBuffer[6]; /* 读取数据 */ uint16_t reply_Data_Content[maxReadResAddrLen] = {0}; for ( uint16_t pos = 0; pos < Register_Number_16; pos++) { for (uint16_t var = 0; var < sizeof(g_RegTblR) / sizeof(SL_RegProcTable); var++) { if (g_RegTblR[var].regId == (Start_Address_16 + pos)) { reply_Data_Content[pos] = g_RegTblR[var].pRegProc(NULL); } } } /* 初始化发送内存 */ //系统内存不足,丢去当前包 uint32_t tempLen = 8 + 2 * Register_Number_16 + queueUartSendInfoSize; if (xPortGetFreeHeapSize() < tempLen + 1024) { return; } uint8_t *Buff = (uint8_t *)pvPortMalloc(tempLen); queueUartSendInfo *sendBuff = (queueUartSendInfo *)Buff; sendBuff->length = 8 + 2 * Register_Number_16; sendBuff->data = Buff + sizeof(queueUartSendInfo); uint8_t *replay_pack = sendBuff->data; /* 起始标志 */ *(replay_pack) = 'G'; *(replay_pack + 1) = 'W'; /* 功能码 */ replay_pack += 2; *replay_pack = SL_Function_Code_Read_Register; /* 回复字节数长度 */ replay_pack += 1; *replay_pack = (uint8_t)((Register_Number_16 * 2) >> 8); *(replay_pack + 1) = (uint8_t)(Register_Number_16 * 2); /* 回复数据内容 */ replay_pack += 2; for (uint8_t var = 0; var < Register_Number_16 * 2; var++) { if (0 == (var & 0x01)) { *(replay_pack + var) = (uint8_t)(reply_Data_Content[var / 2] >> 8); } else { *(replay_pack + var) = (uint8_t)(reply_Data_Content[var / 2]); } } /* 校验位 */ replay_pack += Register_Number_16 * 2; uint16_t packLen = 2 + 1 + 2 + Register_Number_16 * 2 + 3; uint16_t crc_temp = checkModebusCrc(sendBuff->data, packLen - 3); *replay_pack = (uint8_t)(crc_temp >> 8); replay_pack += 1; *replay_pack = (uint8_t)crc_temp; /* 结束标志 */ replay_pack += 1; *replay_pack = 0x16; /* 队列中有空间,则将发送数据 */ if (uxQueueSpacesAvailable(upward_uart_Queue)) { xQueueSend(upward_uart_Queue, &Buff, 10); } else { vPortFree(Buff); } } /** * @brief 写入寄存器 * @param * @retval */ void GW_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen) { uint16_t Register_Start_Address = (gw485RxBuffer[3] << 8) | gw485RxBuffer[4]; uint16_t Register_Number = (gw485RxBuffer[5] << 8) | gw485RxBuffer[6]; /* 将指令中的数据读取出来 */ uint16_t content[maxWriteResAddrLen] = {0}; for (uint16_t var = 0; var < Register_Number; var++) { content[var] = gw485RxBuffer[14 + 2 * var] << 8 | gw485RxBuffer[14 + 2 * var + 1]; } /* 将数据写入到寄存器中 */ for ( uint16_t pos = 0; pos < Register_Number; pos++) { for (uint16_t i = 0; i < sizeof(g_RegTblW) / sizeof(SL_RegProcTable); i++) { // debug_printf("g_RegTblW[i].regId : %x \n", g_RegTblW[i].regId); // debug_printf("Register_Start_Address : %x \n", (Register_Start_Address + pos)); if (g_RegTblW[i].regId == (Register_Start_Address + pos)) { g_RegTblW[i].pRegProc(&content[pos]); } } } } /** * @brief 下发配置文件 * @param * @retval */ void GW_MsgProcFunc_Distribution_Profile(device_handle device, void *pMsg, uint32_t MsgLen) { log_info("in GW_MsgProcFunc_Distribution_Profile\n"); } /** * @brief 读取配置文件 * @param * @retval */ void GW_MsgProcFunc_Read_Profile(device_handle device, void *pMsg, uint32_t MsgLen) { log_info("in GW_MsgProcFunc_Read_Profile\n"); } /** * @brief 状态机函数 * @param * @retval */ void stateMachine(device_handle device) { if (state == wait) { if (analysisWait() == TRUE) { gw485RxTime = xTaskGetTickCount(); } } else if (state == startFlagGW) { analysisStartFlagGW(); } else if (state == functionCodeGW) { analysisFunctionCodeGW(); } else if (state == readRegStartAddressGW) { analysisReadRegStartAddressGW(); } else if (state == readRegStartNumberGW) { analysisReadRegStartNumberGW(); } else if (state == crcCheckBitGW) { analysisCrcCheckBitGW(); } else if (state == endFlagGW) { analysisEndFlagGW(device); } else if (state == writeRegStartAddressGW) { analysisWriteRegStartAddressGW(); } else if (state == writeRegStartNumberGW) { analysisWriteRegStartNumberGW(); } else if (state == cfgFramesNumGW) { analysisCfgFramesNumGW(); } else if (state == cfgLengthGW) { analysisCfgLengthGW(); } else if (state == readCfgLengthGW) { analysisReadCfgLengthGW(); } else if (state == startFlagSL) { analysisStartFlagSL(); } else if (state == portSL) { analysisPortSL(); } else if (state == lengthSL) { analysisLengthSL(); } else if (state == endFlagSL) { analysisEndFlagSL(); } } /** * @brief modbus的crc校验 * @param *arr_buff 需要校验的数据 * len 数据长度 * @retval crc 校验的结果 */ uint16_t checkModebusCrc(uint8_t *arr_buff, uint8_t len) { uint16_t crc = 0xFFFF; uint16_t i, j; for (j = 0; j < len; ++j) { crc = crc ^ (*arr_buff++); for (i = 0; i < 8; ++i) { if ((crc&0x0001) > 0) { crc = crc >> 1; crc = crc ^ 0xa001; } else { crc = crc >> 1; } } } return crc; } /** * @brief 得到两次获取节拍的差值 * @param lastTick 上次获取的节拍值 * @retval */ uint32_t getTickDiff(uint32_t lastTick) { int64_t temp; temp = xTaskGetTickCount() - lastTick; /* 节拍值超过最大值后重新计数 */ if (temp < 0) { temp = portMAX_DELAY - lastTick + xTaskGetTickCount(); } return temp; } /** * @brief 解析智能模块发送来的数据 * @param device 用于接收智能模块发送来的数据的串口设备 * @retval */ void upwardUartDataAnalysis(device_handle device) { /* 每次函数最多执行10ms */ static uint32_t tickstart = 0U; tickstart = xTaskGetTickCount(); /* 2S未解析出来一帧数据,将数据清零 */ if (getTickDiff(gw485RxTime) >= tick_2S) { gw485RxTime = xTaskGetTickCount(); gw485RxBufferIndex = 0; state = wait; } while (uart_dev_char_present(device) == 1 && ((xTaskGetTickCount() - tickstart) < 5)) { gw485RxBuffer[gw485RxBufferIndex++] = uart_dev_in_char(device); stateMachine(device); } if (uart_dev_char_present(device) != 1 && state != wait) { stateMachine(device); } }