206 lines
6.2 KiB
C++
206 lines
6.2 KiB
C++
|
|
#include "RobotProtocolSimplified.h"
|
|||
|
|
#include "VrLog.h"
|
|||
|
|
#include "VrError.h"
|
|||
|
|
#include <cstring>
|
|||
|
|
|
|||
|
|
RobotProtocolSimplified::RobotProtocolSimplified()
|
|||
|
|
: m_pModbusServer(nullptr)
|
|||
|
|
, m_bServerRunning(false)
|
|||
|
|
, m_nPort(502)
|
|||
|
|
, m_connectionStatus(STATUS_DISCONNECTED)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
RobotProtocolSimplified::~RobotProtocolSimplified()
|
|||
|
|
{
|
|||
|
|
Deinitialize();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int RobotProtocolSimplified::Initialize(uint16_t port)
|
|||
|
|
{
|
|||
|
|
if (m_bServerRunning) {
|
|||
|
|
LOG_WARNING("Simplified protocol server is already running\n");
|
|||
|
|
return SUCCESS;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_nPort = port;
|
|||
|
|
|
|||
|
|
// 创建ModbusTCP服务器实例
|
|||
|
|
bool bRet = IYModbusTCPServer::CreateInstance(&m_pModbusServer);
|
|||
|
|
LOG_DEBUG("Create ModbusTCP simplified protocol server %s \n", bRet ? "success" : "failed");
|
|||
|
|
m_bServerRunning = bRet;
|
|||
|
|
|
|||
|
|
// 设置ModbusTCP回调函数
|
|||
|
|
if (m_pModbusServer) {
|
|||
|
|
// 设置写寄存器回调
|
|||
|
|
m_pModbusServer->setWriteRegistersCallback([this](uint8_t unitId, uint16_t startAddress, uint16_t quantity, const uint16_t* values) {
|
|||
|
|
return this->OnWriteRegisters(unitId, startAddress, quantity, values);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 设置连接状态回调
|
|||
|
|
m_pModbusServer->setConnectionStatusCallback([this](bool connected) {
|
|||
|
|
this->OnModbusTCPConnectionChanged(connected);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int nRet = m_pModbusServer->start(m_nPort);
|
|||
|
|
ERR_CODE_RETURN(nRet);
|
|||
|
|
|
|||
|
|
// 设置初始状态
|
|||
|
|
m_connectionStatus = STATUS_CONNECTED;
|
|||
|
|
|
|||
|
|
// 初始化寄存器为0(无报警状态)
|
|||
|
|
ClearAlarmData();
|
|||
|
|
|
|||
|
|
LOG_INFO("ModbusTCP simplified protocol service initialization completed on port %d\n", m_nPort);
|
|||
|
|
return SUCCESS;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void RobotProtocolSimplified::Deinitialize()
|
|||
|
|
{
|
|||
|
|
LOG_DEBUG("Stop ModbusTCP simplified protocol service\n");
|
|||
|
|
|
|||
|
|
// 停止ModbusTCP服务器
|
|||
|
|
StopModbusTCPServer();
|
|||
|
|
|
|||
|
|
// 重置状态
|
|||
|
|
m_connectionStatus = STATUS_DISCONNECTED;
|
|||
|
|
m_bServerRunning = false;
|
|||
|
|
|
|||
|
|
LOG_INFO("ModbusTCP simplified protocol service stopped\n");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int RobotProtocolSimplified::SetAlarmData(const TearingAlarmData& alarmData)
|
|||
|
|
{
|
|||
|
|
if (!m_pModbusServer) {
|
|||
|
|
LOG_ERROR("ModbusTCP server not initialized\n");
|
|||
|
|
return ERR_CODE(DEV_NO_OPEN);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 准备寄存器数据
|
|||
|
|
std::vector<uint16_t> data(TOTAL_REGISTERS, 0);
|
|||
|
|
|
|||
|
|
// 地址0: 复位命令(保持不变,不在这里修改)
|
|||
|
|
// data[RESET_CMD_ADDR] = 0;
|
|||
|
|
|
|||
|
|
// 地址1: 报警标志
|
|||
|
|
data[ALARM_FLAG_ADDR] = alarmData.alarmFlag;
|
|||
|
|
|
|||
|
|
// 地址2: 最大长度
|
|||
|
|
data[MAX_LENGTH_ADDR] = alarmData.maxLength;
|
|||
|
|
|
|||
|
|
// 地址3: 最大宽度
|
|||
|
|
data[MAX_WIDTH_ADDR] = alarmData.maxWidth;
|
|||
|
|
|
|||
|
|
// 地址4-5: 最大撕裂ID (UInt32,大端字节序)
|
|||
|
|
// 高16位存储在地址4(40005)
|
|||
|
|
data[MAX_ID_ADDR] = (alarmData.maxId >> 16) & 0xFFFF;
|
|||
|
|
// 低16位存储在地址5(40006)
|
|||
|
|
data[MAX_ID_ADDR + 1] = alarmData.maxId & 0xFFFF;
|
|||
|
|
|
|||
|
|
// 更新Modbus寄存器(从地址0开始,更新所有寄存器)
|
|||
|
|
m_pModbusServer->updateHoldingRegisters(RESET_CMD_ADDR, data);
|
|||
|
|
|
|||
|
|
LOG_DEBUG("Alarm data updated: flag=%d, length=%d, width=%d, id=%u\n",
|
|||
|
|
alarmData.alarmFlag, alarmData.maxLength, alarmData.maxWidth, alarmData.maxId);
|
|||
|
|
|
|||
|
|
return SUCCESS;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int RobotProtocolSimplified::ClearAlarmData()
|
|||
|
|
{
|
|||
|
|
if (!m_pModbusServer) {
|
|||
|
|
LOG_ERROR("ModbusTCP server not initialized\n");
|
|||
|
|
return ERR_CODE(DEV_NO_OPEN);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清空所有寄存器
|
|||
|
|
std::vector<uint16_t> clearData(TOTAL_REGISTERS, 0);
|
|||
|
|
m_pModbusServer->updateHoldingRegisters(RESET_CMD_ADDR, clearData);
|
|||
|
|
|
|||
|
|
LOG_INFO("Alarm data cleared (all registers reset to 0)\n");
|
|||
|
|
return SUCCESS;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void RobotProtocolSimplified::SetResetCallback(const ResetCallback& callback)
|
|||
|
|
{
|
|||
|
|
m_resetCallback = callback;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void RobotProtocolSimplified::SetConnectionCallback(const ConnectionCallback& callback)
|
|||
|
|
{
|
|||
|
|
m_connectionCallback = callback;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool RobotProtocolSimplified::IsRunning() const
|
|||
|
|
{
|
|||
|
|
return m_bServerRunning;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void RobotProtocolSimplified::StopModbusTCPServer()
|
|||
|
|
{
|
|||
|
|
LOG_DEBUG("Stop ModbusTCP simplified protocol server\n");
|
|||
|
|
|
|||
|
|
if (m_pModbusServer) {
|
|||
|
|
// 释放资源
|
|||
|
|
delete m_pModbusServer;
|
|||
|
|
m_pModbusServer = nullptr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_bServerRunning = false;
|
|||
|
|
LOG_INFO("ModbusTCP simplified protocol server stopped\n");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
IYModbusTCPServer::ErrorCode RobotProtocolSimplified::OnWriteRegisters(uint8_t unitId, uint16_t startAddress, uint16_t quantity, const uint16_t* values)
|
|||
|
|
{
|
|||
|
|
// 只允许写入地址0(复位命令寄存器40001)
|
|||
|
|
if (startAddress != RESET_CMD_ADDR) {
|
|||
|
|
LOG_WARNING("Attempt to write to read-only address: %d (only address 0 is writable)\n", startAddress);
|
|||
|
|
return IYModbusTCPServer::ErrorCode::ILLEGAL_DATA_ADDRESS;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 只允许写入单个寄存器
|
|||
|
|
if (quantity != 1) {
|
|||
|
|
LOG_WARNING("Invalid quantity for reset command register write: %d\n", quantity);
|
|||
|
|
return IYModbusTCPServer::ErrorCode::ILLEGAL_DATA_VALUE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!values) {
|
|||
|
|
LOG_ERROR("Null values pointer in write registers\n");
|
|||
|
|
return IYModbusTCPServer::ErrorCode::SERVER_FAILURE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint16_t resetValue = values[0];
|
|||
|
|
|
|||
|
|
// 任何非零值都触发复位
|
|||
|
|
if (resetValue != 0) {
|
|||
|
|
LOG_INFO("Received reset command via ModbusTCP (value: %d)\n", resetValue);
|
|||
|
|
|
|||
|
|
// 调用复位回调
|
|||
|
|
if (m_resetCallback) {
|
|||
|
|
m_resetCallback();
|
|||
|
|
LOG_DEBUG("Reset callback executed\n");
|
|||
|
|
} else {
|
|||
|
|
LOG_WARNING("Reset callback not set\n");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 执行复位操作:清空报警数据
|
|||
|
|
ClearAlarmData();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return IYModbusTCPServer::ErrorCode::SUCCESS;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void RobotProtocolSimplified::OnModbusTCPConnectionChanged(bool connected)
|
|||
|
|
{
|
|||
|
|
LOG_INFO("ModbusTCP simplified protocol connection status changed: %s\n", connected ? "connected" : "disconnected");
|
|||
|
|
|
|||
|
|
// 更新连接状态
|
|||
|
|
m_connectionStatus = connected ? STATUS_CONNECTED : STATUS_DISCONNECTED;
|
|||
|
|
|
|||
|
|
// 调用连接状态回调
|
|||
|
|
if (m_connectionCallback) {
|
|||
|
|
m_connectionCallback(m_connectionStatus);
|
|||
|
|
}
|
|||
|
|
}
|