Commit abc4ba33 authored by Andreas Müller's avatar Andreas Müller
Browse files

Implementing a switch whether the remote is a little endian system.

parent cb75e559
Pipeline #181 passed with stage
in 25 seconds
......@@ -16,21 +16,21 @@ build:
- dotnet nuget push -s amget -k $AMGET_API_KEY --skip-duplicate src/Modbus.Tcp/bin/Release/*.nupkg
- dotnet nuget push -s amget -k $AMGET_API_KEY --skip-duplicate src/Modbus.Serial/bin/Release/*.nupkg
- dotnet nuget push -s amget -k $AMGET_API_KEY --skip-duplicate src/Modbus.Proxy/bin/Release/*.nupkg
artifacts:
paths:
- src/Modbus.Common/bin/Release/AMWD.Modbus.Common.dll
- src/Modbus.Common/bin/Release/AMWD.Modbus.Common.pdb
- src/Modbus.Common/bin/Release/AMWD.Modbus.Common.xml
- src/Modbus.Tcp/bin/Release/AMWD.Modbus.Tcp.dll
- src/Modbus.Tcp/bin/Release/AMWD.Modbus.Tcp.pdb
- src/Modbus.Tcp/bin/Release/AMWD.Modbus.Tcp.xml
- src/Modbus.Serial/bin/Release/AMWD.Modbus.Serial.dll
- src/Modbus.Serial/bin/Release/AMWD.Modbus.Serial.pdb
- src/Modbus.Serial/bin/Release/AMWD.Modbus.Serial.xml
- src/Modbus.Proxy/bin/Release/AMWD.Modbus.Proxy.dll
- src/Modbus.Proxy/bin/Release/AMWD.Modbus.Proxy.pdb
- src/Modbus.Proxy/bin/Release/AMWD.Modbus.Proxy.xml
expire_in: 1 month
# artifacts:
# paths:
# - src/Modbus.Common/bin/Release/AMWD.Modbus.Common.dll
# - src/Modbus.Common/bin/Release/AMWD.Modbus.Common.pdb
# - src/Modbus.Common/bin/Release/AMWD.Modbus.Common.xml
# - src/Modbus.Tcp/bin/Release/AMWD.Modbus.Tcp.dll
# - src/Modbus.Tcp/bin/Release/AMWD.Modbus.Tcp.pdb
# - src/Modbus.Tcp/bin/Release/AMWD.Modbus.Tcp.xml
# - src/Modbus.Serial/bin/Release/AMWD.Modbus.Serial.dll
# - src/Modbus.Serial/bin/Release/AMWD.Modbus.Serial.pdb
# - src/Modbus.Serial/bin/Release/AMWD.Modbus.Serial.xml
# - src/Modbus.Proxy/bin/Release/AMWD.Modbus.Proxy.dll
# - src/Modbus.Proxy/bin/Release/AMWD.Modbus.Proxy.pdb
# - src/Modbus.Proxy/bin/Release/AMWD.Modbus.Proxy.xml
# expire_in: 1 month
deploy:
stage: deploy
......
......@@ -38,6 +38,11 @@ namespace AMWD.Modbus.Common.Interfaces
/// </summary>
TimeSpan ReceiveTimeout { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the remote is delivering the bytes in little-endian order.
/// </summary>
bool IsLittleEndianRemote { get; set; }
#endregion Properties
#region Control
......
......@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<LangVersion>9.0</LangVersion>
<AssemblyName>AMWD.Modbus.Common</AssemblyName>
<RootNamespace>AMWD.Modbus.Common</RootNamespace>
......@@ -28,7 +28,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.3.0">
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
......
......@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<LangVersion>9.0</LangVersion>
<AssemblyName>AMWD.Modbus.Proxy</AssemblyName>
<RootNamespace>AMWD.Modbus.Proxy</RootNamespace>
......@@ -28,7 +28,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.3.0">
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
......
......@@ -175,6 +175,11 @@ namespace AMWD.Modbus.Serial.Client
}
}
/// <summary>
/// Gets or sets a value indicating whether the remote is delivering the bytes in little-endian order.
/// </summary>
public bool IsLittleEndianRemote { get; set; }
/// <summary>
/// Gets the result of the asynchronous initialization of this instance.
/// </summary>
......@@ -531,13 +536,24 @@ namespace AMWD.Modbus.Serial.Client
list = new List<Register>();
for (int i = 0; i < count; i++)
{
list.Add(new Register
var register = new Register
{
Type = ModbusObjectType.HoldingRegister,
Address = (ushort)(startAddress + i),
HiByte = response.Data[i * 2],
LoByte = response.Data[i * 2 + 1]
});
Address = (ushort)(startAddress + i)
};
if (IsLittleEndianRemote)
{
register.LoByte = response.Data[i * 2];
register.HiByte = response.Data[i * 2 + 1];
}
else
{
register.HiByte = response.Data[i * 2];
register.LoByte = response.Data[i * 2 + 1];
}
list.Add(register);
}
}
catch (IOException ex)
......@@ -599,13 +615,24 @@ namespace AMWD.Modbus.Serial.Client
list = new List<Register>();
for (int i = 0; i < count; i++)
{
list.Add(new Register
var register = new Register
{
Type = ModbusObjectType.InputRegister,
Address = (ushort)(startAddress + i),
HiByte = response.Data[i * 2],
LoByte = response.Data[i * 2 + 1]
});
Address = (ushort)(startAddress + i)
};
if (IsLittleEndianRemote)
{
register.LoByte = response.Data[i * 2];
register.HiByte = response.Data[i * 2 + 1];
}
else
{
register.HiByte = response.Data[i * 2];
register.LoByte = response.Data[i * 2 + 1];
}
list.Add(register);
}
}
catch (IOException ex)
......@@ -827,9 +854,18 @@ namespace AMWD.Modbus.Serial.Client
{
DeviceId = deviceId,
Function = FunctionCode.WriteSingleRegister,
Address = register.Address,
Data = new DataBuffer(new[] { register.HiByte, register.LoByte })
Address = register.Address
};
if (IsLittleEndianRemote)
{
request.Data = new DataBuffer(new[] { register.LoByte, register.HiByte });
}
else
{
request.Data = new DataBuffer(new[] { register.HiByte, register.LoByte });
}
var response = await SendRequest(request, cancellationToken);
if (response.IsTimeout)
throw new ModbusException("Response timed out. Device id invalid?");
......@@ -992,7 +1028,14 @@ namespace AMWD.Modbus.Serial.Client
request.Data.SetByte(0, (byte)(orderedList.Count * 2));
for (int i = 0; i < orderedList.Count; i++)
{
request.Data.SetUInt16(i * 2 + 1, orderedList[i].RegisterValue);
if (IsLittleEndianRemote)
{
request.Data.SetBytes(i * 2, new[] { orderedList[i].LoByte, orderedList[i].HiByte });
}
else
{
request.Data.SetBytes(i * 2, new[] { orderedList[i].HiByte, orderedList[i].LoByte });
}
}
var response = await SendRequest(request, cancellationToken);
if (response.IsTimeout)
......
......@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<LangVersion>9.0</LangVersion>
<AssemblyName>AMWD.Modbus.Serial</AssemblyName>
<RootNamespace>AMWD.Modbus.Serial</RootNamespace>
......@@ -29,7 +29,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
<PackageReference Include="System.IO.Ports" Version="4.7.0" />
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.3.0">
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
......
......@@ -26,9 +26,9 @@ namespace AMWD.Modbus.Tcp.Client
#region Fields
private readonly ILogger logger;
private readonly object reconnectLock = new object();
private readonly SemaphoreSlim sendLock = new SemaphoreSlim(1, 1);
private readonly ConcurrentDictionary<ushort, TaskCompletionSource<Response>> awaitingResponses = new ConcurrentDictionary<ushort, TaskCompletionSource<Response>>();
private readonly object reconnectLock = new();
private readonly SemaphoreSlim sendLock = new(1, 1);
private readonly ConcurrentDictionary<ushort, TaskCompletionSource<Response>> awaitingResponses = new();
private CancellationTokenSource stopCts;
private CancellationTokenSource receiveCts;
......@@ -124,6 +124,11 @@ namespace AMWD.Modbus.Tcp.Client
/// </summary>
public int Port { get; }
/// <summary>
/// Gets or sets a value indicating whether the remote is delivering the bytes in little-endian order.
/// </summary>
public bool IsLittleEndianRemote { get; set; }
/// <summary>
/// Gets the result of the asynchronous initialization of this instance.
/// </summary>
......@@ -474,13 +479,24 @@ namespace AMWD.Modbus.Tcp.Client
list = new List<Register>();
for (int i = 0; i < count; i++)
{
list.Add(new Register
var register = new Register
{
Type = ModbusObjectType.HoldingRegister,
Address = (ushort)(startAddress + i),
HiByte = response.Data[i * 2],
LoByte = response.Data[i * 2 + 1]
});
Address = (ushort)(startAddress + i)
};
if (IsLittleEndianRemote)
{
register.LoByte = response.Data[i * 2];
register.HiByte = response.Data[i * 2 + 1];
}
else
{
register.HiByte = response.Data[i * 2];
register.LoByte = response.Data[i * 2 + 1];
}
list.Add(register);
}
}
catch (SocketException ex)
......@@ -556,13 +572,24 @@ namespace AMWD.Modbus.Tcp.Client
list = new List<Register>();
for (int i = 0; i < count; i++)
{
list.Add(new Register
var register = new Register
{
Type = ModbusObjectType.InputRegister,
Address = (ushort)(startAddress + i),
HiByte = response.Data[i * 2],
LoByte = response.Data[i * 2 + 1]
});
Address = (ushort)(startAddress + i)
};
if (IsLittleEndianRemote)
{
register.LoByte = response.Data[i * 2];
register.HiByte = response.Data[i * 2 + 1];
}
else
{
register.HiByte = response.Data[i * 2];
register.LoByte = response.Data[i * 2 + 1];
}
list.Add(register);
}
}
catch (SocketException ex)
......@@ -817,13 +844,26 @@ namespace AMWD.Modbus.Tcp.Client
try
{
var request = new Request
{
DeviceId = deviceId,
Function = FunctionCode.WriteSingleRegister,
Address = register.Address,
Data = new DataBuffer(new[] { register.HiByte, register.LoByte })
Address = register.Address
};
if (IsLittleEndianRemote)
{
request.Data = new DataBuffer(new[] { register.LoByte, register.HiByte });
}
else
{
request.Data = new DataBuffer(new[] { register.HiByte, register.LoByte });
}
var response = await SendRequest(request, cancellationToken);
if (response.IsTimeout)
throw new SocketException((int)SocketError.TimedOut);
......@@ -1005,7 +1045,14 @@ namespace AMWD.Modbus.Tcp.Client
var data = new DataBuffer(orderedList.Count * 2);
for (int i = 0; i < orderedList.Count; i++)
{
data.SetUInt16(i * 2, orderedList[i].RegisterValue);
if (IsLittleEndianRemote)
{
data.SetBytes(i * 2, new[] { orderedList[i].LoByte, orderedList[i].HiByte });
}
else
{
data.SetBytes(i * 2, new[] { orderedList[i].HiByte, orderedList[i].LoByte });
}
}
try
......
......@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<LangVersion>9.0</LangVersion>
<AssemblyName>AMWD.Modbus.Tcp</AssemblyName>
<RootNamespace>AMWD.Modbus.Tcp</RootNamespace>
......@@ -28,7 +28,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.3.0">
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
......
......@@ -6,9 +6,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.3" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.3" />
</ItemGroup>
<ItemGroup>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment