Exemplo n.º 1
0
        // 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);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Attempts to deploy an SREC (.hex) file to the connected .Net Micro Framework device.  The
        /// signatureFile is used to validate the image once it has been deployed to the device.  If
        /// the signature does not match the image is erased.
        /// </summary>
        /// <param name="filePath">Full path to the SREC (.hex) file</param>
        /// <param name="signatureFile">Full path to the signature file (.sig) for the SREC file identified by the filePath parameter</param>
        /// <param name="entrypoint">Out parameter that is set to the entry point address for the given SREC file</param>
        /// <returns>Returns false if the deployment fails, true otherwise
        /// Possible exceptions: MFFileNotFoundException, MFDeviceNoResponseException, MFUserExitException
        /// </returns>
        public bool Deploy(string filePath, string signatureFile, ref uint entryPoint)
        {
            entryPoint = 0;

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException(filePath);
            }
            if (m_eng == null)
            {
                throw new MFDeviceNoResponseException();
            }

            // make sure we know who we are talking to
            m_eng.TryToConnect(1, 100, true, _DBG.ConnectionSource.Unknown);

            bool     sigExists = File.Exists(signatureFile);
            FileInfo fi        = new FileInfo(filePath);

            ArrayList blocks = new ArrayList();

            entryPoint = _DBG.SRecordFile.Parse(filePath, blocks, sigExists? signatureFile: null);

            if (blocks.Count > 0)
            {
                long total = 0;
                long value = 0;

                for (int i = 0; i < blocks.Count; i++)
                {
                    total += (blocks[i] as _DBG.SRecordFile.Block).data.Length;
                }

                PrepareForDeploy(blocks);

                foreach (_DBG.SRecordFile.Block block in blocks)
                {
                    long len  = block.data.Length;
                    uint addr = block.address;

                    if (EventCancel.WaitOne(0, false))
                    {
                        throw new MFUserExitException();
                    }

                    block.data.Seek(0, SeekOrigin.Begin);

                    if (OnProgress != null)
                    {
                        OnProgress(0, total, string.Format(Properties.Resources.StatusEraseSector, block.address));
                    }

                    // the clr requires erase before writing
                    if (!m_eng.EraseMemory(block.address, (uint)len))
                    {
                        return(false);
                    }

                    while (len > 0)
                    {
                        if (EventCancel.WaitOne(0, false))
                        {
                            throw new MFUserExitException();
                        }

                        int    buflen = len > 1024? 1024: (int)len;
                        byte[] data   = new byte[buflen];

                        if (block.data.Read(data, 0, buflen) <= 0)
                        {
                            return(false);
                        }

                        if (!m_eng.WriteMemory(addr, data))
                        {
                            return(false);
                        }

                        value += buflen;
                        addr  += (uint)buflen;
                        len   -= buflen;

                        if (OnProgress != null)
                        {
                            OnProgress(value, total, string.Format(Properties.Resources.StatusFlashing, fi.Name));
                        }
                    }
                    if (_DBG.ConnectionSource.TinyCLR != m_eng.ConnectionSource)
                    {
                        byte[] emptySig = new byte[128];

                        if (OnProgress != null)
                        {
                            OnProgress(value, total, Properties.Resources.StatusCheckingSignature);
                        }

                        if (!m_eng.CheckSignature(((block.signature == null || block.signature.Length == 0)? emptySig: block.signature), 0))
                        {
                            throw new MFSignatureFailureException(signatureFile);
                        }
                    }
                }
            }

            return(true);
        }
        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 });
            }
        }