/// <summary> /// Erases the deployment sectors of the connected .Net Micro Framework device /// </summary> /// <param name="options">Identifies which areas are to be erased, if no options are given, all /// user sectors will be erased. /// </param> /// <returns>Returns false if the erase fails, true otherwise /// Possible exceptions: MFUserExitException, MFDeviceNoResponseException /// </returns> public bool Erase(params EraseOptions[] options) { bool ret = false; bool fReset = false; if (m_eng == null) { throw new MFDeviceNoResponseException(); } EraseOptions optionFlags = 0; if (options == null || options.Length == 0) { optionFlags = (EraseOptions.Deployment | EraseOptions.FileSystem | EraseOptions.UserStorage); } else { foreach (EraseOptions opt in options) { optionFlags |= opt; } } if (!m_eng.TryToConnect(5, 100, true, _DBG.ConnectionSource.Unknown)) { throw new MFDeviceNoResponseException(); } if (!IsClrDebuggerEnabled()) { fReset = (Ping() == PingConnectionType.TinyCLR); ConnectToTinyBooter(); } _WP.Commands.Monitor_FlashSectorMap.Reply reply = m_eng.GetFlashSectorMap(); if (reply == null) { throw new MFDeviceNoResponseException(); } _WP.Commands.Monitor_Ping.Reply ping = m_eng.GetConnectionSource(); ret = true; long total = 0; long value = 0; bool isConnectedToCLR = ((ping != null) && (ping.m_source == _WP.Commands.Monitor_Ping.c_Ping_Source_TinyCLR)); if (isConnectedToCLR) { m_eng.PauseExecution(); } List <_WP.Commands.Monitor_FlashSectorMap.FlashSectorData> eraseSectors = new List <_WP.Commands.Monitor_FlashSectorMap.FlashSectorData>(); foreach (_WP.Commands.Monitor_FlashSectorMap.FlashSectorData fsd in reply.m_map) { if (EventCancel.WaitOne(0, false)) { throw new MFUserExitException(); } switch (fsd.m_flags & _WP.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK) { case _WP.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOYMENT: if (EraseOptions.Deployment == (optionFlags & EraseOptions.Deployment)) { eraseSectors.Add(fsd); total++; } break; case _WP.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_A: case _WP.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_B: if (EraseOptions.UserStorage == (optionFlags & EraseOptions.UserStorage)) { eraseSectors.Add(fsd); total++; } break; case _WP.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_FS: if (EraseOptions.FileSystem == (optionFlags & EraseOptions.FileSystem)) { eraseSectors.Add(fsd); total++; } break; } } foreach (_WP.Commands.Monitor_FlashSectorMap.FlashSectorData fsd in eraseSectors) { ret &= m_eng.EraseMemory(fsd.m_address, fsd.m_size); value++; if (OnProgress != null) { OnProgress(value, total, string.Format(Properties.Resources.StatusEraseSector, fsd.m_address)); } } // reset if we specifically entered tinybooter for the erase if (fReset) { m_eng.ExecuteMemory(0); } // reboot if we are talking to the clr if (isConnectedToCLR) { if (OnProgress != null) { OnProgress(0, 0, Properties.Resources.StatusRebooting); } m_eng.RebootDevice(_DBG.Engine.RebootOption.RebootClrOnly); m_eng.ResumeExecution(); } return(ret); }
private void EraseDialog_Load(object sender, EventArgs e) { _DBG.Engine engine = m_device.DbgEngine; _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.Reply reply = engine.GetFlashSectorMap(); if (reply != null) { Dictionary <EraseOptions, _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.FlashSectorData> hashBlockType = new Dictionary <EraseOptions, _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.FlashSectorData>(); Dictionary <EraseOptions, string> usageNameHash = new Dictionary <EraseOptions, string>(); for (int i = 0; i < reply.m_map.Length; i++) { _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.FlashSectorData fsd = reply.m_map[i]; string usage = ""; EraseOptions eo = (EraseOptions)(-1); switch (fsd.m_flags & _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK) { case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_BOOTSTRAP: //usage = "Bootstrap"; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CONFIG: case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CODE: if (m_device.DbgEngine.ConnectionSource == _DBG.ConnectionSource.TinyBooter) { usage = "Firmware"; eo = EraseOptions.Firmware; } break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOYMENT: usage = "Deployment"; eo = EraseOptions.Deployment; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_UPDATE: usage = "Update Storage"; eo = EraseOptions.UpdateStorage; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_FS: usage = "File System"; eo = EraseOptions.FileSystem; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_SIMPLE_B: case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_SIMPLE_A: usage = "Simple Storage"; eo = EraseOptions.SimpleStorage; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_A: case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_B: usage = "User Storage"; eo = EraseOptions.UserStorage; break; } if (eo != (EraseOptions)(-1)) { if (hashBlockType.ContainsKey(eo)) { _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.FlashSectorData prev = hashBlockType[eo]; if (prev.m_address + prev.m_size == fsd.m_address) { prev.m_size += fsd.m_size; hashBlockType[eo] = prev; } } else { hashBlockType[eo] = fsd; usageNameHash[eo] = usage; } } } foreach (EraseOptions eo in hashBlockType.Keys) { ListViewItem lvi = listViewEraseSectors.Items.Add(new ListViewItem(new string[] { usageNameHash[eo], string.Format("0x{0:X08}", hashBlockType[eo].m_address), string.Format("0x{0:X08}", hashBlockType[eo].m_size) })); lvi.Tag = eo; if (eo != EraseOptions.Firmware) { lvi.Checked = 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> /// 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); }