gateway_mcu/CH32V303-FreeRTOS/App/application/Src/upUartParse.c

1281 lines
33 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <string.h>
#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不使用该串口,01H4800;02H9600;03H19200;04H38400;05H57600;06H115200) */
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));
log_info("state %d\n", (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 >= ReadRegStartAddressGWMaxLen) {
/* 读取寄存器起始地址 */
uint16_t resAddrLen = ((gw485RxBuffer[5] << 8) | gw485RxBuffer[6]);
if (resAddrLen < maxReadResAddrLen) {
state = readRegStartNumberGW;
return TRUE;
}
log_error("resAddrLen : %d \n", resAddrLen);
}
if (gw485RxBufferIndex < ReadRegStartAddressGWMaxLen) {
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 = endFlagGW;
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 = writeRegStartNumberGW;
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 = ((uint16_t)gw485RxBuffer[frameLength - 3] << 8) | (uint16_t)gw485RxBuffer[frameLength - 2];
if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) {
state = crcCheckBitGW;
return TRUE;
}
// log_error("tempCrc : %x \n", tempCrc);
// log_error("checkModebusCrc : %x \n", checkModebusCrc(gw485RxBuffer, frameLength - 3));
}
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;
sendBuff->data = Buff + queueUartSendInfoSize;
memcpy((char *)sendBuff->data, (char *)&gw485RxBuffer[5], tempLen);
}
else {
Buff = (uint8_t *)pvPortMalloc(tempLen + queueTimeShareSendInfoSize);
queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff;
sendBuff->length = tempLen;
sendBuff->data = Buff + queueTimeShareSendInfoSize;
memcpy((char *)sendBuff->data, (char *)&gw485RxBuffer[5], tempLen);
// printf("\n\n\n\n\n%s\n", (char *)gw485RxBuffer);
// printf("%s\n%d\n\n\n\n\n\n", sendBuff->data, tempLen);
}
/* 通过不同的端口将数据发送到不同的地方 */
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[7 + 2 * var] << 8 | gw485RxBuffer[7 + 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);
}
}