2026-04-23 13:56:52 +08:00
|
|
|
|
#include "main.h"
|
|
|
|
|
|
#include "RS485Task.h"
|
|
|
|
|
|
#include "Public.h"
|
|
|
|
|
|
#include "spiflash.h"
|
|
|
|
|
|
#include "CatOneTask.h"
|
|
|
|
|
|
#include "DebugCmd.h"
|
|
|
|
|
|
#include "update_protocol.h"
|
|
|
|
|
|
#include "bsp.h"
|
|
|
|
|
|
|
|
|
|
|
|
//#define RS485_DBG_LOG(...) { if(RS485DispEn) Debug_Printf(__VA_ARGS__);}
|
|
|
|
|
|
|
|
|
|
|
|
//static uint8_t RS485DispEn = false;
|
|
|
|
|
|
|
|
|
|
|
|
SensorCommPara_t SComm1Para;
|
|
|
|
|
|
SensorCommPara_t SComm2Para;
|
|
|
|
|
|
|
|
|
|
|
|
const uint8_t RS485SensorCmdPayLoadLen[RS485_SENSOR_CMD_END] = {0, 0, 0, 1, 0};
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************
|
|
|
|
|
|
* 函数名称: SavSensorData
|
|
|
|
|
|
* 功能描述: 记录传感器数据
|
|
|
|
|
|
* 参 数: SensorIdx, 传感器序号
|
|
|
|
|
|
Para,传感器结构指针
|
|
|
|
|
|
Data, 传感器数据
|
|
|
|
|
|
Len, 传感器数据长度
|
|
|
|
|
|
* 返 回 值: 无
|
|
|
|
|
|
*****************************************************************************************/
|
|
|
|
|
|
static void SavSensorData(uint8_t SensorIdx, CommUnitData CUData, uint8_t *Data, uint8_t Len)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(Data == NULL) {
|
|
|
|
|
|
memset(CUData->Data[SensorIdx], 0x00, SENSOR_DATA_LEN_MAX);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
memcpy(CUData->Data[SensorIdx], Data, Len);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************
|
|
|
|
|
|
* 函数名称: RS485Analyze
|
|
|
|
|
|
* 功能描述: 485数据解析
|
|
|
|
|
|
* 参 数: SCPara, 传感器发送参数
|
|
|
|
|
|
Para, 传感器结构指针
|
|
|
|
|
|
rData, 传感器数据入口
|
|
|
|
|
|
rLen, 传感器数据长度
|
|
|
|
|
|
* 返 回 值: 无
|
|
|
|
|
|
*****************************************************************************************/
|
|
|
|
|
|
void RS485Analyze(GateWayPara GateWay, SensorCommPara SCPara, CommUnit Para, uint8_t *rData, uint8_t rLen)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint16_t crc16;
|
|
|
|
|
|
uint8_t *Payload;
|
|
|
|
|
|
|
|
|
|
|
|
crc16 = (rData[rLen - 1] << 8)|rData[rLen - 2];
|
|
|
|
|
|
uint16_t Check = CRC_Modbus(0xA001, rData, rLen - 2);
|
|
|
|
|
|
if(crc16 != Check)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
FrameHeader Header = (FrameHeader)rData;
|
|
|
|
|
|
if(Header->Cmd != RS485_SENSOR_CMD_QUERY) {
|
|
|
|
|
|
if(Header->SlvAddr != SCPara->SensorAddr)
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Payload = &rData[sizeof(FrameHeader)];
|
|
|
|
|
|
if(Header->PayloadLen == 0)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if(Header->SlvAddr == 0 || Header->SlvAddr > SENSOR_NUM_MAX)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
SCPara->SensorErrCnt[Header->SlvAddr - 1] = 0;
|
|
|
|
|
|
switch(Header->Cmd) {
|
|
|
|
|
|
case RS485_SENSOR_CMD_SET_ADDR:
|
|
|
|
|
|
if(*Payload == 1) {
|
|
|
|
|
|
MAIN_DBG_LOG("Sensor%d Addr Set succeed!\r\n", Header->SlvAddr);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
MAIN_DBG_LOG("Sensor%d Addr Set failed!\r\n", Header->SlvAddr);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case RS485_SENSOR_CMD_CAIL:
|
|
|
|
|
|
if(*Payload == 1) {
|
|
|
|
|
|
MAIN_DBG_LOG("Sensor%d calibration succeeded!\r\n", Header->SlvAddr);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
MAIN_DBG_LOG("Sensor%d calibration succeeded!\r\n", Header->SlvAddr);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case RS485_SENSOR_CMD_QUERY:
|
|
|
|
|
|
if(Para->Para.SensorN < 16) {
|
|
|
|
|
|
Para->Para.SensorN++;
|
|
|
|
|
|
Para->Para.SensorType[SCPara->SensorAddr - 1] = rData[6] | (rData[7] << 8);
|
|
|
|
|
|
MAIN_DBG_LOG("Found Sensor%d, Type: %d!\r\n", Header->SlvAddr, Para->Para.SensorType[SCPara->SensorAddr - 1]);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case RS485_SENSOR_CMD_READ: {
|
|
|
|
|
|
memcpy(SCPara->SensorData.Data[SCPara->SensorAddr - 1], &rData[sizeof(FrameHeader_t)], Header->PayloadLen);
|
|
|
|
|
|
if(SCPara->SendFlag)
|
|
|
|
|
|
SCPara->ReadSensorCnt++;
|
|
|
|
|
|
DebugDisplaySensorData(Header->SlvAddr, 0, &rData[sizeof(FrameHeader_t)]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void update_on_start(uint8_t* frame, int len, uint8_t* pload, int size)
|
|
|
|
|
|
{
|
|
|
|
|
|
update_protocol_req_t* pReq = (void*)&frame[sizeof(update_protocol_hd_t)];
|
|
|
|
|
|
|
|
|
|
|
|
//TODO:
|
|
|
|
|
|
|
|
|
|
|
|
boot_para_t cfg = {0};
|
|
|
|
|
|
|
|
|
|
|
|
cfg.AppFlag = 0;
|
|
|
|
|
|
cfg.UpdateFlag = APP_UPDATE_FLAG;
|
|
|
|
|
|
cfg.Crc32Check = pReq->AppCrc32;
|
|
|
|
|
|
cfg.PackageNum = pReq->PackageNum;
|
|
|
|
|
|
cfg.AppSize = pReq->AppSize;
|
|
|
|
|
|
/**
|
|
|
|
|
|
操作FALSH ,写升级参数
|
|
|
|
|
|
**/
|
|
|
|
|
|
dev_boot_write_param(cfg);
|
|
|
|
|
|
|
|
|
|
|
|
update_send_cmd(0x01, 1, pReq->PackageNum);
|
|
|
|
|
|
|
|
|
|
|
|
//重启进入BOOT
|
|
|
|
|
|
NVIC_SystemReset();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int update_cmd_process(uint8_t cmd, void* frame, int len, void* pload, int size)
|
|
|
|
|
|
{
|
|
|
|
|
|
int res = -1;
|
|
|
|
|
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
|
|
case 0x81: {
|
|
|
|
|
|
update_on_start(frame, len, pload, size);
|
|
|
|
|
|
|
|
|
|
|
|
res = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int update_process(void* frame, int len)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint8_t cmd = 0;
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t slave_addr = 0;
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t user_data[256] = {0};
|
|
|
|
|
|
|
|
|
|
|
|
int user_data_len = 0;
|
|
|
|
|
|
|
|
|
|
|
|
int res = update_unpack(frame, len, &cmd, &slave_addr, user_data, &user_data_len);
|
|
|
|
|
|
|
|
|
|
|
|
if (res != 0)
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
if (slave_addr != 0x01)
|
|
|
|
|
|
return -2;
|
|
|
|
|
|
|
|
|
|
|
|
res = update_cmd_process(cmd, frame, len, user_data, user_data_len);
|
|
|
|
|
|
|
|
|
|
|
|
if (res != 0)
|
|
|
|
|
|
return -3;
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************
|
|
|
|
|
|
* 函数名称: RS485SensorCmdSend
|
|
|
|
|
|
* 功能描述: 下发传感器指令函数
|
|
|
|
|
|
* 参 数: Para,通讯参数入口
|
|
|
|
|
|
* 返 回 值: 无
|
|
|
|
|
|
*****************************************************************************************/
|
|
|
|
|
|
static void RS485SensorCmdSend(GateWayPara GateWay, SensorCommPara SensorComm)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint8_t sData[50];
|
|
|
|
|
|
uint8_t sLen;
|
|
|
|
|
|
|
|
|
|
|
|
if(SensorComm->Cmd >= RS485_SENSOR_CMD_END)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
FrameHeader Header = (FrameHeader)sData;
|
|
|
|
|
|
|
|
|
|
|
|
Header->Header = 0x7C;
|
|
|
|
|
|
Header->SlvAddr = SensorComm->SensorAddr;
|
|
|
|
|
|
Header->Cmd = SensorComm->Cmd;
|
|
|
|
|
|
//Header->DevType = SensorComm->SensorType;
|
|
|
|
|
|
Header->PayloadLen = SensorComm->CmdParaLen;
|
|
|
|
|
|
|
|
|
|
|
|
sLen = sizeof(FrameHeader_t);
|
|
|
|
|
|
if(SensorComm->CmdParaLen > 0) {
|
|
|
|
|
|
memcpy(&sData[sLen], SensorComm->CmdPara, SensorComm->CmdParaLen);
|
|
|
|
|
|
sLen += SensorComm->CmdParaLen;
|
|
|
|
|
|
}
|
|
|
|
|
|
uint16_t Check = CRC_Modbus(0xA001, sData, sLen);
|
|
|
|
|
|
|
|
|
|
|
|
sData[sLen++] = Check & 0xff;
|
|
|
|
|
|
sData[sLen++] = (Check >> 0x08) & 0x00ff;
|
|
|
|
|
|
|
|
|
|
|
|
if(SensorComm == &SComm1Para)
|
|
|
|
|
|
GateWay->ConfigPara.Rs485Ch1.RS485Send(sData, sLen);
|
|
|
|
|
|
else
|
|
|
|
|
|
GateWay->ConfigPara.Rs485Ch2.RS485Send(sData, sLen);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************
|
|
|
|
|
|
* 函数名称: RS485SensorCmdSend
|
|
|
|
|
|
* 功能描述: 下发传感器指令函数
|
|
|
|
|
|
* 参 数: CommUintAddr, 通讯单元地址
|
|
|
|
|
|
Para,通讯参数入口
|
|
|
|
|
|
* 返 回 值: 无
|
|
|
|
|
|
*****************************************************************************************/
|
|
|
|
|
|
void RS485CmdSend(GateWayPara GateWay, uint8_t CommUintAddr, SensorCommPara SensorComm)
|
|
|
|
|
|
{
|
|
|
|
|
|
SensorCommPara SC;
|
|
|
|
|
|
|
|
|
|
|
|
if(CommUintAddr)
|
|
|
|
|
|
SC = &SComm1Para;
|
|
|
|
|
|
else
|
|
|
|
|
|
SC = &SComm2Para;
|
|
|
|
|
|
|
|
|
|
|
|
SC->Cmd = SensorComm->Cmd;
|
|
|
|
|
|
SC->CmdPara = SensorComm->CmdPara;
|
|
|
|
|
|
SC->CmdParaLen = SensorComm->CmdParaLen;
|
|
|
|
|
|
SC->SensorAddr = SensorComm->SensorAddr;
|
|
|
|
|
|
//SC->SensorType = SensorComm->SensorType;
|
|
|
|
|
|
|
|
|
|
|
|
RS485SensorCmdSend(GateWay, SC);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************
|
|
|
|
|
|
* 函数名称: RS485LoopHandler
|
|
|
|
|
|
* 功能描述: RS485循环处理函数
|
|
|
|
|
|
* 参 数: GateWay, 网关参数句柄
|
|
|
|
|
|
RS485Ch, RS485通道句柄
|
|
|
|
|
|
SCPara, RS485通讯句柄
|
|
|
|
|
|
* 返 回 值: 无
|
|
|
|
|
|
*****************************************************************************************/
|
|
|
|
|
|
static uint8_t CommUintData[512];
|
|
|
|
|
|
int test = 0;
|
|
|
|
|
|
void RS485LoopHandler(GateWayPara GateWay, RS485Para RS485Ch, SensorCommPara SCPara)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint8_t RxBuffTemp[RS485_RX_BUFF_LEN_MAX];
|
|
|
|
|
|
uint8_t RxLenTemp;
|
|
|
|
|
|
uint16_t CommUintLen;
|
|
|
|
|
|
rt_err_t result;
|
|
|
|
|
|
uint8_t MegData[9];
|
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
|
|
if(RS485Ch->Enable == false) {
|
|
|
|
|
|
rt_thread_delay(10);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(RS485Ch->CommUnitEnable == true) { //使用内置通讯单元
|
|
|
|
|
|
if(RS485Ch->QuerySensorFlag == true) { //开机查找传感器
|
|
|
|
|
|
if(SCPara->SensorCnt < SENSOR_NUM_MAX) {
|
|
|
|
|
|
rt_thread_delay(50);
|
|
|
|
|
|
SCPara->Cmd = RS485_SENSOR_CMD_QUERY;
|
|
|
|
|
|
SCPara->SensorAddr = SCPara->SensorCnt + 1;
|
|
|
|
|
|
SCPara->SensorType = 0;
|
|
|
|
|
|
SCPara->CmdParaLen = RS485SensorCmdPayLoadLen[RS485_SENSOR_CMD_QUERY];
|
|
|
|
|
|
SCPara->CmdPara = NULL;
|
|
|
|
|
|
//rt_mutex_take(GateWay->UartRevMutex, RT_WAITING_FOREVER);
|
|
|
|
|
|
SCPara->RS485TimeOutCnt = 0;
|
|
|
|
|
|
SCPara->RS485RxLen = 0;
|
|
|
|
|
|
RS485SensorCmdSend(GateWay, SCPara);
|
|
|
|
|
|
SCPara->SendFlag = true;
|
|
|
|
|
|
SCPara->SensorCnt++;
|
|
|
|
|
|
if(SCPara->SensorCnt >= SENSOR_NUM_MAX) {
|
|
|
|
|
|
SCPara->ReadSensorInterval = 2;
|
|
|
|
|
|
SCPara->SensorCnt = 0;
|
|
|
|
|
|
SCPara->ReadSensorCnt = 0;
|
|
|
|
|
|
RS485Ch->QuerySensorFlag = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-06-12 18:14:43 +08:00
|
|
|
|
else if(RS485Ch->CUPara.Para.SensorN > 0){
|
2026-04-23 13:56:52 +08:00
|
|
|
|
SCPara->SendFlag = false;
|
|
|
|
|
|
if(SCPara->ReadSensorInterval > 0) {
|
|
|
|
|
|
SCPara->ReadSensorInterval--;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
2026-06-12 18:14:43 +08:00
|
|
|
|
if(SCPara->ReadSensorCnt >= RS485Ch->CUPara.Para.SensorN || SCPara->SensorCnt >= SENSOR_NUM_MAX) {
|
2026-04-23 13:56:52 +08:00
|
|
|
|
SCPara->SensorCnt = 0;
|
|
|
|
|
|
SCPara->ReadSensorCnt = 0;
|
|
|
|
|
|
SCPara->ReadSensorInterval = GateWay->ConfigPara.CommUnitReadInterval * 5;
|
2026-06-12 18:14:43 +08:00
|
|
|
|
RS485Ch->CUPara.Para.BatLevel = GateWay->Battery;
|
|
|
|
|
|
CommUintLen = CommUintOrgData(GateWay, &RS485Ch->CUPara.Para, &SCPara->SensorData, CommUintData);
|
2026-04-23 13:56:52 +08:00
|
|
|
|
//AddLog(&CommUintData[2], CommUintLen - 2);
|
|
|
|
|
|
CatOneEthSendQueue(CommUintData, CommUintLen);
|
|
|
|
|
|
if(RS485Ch == &GateWay->ConfigPara.Rs485Ch1) {
|
|
|
|
|
|
MAIN_DBG_LOG("InCommUint1 Send Meg...\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
MAIN_DBG_LOG("InCommUint2 Send Meg...\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
SCPara->SensorCnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
2026-06-12 18:14:43 +08:00
|
|
|
|
if(RS485Ch->CUPara.Para.SensorType[SCPara->SensorCnt] != 0) {
|
2026-04-23 13:56:52 +08:00
|
|
|
|
rt_thread_delay(50);
|
|
|
|
|
|
SCPara->Cmd = RS485_SENSOR_CMD_READ;
|
|
|
|
|
|
SCPara->SensorAddr = SCPara->SensorCnt + 1;
|
2026-06-12 18:14:43 +08:00
|
|
|
|
SCPara->SensorType = RS485Ch->CUPara.Para.SensorType[SCPara->SensorCnt];
|
2026-04-23 13:56:52 +08:00
|
|
|
|
SCPara->CmdParaLen = RS485SensorCmdPayLoadLen[RS485_SENSOR_CMD_READ];
|
|
|
|
|
|
SCPara->CmdPara = NULL;
|
|
|
|
|
|
//rt_mutex_take(GateWay->UartRevMutex, RT_WAITING_FOREVER);
|
|
|
|
|
|
RS485SensorCmdSend(GateWay, SCPara);
|
|
|
|
|
|
SCPara->SendFlag = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
SCPara->SensorCnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else { //读取外置通讯单元
|
|
|
|
|
|
if(SCPara->RS485CommUnitReadTimeDelay >= (GateWay->ConfigPara.CommUnitReadInterval * 5) && SCPara->SendFlag == false) {
|
|
|
|
|
|
if(SCPara->SendUnitCommIdx < COMMUNIT_NUM_MAX) {
|
|
|
|
|
|
if(GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].RegFlag &&
|
|
|
|
|
|
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][2] == 0x02) {
|
|
|
|
|
|
Debug_Printf("RS485Ch%d Read CommUnit: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
|
|
|
|
|
|
((SCPara == &SComm1Para) ? 1 : 2),
|
|
|
|
|
|
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][0],
|
|
|
|
|
|
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][1],
|
|
|
|
|
|
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][2],
|
|
|
|
|
|
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][3],
|
|
|
|
|
|
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][4],
|
|
|
|
|
|
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0][5]);
|
|
|
|
|
|
CommUnitCmdSend(GateWay, GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0], COMM_UNIT_CMD_READ, NULL, 0, RS485Ch->RS485Send);
|
|
|
|
|
|
SCPara->SendFlag = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
SCPara->SendUnitCommIdx++;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
SCPara->SendUnitCommIdx = 0;
|
|
|
|
|
|
SCPara->RS485CommUnitReadTimeDelay = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(SCPara->RS485CommUnitReadTimeDelay < (GateWay->ConfigPara.CommUnitReadInterval * 5))
|
|
|
|
|
|
SCPara->RS485CommUnitReadTimeDelay++;
|
|
|
|
|
|
|
|
|
|
|
|
result = rt_sem_take(SCPara->RS485Rev_Sem, 200);
|
|
|
|
|
|
if(result == RT_EOK) {
|
|
|
|
|
|
memcpy(RxBuffTemp, SCPara->RS485RxBuff, SCPara->RS485RxLen);
|
|
|
|
|
|
RxLenTemp = SCPara->RS485RxLen;
|
|
|
|
|
|
// memset(SCPara->RS485RxBuff, 0x00, RS485_RX_BUFF_LEN_MAX);
|
|
|
|
|
|
SCPara->RS485RxLen = 0;
|
|
|
|
|
|
if(RxBuffTemp[0] == 0x7A && RS485Ch->UpgradeEnable == true) { //升级
|
|
|
|
|
|
update_process(RxBuffTemp,RxLenTemp);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(RxBuffTemp[0] == 0x7A && RS485Ch->CommUnitEnable == true) { //内置通讯单元数据解析
|
|
|
|
|
|
if(SCPara->SendFlag == false) {
|
|
|
|
|
|
SCPara->RS485RxLen = 0;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
RS485Analyze(GateWay, SCPara, &RS485Ch->CUData, RxBuffTemp, RxLenTemp);
|
|
|
|
|
|
//rt_mutex_release(GateWay->UartRevMutex);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(RxBuffTemp[0] == 0x7B && RS485Ch->CommUnitEnable == false){ //读取外部通讯单元数据解析
|
|
|
|
|
|
if(SCPara == &SComm1Para)
|
|
|
|
|
|
ret = GateWay->CommUnitRevCallBack(GateWay, RxBuffTemp, RxLenTemp, GateWay->ConfigPara.Rs485Ch1.RS485Send);
|
|
|
|
|
|
else
|
|
|
|
|
|
ret = GateWay->CommUnitRevCallBack(GateWay, RxBuffTemp, RxLenTemp, GateWay->ConfigPara.Rs485Ch2.RS485Send);
|
|
|
|
|
|
if(ret == 0xff) { //注册信息
|
|
|
|
|
|
SCPara->RS485RxLen = 0;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(SCPara->SendFlag && GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].RevNewDataFlag) {
|
|
|
|
|
|
SCPara->SendUnitCommIdx++;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
SCPara->RS485RxLen = 0;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else { //调试命令解析
|
|
|
|
|
|
DebugAnalyze(GateWay, RxBuffTemp, RxLenTemp);
|
|
|
|
|
|
}
|
|
|
|
|
|
SCPara->RS485RxLen = 0;
|
|
|
|
|
|
SCPara->SendFlag = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
if(RS485Ch->CommUnitEnable == true) {
|
|
|
|
|
|
//rt_mutex_release(GateWay->UartRevMutex);
|
2026-06-12 18:14:43 +08:00
|
|
|
|
if(SCPara->SendFlag == true) { //&& RS485Ch->CUPara.Para.SensorN > 0 && RS485Ch->QuerySensorFlag == false){
|
2026-04-23 13:56:52 +08:00
|
|
|
|
if(RS485Ch == &GateWay->ConfigPara.Rs485Ch1) {
|
|
|
|
|
|
test++;
|
|
|
|
|
|
MAIN_DBG_LOG("InCommUint1, Sensor %d Comm Error, Cmd %d...\r\n", SCPara->SensorAddr, SCPara->Cmd);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
MAIN_DBG_LOG("InCommUint2, Sensor %d Comm Error, Cmd %d...\r\n", SCPara->SensorAddr, SCPara->Cmd);
|
|
|
|
|
|
}
|
|
|
|
|
|
SCPara->SensorErrCnt[SCPara->SensorAddr - 1]++;
|
|
|
|
|
|
if(SCPara->SensorErrCnt[SCPara->SensorAddr - 1] >= 5)
|
|
|
|
|
|
SavSensorData(SCPara->SensorAddr - 1, &SCPara->SensorData, NULL, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(SCPara->SendFlag){
|
|
|
|
|
|
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommErrCnt++;
|
|
|
|
|
|
if(GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommErrCnt == 10) {
|
|
|
|
|
|
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommErrCnt = 0;
|
|
|
|
|
|
if(GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommStatus) {
|
|
|
|
|
|
GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommStatus = 0;
|
|
|
|
|
|
MegData[0] = 7;
|
|
|
|
|
|
MegData[1] = COMM_UNIT_CMD_READ;
|
|
|
|
|
|
memcpy(&MegData[2], GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].Mac[0], 6);
|
|
|
|
|
|
MegData[8] = GateWay->ConfigPara.CommUnitArray[SCPara->SendUnitCommIdx].CommStatus;
|
|
|
|
|
|
CatOneEthSendQueue(MegData, 9); //发送离线消息
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
SCPara->SendUnitCommIdx++;
|
|
|
|
|
|
}
|
|
|
|
|
|
SCPara->SendFlag = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************
|
|
|
|
|
|
* 函数名称: RS485Ch1_Thread_Entry
|
|
|
|
|
|
* 功能描述: RS485通道1任务函数
|
|
|
|
|
|
* 参 数: 任务参数入口
|
|
|
|
|
|
* 返 回 值: 无
|
|
|
|
|
|
*****************************************************************************************/
|
|
|
|
|
|
void RS485Ch1_Thread_Entry(void *parameter)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint8_t InCommUnitMac[6] = {0x01, 0x80, 0x02, 0x00, 0x00, 0x01};
|
|
|
|
|
|
GateWayPara GateWay;
|
|
|
|
|
|
SensorCommPara SCPara;
|
|
|
|
|
|
RS485Para RS485Ch;
|
|
|
|
|
|
|
|
|
|
|
|
SCPara = &SComm1Para;
|
|
|
|
|
|
SCPara->SensorCnt = 0;
|
|
|
|
|
|
SCPara->InitOverFlag = false;
|
|
|
|
|
|
SCPara->ReadSensorInterval = 300;
|
|
|
|
|
|
GateWay = (GateWayPara)parameter;
|
|
|
|
|
|
InCommUnitMac[3] = GateWay->ConfigPara.GwMac[4];
|
|
|
|
|
|
InCommUnitMac[4] = GateWay->ConfigPara.GwMac[5];
|
|
|
|
|
|
RS485Ch = &GateWay->ConfigPara.Rs485Ch1;
|
2026-06-12 18:14:43 +08:00
|
|
|
|
memcpy(RS485Ch->CUPara.Para.Mac, InCommUnitMac, 6);
|
2026-04-23 13:56:52 +08:00
|
|
|
|
if(RS485Ch->CommUnitEnable == true) {
|
|
|
|
|
|
RS485_CH1_POW_ON();
|
2026-06-12 18:14:43 +08:00
|
|
|
|
RS485Ch->CUPara.Para.SensorN = 0;
|
|
|
|
|
|
memset(RS485Ch->CUPara.Para.SensorType, 0x00, sizeof(SENSOR_NUM_MAX * 2));
|
2026-04-23 13:56:52 +08:00
|
|
|
|
RS485Ch->QuerySensorFlag = true;
|
2026-06-12 18:14:43 +08:00
|
|
|
|
RS485Ch->CUPara.Para.CommStatus = true;
|
2026-04-23 13:56:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
SCPara->RS485CommUnitReadTimeDelay = 100;
|
|
|
|
|
|
SCPara->RS485Rev_Sem = rt_sem_create("rsch1sem", 0, RT_IPC_FLAG_FIFO);
|
|
|
|
|
|
if(SCPara->RS485Rev_Sem == RT_NULL) {
|
|
|
|
|
|
Debug_Printf("RS485Ch1Rev Sem Create Failed!\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
Debug_Printf("RS485Ch1Rev Thread is running!\r\n");
|
|
|
|
|
|
|
|
|
|
|
|
rt_thread_delay(3000);
|
|
|
|
|
|
SCPara->InitOverFlag = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
update_init(RS485Ch1UartSend);
|
|
|
|
|
|
while(1) {
|
|
|
|
|
|
RS485LoopHandler(GateWay, RS485Ch, SCPara);
|
|
|
|
|
|
//rt_thread_delay(10);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************
|
|
|
|
|
|
* 函数名称: RS485Ch1RxIrqCallback
|
|
|
|
|
|
* 功能描述: RS485通道1中断处理回调函数
|
|
|
|
|
|
* 参 数: rData 接收到的数据
|
|
|
|
|
|
* 返 回 值: 无
|
|
|
|
|
|
*****************************************************************************************/
|
|
|
|
|
|
void RS485Ch1RxIrqCallback(uint8_t rData)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(SComm1Para.RS485TimeOutCnt == 0) {
|
|
|
|
|
|
SComm1Para.RS485RxLen = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(SComm1Para.RS485RxLen < RS485_RX_BUFF_LEN_MAX)
|
|
|
|
|
|
SComm1Para.RS485RxBuff[SComm1Para.RS485RxLen++] = rData;
|
|
|
|
|
|
|
|
|
|
|
|
SComm1Para.RS485TimeOutCnt = 3;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************
|
|
|
|
|
|
* 函数名称: RS485Ch2_Thread_Entry
|
|
|
|
|
|
* 功能描述: RS485通道1任务函数
|
|
|
|
|
|
* 参 数: 任务参数入口
|
|
|
|
|
|
* 返 回 值: 无
|
|
|
|
|
|
*****************************************************************************************/
|
|
|
|
|
|
void RS485Ch2_Thread_Entry(void *parameter)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint8_t InCommUnitMac[6] = {0x01, 0x80, 0x02, 0x00, 0x00, 0x02};
|
|
|
|
|
|
GateWayPara GateWay;
|
|
|
|
|
|
SensorCommPara SCPara;
|
|
|
|
|
|
RS485Para RS485Ch;
|
|
|
|
|
|
|
|
|
|
|
|
SCPara = &SComm2Para;
|
|
|
|
|
|
SCPara->SensorCnt = 0;
|
|
|
|
|
|
SCPara->InitOverFlag = false;
|
|
|
|
|
|
SCPara->ReadSensorInterval = 0;
|
|
|
|
|
|
GateWay = (GateWayPara)parameter;
|
|
|
|
|
|
InCommUnitMac[3] = GateWay->ConfigPara.GwMac[4];
|
|
|
|
|
|
InCommUnitMac[4] = GateWay->ConfigPara.GwMac[5];
|
|
|
|
|
|
RS485Ch = &GateWay->ConfigPara.Rs485Ch2;
|
2026-06-12 18:14:43 +08:00
|
|
|
|
memcpy(RS485Ch->CUPara.Para.Mac, InCommUnitMac, 6);
|
2026-04-23 13:56:52 +08:00
|
|
|
|
if(RS485Ch->CommUnitEnable == true) {
|
|
|
|
|
|
RS485_CH2_POW_ON();
|
2026-06-12 18:14:43 +08:00
|
|
|
|
RS485Ch->CUPara.Para.SensorN = 0;
|
|
|
|
|
|
memset(RS485Ch->CUPara.Para.SensorType, 0x00, sizeof(SENSOR_NUM_MAX * 2));
|
2026-04-23 13:56:52 +08:00
|
|
|
|
RS485Ch->QuerySensorFlag = true;
|
2026-06-12 18:14:43 +08:00
|
|
|
|
RS485Ch->CUPara.Para.CommStatus = 1;
|
2026-04-23 13:56:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
SCPara->RS485CommUnitReadTimeDelay = 100;
|
|
|
|
|
|
SCPara->RS485Rev_Sem = rt_sem_create("rsch2sem", 0, RT_IPC_FLAG_FIFO);
|
|
|
|
|
|
if(SCPara->RS485Rev_Sem == RT_NULL) {
|
|
|
|
|
|
Debug_Printf("RS485Ch2Rev Sem Create Failed!\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
Debug_Printf("RS485Ch2Rev Thread is running!\r\n");
|
|
|
|
|
|
rt_thread_delay(3000);
|
|
|
|
|
|
SCPara->InitOverFlag = true;
|
|
|
|
|
|
while(1) {
|
|
|
|
|
|
RS485LoopHandler(GateWay, RS485Ch, SCPara);
|
|
|
|
|
|
//rt_thread_delay(10);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************
|
|
|
|
|
|
* 函数名称: RS485Ch2RxIrqCallback
|
|
|
|
|
|
* 功能描述: RS485通道1中断处理回调函数
|
|
|
|
|
|
* 参 数: rData 接收到的数据
|
|
|
|
|
|
* 返 回 值: 无
|
|
|
|
|
|
*****************************************************************************************/
|
|
|
|
|
|
void RS485Ch2RxIrqCallback(uint8_t rData)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(SComm2Para.RS485TimeOutCnt == 0) {
|
|
|
|
|
|
SComm2Para.RS485RxLen = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(SComm2Para.RS485RxLen < RS485_RX_BUFF_LEN_MAX)
|
|
|
|
|
|
SComm2Para.RS485RxBuff[SComm2Para.RS485RxLen++] = rData;
|
|
|
|
|
|
|
|
|
|
|
|
SComm2Para.RS485TimeOutCnt = 3;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void RS485RxOverhandler(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(SComm1Para.RS485TimeOutCnt > 0)
|
|
|
|
|
|
SComm1Para.RS485TimeOutCnt--;
|
|
|
|
|
|
|
|
|
|
|
|
if(SComm1Para.RS485RxLen > 5 && SComm1Para.RS485TimeOutCnt == 0) {
|
|
|
|
|
|
if(SComm1Para.InitOverFlag == true) {
|
|
|
|
|
|
rt_sem_release(SComm1Para.RS485Rev_Sem);
|
|
|
|
|
|
SComm1Para.RS485TimeOutCnt = 20;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
SComm1Para.RS485RxLen = 0;
|
|
|
|
|
|
SComm1Para.RS485TimeOutCnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(SComm2Para.RS485TimeOutCnt > 0)
|
|
|
|
|
|
SComm2Para.RS485TimeOutCnt--;
|
|
|
|
|
|
|
|
|
|
|
|
if(SComm2Para.RS485RxLen > 5 && SComm2Para.RS485TimeOutCnt == 0) {
|
|
|
|
|
|
if(SComm2Para.InitOverFlag == true) {
|
|
|
|
|
|
SComm2Para.RS485TimeOutCnt = 20;
|
|
|
|
|
|
rt_sem_release(SComm2Para.RS485Rev_Sem);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
SComm2Para.RS485RxLen = 0;
|
|
|
|
|
|
SComm2Para.RS485TimeOutCnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
void RS485Ch2RxIrqCallback(uint8_t rData)
|
|
|
|
|
|
{
|
|
|
|
|
|
static bool FrameHeader = false;
|
|
|
|
|
|
static uint8_t rLen = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if(FrameHeader == false) {
|
|
|
|
|
|
if(rData == 0x7a || rData == 0x7b) {
|
|
|
|
|
|
FrameHeader = true;
|
|
|
|
|
|
RS485Chr2RxLen = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if(RS485Chr2RxLen < RS485_RX_BUFF_LEN_MAX) {
|
|
|
|
|
|
RS485Chr2RxBuff[RS485Chr2RxLen++] = rData;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
FrameHeader = false;
|
|
|
|
|
|
RS485Chr2RxLen = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(RS485Chr2RxLen == 6) {
|
|
|
|
|
|
rLen = rData + 8;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(RS485Chr2RxLen > 6) {
|
|
|
|
|
|
if(RS485Chr2RxLen >= rLen) {
|
|
|
|
|
|
rt_sem_release(RS485Ch2Rev_Sem);
|
|
|
|
|
|
FrameHeader = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|