Skip to content

Commit

Permalink
Prepare Interrupt Service Thread for safe raise-priority execution in…
Browse files Browse the repository at this point in the history
… an RTOS

As Meadow.OS is back to allowing a .NET thread to be of a non-Mono priority, the IST is back to running at this higer priority, fixing WildernessLabs/Meadow_Issues#311 . The thread logic is modified to exclude non-deterministic .NET operations such as external type use, heap use, or direct invocation of a user delegate.
  • Loading branch information
alexischr committed Oct 1, 2023
1 parent e677114 commit 53e6880
Showing 1 changed file with 29 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static Meadow.Core.Interop;

namespace Meadow.Devices;
Expand All @@ -19,6 +20,8 @@ public partial class F7GPIOManager : IMeadowIOController
private List<int> _interruptGroupsInUse = new();
private bool _firstInterrupt = true;

private IPin _nullPin = new NullPin();

/// <summary>
/// Hooks up the provided pin to the underlying OS interrupt handling
/// </summary>
Expand Down Expand Up @@ -176,8 +179,6 @@ private void DisconnectInterrupt(int portNumber, int pinNumber)
private void InterruptServiceThreadProc(object o)
{
IntPtr queue = Interop.Nuttx.mq_open(new StringBuilder("/mdw_int"), Nuttx.QueueOpenFlag.ReadOnly);
Output.WriteLineIf((DebugFeatures & (DebugFeature.GpioDetail | DebugFeature.Interrupts)) != 0,
$"IST Started reading queue {queue.ToInt32():X}");

// We get 2 bytes from Nuttx. the first is the GPIOs port and pin the second
// the debounced state of the GPIO
Expand All @@ -188,37 +189,40 @@ private void InterruptServiceThreadProc(object o)
if (_firstInterrupt)
{
// DEV NOTE: this is to force the interp pipeline top build at least some of the call stack and improve the response of first-interrupt results
Interrupt?.Invoke(new NullPin(), false);
Interrupt?.Invoke(_nullPin, false);
_firstInterrupt = false;
}

int priority = 0;
try

var result = Interop.Nuttx.mq_receive(queue, rx_buffer, rx_buffer.Length, ref priority);

// byte 1 contains the port and pin, byte 2 contains the stable state.
if (result >= 0)
{
var result = Interop.Nuttx.mq_receive(queue, rx_buffer, rx_buffer.Length, ref priority);
var irq = rx_buffer[0];
bool state = rx_buffer[1] != 0;
var port = irq >> 4;
var pin = irq & 0xf;
IPin ipin;


// byte 1 contains the port and pin, byte 2 contains the stable state.
if (result >= 0)
lock (_interruptPins) //FIXME: If this is supposed to keep modifications from
//happening on the array, lock()'s are needed at those points also
{
var irq = rx_buffer[0];
bool state = rx_buffer[1] != 0;
var port = irq >> 4;
var pin = irq & 0xf;

lock (_interruptPins)
{
var ipin = _interruptPins[port, pin];
if (ipin != null)
{
Interrupt?.Invoke(ipin, state);
}
}
ipin = _interruptPins[port, pin];
if (ipin == null)
continue;
}

try
{
Interrupt?.Invoke(ipin, state);
}
catch (Exception ex)
{
Thread.Sleep(5000);
}
}
catch (Exception ex)
{
Resolver.Log.Error($"IST: {ex.Message}");
Thread.Sleep(5000);
}
}
}
Expand Down

0 comments on commit 53e6880

Please sign in to comment.