/// <summary> /// Attempts to communicate with the connected .Net Micro Framework device /// </summary> /// <returns></returns> public async Task <PingConnectionType> PingAsync() { var reply = await DebugEngine.GetConnectionSourceAsync(); if (reply != null) { switch (reply.m_source) { case Commands.Monitor_Ping.c_Ping_Source_TinyCLR: return(PingConnectionType.TinyCLR); case Commands.Monitor_Ping.c_Ping_Source_TinyBooter: return(PingConnectionType.TinyBooter); } } return(PingConnectionType.NoConnection); }
/// <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 MFDeviceNoResponseException(); } if (await CheckForMicroBooterAsync(cancellationToken)) { // check if cancellation was requested if (cancellationToken.IsCancellationRequested) { throw new MFUserExitException(); } 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 MFUserExitException(); } await DebugEngine.SendBufferAsync(UTF8Encoding.UTF8.GetBytes(execRec), cancellationToken); // check if cancellation was requested if (cancellationToken.IsCancellationRequested) { throw new MFUserExitException(); } await DebugEngine.SendBufferAsync(UTF8Encoding.UTF8.GetBytes("\n"), cancellationToken); // check if cancellation was requested if (cancellationToken.IsCancellationRequested) { throw new MFUserExitException(); } if (m_evtMicroBooter.WaitOne(1000)) { fRet = true; break; } } return(fRet); } return(false); } Commands.Monitor_Ping.Reply reply = await DebugEngine.GetConnectionSourceAsync(); if (reply == null) { throw new MFDeviceNoResponseException(); } // only execute if we are talking to the tinyBooter, otherwise reboot if (reply.m_source == Commands.Monitor_Ping.c_Ping_Source_TinyBooter) { return(await DebugEngine.ExecuteMemoryAsync(entryPoint)); } else // if we are talking to the CLR then we simply did a deployment update, so reboot { await DebugEngine.RebootDeviceAsync(RebootOption.RebootClrOnly); } 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 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); }
/// <summary> /// Attempt to establish a connection with TinyBooter (with reboot if necessary) /// </summary> /// <returns>true connection was made, false otherwise</returns> public async Task <bool> ConnectToTinyBooterAsync(CancellationToken cancellationToken) { bool ret = false; if (!await DebugEngine.ConnectAsync(2, 500)) { return(false); } if (DebugEngine != null) { if (DebugEngine.ConnectionSource == ConnectionSource.TinyBooter) { return(true); } await DebugEngine.RebootDeviceAsync(RebootOption.EnterBootloader); ///////////////////////////////////////// // FIXME ///////////////////////////////////////// //// tinyBooter is only com port so //if (Transport == TransportType.TcpIp) //{ // _DBG.PortDefinition pdTmp = m_port; // Disconnect(); // try // { // m_port = m_portTinyBooter; // // digi takes forever to reset // if (!Connect(60000, true)) // { // Console.WriteLine(Properties.Resources.ErrorUnableToConnectToTinyBooterSerial); // 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(1, 1000, true, ConnectionSource.Unknown)) { Commands.Monitor_Ping.Reply reply = await DebugEngine.GetConnectionSourceAsync(); ret = (reply.m_source == Commands.Monitor_Ping.c_Ping_Source_TinyBooter); break; } } if (!fConnected) { Debug.WriteLine("Unable to connect to TinyBooter"); } } return(ret); }