1421 lines
49 KiB
C
1421 lines
49 KiB
C
#include "proto_SECS2.h"
|
||
|
||
#include "string.h"
|
||
#include "stdio.h"
|
||
|
||
#include "bsp_DS1302.h"
|
||
#include "bsp_Flash.h"
|
||
|
||
#include "bsp_W5500.h"
|
||
#include "proto_modbus_tcp_master.h"
|
||
|
||
#include "os_timer.h"
|
||
|
||
#define PROTO_SECS2_MESSAGE_DATA_NUM (50) /*解析的最多的数据类型*/
|
||
#define PROTO_SECS2_MESSAGE_DATA_BUFFER_NUM (255) /*解析的数据类型的最多字节数量*/
|
||
|
||
u8 proto_SECS2_Tx_Buffer[2048];
|
||
|
||
/*数据接收解析*/
|
||
static proto_SECS2_MessageData_t proto_SECS2_Rx_MessageData[PROTO_SECS2_MESSAGE_DATA_NUM];
|
||
static u8 proto_SECS2_Rx_MessageDataBuffer[PROTO_SECS2_MESSAGE_DATA_BUFFER_NUM];
|
||
|
||
// 发送单个报警项
|
||
static void send_alarm_item(proto_SECS2_MessageData_t *MessageData, u8 *Tx, u16 *TxLen, u8 index, u8 is_alarm, const char *start_str, const char *duration_str);
|
||
|
||
/*发送的数据*/
|
||
static proto_SECS2_MessageData_t proto_SECS2_Tx_MessageData[PROTO_SECS2_MESSAGE_DATA_NUM];
|
||
|
||
static u8 proto_SECS2_Rx_MessageDataAnalysis_List(u8 *pData, u16 Len);
|
||
static u16 proto_HSMS_AddData(u8 *pTxData, proto_SECS2_MessageData_t *pData);
|
||
static void proto_SECS2_Rx_Task(proto_HSMS_Header_Data_t *pHeader_Data, u8 *pData, u16 Len);
|
||
static void proto_SECS2_Tx_Alarm_Task(void);
|
||
static void proto_SECS2_Tx_Dev_State_Task(void);
|
||
static void proto_SECS2_Tx_Set_Ask_Task(void);
|
||
|
||
proto_SECS2_t SECS2 =
|
||
{
|
||
.Set_Ask.flag = 0,
|
||
.Rx_DataAnalysis = proto_SECS2_Rx_Task,
|
||
.Tx_Alarm_Task = proto_SECS2_Tx_Alarm_Task,
|
||
.Tx_Dev_State_Task = proto_SECS2_Tx_Dev_State_Task,
|
||
.Tx_Set_Ask_Task = proto_SECS2_Tx_Set_Ask_Task,
|
||
};
|
||
|
||
proto_SECS2_t *pSECS2 = &SECS2;
|
||
|
||
static void proto_SECS2_Send(proto_HSMS_Header_Data_t *pHeader_Data, u8 *pData, u16 Len)
|
||
{
|
||
HSMS.Tx_RsqData(pHeader_Data, pData, Len, NULL);
|
||
}
|
||
|
||
/**
|
||
* @brief 发送 S1F3 响应(单个数据、多个数据、全部数据)
|
||
* @param pHeader_Data HSMS 消息头
|
||
* @param pIndexArray 请求的索引数组(uint32)
|
||
* @param IndexCount 索引数量
|
||
*/
|
||
void proto_SECS2_Tx_S1F3(proto_HSMS_Header_Data_t *pHeader_Data, u32 *pIndexArray, u8 IndexCount) {
|
||
u8 *Tx = proto_SECS2_Tx_Buffer;
|
||
u16 TxLen = 0;
|
||
proto_SECS2_MessageData_t MessageData;
|
||
u8 list_count;
|
||
u8 i;
|
||
|
||
pHeader_Data->Header_Byte3++; /* 响应 Function 加 1 */
|
||
pHeader_Data->Header_Byte2.Analysis_Data.Wait = 0;
|
||
|
||
u8 has_all = 0;
|
||
for (i = 0; i < IndexCount; i++) {
|
||
if (pIndexArray[i] == 0xFFFFFFFF) {
|
||
has_all = 1;
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* 辅助宏:只添加数据值(不包含索引) */
|
||
#define ADD_VALUE(type, value_ptr, data_num) \
|
||
do { \
|
||
MessageData.DataType = type; \
|
||
MessageData.pData = value_ptr; \
|
||
MessageData.DataNum = data_num; \
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData); \
|
||
} while(0)
|
||
|
||
u8 total_items = 0;
|
||
if (has_all) {
|
||
total_items = 26 + 4 + 1; // 浮点 + 整数 + SN
|
||
} else {
|
||
for (i = 0; i < IndexCount; i++) {
|
||
u32 idx = pIndexArray[i];
|
||
if ((idx >= 40050 && idx <= 40100 && ((idx - 40050) % 2 == 0)) ||
|
||
(idx >= 40250 && idx <= 40252) ||
|
||
(idx == 9527) || (idx == 3001)) {
|
||
total_items++;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 外层列表 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = total_items;
|
||
MessageData.pData = &list_count;
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
if (has_all) {
|
||
/* 浮点数据 */
|
||
for (i = 0; i < 26; i++) {
|
||
float val = modbus_tcp.data.float_values[i];
|
||
ADD_VALUE(PROTO_SECS2_DATA_TYPE_4Byte_float, &val, 1);
|
||
}
|
||
/* 整数数据(3个) */
|
||
for (i = 0; i < 3; i++) {
|
||
u16 val = modbus_tcp.data.int_values[i];
|
||
ADD_VALUE(PROTO_SECS2_DATA_TYPE_2Byte_uint, &val, 1);
|
||
}
|
||
/* SN(9527):从 40253 读取整数并转为字符串 */
|
||
ADD_VALUE(PROTO_SECS2_DATA_TYPE_ASCII, modbus_tcp.data.sn_str, strlen(modbus_tcp.data.sn_str));
|
||
} else {
|
||
for (i = 0; i < IndexCount; i++) {
|
||
u32 idx = pIndexArray[i];
|
||
|
||
if (idx == 9527) {
|
||
ADD_VALUE(PROTO_SECS2_DATA_TYPE_ASCII, modbus_tcp.data.sn_str, strlen(modbus_tcp.data.sn_str));
|
||
}
|
||
else if (idx >= 40050 && idx <= 40100 && ((idx - 40050) % 2 == 0)) {
|
||
u8 float_idx = (idx - 40050) / 2;
|
||
if (float_idx < 26) {
|
||
float val = modbus_tcp.data.float_values[float_idx];
|
||
ADD_VALUE(PROTO_SECS2_DATA_TYPE_4Byte_float, &val, 1);
|
||
}
|
||
}
|
||
else if (idx >= 40250 && idx <= 40252) {
|
||
u8 int_idx = idx - 40250;
|
||
u16 val = modbus_tcp.data.int_values[int_idx];
|
||
ADD_VALUE(PROTO_SECS2_DATA_TYPE_2Byte_uint, &val, 1);
|
||
}
|
||
else if(idx == 3001)/*设备状态查询*/
|
||
{
|
||
|
||
ADD_VALUE(PROTO_SECS2_DATA_TYPE_2Byte_uint,&modbus_tcp.status_ctx.device_status,1);
|
||
}
|
||
/* 其他索引忽略(不添加到列表) */
|
||
}
|
||
}
|
||
|
||
#undef ADD_VALUE
|
||
|
||
proto_SECS2_Send(pHeader_Data, Tx, TxLen);
|
||
}
|
||
|
||
void proto_SECS2_Tx_S2F49(proto_HSMS_Header_Data_t *pHeader_Data, void *pData, u16 Len)
|
||
{
|
||
u8 list_count = 0;
|
||
char empty_ascii_1[] = "";
|
||
u8 *Tx = proto_SECS2_Tx_Buffer, TxLen = 0;
|
||
u8 Tx_Data = (u8)pData;
|
||
proto_SECS2_MessageData_t MessageData;
|
||
|
||
pHeader_Data->Header_Byte3++;
|
||
pHeader_Data->Header_Byte2.Analysis_Data.Wait = 0;
|
||
|
||
/*List 2 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 2;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_Binary;
|
||
MessageData.pData = (void *)(&Tx_Data);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 1;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 第四层列表:2个元素 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 2;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)&empty_ascii_1;
|
||
MessageData.DataNum = strlen(empty_ascii_1);
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)&empty_ascii_1;
|
||
MessageData.DataNum = strlen(empty_ascii_1);
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/*将发送数据拼接到HSMS后面*/
|
||
proto_SECS2_Send(pHeader_Data, Tx, TxLen);
|
||
}
|
||
|
||
void proto_SECS2_Tx_S1F1(proto_HSMS_Header_Data_t *pHeader_Data, void *pData, u16 Len)
|
||
{
|
||
u8 *Tx = proto_SECS2_Tx_Buffer, TxLen = 0;
|
||
u8 list_count = 0;
|
||
proto_SECS2_MessageData_t MessageData;
|
||
|
||
pHeader_Data->Header_Byte3++;
|
||
pHeader_Data->Header_Byte2.Analysis_Data.Wait = 0;
|
||
|
||
/*List 2 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 2;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/*ASCII Station_Type[8] */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)Usr_Flash.FlashData.Station_Type;
|
||
MessageData.DataNum = strlen(Usr_Flash.FlashData.Station_Type);
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/*软件版本号 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)Usr_Flash.FlashData.Version;
|
||
MessageData.DataNum = strlen(Usr_Flash.FlashData.Version);
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
/*将发送数据拼接到HSMS后面*/
|
||
proto_SECS2_Send(pHeader_Data, Tx, TxLen);
|
||
}
|
||
|
||
void proto_SECS2_Tx_S6F11(proto_HSMS_Header_Data_t *pHeader_Base, u8 index, u8 is_alarm, const char *start_str, u32 duration_sec)
|
||
{
|
||
u8 *Tx = proto_SECS2_Tx_Buffer;
|
||
u16 TxLen = 0;
|
||
u8 list_count;
|
||
u8 data_id = 0;
|
||
u32 alarm_all = 111101;
|
||
proto_SECS2_MessageData_t MessageData;
|
||
|
||
proto_HSMS_Header_Data_t Header = *pHeader_Base;
|
||
Header.Header_Byte2.Analysis_Data.Wait = PROTO_ALARM_CHANGE_RX_WAIT;
|
||
|
||
/* 外层列表:3个元素 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 3;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* Data ID 从 Flash 读取 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_4Byte_uint;
|
||
MessageData.pData = (void *)&data_id;
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* Collection Event ID 从 Flash 读取 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_4Byte_uint;
|
||
MessageData.pData = (void *)&alarm_all;
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 第三层列表:1个元素 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 1;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 第四层列表:2个元素 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 2;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* Report ID - 置空(或从 Flash 读取) */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_4Byte_uint;
|
||
u32 empty_report_id = 2329004;
|
||
MessageData.pData = (void *)&empty_report_id;
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 报警数据列表:只包含 1 个报警项 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 1;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
char duration_str[20];
|
||
snprintf(duration_str, sizeof(duration_str), "%u", duration_sec);
|
||
|
||
// 调用send_alarm_item 发送单个报警项
|
||
send_alarm_item(&MessageData, Tx, &TxLen, index, is_alarm, start_str, duration_str);
|
||
|
||
/* 发送消息 */
|
||
proto_SECS2_Send(&Header, Tx, TxLen);
|
||
}
|
||
|
||
char alarm_description[40];
|
||
char ip_description[32];
|
||
|
||
// 发送单个报警项
|
||
static void send_alarm_item(proto_SECS2_MessageData_t *MessageData, u8 *Tx, u16 *TxLen, u8 index, u8 is_alarm, const char *start_str, const char *duration_str)
|
||
{
|
||
u8 list_count;
|
||
u32 alarm_id_to_send;
|
||
char alarm_type[20];
|
||
char empty_ascii[1] = "";
|
||
u8 empty_uint1 = 3;
|
||
u8 empty_uint2 = 1;
|
||
char fixed_ascii[2] = "1";
|
||
char fixed_ip[] = "IDS_16403_ALERT_61411";
|
||
char begin_warning[6] = "Begin";
|
||
char end_warning[6] = "End";
|
||
char device_type[6] = "PUMP";
|
||
char fixed_value1[] = "Over Trigger(High)";
|
||
char fixed_value2[] = "Equipment";
|
||
char fixed_value3[] = "{e957e31d-3e46-4a66-a6ab-144c0b71d400}";
|
||
|
||
|
||
// 设置报警ID和描述
|
||
if (90 == index && 1 == is_alarm) {
|
||
// 特殊:离线报警(仅用于设备状态,但也可保留)
|
||
alarm_id_to_send = 90;
|
||
snprintf(alarm_description, sizeof(alarm_description), "%s", "SCRUBBER Offline");
|
||
strncpy(alarm_type, "Major Alarm", sizeof(alarm_type));
|
||
} else if (is_alarm) {
|
||
// 普通报警:index 0~23
|
||
alarm_id_to_send = index;
|
||
const char *desc = (index < 24) ? proto_modbus_master_alarm[index] : "Unknown Alarm";
|
||
snprintf(alarm_description, sizeof(alarm_description), "%s", desc);
|
||
strncpy(alarm_type, "Major Alarm", sizeof(alarm_type));
|
||
} else {
|
||
// 警告:index 0~63
|
||
alarm_id_to_send = 24 + index;
|
||
const char *desc = (index < 65) ? proto_modbus_master_warning[index] : "Unknown Warning";
|
||
snprintf(alarm_description, sizeof(alarm_description), "%s", desc);
|
||
strncpy(alarm_type, "Major Warning", sizeof(alarm_type));
|
||
}
|
||
|
||
/* 单个报警项列表:19个元素 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 19;
|
||
MessageData->pData = (void *)(&list_count);
|
||
MessageData->DataNum = 1;
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 1. AlarmID */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_4Byte_uint;
|
||
MessageData->pData = (void *)&alarm_id_to_send;
|
||
MessageData->DataNum = 1;
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 2. 报警类型 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)alarm_type;
|
||
MessageData->DataNum = strlen(alarm_type);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 3. 报警机台和位置 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)Usr_Flash.FlashData.Device_Model;
|
||
MessageData->DataNum = strlen(Usr_Flash.FlashData.Device_Model);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 4.从传IP占位改为传文档固定值*/
|
||
sprintf(ip_description, "%d.%d.%d.%d:%d", W5500.IP_Addr[0], W5500.IP_Addr[1], W5500.IP_Addr[2], W5500.IP_Addr[3], (W5500.W5500_Class[0].ConfigData.Port[0] << 8) | W5500.W5500_Class[0].ConfigData.Port[1]);
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)fixed_ip;
|
||
MessageData->DataNum = strlen(fixed_ip);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 5. 设备型号 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)Usr_Flash.FlashData.Device_ID;
|
||
MessageData->DataNum = strlen(Usr_Flash.FlashData.Device_ID);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 6. 报警描述 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)alarm_description;
|
||
MessageData->DataNum = strlen(alarm_description);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 7. Over Trigger 传文档固定值*/
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)fixed_value1;
|
||
MessageData->DataNum = strlen(fixed_value1);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 8. Equipment 传文档固定值*/
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)fixed_value2;
|
||
MessageData->DataNum = strlen(fixed_value2);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 9. Begin Warning */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
if (strcmp(duration_str, "0") == 0)
|
||
{
|
||
MessageData->pData = (void *)begin_warning;
|
||
MessageData->DataNum = strlen(begin_warning);
|
||
}
|
||
else
|
||
{
|
||
MessageData->pData = (void *)end_warning;
|
||
MessageData->DataNum = strlen(end_warning);
|
||
}
|
||
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 10. Variable data 2 - 传文档固定值 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)fixed_value3;
|
||
MessageData->DataNum = strlen(fixed_value3);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 11. 设备类型 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)&Usr_Flash.FlashData.Station_Type;
|
||
MessageData->DataNum = strlen(Usr_Flash.FlashData.Station_Type);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 12. Sensor名称 -使用报警索引表示传感器名称 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_4Byte_uint;
|
||
MessageData->pData = (void *)&alarm_id_to_send;
|
||
MessageData->DataNum = 1;
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 13. 报警值 - 置3 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_4Byte_uint;
|
||
MessageData->pData = (void *)&empty_uint1;
|
||
MessageData->DataNum = 1;
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 14. 报警单位 - 置1 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_4Byte_uint;
|
||
MessageData->pData = (void *)&empty_uint2;
|
||
MessageData->DataNum = 1;
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 15. 开始时间 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)start_str;
|
||
MessageData->DataNum = strlen(start_str);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 16. 报警时长 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)duration_str;
|
||
MessageData->DataNum = strlen(duration_str);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 17. 报警类型 (策略报警/机台报警) - 置1 */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)fixed_ascii;
|
||
MessageData->DataNum = 1;
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 18. 机台名称(flash) */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)Usr_Flash.FlashData.Station_Name;
|
||
MessageData->DataNum = strlen(Usr_Flash.FlashData.Station_Name);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
|
||
/* 19. 腔体名称(flash) */
|
||
MessageData->DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData->pData = (void *)Usr_Flash.FlashData.Chamber_Name;
|
||
MessageData->DataNum = strlen(Usr_Flash.FlashData.Chamber_Name);
|
||
*TxLen += proto_HSMS_AddData(&Tx[*TxLen], MessageData);
|
||
}
|
||
|
||
|
||
void proto_SECS2_Tx_S1F13(proto_HSMS_Header_Data_t *pHeader_Data, void *pData, u16 Len)
|
||
{
|
||
u8 *Tx = proto_SECS2_Tx_Buffer, TxLen = 0;
|
||
u8 list_count;
|
||
proto_SECS2_MessageData_t MessageData;
|
||
|
||
pHeader_Data->Header_Byte3++;
|
||
pHeader_Data->Header_Byte2.Analysis_Data.Wait = 0;
|
||
|
||
/*List 2*/
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 2;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/*Binary 0*/
|
||
u8 bool_value = 0;
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_Binary;
|
||
MessageData.pData = (void *)(&bool_value);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/*List 2*/
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 2;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/*ASCII PK1143*/
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)Usr_Flash.FlashData.Manufacturer;
|
||
MessageData.DataNum = strlen(Usr_Flash.FlashData.Manufacturer);
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/*ASCII 001181*/
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)Usr_Flash.FlashData.Version;
|
||
MessageData.DataNum = strlen(Usr_Flash.FlashData.Version);
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/*将发送数据拼接到HSMS后面*/
|
||
proto_SECS2_Send(pHeader_Data, Tx, TxLen);
|
||
}
|
||
|
||
void proto_SECS2_Tx_S2F31(proto_HSMS_Header_Data_t *pHeader_Data, void *pData, u16 Len, u8 bool)
|
||
{
|
||
u8 *Tx = proto_SECS2_Tx_Buffer, TxLen = 0;
|
||
proto_SECS2_MessageData_t MessageData;
|
||
|
||
pHeader_Data->Header_Byte3++;
|
||
pHeader_Data->Header_Byte2.Analysis_Data.Wait = 0;
|
||
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_Binary;
|
||
MessageData.pData = (void *)(&bool);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/*将发送数据拼接到HSMS后面*/
|
||
proto_SECS2_Send(pHeader_Data, Tx, TxLen);
|
||
}
|
||
|
||
void proto_SECS2_Tx_Device_S6F11(proto_HSMS_Header_Data_t *pHeader_Data, void *pData,u8 device_status, u16 Len)
|
||
{
|
||
u8 *Tx = proto_SECS2_Tx_Buffer;
|
||
u16 TxLen = 0;
|
||
u8 list_count;
|
||
char temp_buffer[5] = "";
|
||
|
||
|
||
// 构建状态字符串
|
||
char status_buffer[20] = "";
|
||
char time_string[17]; // 16位时间字符串 + 1个null终止符
|
||
|
||
proto_SECS2_MessageData_t MessageData;
|
||
|
||
/* 外层列表:3个元素 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 3;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 第一个元素: Data ID (U4) */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_4Byte_uint;
|
||
u32 data_id = 1;
|
||
// MessageData.pData = (void *)&Usr_Flash.FlashData.Data_ID1;
|
||
MessageData.pData = (void *)data_id;
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 第二个元素: Collection event ID (U4) */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_4Byte_uint;
|
||
// MessageData.pData = (void *)&Usr_Flash.FlashData.Collection_event_ID1;
|
||
u32 collection_event_id = 2;
|
||
MessageData.pData = (void *)collection_event_id;
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 第三层列表:1个元素 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 1;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 第四层列表:2个元素 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 2;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* Report ID (U4) */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_4Byte_uint;
|
||
// MessageData.pData = (void *)&Usr_Flash.FlashData.Report_ID1;
|
||
u32 report_id = 3;
|
||
MessageData.pData = (void *)report_id;
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 第五层列表:6个元素 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_List;
|
||
list_count = 6;
|
||
MessageData.pData = (void *)(&list_count);
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 1. 机台名称(flash) */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)Usr_Flash.FlashData.Station_Name;
|
||
MessageData.DataNum = strlen(Usr_Flash.FlashData.Station_Name);
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 2. 腔体名称(flash) */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)Usr_Flash.FlashData.Chamber_Name;
|
||
MessageData.DataNum = strlen(Usr_Flash.FlashData.Chamber_Name);
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 3. 附属设备类型 */
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)Usr_Flash.FlashData.Station_Type;
|
||
MessageData.DataNum = strlen(Usr_Flash.FlashData.Station_Type);
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 4. 附属设备状态 */
|
||
sprintf(temp_buffer, "%d", device_status);
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)&temp_buffer;
|
||
MessageData.DataNum = 1;
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 5. 状态切换成功时间 - 从DS1302获取 */
|
||
DS1302.GetTimeWithMs(time_string, sizeof(time_string));
|
||
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)&time_string;
|
||
MessageData.DataNum = strlen(time_string); // 16位时间字符串长度
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 6. 腔体位置 - 设为空(ALL表示没有具体位置)*/
|
||
MessageData.DataType = PROTO_SECS2_DATA_TYPE_ASCII;
|
||
MessageData.pData = (void *)"ALL";
|
||
MessageData.DataNum = 3; // "ALL"的长度
|
||
TxLen += proto_HSMS_AddData(&Tx[TxLen], &MessageData);
|
||
|
||
/* 将发送数据拼接到HSMS后面 */
|
||
proto_SECS2_Send(pHeader_Data, Tx, TxLen);
|
||
}
|
||
|
||
/*警报主动上传*/
|
||
static void proto_SECS2_Tx_Alarm_Task(void)
|
||
{
|
||
static u32 Sys_Byte;
|
||
/*1s判断一次*/
|
||
if (TIME_TRUE == OsTimer_CheckTimeOut(modbus_tcp.alarm_ctx.alarm_task_tick, osTime_MSecTick, 1000))
|
||
{
|
||
modbus_tcp.alarm_ctx.alarm_task_tick = osTime_MSecTick;
|
||
|
||
// ----- 读取报警位(24位)-----
|
||
u64 alarm_now = ((u64)(modbus_tcp.data.reg_status[2] & 0xFF) << 0) |
|
||
((u64)modbus_tcp.data.reg_status[3] << 8);
|
||
|
||
// ----- 读取警告位(64位)-----
|
||
u64 warning_now = ((u64)modbus_tcp.data.reg_status[4] << 0) |
|
||
((u64)modbus_tcp.data.reg_status[5] << 16) |
|
||
((u64)modbus_tcp.data.reg_status[6] << 32) |
|
||
((u64)modbus_tcp.data.reg_status[7] << 48);
|
||
|
||
warning_now &= ~((u64)0xFC << 48);/*清除bit2,3,4,5,6,7这些是状态控制*/
|
||
|
||
u64 changed_alarm = alarm_now ^ modbus_tcp.alarm_ctx.alarm_status_last;
|
||
u64 changed_warning = warning_now ^ modbus_tcp.alarm_ctx.warning_status_last;
|
||
|
||
u32 now_sec = DS1302.GetCurrentSeconds();
|
||
char now_str[17];
|
||
DS1302.GetTimeWithMs(now_str, sizeof(now_str));
|
||
|
||
proto_HSMS_Header_Data_t Header;
|
||
Header.Device_Id = HSMS.Flash_ConfigData.Device_Id;
|
||
Header.Header_Byte2.Analysis_Data.Stream = 6;
|
||
Header.Header_Byte2.Analysis_Data.Wait = PROTO_ALARM_CHANGE_RX_WAIT;
|
||
Header.Header_Byte3 = 11;
|
||
Header.PType = proto_HSMS_PTYPE_SECS2;
|
||
Header.SType = PROTO_HSMS_STYPE_Data_Message;
|
||
|
||
/*处于PM状态时不上传报警,但更新状态*/
|
||
u8 pm_status = (modbus_tcp.data.reg_status[0] >> 8) & PROTO_MODBUS_DEVICE_STATUS_PM;
|
||
if(pm_status == PROTO_MODBUS_DEVICE_STATUS_PM)
|
||
{
|
||
modbus_tcp.alarm_ctx.pm_status = PROTO_MODBUS_MASTER_MODE_PM;
|
||
modbus_tcp.alarm_ctx.alarm_status_last = alarm_now;
|
||
modbus_tcp.alarm_ctx.warning_status_last = warning_now;
|
||
return;
|
||
}else
|
||
{
|
||
modbus_tcp.alarm_ctx.pm_status = 0;
|
||
}
|
||
|
||
/*处理离线报警*/
|
||
if(modbus_tcp.alarm_ctx.offline != modbus_tcp.alarm_ctx.last_offline_state)
|
||
{
|
||
if(modbus_tcp.alarm_ctx.offline == 1 && modbus_tcp.alarm_ctx.last_offline_state == 0)/*在线->离线*/
|
||
{
|
||
modbus_tcp.alarm_ctx.offline_start_sec = now_sec;
|
||
strcpy(modbus_tcp.alarm_ctx.offline_start_str,now_str);
|
||
pSECS2->sys_count++;
|
||
Header.Sys_Byte = pSECS2->sys_count;
|
||
proto_SECS2_Tx_S6F11(&Header, 90, 1, now_str, 0);
|
||
}else if(modbus_tcp.alarm_ctx.offline == 0 && modbus_tcp.alarm_ctx.last_offline_state == 1)
|
||
{
|
||
u32 duration = now_sec - modbus_tcp.alarm_ctx.offline_start_sec;
|
||
pSECS2->sys_count++;
|
||
Header.Sys_Byte = pSECS2->sys_count;
|
||
proto_SECS2_Tx_S6F11(&Header, 90, 1, modbus_tcp.alarm_ctx.offline_start_str, duration);
|
||
memset(modbus_tcp.alarm_ctx.offline_start_str,0,15);
|
||
modbus_tcp.alarm_ctx.offline_start_sec = 0;
|
||
}
|
||
modbus_tcp.alarm_ctx.last_offline_state = modbus_tcp.alarm_ctx.offline;
|
||
}
|
||
|
||
if (changed_alarm == 0 && changed_warning == 0) {
|
||
modbus_tcp.alarm_ctx.alarm_status_last = alarm_now;
|
||
modbus_tcp.alarm_ctx.warning_status_last = warning_now;
|
||
return;
|
||
}
|
||
|
||
static u8 alarm_active = 0;
|
||
// ----- 处理报警(24个)-----
|
||
for (u8 i = 0; i < 24; i++) {
|
||
if (changed_alarm & ((u64)1 << i)) {
|
||
if (alarm_now & ((u64)1 << i)) { // 激活
|
||
alarm_active += 1;
|
||
strcpy(modbus_tcp.alarm_ctx.alarm_start_str[i], now_str);
|
||
modbus_tcp.alarm_ctx.alarm_start_sec[i] = now_sec;
|
||
pSECS2->sys_count++;
|
||
Header.Sys_Byte = pSECS2->sys_count;
|
||
proto_SECS2_Tx_S6F11(&Header, i, 1, now_str, 0);
|
||
} else { // 消失
|
||
if(alarm_active >= 1)
|
||
{
|
||
alarm_active -= 1;
|
||
}
|
||
u32 duration = now_sec - modbus_tcp.alarm_ctx.alarm_start_sec[i];
|
||
pSECS2->sys_count++;
|
||
Header.Sys_Byte = pSECS2->sys_count;
|
||
proto_SECS2_Tx_S6F11(&Header, i, 1,
|
||
modbus_tcp.alarm_ctx.alarm_start_str[i], duration);
|
||
// 清空记录
|
||
modbus_tcp.alarm_ctx.alarm_start_str[i][0] = '\0';
|
||
modbus_tcp.alarm_ctx.alarm_start_sec[i] = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// ----- 处理警告(64个)-----
|
||
for (u8 i = 0; i < 64; i++) {
|
||
if (changed_warning & ((u64)1 << i)) {
|
||
if (warning_now & ((u64)1 << i)) { // 激活
|
||
strcpy(modbus_tcp.alarm_ctx.warning_start_str[i], now_str);
|
||
modbus_tcp.alarm_ctx.warning_start_sec[i] = now_sec;
|
||
pSECS2->sys_count++;
|
||
Header.Sys_Byte = pSECS2->sys_count;
|
||
proto_SECS2_Tx_S6F11(&Header, i, 0, now_str, 0);
|
||
} else { // 消失
|
||
u32 duration = now_sec - modbus_tcp.alarm_ctx.warning_start_sec[i];
|
||
pSECS2->sys_count++;
|
||
Header.Sys_Byte = pSECS2->sys_count;
|
||
proto_SECS2_Tx_S6F11(&Header, i, 0,
|
||
modbus_tcp.alarm_ctx.warning_start_str[i], duration);
|
||
modbus_tcp.alarm_ctx.warning_start_str[i][0] = '\0';
|
||
modbus_tcp.alarm_ctx.warning_start_sec[i] = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 更新缓存
|
||
modbus_tcp.alarm_ctx.alarm_status_last = alarm_now;
|
||
modbus_tcp.alarm_ctx.warning_status_last = warning_now;
|
||
modbus_tcp.alarm_ctx.alarm = alarm_active > 0?PROTO_MODBUS_MASTER_MODE_ALARM:PROTO_MODBUS_MASTER_MODE_RUN;
|
||
}
|
||
}
|
||
|
||
/*设备状态*/
|
||
static void proto_SECS2_Tx_Dev_State_Task(void)
|
||
{
|
||
/*1s判断一次*/
|
||
if (TIME_TRUE == OsTimer_CheckTimeOut(modbus_tcp.status_ctx.status_task_tick, osTime_MSecTick, 1000))
|
||
{
|
||
modbus_tcp.status_ctx.status_task_tick = osTime_MSecTick;
|
||
u8 device_status = PROTO_MODBUS_MASTER_MODE_IDLE; // 默认空闲
|
||
u16 reg = modbus_tcp.data.reg_status[7]; // 40007 寄存器
|
||
|
||
// ----- 按优先级判断状态 -----
|
||
// 1. 离线(由 alarm_ctx.offline 标识)
|
||
if (modbus_tcp.alarm_ctx.offline) {
|
||
device_status = PROTO_MODBUS_MASTER_MODE_OFFLINE;
|
||
}
|
||
// 2. PM 状态
|
||
else if (modbus_tcp.alarm_ctx.pm_status == PROTO_MODBUS_MASTER_MODE_PM) {
|
||
device_status = PROTO_MODBUS_MASTER_MODE_PM;
|
||
}
|
||
// 3. 报警(有激活的一级报警)
|
||
else if (modbus_tcp.alarm_ctx.alarm == PROTO_MODBUS_MASTER_MODE_ALARM) {
|
||
device_status = PROTO_MODBUS_MASTER_MODE_ALARM;
|
||
}
|
||
// 4. IDLE 模式(IDLE开位=1)
|
||
else if ((modbus_tcp.data.reg_status[2] >> 8) & (1 << 6)) {
|
||
device_status = PROTO_MODBUS_MASTER_MODE_IDLE;
|
||
}
|
||
// 5. 运行状态:启动位=1 且 停止位=0 且 IDLE关=0,绿灯亮
|
||
else if ((modbus_tcp.data.reg_status[2] >> 8) & 2) {
|
||
device_status = PROTO_MODBUS_MASTER_MODE_RUN;
|
||
}
|
||
// 其他情况(如停止位=1,或无效组合)默认视为 IDLE
|
||
else {
|
||
device_status = PROTO_MODBUS_MASTER_MODE_IDLE;
|
||
}
|
||
|
||
// 保存当前状态到上下文
|
||
modbus_tcp.status_ctx.device_status = device_status;
|
||
|
||
// 检测状态是否变化
|
||
if (device_status != modbus_tcp.status_ctx.device_status_last) {
|
||
// 发送 S6F11 状态变更消息
|
||
proto_HSMS_Header_Data_t Header_Data;
|
||
Header_Data.Device_Id = HSMS.Flash_ConfigData.Device_Id;
|
||
Header_Data.Header_Byte2.Analysis_Data.Stream = 6;
|
||
Header_Data.Header_Byte2.Analysis_Data.Wait = PROTO_STATE_CHANGE_RX_WAIT;
|
||
Header_Data.Header_Byte3 = 11;
|
||
Header_Data.PType = proto_HSMS_PTYPE_SECS2;
|
||
Header_Data.SType = PROTO_HSMS_STYPE_Data_Message;
|
||
pSECS2->sys_count++;
|
||
Header_Data.Sys_Byte = pSECS2->sys_count;
|
||
|
||
// 发送设备状态信息(device_status 直接作为状态值传给发送函数)
|
||
proto_SECS2_Tx_Device_S6F11(&Header_Data, NULL, device_status, 0);
|
||
|
||
// 更新 last 值
|
||
modbus_tcp.status_ctx.device_status_last = device_status;
|
||
}
|
||
|
||
// 特别处理离线状态的 last_offline_state(保持同步)
|
||
if (modbus_tcp.alarm_ctx.offline != modbus_tcp.alarm_ctx.last_offline_state) {
|
||
modbus_tcp.alarm_ctx.last_offline_state = modbus_tcp.alarm_ctx.offline;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/*设备响应*/
|
||
static void proto_SECS2_Tx_Set_Ask_Task(void)
|
||
{
|
||
if(modbus_tcp.alarm_ctx.offline == 1 && pSECS2->Set_Ask.flag != 0)
|
||
{
|
||
proto_HSMS_Header_Data_t Header_Data;
|
||
Header_Data.Device_Id = HSMS.Flash_ConfigData.Device_Id;
|
||
Header_Data.Header_Byte2.Analysis_Data.Stream = 2; /*S2*/
|
||
Header_Data.Header_Byte2.Analysis_Data.Wait = PROTO_STATE_CHANGE_RX_WAIT;
|
||
Header_Data.Header_Byte3 = 49; /*F49*/
|
||
|
||
Header_Data.PType = proto_HSMS_PTYPE_SECS2;
|
||
Header_Data.SType = PROTO_HSMS_STYPE_Data_Message;
|
||
Header_Data.Sys_Byte = pSECS2->Set_Ask.sys_count;
|
||
proto_SECS2_Tx_S2F49(&Header_Data, 1, 0);
|
||
pSECS2->Set_Ask.flag = 0;
|
||
modbus_tcp.write_result = 0;
|
||
}
|
||
|
||
if(modbus_tcp.write_pending == 2 || modbus_tcp.write_pending == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
proto_HSMS_Header_Data_t Header_Data;
|
||
Header_Data.Device_Id = HSMS.Flash_ConfigData.Device_Id;
|
||
Header_Data.Header_Byte2.Analysis_Data.Stream = 2; /*S2*/
|
||
Header_Data.Header_Byte2.Analysis_Data.Wait = PROTO_STATE_CHANGE_RX_WAIT;
|
||
Header_Data.Header_Byte3 = 49; /*F49*/
|
||
|
||
Header_Data.PType = proto_HSMS_PTYPE_SECS2;
|
||
Header_Data.SType = PROTO_HSMS_STYPE_Data_Message;
|
||
Header_Data.Sys_Byte = pSECS2->Set_Ask.sys_count;
|
||
|
||
/*0为成功,1为失败*/
|
||
if(modbus_tcp.write_result == 1 && pSECS2->Set_Ask.flag == 1)
|
||
{
|
||
proto_SECS2_Tx_S2F49(&Header_Data, 0, 0);
|
||
pSECS2->Set_Ask.flag = 0;
|
||
modbus_tcp.write_result = 0;
|
||
}else if(modbus_tcp.write_result == 1 && pSECS2->Set_Ask.flag == 2)
|
||
{
|
||
proto_SECS2_Tx_S2F49(&Header_Data, 0, 0);
|
||
pSECS2->Set_Ask.flag = 0;
|
||
modbus_tcp.write_result = 0;
|
||
}else if(modbus_tcp.write_result == 1 && pSECS2->Set_Ask.flag == 3)
|
||
{
|
||
proto_SECS2_Tx_S2F49(&Header_Data, 0, 0);
|
||
pSECS2->Set_Ask.flag = 0;
|
||
modbus_tcp.write_result = 0;
|
||
}else if(modbus_tcp.write_result == 1 && pSECS2->Set_Ask.flag == 4 )
|
||
{
|
||
proto_SECS2_Tx_S2F49(&Header_Data, 0, 0);
|
||
pSECS2->Set_Ask.flag = 0;
|
||
modbus_tcp.write_result = 0;
|
||
}else if(modbus_tcp.write_result == 0 && pSECS2->Set_Ask.flag != 0)
|
||
{
|
||
proto_SECS2_Tx_S2F49(&Header_Data, 1, 0);
|
||
pSECS2->Set_Ask.flag = 0;
|
||
modbus_tcp.write_result = 0;
|
||
}
|
||
}
|
||
|
||
static void proto_SECS2_Rx_Task(proto_HSMS_Header_Data_t *pHeader_Data, u8 *pData, u16 Len)
|
||
{
|
||
u16 SnFm;
|
||
u8 DataNum;
|
||
|
||
/* 获取 Stream 和 Function */
|
||
SnFm = pHeader_Data->Header_Byte2.Analysis_Data.Stream << 8 | pHeader_Data->Header_Byte3;
|
||
// 无需回复
|
||
if (1 != pHeader_Data->Header_Byte2.Analysis_Data.Wait)
|
||
{
|
||
if (PROTO_SECS2_S6F12 == SnFm)
|
||
{
|
||
/* 处理 S5F2 */
|
||
}
|
||
else
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
|
||
DataNum = proto_SECS2_Rx_MessageDataAnalysis_List(pData, Len);
|
||
|
||
if (PROTO_SECS2_S1F1 == SnFm || PROTO_SECS2_S1F13 == SnFm) /*S1F1不进行数据判断*/
|
||
{
|
||
}
|
||
else if (0 == DataNum) /*没有解析数据*/
|
||
{
|
||
return;
|
||
}
|
||
|
||
/*记录系统计数*/
|
||
pSECS2->sys_count = pHeader_Data->Sys_Byte;
|
||
|
||
/*回复对应指令*/
|
||
switch (SnFm)
|
||
{
|
||
case PROTO_SECS2_S1F3:
|
||
{
|
||
if (DataNum == 0)
|
||
return;
|
||
|
||
u32 index_array[PROTO_SECS2_MESSAGE_DATA_NUM];
|
||
u8 index_count = 0;
|
||
u8 i;
|
||
|
||
/* 提取所有索引(假设为 4Byte_uint 类型) */
|
||
for (i = 0; i < DataNum; i++)
|
||
{
|
||
if (proto_SECS2_Rx_MessageData[i].DataType == PROTO_SECS2_DATA_TYPE_4Byte_uint)
|
||
{
|
||
u32 *pIndex = (u32 *)proto_SECS2_Rx_MessageData[i].pData;
|
||
index_array[index_count++] = *pIndex;
|
||
}
|
||
}
|
||
|
||
if (index_count > 0)
|
||
{
|
||
proto_SECS2_Tx_S1F3(pHeader_Data, index_array, index_count);
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PROTO_SECS2_S2F49:
|
||
{
|
||
u8 *pCmdData;
|
||
char pText[11];
|
||
|
||
/*Device Status*/
|
||
pCmdData = proto_SECS2_Rx_MessageData[3].pData;
|
||
snprintf(pText, 11, "%s", pCmdData);
|
||
if (0 == strncmp(pText, DEVICE_START, strlen(DEVICE_START)))
|
||
{
|
||
modbus_tcp.write(CONTROL_BIT_START);
|
||
pSECS2->Set_Ask.flag = 1;
|
||
}
|
||
else if (0 == strncmp(pText, DEVICE_STOP, strlen(DEVICE_STOP)))
|
||
{
|
||
modbus_tcp.write(CONTROL_BIT_STOP);
|
||
pSECS2->Set_Ask.flag = 2;
|
||
}
|
||
else if (0 == strncmp(pText, DEVICE_IDLE_OPEN, strlen(DEVICE_IDLE_OPEN)))
|
||
{
|
||
modbus_tcp.write(CONTROL_BIT_IDLE_OPEN);
|
||
pSECS2->Set_Ask.flag = 3;
|
||
}
|
||
else if (0 == strncmp(pText, DEVICE_IDLE_CLOSE, strlen(DEVICE_IDLE_CLOSE)))
|
||
{
|
||
modbus_tcp.write(CONTROL_BIT_IDLE_CLOSE);
|
||
pSECS2->Set_Ask.flag = 4;
|
||
}
|
||
else /*错误指令*/
|
||
{
|
||
proto_SECS2_Tx_S2F49(pHeader_Data, 0, 0);
|
||
return;
|
||
}
|
||
pSECS2->Set_Ask.sys_count = pSECS2->sys_count;
|
||
}
|
||
break;
|
||
|
||
case PROTO_SECS2_S1F1:
|
||
{
|
||
proto_SECS2_Tx_S1F1(pHeader_Data, NULL, 0);
|
||
}
|
||
break;
|
||
|
||
case PROTO_SECS2_S6F12: // 修改:S5F2改为S6F12
|
||
{
|
||
if (PROTO_SECS2_DATA_TYPE_Binary == proto_SECS2_Rx_MessageData[0].DataType)
|
||
{
|
||
u8 *pMessageData = proto_SECS2_Rx_MessageData[0].pData;
|
||
if (0 == pMessageData[0])
|
||
{
|
||
// PM100.Alarm_Control.Reset(); /*消除当前报警*/
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PROTO_SECS2_S1F13:
|
||
{
|
||
proto_SECS2_Tx_S1F13(pHeader_Data, NULL, 0);
|
||
}
|
||
break;
|
||
|
||
case PROTO_SECS2_S2F31: /*时间校准*/
|
||
{
|
||
if (PROTO_SECS2_DATA_TYPE_ASCII == proto_SECS2_Rx_MessageData[0].DataType)
|
||
{
|
||
u8 *pMessageData = proto_SECS2_Rx_MessageData[0].pData;
|
||
|
||
u16 year = 2000 + (u16)(pMessageData[2] - '0') * 10 + (u16)(pMessageData[3] - '0');
|
||
|
||
u8 month = (u16)(pMessageData[4] - '0') * 10 + (u16)(pMessageData[5] - '0');
|
||
|
||
u8 day = (u16)(pMessageData[6] - '0') * 10 + (u16)(pMessageData[7] - '0');
|
||
|
||
u8 hour = (u16)(pMessageData[8] - '0') * 10 + (u16)(pMessageData[9] - '0');
|
||
|
||
u8 min = (u16)(pMessageData[10] - '0') * 10 + (u16)(pMessageData[11] - '0');
|
||
|
||
u8 sec = (u16)(pMessageData[12] - '0') * 10 + (u16)(pMessageData[13] - '0');
|
||
|
||
u32 ms = 0;
|
||
ms = (u32)(pMessageData[14] - '0') * 10 + (u32)(pMessageData[15] - '0');
|
||
|
||
if (DS1302.SetTimeWithMs(year,month,day,hour,min,sec,ms)) /*时间返回*/
|
||
{
|
||
/* 时间设置成功 */
|
||
proto_SECS2_Tx_S2F31(pHeader_Data, NULL, 0, 0);
|
||
}
|
||
else /*时间异常*/
|
||
{
|
||
proto_SECS2_Tx_S2F31(pHeader_Data, NULL, 0, 1);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
default: /*无需处理的命令*/
|
||
{
|
||
/* 不处理 */
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*进行List的数据分包处理*/
|
||
static u8 proto_SECS2_Rx_MessageDataAnalysis_List(u8 *pData, u16 Len)
|
||
{
|
||
u8 RecursionNum = 0; /*递归次数*/
|
||
u8 MessageDataNum = 0; /*数据项数量*/
|
||
u16 LenIndex = 0;
|
||
u8 i, k;
|
||
|
||
/* 遍历接收的数据 */
|
||
while (LenIndex < Len)
|
||
{
|
||
RecursionNum++;
|
||
if (RecursionNum > 100)
|
||
{
|
||
break;
|
||
}
|
||
|
||
u8 format_byte = pData[LenIndex];
|
||
u8 data_type = format_byte >> 2;
|
||
u8 length_bytes_count = format_byte & 0x03; // 长度字节数
|
||
|
||
/* 跳过格式字节 */
|
||
LenIndex++;
|
||
|
||
/* 读取长度 */
|
||
u16 data_length = 0;
|
||
|
||
if (length_bytes_count == 1)
|
||
{
|
||
/* 1字节长度 */
|
||
data_length = pData[LenIndex];
|
||
LenIndex++;
|
||
}
|
||
else if (length_bytes_count == 2)
|
||
{
|
||
/* 2字节长度(大端序) */
|
||
data_length = (pData[LenIndex] << 8) | pData[LenIndex + 1];
|
||
LenIndex += 2;
|
||
}
|
||
else
|
||
{
|
||
/* 不支持其他长度格式 */
|
||
return 0;
|
||
}
|
||
|
||
/* 如果是list类型,记录并跳过 */
|
||
if (data_type == PROTO_SECS2_DATA_TYPE_List)
|
||
{
|
||
// 列表长度就是元素个数
|
||
proto_SECS2_Rx_MessageData[MessageDataNum].DataType = data_type;
|
||
proto_SECS2_Rx_MessageData[MessageDataNum].ByteLen = data_length;
|
||
proto_SECS2_Rx_MessageData[MessageDataNum].pData = &pData[LenIndex];
|
||
MessageDataNum++;
|
||
|
||
// 对于列表,data_length 是元素个数,不是字节数
|
||
// 这里需要特殊处理,或者将列表视为特殊项
|
||
}
|
||
else
|
||
{
|
||
/* 记录数据类型和地址 */
|
||
proto_SECS2_Rx_MessageData[MessageDataNum].DataType = data_type;
|
||
proto_SECS2_Rx_MessageData[MessageDataNum].ByteLen = data_length;
|
||
proto_SECS2_Rx_MessageData[MessageDataNum].pData = &pData[LenIndex];
|
||
LenIndex += data_length;
|
||
MessageDataNum++;
|
||
}
|
||
}
|
||
|
||
/*将数据重新排序为小端序方便进行数据解析*/
|
||
LenIndex = 0;
|
||
for (i = 0; i < MessageDataNum; i++)
|
||
{
|
||
switch (proto_SECS2_Rx_MessageData[i].DataType)
|
||
{
|
||
case PROTO_SECS2_DATA_TYPE_Binary:
|
||
case PROTO_SECS2_DATA_TYPE_Bool:
|
||
case PROTO_SECS2_DATA_TYPE_JIS_8:
|
||
case PROTO_SECS2_DATA_TYPE_1Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_1Byte_int:
|
||
case PROTO_SECS2_DATA_TYPE_ASCII:
|
||
{
|
||
memcpy(&proto_SECS2_Rx_MessageDataBuffer[LenIndex],
|
||
proto_SECS2_Rx_MessageData[i].pData,
|
||
proto_SECS2_Rx_MessageData[i].ByteLen);
|
||
proto_SECS2_Rx_MessageData[i].DataNum = proto_SECS2_Rx_MessageData[i].ByteLen;
|
||
proto_SECS2_Rx_MessageData[i].pData = &proto_SECS2_Rx_MessageDataBuffer[LenIndex];
|
||
LenIndex += proto_SECS2_Rx_MessageData[i].ByteLen;
|
||
}
|
||
break;
|
||
|
||
case PROTO_SECS2_DATA_TYPE_2Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_2Byte_int:
|
||
case PROTO_SECS2_DATA_TYPE_2Byte_char:
|
||
{
|
||
u8 *p = proto_SECS2_Rx_MessageData[i].pData;
|
||
for (k = 0; k < 2; k++)
|
||
{
|
||
proto_SECS2_Rx_MessageDataBuffer[LenIndex + k] = p[1 - k];
|
||
}
|
||
proto_SECS2_Rx_MessageData[i].DataNum = proto_SECS2_Rx_MessageData[i].ByteLen / 2;
|
||
proto_SECS2_Rx_MessageData[i].pData = &proto_SECS2_Rx_MessageDataBuffer[LenIndex];
|
||
LenIndex += proto_SECS2_Rx_MessageData[i].ByteLen;
|
||
}
|
||
break;
|
||
|
||
case PROTO_SECS2_DATA_TYPE_4Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_4Byte_float:
|
||
case PROTO_SECS2_DATA_TYPE_4Byte_int:
|
||
{
|
||
u8 *p = proto_SECS2_Rx_MessageData[i].pData;
|
||
for (k = 0; k < 4; k++)
|
||
{
|
||
proto_SECS2_Rx_MessageDataBuffer[LenIndex + k] = p[3 - k];
|
||
}
|
||
|
||
proto_SECS2_Rx_MessageData[i].DataNum = proto_SECS2_Rx_MessageData[i].ByteLen / 4;
|
||
proto_SECS2_Rx_MessageData[i].pData = &proto_SECS2_Rx_MessageDataBuffer[LenIndex];
|
||
LenIndex += proto_SECS2_Rx_MessageData[i].ByteLen;
|
||
}
|
||
break;
|
||
|
||
case PROTO_SECS2_DATA_TYPE_8Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_8Byte_float:
|
||
case PROTO_SECS2_DATA_TYPE_8Byte_int:
|
||
{
|
||
u8 *p = proto_SECS2_Rx_MessageData[i].pData;
|
||
for (k = 0; k < 8; k++)
|
||
{
|
||
proto_SECS2_Rx_MessageDataBuffer[LenIndex + k] = p[7 - k];
|
||
}
|
||
|
||
proto_SECS2_Rx_MessageData[i].DataNum = proto_SECS2_Rx_MessageData[i].ByteLen / 8;
|
||
proto_SECS2_Rx_MessageData[i].pData = &proto_SECS2_Rx_MessageDataBuffer[LenIndex];
|
||
LenIndex += proto_SECS2_Rx_MessageData[i].ByteLen;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
/* 其他类型不处理 */
|
||
break;
|
||
}
|
||
}
|
||
return MessageDataNum;
|
||
}
|
||
|
||
static u16 proto_HSMS_AddData(u8 *pTxData, proto_SECS2_MessageData_t *pData)
|
||
{
|
||
u8 *p, i;
|
||
u16 Byte_Len = 0;
|
||
u16 data_length;
|
||
p = (u8 *)pData->pData;
|
||
|
||
/* 计算数据字节长度 */
|
||
switch (pData->DataType)
|
||
{
|
||
case PROTO_SECS2_DATA_TYPE_Binary:
|
||
case PROTO_SECS2_DATA_TYPE_Bool:
|
||
case PROTO_SECS2_DATA_TYPE_JIS_8:
|
||
case PROTO_SECS2_DATA_TYPE_1Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_1Byte_int:
|
||
data_length = 1 * pData->DataNum;
|
||
break;
|
||
|
||
case PROTO_SECS2_DATA_TYPE_ASCII:
|
||
data_length = pData->DataNum;
|
||
break;
|
||
|
||
case PROTO_SECS2_DATA_TYPE_2Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_2Byte_int:
|
||
case PROTO_SECS2_DATA_TYPE_2Byte_char:
|
||
data_length = 2 * pData->DataNum;
|
||
break;
|
||
|
||
case PROTO_SECS2_DATA_TYPE_4Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_4Byte_float:
|
||
case PROTO_SECS2_DATA_TYPE_4Byte_int:
|
||
data_length = 4 * pData->DataNum;
|
||
break;
|
||
|
||
case PROTO_SECS2_DATA_TYPE_8Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_8Byte_float:
|
||
case PROTO_SECS2_DATA_TYPE_8Byte_int:
|
||
data_length = 8 * pData->DataNum;
|
||
break;
|
||
|
||
case PROTO_SECS2_DATA_TYPE_List:
|
||
data_length = 1; // 列表元素个数占1字节
|
||
break;
|
||
|
||
default:
|
||
data_length = 0;
|
||
break;
|
||
}
|
||
|
||
/* 根据数据长度选择长度字节数 */
|
||
if (data_length <= 255)
|
||
{
|
||
/* 长度范围为1(1个长度字节) */
|
||
pTxData[0] = (pData->DataType << 2) | 0x01;
|
||
pTxData[1] = (u8)data_length;
|
||
Byte_Len = 2 + data_length;
|
||
}
|
||
else
|
||
{
|
||
/* 长度范围为2(2个长度字节) */
|
||
pTxData[0] = (pData->DataType << 2) | 0x02;
|
||
pTxData[1] = (u8)(data_length >> 8); // 高字节
|
||
pTxData[2] = (u8)(data_length); // 低字节
|
||
Byte_Len = 3 + data_length;
|
||
}
|
||
|
||
switch (pData->DataType)
|
||
{
|
||
/* 添加List */
|
||
case PROTO_SECS2_DATA_TYPE_List:
|
||
{
|
||
u8 length_byte_count = (pTxData[0] & 0x03); // 获取长度字节数
|
||
if (length_byte_count == 1)
|
||
{
|
||
pTxData[1] = *(u8 *)pData->pData; /* 列表元素个数 */
|
||
return 2; // 格式字节 + 长度字节
|
||
}
|
||
else
|
||
{
|
||
pTxData[1] = 0; // 高位字节为0(元素个数不会超过255)
|
||
pTxData[2] = *(u8 *)pData->pData; /* 列表元素个数 */
|
||
return 3; // 格式字节 + 2个长度字节
|
||
}
|
||
}
|
||
break;
|
||
|
||
/* 1字节类型 */
|
||
case PROTO_SECS2_DATA_TYPE_Binary:
|
||
case PROTO_SECS2_DATA_TYPE_Bool:
|
||
case PROTO_SECS2_DATA_TYPE_JIS_8:
|
||
case PROTO_SECS2_DATA_TYPE_1Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_1Byte_int:
|
||
{
|
||
u8 offset = (pTxData[0] & 0x03) + 1; // 计算数据偏移
|
||
if (pData->DataNum == 1)
|
||
{
|
||
pTxData[offset] = p[0];
|
||
}
|
||
else
|
||
{
|
||
memcpy(&pTxData[offset], p, pData->DataNum);
|
||
}
|
||
}
|
||
break;
|
||
|
||
case PROTO_SECS2_DATA_TYPE_ASCII:
|
||
{
|
||
u8 offset = (pTxData[0] & 0x03) + 1; // 计算数据偏移
|
||
memcpy(&pTxData[offset], p, pData->DataNum);
|
||
}
|
||
break;
|
||
|
||
/* 2字节类型 - 需要字节序转换 */
|
||
case PROTO_SECS2_DATA_TYPE_2Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_2Byte_int:
|
||
case PROTO_SECS2_DATA_TYPE_2Byte_char:
|
||
{
|
||
u8 offset = (pTxData[0] & 0x03) + 1; // 计算数据偏移
|
||
|
||
if (pData->DataNum == 1)
|
||
{
|
||
// 单个元素
|
||
pTxData[offset] = p[1]; // 高位字节
|
||
pTxData[offset + 1] = p[0]; // 低位字节
|
||
}
|
||
else
|
||
{
|
||
// 多个元素 - 需要批量转换
|
||
for (i = 0; i < pData->DataNum; i++)
|
||
{
|
||
pTxData[offset + i * 2] = p[i * 2 + 1];
|
||
pTxData[offset + i * 2 + 1] = p[i * 2];
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
/* 4字节类型 - 需要字节序转换 */
|
||
case PROTO_SECS2_DATA_TYPE_4Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_4Byte_float:
|
||
case PROTO_SECS2_DATA_TYPE_4Byte_int:
|
||
{
|
||
u8 offset = (pTxData[0] & 0x03) + 1; // 计算数据偏移
|
||
|
||
if (pData->DataNum == 1)
|
||
{
|
||
// 单个元素
|
||
pTxData[offset] = p[3];
|
||
pTxData[offset + 1] = p[2];
|
||
pTxData[offset + 2] = p[1];
|
||
pTxData[offset + 3] = p[0];
|
||
}
|
||
else
|
||
{
|
||
// 多个元素 - 需要批量转换
|
||
for (i = 0; i < pData->DataNum; i++)
|
||
{
|
||
pTxData[offset + i * 4] = p[i * 4 + 3];
|
||
pTxData[offset + i * 4 + 1] = p[i * 4 + 2];
|
||
pTxData[offset + i * 4 + 2] = p[i * 4 + 1];
|
||
pTxData[offset + i * 4 + 3] = p[i * 4];
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
/* 8字节类型 - 需要字节序转换 */
|
||
case PROTO_SECS2_DATA_TYPE_8Byte_uint:
|
||
case PROTO_SECS2_DATA_TYPE_8Byte_float:
|
||
case PROTO_SECS2_DATA_TYPE_8Byte_int:
|
||
{
|
||
u8 offset = (pTxData[0] & 0x03) + 1; // 计算数据偏移
|
||
|
||
if (pData->DataNum == 1)
|
||
{
|
||
// 单个元素
|
||
for (i = 0; i < 8; i++)
|
||
{
|
||
pTxData[offset + i] = p[7 - i];
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 多个元素 - 需要批量转换
|
||
for (i = 0; i < pData->DataNum; i++)
|
||
{
|
||
for (u8 j = 0; j < 8; j++)
|
||
{
|
||
pTxData[offset + i * 8 + j] = p[i * 8 + 7 - j];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
|
||
return Byte_Len;
|
||
}
|