Skip to content

Commit

Permalink
Work on Debuger Engine (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
josesimoes authored Nov 3, 2017
1 parent a1b7543 commit 55f68e7
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 62 deletions.
4 changes: 2 additions & 2 deletions source/USB Test App WPF/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ private async void ConnectDeviceButton_ClickAsync(object sender, RoutedEventArgs
await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(async () =>
{
bool connectResult = await (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.ConnectAsync(3000, true);
bool connectResult = await (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.ConnectAsync(5000, true);
(DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.Start();
//(DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.Start();
var di = await (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].GetDeviceInfoAsync();
Expand Down
142 changes: 82 additions & 60 deletions source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,72 @@ public async Task<bool> ConnectAsync(int timeout, bool force = false, Connection
return true;
}

public async Task ProcessBackgroundMessages()
{
var reassembler = new MessageReassembler(m_ctrl);

while (!backgroundProcessorCancellation.IsCancellationRequested)
{
var semaphoreEntered = await semaphore.WaitAsync(500);

if (semaphoreEntered)
{
try
{
var message = await reassembler.ProcessAsync(backgroundProcessorCancellation.Token.AddTimeout(new TimeSpan(0, 0, 0, 500)));

if (message != null)
{
// there was a message, throw it to Processor, no need to wait for execution
ProcessMessageAsync(message, false).FireAndForget();
}
}
catch (Exception) { }
finally
{
semaphore.Release();
}
}

// no need to rush into the next attempt, wait here
if ((!backgroundProcessorCancellation.IsCancellationRequested)) await Task.Delay(500);
};
}

public void ProcessSpuriousChars()
{
int read = 0;

while (noiseHandlingCancellation.IsCancellationRequested)
{
var semaphoreTaken = m_notifyNoise.WaitHandle.WaitOne(250);

if (semaphoreTaken)
{
while ((read = m_notifyNoise.Available) > 0)
{
byte[] buffer = new byte[m_notifyNoise.Available];

m_notifyNoise.Read(buffer, 0, buffer.Length);

if (SpuriousCharactersReceived != null)
{
SpuriousCharactersReceived.Invoke(this, new StringEventArgs(UTF8Encoding.UTF8.GetString(buffer, 0, buffer.Length)));
}
}
}
}
}

public void Disconnect()
{
// better do this inside of try/catch because we can't be sure that the device is actually connected or that the
// operation can be successful
try
{
// cancel background processors, if they are running
noiseHandlingCancellation.Cancel();

// cancel background processor, if running
backgroundProcessorCancellation.Cancel();

// update flag
Expand Down Expand Up @@ -280,6 +337,10 @@ protected virtual void Dispose(bool disposing)
{
// TODO: dispose managed state (managed objects).

//noiseHandlingCancellation.Cancel();

//backgroundProcessorCancellation.Cancel();

try
{
if (IsConnected)
Expand Down Expand Up @@ -496,86 +557,36 @@ public void ProcessExited()
throw new NotImplementedException();
}

public async Task<byte[]> ReadBufferAsync(uint bytesToRead, TimeSpan waitTimeout, CancellationToken cancellationToken)
public Task<byte[]> ReadBufferAsync(uint bytesToRead, TimeSpan waitTimeout, CancellationToken cancellationToken)
{
return await m_portDefinition.ReadBufferAsync(bytesToRead, waitTimeout, cancellationToken);
return m_portDefinition.ReadBufferAsync(bytesToRead, waitTimeout, cancellationToken);
}

private OutgoingMessage CreateMessage(uint cmd, uint flags, object payload)
{
return new OutgoingMessage(m_ctrl, CreateConverter(), cmd, flags, payload);
}

public async Task Start()
public void Start()
{
var reassembler = new MessageReassembler(m_ctrl);

// check if cancellation token needs to be renewed
if (backgroundProcessorCancellation.IsCancellationRequested)
{
backgroundProcessorCancellation = new CancellationTokenSource();
}

// start task to process background messages
await Task.Factory.StartNew(async () =>
Task.Factory.StartNew(async () =>
{
while (!backgroundProcessorCancellation.IsCancellationRequested && IsConnected)
{
var semaphoreEntered = await semaphore.WaitAsync(500);
if (semaphoreEntered)
{
try
{
var message = await reassembler.ProcessAsync(backgroundProcessorCancellation.Token.AddTimeout(new TimeSpan(0, 0, 0, 500)));
if (message != null)
{
// there was a message, throw it to Processor, no need to wait for execution
ProcessMessageAsync(message, false).FireAndForget();
}
}
catch (OperationCanceledException) { }
finally
{
semaphore.Release();
}
}
// no need to rush into the next attempt, wait here
if ((!backgroundProcessorCancellation.IsCancellationRequested && IsConnected)) await Task.Delay(500);
};
await ProcessBackgroundMessages();
}, backgroundProcessorCancellation.Token);


// start task to tx spurious characters
await Task.Factory.StartNew(() =>
Task.Factory.StartNew(() =>
{
int read = 0;
while (noiseHandlingCancellation.IsCancellationRequested)
{
var semaphoreTaken = m_notifyNoise.WaitHandle.WaitOne(250);
if (semaphoreTaken)
{
while ((read = m_notifyNoise.Available) > 0)
{
byte[] buffer = new byte[m_notifyNoise.Available];
m_notifyNoise.Read(buffer, 0, buffer.Length);
if (SpuriousCharactersReceived != null)
{
SpuriousCharactersReceived.Invoke(this, new StringEventArgs(UTF8Encoding.UTF8.GetString(buffer, 0, buffer.Length)));
}
}
}
}
ProcessSpuriousChars();
}, noiseHandlingCancellation.Token);

}


Expand Down Expand Up @@ -1506,8 +1517,19 @@ public async Task<bool> SetIPOfStackFrameAsync(uint pid, uint depth, uint IP, ui
foreach (IncomingMessage message in replies)
{
// reply is a match for request which m_seq is same as reply m_seqReply
resolveAssemblies.Add(requests.Find(req => req.Header.Seq == message.Header.SeqReply).Payload as Commands.DebuggingResolveAssembly);
resolveAssemblies[resolveAssemblies.Count - 1].Result = message.Payload as Commands.DebuggingResolveAssembly.Reply;
// need to check for null or invalid payload
var payload = requests.Find(req => req.Header.Seq == message.Header.SeqReply).Payload;

if (payload != null)
{
resolveAssemblies.Add(payload as Commands.DebuggingResolveAssembly);
resolveAssemblies[resolveAssemblies.Count - 1].Result = message.Payload as Commands.DebuggingResolveAssembly.Reply;
}
else
{
// failure
return null;
}
}
}

Expand Down

0 comments on commit 55f68e7

Please sign in to comment.