Search code examples
c#floating-point.net-6.0.net-7.0

Using Span<T> on ARM gives "System.DataMisalignedException:"


I am trying to read data and convert it from a Modbus RTU sensor using .NET 7. Everything is working on my Linux-x64 machine but not when i try to run it on the RevPi core S linux-arm...

Modbus RTU config Sensor Instructions

I am using FluentModbus version 5.0.2:


fluentClient = new ModbusRtuClient()
{
    BaudRate = 9600,
    Parity = Parity.None,
    StopBits = StopBits.One
};
fluentClient.Connect("/dev/ttyUSB" + port, ModbusEndianness.LittleEndian);

Console.WriteLine("Reading Calibration");
var calibration = fluentClient.ReadHoldingRegisters(1, 8704, 4);

var hexCalibration = Convert.ToHexString(calibration);

foreach (var item in calibration)
{
    Console.Write(item);
}

foreach (var item in hexCalibration)
{
    Console.Write(item);
}
//The code below works perfect on my machine running Ubuntu 22.04(linux-x64) but does not work //on RevPi Core running Debian custom Buster image (Linux-arm).
var floatCalibration = fluentClient.ReadHoldingRegisters<float>(1, 8704, 4);
Console.WriteLine("calibration K: " + floatCalibration[0]);
Console.WriteLine("calibration B: " + floatCalibration[1]);

Terminal output My computer:

Reading Calibration
000631541535764
0000003F9A993940
calibration K: 0.5
calibration B: 2.9

Terminal output RevPi Core:

Reading Calibration
000631541535764
0000003F9A993940
Unhandled exception. System.DataMisalignedException: A datatype misalignment was detected in a load or store instruction.
   at exsys.Program.Main(String[] args) in /home/user/FunctionTest/Program.cs:line 179
Aborted

And this is line 179: Console.WriteLine("calibration K: " + floatCalibration[0]);

Is it not possible to use .Net7 Span<float> on linux Arm? I have tried different setups, but no luck yet. Maybe someone else have run in to this issue?

Tried dotnet publish to self contained linux-x64 and everything works fine. i only get the error when compiling to linux-arm and running it. Tried different converting setups but no luck. I have updated the image on the RevPi Core S released in November 2022, but it did not help. Tried first running on .NET 6 and now on .NET 7. Same error on both.


Solution

  • FluentModbus is breaking alignment here:

    and then calls MemoryMarshal.Cast which is a problem on ARM, because the documentation says

    This method is supported only on platforms that support misaligned memory access or when the memory block is aligned by other means.

    ARM is not a platform that supports misaligned memory access.

    A good workaround would be to allocate a float[], call the version of ReadHoldingRegisters that returns Span<byte>, and call CopyTo(MemoryMarshal.AsBytes(destFloatArray)).