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