public override void OnAction(IMFDeployForm form, MFDevice device) { _DBG.Engine engine = device.DbgEngine; if (device.ConnectToTinyBooter()) { // ExecuteMemory at address 0 performs an enumerate and execute, which // will clear the bootloader entry flag engine.ExecuteMemory(0); } else { form.DumpToOutput("Unable to connect to TinyBooter!"); } }
/// <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); }
// Write the concatonated header and configuration data to the Flash config sector private void WriteConfig(string configName, byte[] data, bool staticSize, bool updateConfigSector) { _DBG.Engine engine = m_device.DbgEngine; if (!m_init) { InitializeConfigData(); } // updating the config if (m_cfgHash.ContainsKey(configName)) { ConfigIndexData cid = (ConfigIndexData)m_cfgHash[configName]; // If old and new data are different sizes if (cid.Size != data.Length) { // If data comes from a well defined structure, its size cannot vary if (staticSize) { throw new MFInvalidConfigurationDataException(); } uint newNextIndex, oldNextIndex; byte[] temp; int diff = 0; // Figure out where any following configuration data will start newNextIndex = (uint)(cid.Index + data.Length); while (0 != (newNextIndex % 4)) { newNextIndex++; // Force a 4 byte boundary } // Figure out where any following configuration data previously started oldNextIndex = (uint)(cid.Index + cid.Size); while (0 != (oldNextIndex % 4)) { oldNextIndex++; // Force a 4 byte boundary } diff = (int)newNextIndex - (int)oldNextIndex; // Find the adjusted difference in size between old and new config data temp = new byte[m_lastCfgIndex + diff]; // Create a new byte array to contain all the configuration data Array.Copy(m_all_cfg_data, temp, cid.Index); // Copy all preceding data to new array Array.Copy(data, 0, temp, cid.Index, data.Length); // Copy new configuration to new array if (oldNextIndex < m_lastCfgIndex) // Copy all following data (if it exists) to new array { Array.Copy(m_all_cfg_data, oldNextIndex, temp, newNextIndex, (m_all_cfg_data.Length - oldNextIndex)); } // Update the local copy of the configuration list m_all_cfg_data = temp; m_lastCfgIndex += diff; } else { // Copy the new configuration data on top of the old Array.Copy(data, 0, m_all_cfg_data, cid.Index, data.Length); } } else // adding a new configuration to the end of the current list { uint newLastIndex; if (m_lastCfgIndex == -1) { throw new MFConfigurationSectorOutOfMemoryException(); } // Find the new size of the whole configuration list newLastIndex = (uint)(m_lastCfgIndex + data.Length); while (0 != (newLastIndex % 4)) { newLastIndex++; // Force a 4 byte boundary } byte[] temp = new byte[m_lastCfgIndex >= m_all_cfg_data.Length ? m_lastCfgIndex + data.Length : m_all_cfg_data.Length]; Array.Copy(m_all_cfg_data, 0, temp, 0, m_all_cfg_data.Length); Array.Copy(data, 0, temp, m_lastCfgIndex, data.Length); // Update the local copy of the configuration list m_all_cfg_data = temp; m_lastCfgIndex = (int)newLastIndex; } if (!updateConfigSector) { return; } // Rewrite entire configuration list to Flash if (!engine.EraseMemory(m_cfg_sector.m_address, (uint)m_all_cfg_data.Length)) { throw new MFConfigSectorEraseFailureException(); } if (!engine.WriteMemory(m_cfg_sector.m_address, m_all_cfg_data)) { throw new MFConfigSectorWriteFailureException(); } // Rebuild hash table m_cfgHash.Clear(); uint hal_config_block_size = 0; unsafe { hal_config_block_size = (uint)sizeof(HAL_CONFIG_BLOCK); } int index = (int)m_StaticConfig.ConfigurationLength; byte[] headerData = new byte[hal_config_block_size]; HAL_CONFIG_BLOCK cfg_header; while (index < m_lastCfgIndex) { // Read in next configuration header Array.Copy(m_all_cfg_data, index, headerData, 0, hal_config_block_size); cfg_header = (HAL_CONFIG_BLOCK)UnmarshalData(headerData, typeof(HAL_CONFIG_BLOCK)); m_cfgHash[cfg_header.DriverNameString] = new ConfigIndexData(index, (int)(cfg_header.Size + hal_config_block_size)); // Index of next configuration header must lie on a 4 byte boundary index += (int)(cfg_header.Size + hal_config_block_size); while (0 != (index % 4)) { index++; // Force a 4 byte boundary } } // we need to perform signature check regardless of key update, in order for the device to write from ram buffer to flash if (!engine.CheckSignature(new byte[TINYBOOTER_KEY_CONFIG.c_KeySignatureLength], 0)) { if (engine.ConnectionSource == Microsoft.SPOT.Debugger.ConnectionSource.TinyBooter) { throw new MFConfigSectorWriteFailureException(); } } if (engine.ConnectionSource == Microsoft.SPOT.Debugger.ConnectionSource.TinyBooter && m_fRestartClr) { engine.ExecuteMemory(c_EnumerateAndLaunchAddr); } }
private void UploadWithTinyBooter() { m_eng.OnNoise -= new _DBG.NoiseEventHandler(OnNoise); foreach (_DBG.SRecordFile.Block bl in m_blocks) { long offset = 0; uint location = bl.address; byte[] buf = bl.data.ToArray(); long count = bl.data.Length; OnProgress(bl, (int)offset, false); byte[] chunk = new byte[4096]; while (count != 0) { long length = System.Math.Min(4096, count); if (length != 4096) { chunk = new byte[length]; } Array.Copy(buf, offset, chunk, 0, length); if (!m_eng.WriteMemory(location, chunk)) { return; } location += (uint)length; offset += length; count -= length; OnProgress(bl, (int)offset, false); } if (!m_eng.CheckSignature(bl.signature, 0)) { this.NewText("Check Signature failed!"); return; } OnProgress(bl, (int)count, true); } uint address = uint.MaxValue; foreach (_DBG.SRecordFile.Block bl in m_blocks) { if (bl.executable) { address = bl.address; } } if (address != uint.MaxValue) { m_eng.ExecuteMemory(address); } m_eng.OnNoise += new _DBG.NoiseEventHandler(OnNoise); if (m_fDisconnect) { this.Invoke(new Callback_Bool(this.StartOrStop), new object[] { false }); } }