From 737dec3c384f394fd6f9849b4480b697d1ba35d5 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期二, 17 三月 2026 09:16:44 +0800
Subject: [PATCH] chore: 提交所有当前改动
---
Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Memory/MemoryStore.cs | 113 ++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 97 insertions(+), 16 deletions(-)
diff --git a/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Memory/MemoryStore.cs b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Memory/MemoryStore.cs
index 9583b42..295dc8b 100644
--- a/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Memory/MemoryStore.cs
+++ b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Memory/MemoryStore.cs
@@ -62,7 +62,13 @@
_config = config ?? throw new ArgumentNullException(nameof(config));
_mRegion = new MRegion(config.MRegionSize);
- _dbRegion = new DBRegion((ushort)config.DBBlockCount, config.DBBlockSize);
+ var configuredDbNumbers = ResolveConfiguredDbNumbers();
+ var initialDbNumber = configuredDbNumbers.FirstOrDefault();
+ _dbRegion = new DBRegion(initialDbNumber == 0 ? (ushort)1 : initialDbNumber, config.DBBlockSize);
+ foreach (var dbNumber in configuredDbNumbers)
+ {
+ _dbRegion.EnsureBlock(dbNumber);
+ }
_iRegion = new IRegion(config.IRegionSize);
_qRegion = new QRegion(config.QRegionSize);
_tRegion = new TRegion(config.TRegionCount);
@@ -125,7 +131,7 @@
return regionType switch
{
"M" => ReadMRegion<T>(offset),
- "DB" => ReadDBRegion<T>(dbNumber.Value, offset),
+ "DB" => ReadDBRegion<T>(dbNumber.Value, offset, bitOffset),
"I" => ReadIRegion<T>(offset, bitOffset),
"Q" => ReadQRegion<T>(offset, bitOffset),
"T" => ReadTRegion<T>(offset),
@@ -204,7 +210,7 @@
WriteMRegion(offset, value);
break;
case "DB":
- WriteDBRegion(dbNumber.Value, offset, value);
+ WriteDBRegion(dbNumber.Value, offset, bitOffset, value);
break;
case "I":
WriteIRegion(offset, bitOffset, value);
@@ -280,12 +286,12 @@
return new Dictionary<string, byte[]>
{
- ["M"] = _mRegion.Read(0, (ushort)_mRegion.Size),
+ ["M"] = ReadAllFromRegion(_mRegion, _mRegion.Size),
["DB"] = ExportDBRegion(),
- ["I"] = _iRegion.Read(0, (ushort)_iRegion.Size),
- ["Q"] = _qRegion.Read(0, (ushort)_qRegion.Size),
- ["T"] = _tRegion.Read(0, (ushort)_tRegion.Size),
- ["C"] = _cRegion.Read(0, (ushort)_cRegion.Size)
+ ["I"] = ReadAllFromRegion(_iRegion, _iRegion.Size),
+ ["Q"] = ReadAllFromRegion(_qRegion, _qRegion.Size),
+ ["T"] = ReadAllFromRegion(_tRegion, _tRegion.Size),
+ ["C"] = ReadAllFromRegion(_cRegion, _cRegion.Size)
};
}
@@ -381,6 +387,13 @@
offset = ushort.Parse(offsetPart.Substring(3));
else if (offsetPart.StartsWith("DBB"))
offset = ushort.Parse(offsetPart.Substring(3));
+ else if (offsetPart.StartsWith("DBX"))
+ {
+ var dbxParts = offsetPart.Substring(3).Split('.');
+ offset = ushort.Parse(dbxParts[0]);
+ var bit = dbxParts.Length > 1 ? byte.Parse(dbxParts[1]) : (byte)0;
+ return ("DB", offset, dbNumber, bit);
+ }
else
offset = ushort.Parse(offsetPart);
}
@@ -437,11 +450,11 @@
/// 娉ㄦ剰锛歴tring绫诲瀷涓嶅彈姝ゆ硾鍨嬫柟娉曟敮鎸侊紙鍙梬here T : struct绾︽潫锛�
/// 璇蜂娇鐢╓riteBytes/ReadBytes鎴栭�氳繃DBRegion鐩存帴璁块棶瀛楃涓�
/// </summary>
- private T ReadDBRegion<T>(ushort dbNumber, ushort offset) where T : struct
+ private T ReadDBRegion<T>(ushort dbNumber, ushort offset, byte? bitOffset) where T : struct
{
return typeof(T).Name switch
{
- "Boolean" => (T)(object)_dbRegion.ReadBool(dbNumber, offset, 0),
+ "Boolean" => (T)(object)_dbRegion.ReadBool(dbNumber, offset, bitOffset ?? 0),
"Int16" => (T)(object)_dbRegion.ReadInt(dbNumber, offset),
"Int32" => (T)(object)_dbRegion.ReadDInt(dbNumber, offset),
"Single" => (T)(object)_dbRegion.ReadReal(dbNumber, offset),
@@ -507,12 +520,12 @@
/// 娉ㄦ剰锛歴tring绫诲瀷涓嶅彈姝ゆ硾鍨嬫柟娉曟敮鎸侊紙鍙梬here T : struct绾︽潫锛�
/// 璇蜂娇鐢╓riteBytes/ReadBytes鎴栭�氳繃DBRegion鐩存帴璁块棶瀛楃涓�
/// </summary>
- private void WriteDBRegion<T>(ushort dbNumber, ushort offset, T value) where T : struct
+ private void WriteDBRegion<T>(ushort dbNumber, ushort offset, byte? bitOffset, T value) where T : struct
{
switch (typeof(T).Name)
{
case "Boolean":
- _dbRegion.WriteBool(dbNumber, offset, 0, (bool)(object)value);
+ _dbRegion.WriteBool(dbNumber, offset, bitOffset ?? 0, (bool)(object)value);
break;
case "Int16":
_dbRegion.WriteInt(dbNumber, offset, (short)(object)value);
@@ -671,11 +684,11 @@
private byte[] ExportDBRegion()
{
var result = new List<byte>();
- for (ushort i = 1; i <= _config.DBBlockCount; i++)
+ foreach (var dbNumber in ResolveConfiguredDbNumbers())
{
try
{
- var blockData = _dbRegion.Read(i, 0, (ushort)_config.DBBlockSize);
+ var blockData = ReadAllFromDbBlock(dbNumber, _config.DBBlockSize);
result.AddRange(blockData);
}
catch (ArgumentException)
@@ -696,19 +709,87 @@
private void ImportDBRegion(byte[] data)
{
int offset = 0;
- for (ushort i = 1; i <= _config.DBBlockCount && offset < data.Length; i++)
+ foreach (var dbNumber in ResolveConfiguredDbNumbers())
{
+ if (offset >= data.Length)
+ {
+ break;
+ }
+
var blockSize = Math.Min(_config.DBBlockSize, data.Length - offset);
var blockData = new byte[blockSize];
Array.Copy(data, offset, blockData, 0, blockSize);
- _dbRegion.Write(i, 0, blockData);
+ _dbRegion.Write(dbNumber, 0, blockData);
offset += blockSize;
}
}
/// <summary>
+ /// 鎸夊垎鐗囪鍙栨暣涓尯鍩燂紝閬垮厤闀垮害瓒呰繃 ushort 瀵艰嚧婧㈠嚭銆�
+ /// </summary>
+ private static byte[] ReadAllFromRegion(IMemoryRegion region, int totalSize)
+ {
+ if (totalSize <= 0)
+ {
+ return Array.Empty<byte>();
+ }
+
+ var result = new byte[totalSize];
+ var copied = 0;
+ while (copied < totalSize)
+ {
+ var chunkLength = (ushort)Math.Min(ushort.MaxValue, totalSize - copied);
+ var chunk = region.Read((ushort)copied, chunkLength);
+ Buffer.BlockCopy(chunk, 0, result, copied, chunkLength);
+ copied += chunkLength;
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// 鎸夊垎鐗囪鍙栨暣涓� DB 鍧楋紝閬垮厤 DBBlockSize=65536 鏃� ushort 杞崲涓� 0銆�
+ /// </summary>
+ private byte[] ReadAllFromDbBlock(ushort dbNumber, int blockSize)
+ {
+ if (blockSize <= 0)
+ {
+ return Array.Empty<byte>();
+ }
+
+ var result = new byte[blockSize];
+ var copied = 0;
+ while (copied < blockSize)
+ {
+ var chunkLength = (ushort)Math.Min(ushort.MaxValue, blockSize - copied);
+ var chunk = _dbRegion.Read(dbNumber, (ushort)copied, chunkLength);
+ Buffer.BlockCopy(chunk, 0, result, copied, chunkLength);
+ copied += chunkLength;
+ }
+
+ return result;
+ }
+
+ /// <summary>
/// 閲婃斁璧勬簮
/// </summary>
+ private List<ushort> ResolveConfiguredDbNumbers()
+ {
+ if (_config.DBBlockNumbers != null && _config.DBBlockNumbers.Count > 0)
+ {
+ return _config.DBBlockNumbers
+ .Where(x => x > 0 && x <= ushort.MaxValue)
+ .Distinct()
+ .Select(x => (ushort)x)
+ .ToList();
+ }
+
+ return Enumerable
+ .Range(1, Math.Max(1, _config.DBBlockCount))
+ .Select(x => (ushort)x)
+ .ToList();
+ }
+
public void Dispose()
{
Dispose(true);
--
Gitblit v1.9.3