/// <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); }
private async Task PrepareForDeployAsync(List <SRecordFile.Block> blocks, CancellationToken cancellationToken, IProgress <ProgressReport> progress = null) { const uint c_DeploySector = Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOYMENT; const uint c_SectorUsageMask = Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK; bool fEraseDeployment = false; // if vsdebug is not enabled then we cannot write/erase if (!IsClrDebuggerEnabled) { progress?.Report(new ProgressReport(0, 1, "Connecting to TinyBooter...")); // only check for signature file if we are uploading firmware if (!await ConnectToNanoBooterAsync(cancellationToken)) { throw new NanoFrameworkDeviceNoResponseException(); } } var flasSectorsMap = DebugEngine.GetFlashSectorMap(); if (flasSectorsMap == null || flasSectorsMap.Count == 0) { throw new NanoFrameworkDeviceNoResponseException(); } foreach (SRecordFile.Block bl in blocks) { foreach (Commands.Monitor_FlashSectorMap.FlashSectorData sector in flasSectorsMap) { if (sector.m_StartAddress == bl.address) { // only support writing with CLR to the deployment sector and RESERVED sector (for digi) if (c_DeploySector == (c_SectorUsageMask & sector.m_flags)) { fEraseDeployment = true; } else { if (DebugEngine.ConnectionSource != ConnectionSource.nanoBooter) { progress?.Report(new ProgressReport(0, 1, "Connecting to nanoBooter...")); // only check for signature file if we are uploading firmware if (!await ConnectToNanoBooterAsync(cancellationToken)) { throw new NanoFrameworkDeviceNoResponseException(); } } } break; } } } if (fEraseDeployment) { await EraseAsync(EraseOptions.Deployment, cancellationToken, progress); } else if (DebugEngine.ConnectionSource != ConnectionSource.nanoBooter) { //if we are not writing to the deployment sector then assure that we are talking with nanoBooter await ConnectToNanoBooterAsync(cancellationToken); } if (DebugEngine.ConnectionSource == ConnectionSource.nanoCLR) { DebugEngine.PauseExecution(); } }