From f56051fa3102feb35ea60650ebda80f49e62d025 Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期二, 05 八月 2025 14:54:24 +0800
Subject: [PATCH] 1. SGMeasurement实现规划的地址 2. 优化读取位时输入的地址不是8的倍数的问题 3. 添加读写心跳的功能
---
SourceCode/Bond/SGMeasurement/CCLinkPerformance/PerformanceMelsec.cpp | 70 +++++++++++++++++++++++------------
1 files changed, 46 insertions(+), 24 deletions(-)
diff --git a/SourceCode/Bond/SGMeasurement/CCLinkPerformance/PerformanceMelsec.cpp b/SourceCode/Bond/SGMeasurement/CCLinkPerformance/PerformanceMelsec.cpp
index 58b229a..b8e6a84 100644
--- a/SourceCode/Bond/SGMeasurement/CCLinkPerformance/PerformanceMelsec.cpp
+++ b/SourceCode/Bond/SGMeasurement/CCLinkPerformance/PerformanceMelsec.cpp
@@ -703,18 +703,19 @@
return nRet;
}
- if (nDevNo % 8 != 0) {
- UpdateLastError(ERROR_CODE_INVALID_PARAM);
- return ERROR_CODE_INVALID_PARAM;
- }
-
const short nDevType = CalculateDeviceType(station, enDevType);
- const long nWordCount = (nBitCount + 15) / 16;
- const long nByteSize = nWordCount * sizeof(short);
+
+ // === 自动对齐到起始字 ===
+ long nWordAlignedStartBit = nDevNo / 16 * 16;
+ long nBitOffset = nDevNo - nWordAlignedStartBit;
+ long nTotalBits = nBitOffset + nBitCount;
+ long nWordCount = (nTotalBits + 15) / 16;
+ long nByteSize = nWordCount * sizeof(short);
std::vector<char> vecRaw;
- nRet = ReadDataEx(station, nDevType, nDevNo, nByteSize, vecRaw);
+ nRet = ReadDataEx(station, nDevType, nWordAlignedStartBit, nByteSize, vecRaw);
if (nRet != 0) {
+ UpdateLastError(nRet);
return nRet;
}
@@ -722,10 +723,11 @@
for (long i = 0; i < nWordCount; ++i) {
short word = static_cast<unsigned char>(vecRaw[i * 2]) |
(static_cast<unsigned char>(vecRaw[i * 2 + 1]) << 8);
+
for (int j = 0; j < 16; ++j) {
- vecData.push_back((word & (1 << j)) != 0);
- if (vecData.size() >= static_cast<size_t>(nBitCount)) {
- return 0;
+ long bitIndex = i * 16 + j;
+ if (bitIndex >= nBitOffset && vecData.size() < static_cast<size_t>(nBitCount)) {
+ vecData.push_back((word & (1 << j)) != 0);
}
}
}
@@ -826,30 +828,48 @@
return nRet;
}
- if (nDevNo % 8 != 0) {
- UpdateLastError(ERROR_CODE_INVALID_PARAM);
- return ERROR_CODE_INVALID_PARAM;
+ const short nDevType = CalculateDeviceType(station, enDevType);
+
+ // === 1. 自动对齐起始地址 ===
+ long nWordAlignedStartBit = nDevNo / 16 * 16;
+ long nBitOffset = nDevNo - nWordAlignedStartBit;
+ long nTotalBits = nBitOffset + static_cast<long>(vecData.size());
+ size_t nWordCount = (nTotalBits + 15) / 16;
+
+ // === 2. 先读取原始值以支持非对齐覆盖 ===
+ std::vector<char> vecRaw;
+ nRet = ReadDataEx(station, nDevType, nWordAlignedStartBit, static_cast<long>(nWordCount * sizeof(short)), vecRaw);
+ if (nRet != 0) {
+ UpdateLastError(nRet);
+ return nRet;
}
- const short nDevType = CalculateDeviceType(station, enDevType);
- const size_t nWordCount = (vecData.size() + 15) / 16;
-
+ // === 3. 合并新数据 ===
std::vector<short> vecWordBuffer(nWordCount, 0);
+ for (size_t i = 0; i < nWordCount; ++i) {
+ vecWordBuffer[i] = static_cast<unsigned char>(vecRaw[i * 2]) | (static_cast<unsigned char>(vecRaw[i * 2 + 1]) << 8);
+ }
+
for (size_t i = 0; i < vecData.size(); ++i) {
+ size_t bitIndex = nBitOffset + i;
+ size_t wordIdx = bitIndex / 16;
+ size_t bitPos = bitIndex % 16;
if (vecData[i]) {
- vecWordBuffer[i / 16] |= (1 << (i % 16));
+ vecWordBuffer[wordIdx] |= (1 << bitPos);
+ }
+ else {
+ vecWordBuffer[wordIdx] &= ~(1 << bitPos);
}
}
- // 转换 short -> char
- std::vector<char> vecByteBuffer;
- vecByteBuffer.resize(nWordCount * sizeof(short));
+ // === 4. 转为字节流写入 ===
+ std::vector<char> vecByteBuffer(nWordCount * 2);
for (size_t i = 0; i < nWordCount; ++i) {
vecByteBuffer[i * 2] = static_cast<char>(vecWordBuffer[i] & 0xFF);
vecByteBuffer[i * 2 + 1] = static_cast<char>((vecWordBuffer[i] >> 8) & 0xFF);
}
- return WriteDataEx(station, nDevType, nDevNo, vecByteBuffer);
+ return WriteDataEx(station, nDevType, nWordAlignedStartBit, vecByteBuffer);
}
// 扩展写字数据
@@ -1146,7 +1166,7 @@
}
// 扩展位软元件设置
-long CPerformanceMelsec::SetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo) {
+long CPerformanceMelsec::SetBitDeviceEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo) {
std::lock_guard<std::mutex> lock(m_mtx);
// 检查参数有效性
@@ -1156,6 +1176,7 @@
return nRet;
}
+ long nDevType = static_cast<long>(enDevType);
nRet = mdDevSetEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo);
if (nRet != 0) {
UpdateLastError(nRet);
@@ -1166,7 +1187,7 @@
}
// 扩展位软元件复位
-long CPerformanceMelsec::ResetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo) {
+long CPerformanceMelsec::ResetBitDeviceEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo) {
std::lock_guard<std::mutex> lock(m_mtx);
// 检查参数有效性
@@ -1176,6 +1197,7 @@
return nRet;
}
+ long nDevType = static_cast<long>(enDevType);
nRet = mdDevRstEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo);
if (nRet != 0) {
UpdateLastError(nRet);
--
Gitblit v1.9.3