private void WaitForProcessExit() { try { if (string.Equals(m_transport.ToLower(), "emulator")) { Process[] p = Process.GetProcessesByName("Microsoft.SPOT.Emulator.Sample.SampleEmulator"); if (p != null && p.Length > 0) { m_emulatorProcess = p[p.Length - 1]; m_emulatorProcess.WaitForExit(); m_deviceDone.Set(); } } else { int retries = 90; // 15 minutes while (true) { if (!m_deviceDone.WaitOne(10000)) { if (m_engine.TryToConnect(10, 500, true, ConnectionSource.Unknown)) { Commands.Monitor_Ping.Reply ping = m_engine.GetConnectionSource(); if (ping != null) { if (0 != (ping.m_dbg_flags & Commands.Monitor_Ping.c_Ping_DbgFlag_AppExit)) { m_deviceDone.Set(); break; } } } else if (retries-- <= 0) { break; } } } } } catch { } }
/// <summary> /// Starts execution on the connected .Net Micro Framework device at the supplied address (parameter entrypoint). /// This method is generally used after the Deploy method to jump into the code that was deployed. /// </summary> /// <param name="entrypoint">Entry point address for execution to begin</param> /// <param name="cancellationToken">Cancellation token for caller to cancel task execution</param> /// <returns>Returns false if execution fails, true otherwise /// Possible exceptions: MFDeviceNoResponseException /// </returns> public async Task <bool> ExecuteAync(uint entryPoint, CancellationToken cancellationToken) { if (DebugEngine == null) { throw new NanoFrameworkDeviceNoResponseException(); } if (await CheckForMicroBooterAsync(cancellationToken)) { // check if cancellation was requested if (cancellationToken.IsCancellationRequested) { throw new NanoUserExitException(); } if (m_execSrecHash.ContainsKey(entryPoint)) { string execRec = (string)m_execSrecHash[entryPoint]; bool fRet = false; for (int retry = 0; retry < 10; retry++) { // check if cancellation was requested if (cancellationToken.IsCancellationRequested) { throw new NanoUserExitException(); } await DebugEngine.SendBufferAsync(UTF8Encoding.UTF8.GetBytes(execRec), TimeSpan.FromMilliseconds(1000), cancellationToken); // check if cancellation was requested if (cancellationToken.IsCancellationRequested) { throw new NanoUserExitException(); } await DebugEngine.SendBufferAsync(UTF8Encoding.UTF8.GetBytes("\n"), TimeSpan.FromMilliseconds(1000), cancellationToken); // check if cancellation was requested if (cancellationToken.IsCancellationRequested) { throw new NanoUserExitException(); } if (m_evtMicroBooter.WaitOne(1000)) { fRet = true; break; } } return(fRet); } return(false); } Commands.Monitor_Ping.Reply reply = DebugEngine.GetConnectionSource(); if (reply == null) { throw new NanoFrameworkDeviceNoResponseException(); } // only execute if we are talking to the nanoBooter, otherwise reboot if (reply.m_source == Commands.Monitor_Ping.c_Ping_Source_NanoBooter) { return(DebugEngine.ExecuteMemory(entryPoint)); } else // if we are talking to the CLR then we simply did a deployment update, so reboot { DebugEngine.RebootDevice(RebootOptions.ClrOnly); } return(true); }
/// <summary> /// Erases the deployment sectors of the connected .Net Micro Framework device /// </summary> /// <param name="options">Identifies which areas are to be erased</param> /// <param name="cancellationToken">Cancellation token to allow caller to cancel task</param> /// <param name="progress">Progress report of execution</param> /// <returns>Returns false if the erase fails, true otherwise /// Possible exceptions: MFUserExitException, MFDeviceNoResponseException /// </returns> public async Task <bool> EraseAsync(EraseOptions options, CancellationToken cancellationToken, IProgress <ProgressReport> progress = null) { bool ret = false; bool fReset = false; if (DebugEngine == null) { throw new NanoFrameworkDeviceNoResponseException(); } if (!await DebugEngine.ConnectAsync(500, true)) { throw new NanoFrameworkDeviceNoResponseException(); } if (!IsClrDebuggerEnabled || 0 != (options & EraseOptions.Firmware)) { fReset = (Ping() == PingConnectionType.nanoCLR); if (!await ConnectToNanoBooterAsync(cancellationToken)) { throw new NanoBooterConnectionFailureException(); } } var reply = DebugEngine.GetFlashSectorMap(); if (reply == null) { throw new NanoFrameworkDeviceNoResponseException(); } Commands.Monitor_Ping.Reply ping = DebugEngine.GetConnectionSource(); ret = true; long total = 0; long value = 0; bool isConnectedToCLR = ((ping != null) && (ping.m_source == Commands.Monitor_Ping.c_Ping_Source_NanoCLR)); if (isConnectedToCLR) { DebugEngine.PauseExecution(); } List <Commands.Monitor_FlashSectorMap.FlashSectorData> eraseSectors = new List <Commands.Monitor_FlashSectorMap.FlashSectorData>(); foreach (Commands.Monitor_FlashSectorMap.FlashSectorData flashSectorData in reply) { if (cancellationToken.IsCancellationRequested) { throw new NanoUserExitException(); } switch (flashSectorData.m_flags & Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK) { case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOYMENT: if (EraseOptions.Deployment == (options & EraseOptions.Deployment)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_UPDATE: if (EraseOptions.UpdateStorage == (options & EraseOptions.UpdateStorage)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_SIMPLE_A: case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_SIMPLE_B: if (EraseOptions.SimpleStorage == (options & EraseOptions.SimpleStorage)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_A: case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_B: if (EraseOptions.UserStorage == (options & EraseOptions.UserStorage)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_FS: if (EraseOptions.FileSystem == (options & EraseOptions.FileSystem)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CONFIG: if (EraseOptions.Configuration == (options & EraseOptions.Configuration)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CODE: if (EraseOptions.Firmware == (options & EraseOptions.Firmware)) { eraseSectors.Add(flashSectorData); total++; } break; } } foreach (Commands.Monitor_FlashSectorMap.FlashSectorData flashSectorData in eraseSectors) { progress?.Report(new ProgressReport(value, total, string.Format("Erasing sector 0x{0:x08}", flashSectorData.m_StartAddress))); var eraseResult = DebugEngine.EraseMemory(flashSectorData.m_StartAddress, (flashSectorData.m_NumBlocks * flashSectorData.m_BytesPerBlock)); ret &= eraseResult.Success; value++; } // reset if we specifically entered nanoBooter to erase if (fReset) { DebugEngine.ExecuteMemory(0); } // reboot if we are talking to the CLR if (isConnectedToCLR) { progress?.Report(new ProgressReport(0, 0, "Rebooting...")); var rebootOptions = RebootOptions.ClrOnly; // if we've just erase the deployment area there is no more app so the execution engine can't be gracefully stopped if ((options & EraseOptions.Deployment) == EraseOptions.Deployment) { rebootOptions |= RebootOptions.NoShutdown; } DebugEngine.RebootDevice(rebootOptions); } return(ret); }
/// <summary> /// Attempt to establish a connection with nanoBooter (with reboot if necessary) /// </summary> /// <returns>true connection was made, false otherwise</returns> public async Task <bool> ConnectToNanoBooterAsync(CancellationToken cancellationToken) { bool ret = false; if (!await DebugEngine.ConnectAsync(1000, true)) { return(false); } if (DebugEngine != null) { if (DebugEngine.ConnectionSource == ConnectionSource.nanoBooter) { return(true); } DebugEngine.RebootDevice(RebootOptions.EnterBootloader); ///////////////////////////////////////// // FIXME ///////////////////////////////////////// //// nanoBooter is only com port so //if (Transport == TransportType.TcpIp) //{ // _DBG.PortDefinition pdTmp = m_port; // Disconnect(); // try // { // m_port = m_portNanoBooter; // // digi takes forever to reset // if (!Connect(60000, true)) // { // Console.WriteLine(Properties.Resources.ErrorUnableToConnectToNanoBooterSerial); // return false; // } // } // finally // { // m_port = pdTmp; // } //} bool fConnected = false; for (int i = 0; i < 40; i++) { // check if cancellation was requested if (cancellationToken.IsCancellationRequested) { return(false); } if (fConnected = await DebugEngine.ConnectAsync(1000, true, ConnectionSource.Unknown)) { Commands.Monitor_Ping.Reply reply = DebugEngine.GetConnectionSource(); ret = (reply.m_source == Commands.Monitor_Ping.c_Ping_Source_NanoBooter); break; } } if (!fConnected) { //Debug.WriteLine("Unable to connect to NanoBooter"); } } return(ret); }
/// <summary> /// Erases the deployment sectors of the connected .Net Micro Framework device /// </summary> /// <param name="options">Identifies which areas are to be erased</param> /// <param name="cancellationToken">Cancellation token to allow caller to cancel task</param> /// <param name="progress">Progress report of execution</param> /// <returns>Returns false if the erase fails, true otherwise /// Possible exceptions: MFUserExitException, MFDeviceNoResponseException /// </returns> public async Task <bool> EraseAsync(EraseOptions options, CancellationToken cancellationToken, IProgress <ProgressReport> progress = null) { bool ret = false; bool fReset = false; if (DebugEngine == null) { throw new MFDeviceNoResponseException(); } if (!await DebugEngine.ConnectAsync(2, 500, true)) { throw new MFDeviceNoResponseException(); } if (!IsClrDebuggerEnabled || 0 != (options & EraseOptions.Firmware)) { fReset = (await PingAsync() == PingConnectionType.TinyCLR); if (!await ConnectToTinyBooterAsync(cancellationToken)) { throw new MFTinyBooterConnectionFailureException(); } } var reply = await DebugEngine.GetFlashSectorMapAsync(); if (reply == null) { throw new MFDeviceNoResponseException(); } Commands.Monitor_Ping.Reply ping = await DebugEngine.GetConnectionSourceAsync(); ret = true; long total = 0; long value = 0; bool isConnectedToCLR = ((ping != null) && (ping.m_source == Commands.Monitor_Ping.c_Ping_Source_TinyCLR)); if (isConnectedToCLR) { await DebugEngine.PauseExecutionAsync(); } List <Commands.Monitor_FlashSectorMap.FlashSectorData> eraseSectors = new List <Commands.Monitor_FlashSectorMap.FlashSectorData>(); foreach (Commands.Monitor_FlashSectorMap.FlashSectorData flashSectorData in reply) { if (cancellationToken.IsCancellationRequested) { throw new MFUserExitException(); } switch (flashSectorData.m_flags & Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK) { case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOYMENT: if (EraseOptions.Deployment == (options & EraseOptions.Deployment)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_UPDATE: if (EraseOptions.UpdateStorage == (options & EraseOptions.UpdateStorage)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_SIMPLE_A: case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_SIMPLE_B: if (EraseOptions.SimpleStorage == (options & EraseOptions.SimpleStorage)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_A: case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_B: if (EraseOptions.UserStorage == (options & EraseOptions.UserStorage)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_FS: if (EraseOptions.FileSystem == (options & EraseOptions.FileSystem)) { eraseSectors.Add(flashSectorData); total++; } break; case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CONFIG: case Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CODE: if (EraseOptions.Firmware == (options & EraseOptions.Firmware)) { eraseSectors.Add(flashSectorData); total++; } break; } } foreach (Commands.Monitor_FlashSectorMap.FlashSectorData flashSectorData in eraseSectors) { progress?.Report(new ProgressReport(value, total, string.Format("Erasing sector 0x{0:x08}", flashSectorData.m_address))); ret &= await DebugEngine.EraseMemoryAsync(flashSectorData.m_address, flashSectorData.m_size); value++; } // reset if we specifically entered tinybooter for the erase if (fReset) { await DebugEngine.ExecuteMemoryAsync(0); } // reboot if we are talking to the clr if (isConnectedToCLR) { progress?.Report(new ProgressReport(0, 0, "Rebooting...")); await DebugEngine.RebootDeviceAsync(RebootOption.RebootClrOnly); } return(ret); }
public async Task <bool> ProcessMessage(IncomingMessage msg, bool fReply, CancellationToken cancellationToken) { msg.Payload = Commands.ResolveCommandToPayload(msg.Header.Cmd, fReply, _parent.Capabilities); if (fReply == true) { Request reply = null; if (request.MatchesReply(msg)) { reply = request; // FIXME: check if this return can happen here without the QueueNotify call bellow return(true); } else if (reply != null) { // FIXME reply.Signal(msg); return(true); } } else { Packet bp = msg.Header; switch (bp.Cmd) { case Commands.c_Monitor_Ping: { Commands.Monitor_Ping.Reply cmdReply = new Commands.Monitor_Ping.Reply(); cmdReply.m_source = Commands.Monitor_Ping.c_Ping_Source_Host; // FIXME //cmdReply.m_dbg_flags = (m_stopDebuggerOnConnect ? Commands.Monitor_Ping.c_Ping_DbgFlag_Stop : 0); await msg.ReplyAsync(_parent.CreateConverter(), Flags.c_NonCritical, cmdReply, cancellationToken); //m_evtPing.Set(); return(true); } case Commands.c_Monitor_Message: { Commands.Monitor_Message payload = msg.Payload as Commands.Monitor_Message; Debug.Assert(payload != null); if (payload != null) { // FIXME //QueueNotify(m_eventMessage, msg, payload.ToString()); } return(true); } case Commands.c_Debugging_Messaging_Query: case Commands.c_Debugging_Messaging_Reply: case Commands.c_Debugging_Messaging_Send: { Debug.Assert(msg.Payload != null); if (msg.Payload != null) { // FIXME //QueueRpc(msg); } return(true); } } } // FIXME //if (m_eventCommand != null) //{ // QueueNotify(m_eventCommand, msg, fReply); // return true; //} return(false); }