Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to support Linux ARMv7 32bits for doubles and floats #97

Open
RexHung opened this issue Feb 25, 2024 · 2 comments
Open

Comments

@RexHung
Copy link

RexHung commented Feb 25, 2024

When I use float on Linux ARMv7 32, I get a System.DataMisalignedException exception. Is it possible to support Linux ARMv7 32bits for doubles and floats? Or is there a workaround?

  System.DataMisalignedException: A datatype misalignment was detected in a load or store instruction.
     at Secs4Net.Item.MemoryItem`1.EncodeTo(IBufferWriter`1 buffer) in /src/secs4net-2.4.3/src/Secs4Net/Item.Memory.cs:line 66
     at Secs4Net.Item.ListItem.EncodeTo(IBufferWriter`1 buffer) in /src/secs4net-2.4.3/src/Secs4Net/Item.List.cs:line 46
     at Secs4Net.SecsGem.SendDataMessageAsync(SecsMessage message, Int32 id, CancellationToken cancellation) in /src/secs4net-2.4.3/src/Secs4Net/SecsGem.cs:line 90
     at Secs4Net.PrimaryMessageWrapper.TryReplyAsync(SecsMessage replyMessage, CancellationToken cancellation) in /src/secs4net-2.4.3/src/Secs4Net/PrimaryMessageWrapper.cs:line 70
     at TestSecsWebApp.DeviceWorker.ExecuteAsync(CancellationToken stoppingToken) in /src/TestSecsWebApp/DeviceWorker.cs:line 133
@mkjeff
Copy link
Owner

mkjeff commented Feb 25, 2024

I have a Raspberry Pi 2 Model B, maybe I can try it when I have time (no guarantee)

@RexHung
Copy link
Author

RexHung commented Feb 26, 2024

I made a workaround which is using an unsigned long integer for casting double values and an unsigned integer for casting float values.

Besides the workaround of float and double, the backlog of the socket instance should be changed from 0 to 1 (it seems Linux-Arm uses the waiting queue differently.).

        if (typeof(T) == typeof(float))
        {
            ref var iValue = ref Unsafe.As<byte, uint>(ref MemoryMarshal.GetReference(bufferByteSpan));
            var span = MemoryMarshal.CreateSpan<uint>(ref iValue, bufferByteSpan.Length / sizeof(float));
            ref var rStart = ref MemoryMarshal.GetReference(span);
            ref var rEnd = ref Unsafe.Add(ref rStart, span.Length);
            while (Unsafe.IsAddressLessThan(ref rStart, ref rEnd))
            {
                rStart = BitConverter.SingleToUInt32Bits(BinaryPrimitives.ReadSingleBigEndian(rStart.AsReadOnlyBytes()));
                rStart = ref Unsafe.Add(ref rStart, 1u);
            }
        }
        if (typeof(T) == typeof(double))
        {
            ref var lValue = ref Unsafe.As<byte, ulong>(ref MemoryMarshal.GetReference(bufferByteSpan));
            var span = MemoryMarshal.CreateSpan<ulong>(ref lValue, bufferByteSpan.Length / sizeof(double));
            ref var rStart = ref MemoryMarshal.GetReference(span);
            ref var rEnd = ref Unsafe.Add(ref rStart, span.Length);
            while (Unsafe.IsAddressLessThan(ref rStart, ref rEnd))
            {
                rStart = BitConverter.DoubleToUInt64Bits(BinaryPrimitives.ReadDoubleBigEndian(rStart.AsReadOnlyBytes()));
                rStart = ref Unsafe.Add(ref rStart, 1u);
            }
        }
        if (typeof(T) != typeof(float) && typeof(T) != typeof(double))
        {
            ReverseEndiannessHelper<T>.Reverse(Cast(bufferByteSpan));
        }

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants