Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/devices/Common/ClassVisibility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public partial class NumberHelper
}
}

namespace System.Device
namespace Iot.Device
{
public partial class DelayHelper
{
Expand Down Expand Up @@ -55,9 +55,9 @@ internal partial class NumberHelper
}
}

namespace System.Device
namespace Iot.Device
{
internal partial class DelayHelper
public partial class DelayHelper
{
}
}
Expand Down
14 changes: 12 additions & 2 deletions src/devices/Common/System/Device/DelayHelper.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using System.Threading;

namespace System.Device
namespace Iot.Device

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot changing the namespace without moving the helper in the other assembly raise a problem in terms of binary compatibility for the future.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — once Iot.Device.DelayHelper ships as public API of Iot.Device.Bindings, it's locked into that assembly. It can't be forwarded to System.Device.Gpio later (the dependency runs the other way, and the namespace differs), so honoring the original issue ("part of System.Device.Gpio") would then be a binary-breaking change.

The clean fix is to give it its permanent home now, before it's public: move DelayHelper into the System.Device.Gpio project with the System.Device namespace (where it already lives today), and drop the namespace change to Iot.Device. That does conflict with the earlier triage note to keep it in Iot.Device.Bindings, so I don't want to move assemblies unilaterally.

Which assembly should be the final home — System.Device.Gpio (matches the issue, avoids the compat trap) or Iot.Device.Bindings (earlier triage)? I'll implement whichever you confirm.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@raffaeler As we don't have any plans in moving stuff from Iot.Device.Bindings to System.Device in the near future, I guess the Iot.Device namespace is the better one for this.

{
/// <summary>
/// Helpers for short waits.
/// Helpers for short, high precision waits. Prefer these over <see cref="Thread.Sleep(int)"/> when a device
/// binding needs to honor sub-millisecond timing requirements from a datasheet.
/// </summary>
static partial class DelayHelper
{
Expand Down Expand Up @@ -79,7 +81,15 @@ public static void DelayMicroseconds(int microseconds, bool allowThreadYield)
/// True to allow yielding the thread. If this is set to false, on single-proc systems
/// this will prevent all other code from running.
/// </param>
/// <remarks>
/// This overload is intended for internal use only. For millisecond scale waits prefer
/// <see cref="Thread.Sleep(int)"/>, which lets the operating system schedule other work.
/// </remarks>
#if BUILDING_IOT_DEVICE_BINDINGS
internal static void DelayMilliseconds(int milliseconds, bool allowThreadYield)
#else
public static void DelayMilliseconds(int milliseconds, bool allowThreadYield)
#endif
{
/* We have this as a separate method for now to make calling code clearer
* and to allow us to add additional logic to the millisecond wait in the
Expand Down
48 changes: 48 additions & 0 deletions src/devices/Common/tests/DelayHelperTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using Xunit;

namespace Iot.Device.Common.Tests
{
public class DelayHelperTest
{
// Timing tests only verify the guaranteed lower bound (the helper waits for *at least* the
// requested time). A small, consistent tolerance absorbs the resolution of the underlying
// timer and the conversion between Stopwatch ticks and TimeSpan ticks.
private static readonly TimeSpan Tolerance = TimeSpan.FromMilliseconds(1);

[Theory]
[InlineData(true)]
[InlineData(false)]
public void DelayWaitsAtLeastTheRequestedTime(bool allowThreadYield)
{
TimeSpan requested = TimeSpan.FromMilliseconds(20);

Stopwatch stopwatch = Stopwatch.StartNew();
DelayHelper.Delay(requested, allowThreadYield);
stopwatch.Stop();

Assert.True(
stopwatch.Elapsed >= requested - Tolerance,
$"Expected to wait at least {requested.TotalMilliseconds}ms but only waited {stopwatch.Elapsed.TotalMilliseconds}ms.");
}

[Fact]
public void DelayMicrosecondsWaitsAtLeastTheRequestedTime()
{
const int microseconds = 5000; // 5ms
TimeSpan requested = TimeSpan.FromMilliseconds(5);

Stopwatch stopwatch = Stopwatch.StartNew();
DelayHelper.DelayMicroseconds(microseconds, allowThreadYield: true);
stopwatch.Stop();

Assert.True(
stopwatch.Elapsed >= requested - Tolerance,
$"Expected to wait at least {requested.TotalMilliseconds}ms but only waited {stopwatch.Elapsed.TotalMilliseconds}ms.");
}
}
}
1 change: 1 addition & 0 deletions src/devices/SoftPwm/SoftwarePwmChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Diagnostics;
using System.Globalization;
using System.Threading;
using Iot.Device;

namespace System.Device.Pwm.Drivers
{
Expand Down
Loading