コード例 #1
0
        /// <summary>
        /// Attempts to deploy an SREC (.hex) file to the connected nanoFramework device.
        /// </summary>
        /// <param name="srecFile">Storage file with the SREC (.hex) file</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 async Task <Tuple <uint, bool> > DeployAsync(StorageFile srecFile, CancellationToken cancellationToken, IProgress <ProgressReport> progress = null)
        {
            uint entryPoint = 0;
            List <SRecordFile.Block> blocks = new List <SRecordFile.Block>();

            if (!srecFile.IsAvailable)
            {
                throw new FileNotFoundException(srecFile.Path);
            }

            if (DebugEngine == null)
            {
                throw new NanoFrameworkDeviceNoResponseException();
            }

            // make sure we know who we are talking to
            if (await CheckForMicroBooterAsync(cancellationToken))
            {
                var reply = await DeploySRECAsync(srecFile, cancellationToken);

                // check if request was successful
                if (reply.Item2)
                {
                    entryPoint = reply.Item1;

                    return(new Tuple <uint, bool>(entryPoint, true));
                }
                else
                {
                    return(new Tuple <uint, bool>(0, false));
                }
            }

            await DebugEngine.ConnectAsync(1000, false, ConnectionSource.Unknown);

            var parseResult = await SRecordFile.ParseAsync(srecFile);

            entryPoint = parseResult.Item1;
            blocks     = parseResult.Item2;

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

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

                await PrepareForDeployAsync(blocks, cancellationToken, progress);



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

                    // check if cancellation was requested
                    if (cancellationToken.IsCancellationRequested)
                    {
                        throw new NanoUserExitException();
                    }

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

                    progress?.Report(new ProgressReport(0, total, string.Format("Erasing sector 0x{0:x08}", block.address)));

                    // the clr requires erase before writing
                    var eraseResult = DebugEngine.EraseMemory(block.address, (uint)len);

                    if (!eraseResult.Success)
                    {
                        return(new Tuple <uint, bool>(0, false));
                    }

                    while (len > 0)
                    {
                        // check if cancellation was requested
                        if (cancellationToken.IsCancellationRequested)
                        {
                            throw new NanoUserExitException();
                        }

                        uint   buflen = len > DebugEngine.WireProtocolPacketSize ? DebugEngine.WireProtocolPacketSize : (uint)len;
                        byte[] data   = new byte[buflen];

                        if (block.data.Read(data, 0, (int)buflen) <= 0)
                        {
                            return(new Tuple <uint, bool>(0, false));
                        }

                        var writeResult = DebugEngine.WriteMemory(addr, data);
                        if (writeResult.Success == false)
                        {
                            return(new Tuple <uint, bool>(0, false));
                        }

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

                        progress?.Report(new ProgressReport(value, total, string.Format("Deploying {0}...", srecFile.Name)));
                    }
                }
            }

            return(new Tuple <uint, bool>(entryPoint, true));
        }
コード例 #2
0
        /// <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);
        }