GrabBag/App/BeltTearing/BeltTearingServer/RobotProtocolSimplified.cpp

206 lines
6.2 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 "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位存储在地址440005
data[MAX_ID_ADDR] = (alarmData.maxId >> 16) & 0xFFFF;
// 低16位存储在地址540006
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);
}
}