internal void CreateDeploymentData(BackgroundWorker backgroundWorker, DoWorkEventArgs doWorkEventArgs) { MFDevice device = doWorkEventArgs.Argument as MFDevice; _DBG.Engine eng = device.DbgEngine; Commands.Monitor_FlashSectorMap.Reply flashMap = eng.GetFlashSectorMap(); //find deployment sectors. uint addressStart = 0; uint cBytes = 0; //First, find out where the deployment sectors are for (int iSector = flashMap.m_map.Length - 1; iSector >= 0; iSector--) { Commands.Monitor_FlashSectorMap.FlashSectorData flashSectorData = flashMap.m_map[iSector]; if ((flashSectorData.m_flags & Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK) == Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOYMENT) { addressStart = flashSectorData.m_address; cBytes += flashSectorData.m_size; } } if (cBytes == 0) { throw new ApplicationException("Could not find deployment sectorsd"); } byte[] deploymentData = new byte[cBytes]; //Read deployment data if (!CreateDeploymentReadHelper(backgroundWorker, doWorkEventArgs, eng, addressStart, deploymentData)) { return; } //create deployment stream MemoryStream deploymentStream = new MemoryStream(); deploymentStream.Write(deploymentData, 0, deploymentData.Length); //convert to srec MFApplicationDeploymentData data = new MFApplicationDeploymentData(); MemoryStream streamSrec = new MemoryStream(); data.BinaryData = deploymentData; deploymentStream.Seek(0, SeekOrigin.Begin); new BinToSrec().DoConversion(deploymentStream, streamSrec, addressStart); //Get bytes long pos = streamSrec.Seek(0, SeekOrigin.Current); data.HexData = new byte[(int)pos]; streamSrec.Seek(0, SeekOrigin.Begin); streamSrec.Read(data.HexData, 0, (int)pos); doWorkEventArgs.Result = data; }
private void PrepareForDeploy(ArrayList blocks) { const uint c_DeploySector = _WP.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOYMENT; const uint c_SectorUsageMask = _WP.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK; bool fEraseDeployment = false; // if vsdebug is not enabled then we cannot write/erase if (!IsClrDebuggerEnabled()) { if (OnProgress != null) { OnProgress(0, 1, Properties.Resources.StatusConnectingToTinyBooter); } // only check for signature file if we are uploading firmware if (!ConnectToTinyBooter()) { throw new MFDeviceNoResponseException(); } } _WP.Commands.Monitor_FlashSectorMap.Reply map = m_eng.GetFlashSectorMap(); if (map == null) { throw new MFDeviceNoResponseException(); } foreach (_DBG.SRecordFile.Block bl in blocks) { foreach (_WP.Commands.Monitor_FlashSectorMap.FlashSectorData sector in map.m_map) { if (sector.m_address == 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 (m_eng.ConnectionSource != _DBG.ConnectionSource.TinyBooter) { if (OnProgress != null) { OnProgress(0, 1, Properties.Resources.StatusConnectingToTinyBooter); } // only check for signature file if we are uploading firmware if (!ConnectToTinyBooter()) { throw new MFDeviceNoResponseException(); } } } break; } } } if (fEraseDeployment) { this.Erase(EraseOptions.Deployment); } else if (m_eng.ConnectionSource != _DBG.ConnectionSource.TinyBooter) { //if we are not writing to the deployment sector then assure that we are talking with TinyBooter ConnectToTinyBooter(); } if (m_eng.ConnectionSource == _DBG.ConnectionSource.TinyCLR) { m_eng.PauseExecution(); } }
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; } } } }
internal void CreateDeploymentData(BackgroundWorker backgroundWorker, DoWorkEventArgs doWorkEventArgs) { MFDevice device = doWorkEventArgs.Argument as MFDevice; _DBG.Engine eng = device.DbgEngine; Commands.Monitor_FlashSectorMap.Reply flashMap = eng.GetFlashSectorMap(); //find deployment sectors. MemoryStream deploymentStream = new MemoryStream(); //this duplicates LoadDeploymentAssemblies logic, as how to find assemblies in the deployment sectors int iSectorStart = -1, iSectorEnd = 0; uint address, addressAssemblyStart, addressStart = 0, addressEnd = 0; int iSector; //First, find out where the deployment sectors are for (iSector = 0; iSector < flashMap.m_map.Length; iSector++) { Commands.Monitor_FlashSectorMap.FlashSectorData flashSectorData = flashMap.m_map[iSector]; if ((flashSectorData.m_flags & Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK) == Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOYMENT) { if (iSectorStart < 0) { iSectorStart = iSector; addressStart = flashSectorData.m_address; } iSectorEnd = iSector; addressEnd = flashSectorData.m_address + flashSectorData.m_size; } } if (iSectorStart < 0) { throw new ApplicationException("Could not find deployment sectors"); } address = addressStart; iSector = iSectorStart; while (true) { if (backgroundWorker.WorkerReportsProgress) { int progress = (int)(100.0 * (double)address / (double)addressEnd); backgroundWorker.ReportProgress(progress); } //read assembly header uint assemblyHeaderSize = (uint)Marshal.SizeOf(typeof(CLR_RECORD_ASSEMBLY)); byte[] assemblyHeaderBytes = null; byte[] assemblyDataBytes = null; if (address + assemblyHeaderSize >= addressEnd) { break; } addressAssemblyStart = address; if (!CreateDeploymentReadHelper(backgroundWorker, doWorkEventArgs, eng, ref address, addressStart, addressEnd, assemblyHeaderSize, out assemblyHeaderBytes)) { return; } GCHandle gch = GCHandle.Alloc(assemblyHeaderBytes, GCHandleType.Pinned); CLR_RECORD_ASSEMBLY assemblyHeader = (CLR_RECORD_ASSEMBLY)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(CLR_RECORD_ASSEMBLY)); gch.Free(); //check if valid header //check marker bool fValidAssembly = assemblyHeader.marker == CLR_RECORD_ASSEMBLY.MARKER_ASSEMBLY_V1; if (fValidAssembly) { //check header crc uint crcHeader = assemblyHeader.headerCRC; //clear headerCRC int headerCRCOffset = 8; int headerCRCSize = 4; Array.Clear(assemblyHeaderBytes, headerCRCOffset, headerCRCSize); uint crc = _DBG.CRC.ComputeCRC(assemblyHeaderBytes, 0); //Reset headerCRC Array.Copy(BitConverter.GetBytes(crcHeader), 0, assemblyHeaderBytes, headerCRCOffset, headerCRCSize); fValidAssembly = (crcHeader == crc); } if (fValidAssembly) { uint assemblyTotalSize = assemblyHeader.startOfTables[CLR_RECORD_ASSEMBLY.TBL_EndOfAssembly]; uint assemblyDataSize = assemblyTotalSize - assemblyHeaderSize; if (address + assemblyDataSize >= addressEnd) { break; } //read body if (!CreateDeploymentReadHelper(backgroundWorker, doWorkEventArgs, eng, ref address, addressStart, addressEnd, assemblyDataSize, out assemblyDataBytes)) { return; } //check if valid body (crc) uint crc = _DBG.CRC.ComputeCRC(assemblyDataBytes, 0); fValidAssembly = (crc == assemblyHeader.assemblyCRC); } if (fValidAssembly) { // add to compact stream deploymentStream.Write(assemblyHeaderBytes, 0, assemblyHeaderBytes.Length); deploymentStream.Write(assemblyDataBytes, 0, assemblyDataBytes.Length); // make sure we are on 4 byte boundary if (0 != (address % sizeof(UInt32))) { byte[] buff = new byte[sizeof(UInt32) - (address % sizeof(UInt32))]; deploymentStream.Write(buff, 0, buff.Length); address += sizeof(UInt32) - (address % sizeof(UInt32)); } } else { //if no, clear assemblyData, jump to next sector (if in middle of sector), or finish (if at beginning of sector) while (iSector < iSectorEnd) { Commands.Monitor_FlashSectorMap.FlashSectorData flashSectorData = flashMap.m_map[iSector]; if (addressAssemblyStart >= flashSectorData.m_address && addressAssemblyStart < flashSectorData.m_address + flashSectorData.m_size) { // jump to next sector address = flashSectorData.m_address + flashSectorData.m_size; System.Diagnostics.Debug.Assert(address == flashMap.m_map[iSector + 1].m_address); break; } iSector++; } } } //Finished reading //convert to srec MFApplicationDeploymentData data = new MFApplicationDeploymentData(); long deploymentLength = deploymentStream.Seek(0, SeekOrigin.Current); MemoryStream streamSrec = new MemoryStream(); deploymentStream.Seek(0, SeekOrigin.Begin); data.BinaryData = new byte[(int)deploymentLength]; deploymentStream.Read(data.BinaryData, 0, (int)deploymentLength); deploymentStream.Seek(0, SeekOrigin.Begin); new BinToSrec().DoConversion(deploymentStream, streamSrec, flashMap.m_map[iSectorStart].m_address); //add zero bytes to all other deployment sectors? //Get bytes long pos = streamSrec.Seek(0, SeekOrigin.Current); data.HexData = new byte[pos]; streamSrec.Seek(0, SeekOrigin.Begin); streamSrec.Read(data.HexData, 0, (int)pos); doWorkEventArgs.Result = data; }
// Initialize the internal structures. private void InitializeConfigData() { uint hal_config_block_size = 0; uint hal_config_static_size = 0; int index = 0; unsafe { hal_config_block_size = (uint)sizeof(HAL_CONFIG_BLOCK); hal_config_static_size = (uint)sizeof(HAL_CONFIGURATION_SECTOR) - hal_config_block_size; } m_cfg_sector.m_address = uint.MaxValue; m_cfg_sector.m_size = 0; _DBG.Engine engine = m_device.DbgEngine; if (!engine.TryToConnect(10, 100, true, Microsoft.SPOT.Debugger.ConnectionSource.Unknown)) { throw new MFDeviceNoResponseException(); } if (m_device.DbgEngine.PortDefinition is _DBG.PortDefinition_Tcp) { m_device.UpgradeToSsl(); } _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.Reply reply = engine.GetFlashSectorMap(); // Find the config sector foreach (_DBG.WireProtocol.Commands.Monitor_FlashSectorMap.FlashSectorData fsd in reply.m_map) { const uint usage_mask = _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK; const uint usage_cfg = _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CONFIG; if (usage_cfg == (fsd.m_flags & usage_mask)) { m_cfg_sector = fsd; break; } } // read in the configuration data if the config sector was found if (m_cfg_sector.m_address != uint.MaxValue) { int hal_static_cfg_size = 0; unsafe { hal_static_cfg_size = sizeof(HAL_CONFIGURATION_SECTOR); } // read in the static portion of the config sector engine.ReadMemory(m_cfg_sector.m_address, (uint)hal_static_cfg_size, out m_all_cfg_data); m_StaticConfig = (HAL_CONFIGURATION_SECTOR)UnmarshalData(m_all_cfg_data, typeof(HAL_CONFIGURATION_SECTOR)); // uninitialized config sector, lets try to fix it if (m_StaticConfig.ConfigurationLength == 0xFFFFFFFF) { m_StaticConfig.ConfigurationLength = (uint)hal_static_cfg_size; m_StaticConfig.Version.Major = 3; m_StaticConfig.Version.Minor = 0; m_StaticConfig.Version.Extra = 0; m_StaticConfig.Version.TinyBooter = 4; } if (m_StaticConfig.ConfigurationLength >= m_cfg_sector.m_size) { throw new MFInvalidConfigurationSectorException(); } if (m_StaticConfig.Version.TinyBooter == 4) { m_fStaticCfgOK = true; } else { m_fStaticCfgOK = (m_StaticConfig.ConfigurationLength != hal_config_static_size); } // determine if we have a new or old version of the config (security keys are only supported in the new version) m_fValidConfig = (m_StaticConfig.Version.TinyBooter == CONFIG_SECTOR_VERSION.c_CurrentTinyBooterVersion); if (m_fStaticCfgOK) { m_firmwareKeyLocked = CheckKeyLocked(m_StaticConfig, true); m_deployKeyLocked = CheckKeyLocked(m_StaticConfig, false); } // move to the dynamic configuration section index = (int)m_StaticConfig.ConfigurationLength; m_lastCfgIndex = index; while (true) { byte[] data; // read the next configuration block engine.ReadMemory((uint)(m_cfg_sector.m_address + index), hal_config_block_size, out data); HAL_CONFIG_BLOCK cfg_header = (HAL_CONFIG_BLOCK)UnmarshalData(data, typeof(HAL_CONFIG_BLOCK)); // out of memory or last record if (cfg_header.Size > m_cfg_sector.m_size) { // last record or bogus entry m_lastCfgIndex = index; // save the configuration data for later use m_all_cfg_data = new byte[m_lastCfgIndex]; int idx = 0; byte[] tmp; while (idx < index) { int size = 512; if ((index - idx) < size) { size = index - idx; } engine.ReadMemory((uint)(m_cfg_sector.m_address + idx), (uint)size, out tmp); Array.Copy(tmp, 0, m_all_cfg_data, idx, tmp.Length); idx += size; } break; // no more configs } // move to the next configuration block if (cfg_header.Size + hal_config_block_size + index > m_cfg_sector.m_size) { // end of config sector break; } m_cfgHash[cfg_header.DriverNameString] = new ConfigIndexData(index, (int)(cfg_header.Size + hal_config_block_size)); index += (int)(cfg_header.Size + hal_config_block_size); while (0 != (index % 4)) { index++; } } } m_init = true; }
public override void OnAction(IMFDeployForm form, MFDevice device) { if (form == null || device == null) { return; } _DBG.Engine engine = device.DbgEngine; _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.Reply reply = engine.GetFlashSectorMap(); if (reply != null) { form.DumpToOutput(" Sector Start Size Usage"); form.DumpToOutput("-----------------------------------------------"); for (int i = 0; i < reply.m_map.Length; i++) { _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.FlashSectorData fsd = reply.m_map[i]; string usage = ""; 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_CODE: usage = "Code"; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CONFIG: usage = "Configuration"; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOYMENT: usage = "Deployment"; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_UPDATE: usage = "Update Storage"; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_FS: usage = "File System"; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_SIMPLE_A: usage = "Simple Storage (A)"; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_SIMPLE_B: usage = "Simple Storage (B)"; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_A: usage = "EWR Storage (A)"; break; case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_B: usage = "EWR Storage (B)"; break; } form.DumpToOutput(string.Format("{0,5} {1,12}{2,12} {3}", i, string.Format("0x{0:x08}", fsd.m_address), string.Format("0x{0:x08}", fsd.m_size), usage)); } } }
private void buttonEraseDeployment_Click(object sender, EventArgs e) { bool bWasStarted = EnsureDebuggerConnection(); Cursor old = Cursor.Current; Cursor = Cursors.WaitCursor; buttonEraseDeployment.Text = "Erasing..."; buttonEraseDeployment.Update(); NewText("Erasing Deployment Sector...\r\n"); try { _DBG.WireProtocol.Commands.Monitor_Ping.Reply ping = m_eng.GetConnectionSource(); if (ping == null) { NewText("Unable to connect to device\r\n"); return; } bool fClrConnection = ping.m_source == _DBG.WireProtocol.Commands.Monitor_Ping.c_Ping_Source_TinyCLR; if (fClrConnection) { m_eng.PauseExecution(); } _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.Reply status = m_eng.GetFlashSectorMap() as _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.Reply; if (status == null) { NewText("Erase Deployment may Not be supported on this device build\r\n"); } else { const uint c_deployFlag = _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOYMENT; const uint c_usageMask = _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK; foreach (_DBG.WireProtocol.Commands.Monitor_FlashSectorMap.FlashSectorData sector in status.m_map) { if (c_deployFlag == (c_usageMask & sector.m_flags)) { NewText(string.Format("Erasing sector at 0x{0:x08}\r\n", sector.m_address)); m_eng.EraseMemory(sector.m_address, sector.m_size); } } if (fClrConnection) { m_eng.RebootDevice(_DBG.Engine.RebootOption.RebootClrOnly); } NewText("Erase Deployment Successfull"); } } catch (Exception ex) { NewText("Exception: " + ex.Message + "\r\n"); } finally { buttonEraseDeployment.Text = "Erase Deployment"; Cursor = old; if (!bWasStarted) { m_eng.Stop(); m_eng = null; } } }