diff --git a/src/devices/Common/ClassVisibility.cs b/src/devices/Common/ClassVisibility.cs index 4f22c20709..1b2cd226f0 100644 --- a/src/devices/Common/ClassVisibility.cs +++ b/src/devices/Common/ClassVisibility.cs @@ -24,7 +24,7 @@ public partial class NumberHelper } } -namespace System.Device +namespace Iot.Device { public partial class DelayHelper { @@ -55,9 +55,9 @@ internal partial class NumberHelper } } -namespace System.Device +namespace Iot.Device { - internal partial class DelayHelper + public partial class DelayHelper { } } diff --git a/src/devices/Common/System/Device/DelayHelper.cs b/src/devices/Common/System/Device/DelayHelper.cs index e2aafabc2b..243d4ea6c1 100644 --- a/src/devices/Common/System/Device/DelayHelper.cs +++ b/src/devices/Common/System/Device/DelayHelper.cs @@ -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 { /// - /// Helpers for short waits. + /// Helpers for short, high precision waits. Prefer these over when a device + /// binding needs to honor sub-millisecond timing requirements from a datasheet. /// static partial class DelayHelper { @@ -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. /// + /// + /// This overload is intended for internal use only. For millisecond scale waits prefer + /// , which lets the operating system schedule other work. + /// +#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 diff --git a/src/devices/Common/tests/DelayHelperTest.cs b/src/devices/Common/tests/DelayHelperTest.cs new file mode 100644 index 0000000000..75b916ec9c --- /dev/null +++ b/src/devices/Common/tests/DelayHelperTest.cs @@ -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."); + } + } +} diff --git a/src/devices/SoftPwm/SoftwarePwmChannel.cs b/src/devices/SoftPwm/SoftwarePwmChannel.cs index ca33393460..2434b3d7e6 100644 --- a/src/devices/SoftPwm/SoftwarePwmChannel.cs +++ b/src/devices/SoftPwm/SoftwarePwmChannel.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Globalization; using System.Threading; +using Iot.Device; namespace System.Device.Pwm.Drivers {