Esempio n. 1
0
        internal static async System.Threading.Tasks.Task <ExitCodes> UpdateFirmwareAsync(
            EspTool espTool,
            EspTool.DeviceInfo esp32Device,
            string targetName,
            bool updateFw,
            string fwVersion,
            bool stable,
            string applicationPath,
            string deploymentAddress,
            VerbosityLevel verbosity)
        {
            ExitCodes operationResult = ExitCodes.OK;
            uint      address         = 0;

            // if a target name wasn't specified use the default (and only available) ESP32 target
            if (string.IsNullOrEmpty(targetName))
            {
                targetName = _esp32TargetName;
            }

            Esp32Firmware firmware = new Esp32Firmware(
                targetName,
                fwVersion,
                stable)
            {
                Verbosity = verbosity
            };

            // need to download update package?
            if (updateFw)
            {
                operationResult = await firmware.DownloadAndExtractAsync(esp32Device.FlashSize);

                if (operationResult != ExitCodes.OK)
                {
                    return(operationResult);
                }
                // download successful
            }

            // need to include application file?
            if (!string.IsNullOrEmpty(applicationPath))
            {
                // check application file
                if (File.Exists(applicationPath))
                {
                    if (!updateFw)
                    {
                        // this is a deployment operation only
                        // try parsing the deployment address from parameter
                        // need to remove the leading 0x and to specify that hexadecimal values are allowed
                        if (!uint.TryParse(deploymentAddress.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier, System.Globalization.CultureInfo.InvariantCulture, out address))
                        {
                            return(ExitCodes.E9009);
                        }
                    }

                    string applicationBinary = new FileInfo(applicationPath).FullName;
                    firmware.FlashPartitions = new Dictionary <int, string>()
                    {
                        {
                            updateFw?firmware.DeploymentPartionAddress : (int)address,
                            applicationBinary
                        }
                    };
                }
                else
                {
                    return(ExitCodes.E9008);
                }
            }

            if (verbosity >= VerbosityLevel.Normal)
            {
                Console.Write($"Erasing flash...");
            }

            if (updateFw)
            {
                // erase flash
                operationResult = espTool.EraseFlash();
            }
            else
            {
                // erase flash segment

                // need to get deployment address here
                // length must both be multiples of the SPI flash erase sector size. This is 0x1000 (4096) bytes for supported flash chips.

                var flashPartition = firmware.FlashPartitions.First();

                var fileStream = File.OpenRead(flashPartition.Value);

                uint fileLength = (uint)Math.Ceiling((decimal)fileStream.Length / 0x1000) * 0x1000;

                operationResult = espTool.EraseFlashSegment(address, fileLength);
            }

            if (operationResult == ExitCodes.OK)
            {
                if (verbosity >= VerbosityLevel.Normal)
                {
                    Console.WriteLine("OK");
                }
                else
                {
                    Console.WriteLine("");
                }

                if (verbosity >= VerbosityLevel.Normal)
                {
                    Console.Write($"Flashing firmware...");
                }

                // write to flash
                operationResult = espTool.WriteFlash(firmware.FlashPartitions);

                if (operationResult == ExitCodes.OK)
                {
                    if (verbosity >= VerbosityLevel.Normal)
                    {
                        Console.WriteLine("OK");
                    }
                    else
                    {
                        Console.WriteLine("");
                    }
                }
            }

            return(operationResult);
        }
Esempio n. 2
0
        static async Task RunOptionsAndReturnExitCodeAsync(Options o)
        {
            #region parse verbosity option

            switch (o.Verbosity)
            {
            // quiet
            case "q":
            case "quiet":
                verbosityLevel = VerbosityLevel.Quiet;
                break;

            // minimal
            case "m":
            case "minimal":
                verbosityLevel = VerbosityLevel.Minimal;
                break;

            // normal
            case "n":
            case "normal":
                verbosityLevel = VerbosityLevel.Normal;
                break;

            // detailed
            case "d":
            case "detailed":
                verbosityLevel = VerbosityLevel.Detailed;
                break;

            // diagnostic
            case "diag":
            case "diagnostic":
                verbosityLevel = VerbosityLevel.Diagnostic;
                break;

            default:
                throw new ArgumentException("Invalid option for Verbosity");
            }

            #endregion

            Console.WriteLine(headerInfo);
            Console.WriteLine(copyrightInfo);
            Console.WriteLine();

            #region target processing

            // if a target name was specified, try to be smart and set the platform accordingly (in case it wasn't specified)
            if (string.IsNullOrEmpty(o.Platform) &&
                !string.IsNullOrEmpty(o.TargetName))
            {
                // easiest one: ESP32
                if (o.TargetName.Contains("ESP32"))
                {
                    o.Platform = "esp32";
                }
                else if (
                    o.TargetName.Contains("ST") ||
                    o.TargetName.Contains("MBN_QUAIL") ||
                    o.TargetName.Contains("NETDUINO3") ||
                    o.TargetName.Contains("GHI FEZ") ||
                    o.TargetName.Contains("IngenuityMicro") ||
                    o.TargetName.Contains("ORGPAL")
                    )
                {
                    // candidates for STM32
                    o.Platform = "stm32";
                }
                else if (
                    o.TargetName.Contains("TI_CC1352")
                    )
                {
                    // candidates for TI CC13x2
                    o.Platform = "cc13x2";
                }
                else
                {
                    // other supported platforms will go here
                    // in case a wacky target is entered by the user, the package name will be checked against Bintray repo
                }
            }

            #endregion

            #region platform specific options

            // if an option was specified and has an obvious platform, try to be smart and set the platform accordingly (in case it wasn't specified)
            if (string.IsNullOrEmpty(o.Platform))
            {
                // JTAG related
                if (
                    o.ListJtagDevices ||
                    !string.IsNullOrEmpty(o.JtagDeviceId) ||
                    o.HexFile.Any() ||
                    o.BinFile.Any())
                {
                    o.Platform = "stm32";
                }
                // DFU related
                else if (
                    o.ListDevicesInDfuMode ||
                    !string.IsNullOrEmpty(o.DfuDeviceId) ||
                    !string.IsNullOrEmpty(o.DfuFile))
                {
                    o.Platform = "stm32";
                }
                // ESP32 related
                else if (
                    !string.IsNullOrEmpty(o.SerialPort) ||
                    (o.BaudRate != 921600) ||
                    (o.Esp32FlashMode != "dio") ||
                    (o.Esp32FlashFrequency != 40))
                {
                    o.Platform = "esp32";
                }
            }

            #endregion


            #region ESP32 platform options

            if (o.Platform == "esp32")
            {
                // COM port is mandatory for ESP32
                if (string.IsNullOrEmpty(o.SerialPort))
                {
                    _exitCode = ExitCodes.E6001;
                    return;
                }

                EspTool espTool;

                try
                {
                    espTool = new EspTool(
                        o.SerialPort,
                        o.BaudRate,
                        o.Esp32FlashMode,
                        o.Esp32FlashFrequency);
                }
                catch (Exception)
                {
                    _exitCode = ExitCodes.E4005;
                    return;
                }

                EspTool.DeviceInfo esp32Device;

                if (espTool.ComPortAvailable)
                {
                    try
                    {
                        esp32Device = espTool.TestChip();
                    }
                    catch (EspToolExecutionException ex)
                    {
                        _exitCode     = ExitCodes.E4000;
                        _extraMessage = ex.Message;

                        return;
                    }
                }
                else
                {
                    // couldn't open COM port
                    // done here, this command has no further processing
                    _exitCode = ExitCodes.E6000;

                    return;
                }

                if (verbosityLevel >= VerbosityLevel.Normal)
                {
                    Console.WriteLine($"Connected to ESP32 { esp32Device.ChipName } with MAC address { esp32Device.MacAddress }");
                    Console.WriteLine($"features { esp32Device.Features }");

                    string flashSize = esp32Device.FlashSize >= 0x10000 ? $"{ esp32Device.FlashSize / 0x100000 }MB" : $"{ esp32Device.FlashSize / 0x400 }kB";

                    Console.WriteLine($"Flash information: manufacturer 0x{ esp32Device.FlashManufacturerId } device 0x{ esp32Device.FlashDeviceModelId } size { flashSize }");
                }

                // set verbosity
                espTool.Verbosity = verbosityLevel;

                // backup requested
                if (!string.IsNullOrEmpty(o.BackupPath) ||
                    !string.IsNullOrEmpty(o.BackupFile))
                {
                    try
                    {
                        // backup path specified, backup deployment
                        _exitCode = Esp32Operations.BackupFlash(espTool, esp32Device, o.BackupPath, o.BackupFile, verbosityLevel);
                        if (_exitCode != ExitCodes.OK)
                        {
                            // done here
                            return;
                        }
                    }
                    catch (ReadEsp32FlashException ex)
                    {
                        _exitCode     = ExitCodes.E4004;
                        _extraMessage = ex.Message;

                        // done here
                        return;
                    }
                }

                // update operation requested?
                if (o.Update)
                {
                    try
                    {
                        // write flash
                        _exitCode = await Esp32Operations.UpdateFirmwareAsync(
                            espTool,
                            esp32Device,
                            o.TargetName,
                            true,
                            o.FwVersion,
                            o.Stable,
                            o.DeploymentImage,
                            null,
                            verbosityLevel);

                        if (_exitCode != ExitCodes.OK)
                        {
                            // done here
                            return;
                        }

                        // done here
                        _exitCode = ExitCodes.OK;
                        return;
                    }
                    catch (ReadEsp32FlashException ex)
                    {
                        _exitCode     = ExitCodes.E4004;
                        _extraMessage = ex.Message;
                    }
                    catch (WriteEsp32FlashException ex)
                    {
                        _exitCode     = ExitCodes.E4003;
                        _extraMessage = ex.Message;
                    }
                    catch (EspToolExecutionException ex)
                    {
                        _exitCode     = ExitCodes.E4000;
                        _extraMessage = ex.Message;
                    }
                }

                // it's OK to deploy after update
                if (o.Deploy)
                {
                    // need to take care of flash address
                    string appFlashAddress = null;

                    if (o.FlashAddress.Any())
                    {
                        // take the first address, it should be the only one valid
                        appFlashAddress = o.FlashAddress.ElementAt(0);
                    }
                    else
                    {
                        _exitCode = ExitCodes.E9009;
                        return;
                    }

                    // this to flash a deployment image without updating the firmware
                    try
                    {
                        // write flash
                        _exitCode = await Esp32Operations.UpdateFirmwareAsync(
                            espTool,
                            esp32Device,
                            null,
                            false,
                            null,
                            false,
                            o.DeploymentImage,
                            appFlashAddress,
                            verbosityLevel);

                        if (_exitCode != ExitCodes.OK)
                        {
                            // done here
                            return;
                        }

                        // done here
                        _exitCode = ExitCodes.OK;
                        return;
                    }
                    catch (ReadEsp32FlashException ex)
                    {
                        _exitCode     = ExitCodes.E4004;
                        _extraMessage = ex.Message;
                    }
                    catch (WriteEsp32FlashException ex)
                    {
                        _exitCode     = ExitCodes.E4003;
                        _extraMessage = ex.Message;
                    }
                    catch (EspToolExecutionException ex)
                    {
                        _exitCode     = ExitCodes.E4000;
                        _extraMessage = ex.Message;
                    }
                }

                // done here
                return;
            }

            #endregion

            #region STM32 platform options

            if (o.Platform == "stm32")
            {
                if (o.ListDevicesInDfuMode)
                {
                    var connecteDevices = StmDfuDevice.ListDfuDevices();

                    if (connecteDevices.Count == 0)
                    {
                        Console.WriteLine("No DFU devices found");
                    }
                    else
                    {
                        Console.WriteLine("-- Connected DFU devices --");

                        foreach (string deviceId in connecteDevices)
                        {
                            Console.WriteLine(deviceId);
                        }

                        Console.WriteLine("---------------------------");
                    }

                    // done here, this command has no further processing
                    _exitCode = ExitCodes.OK;

                    return;
                }

                if (o.ListJtagDevices)
                {
                    try
                    {
                        var connecteDevices = StmJtagDevice.ListDevices();

                        if (connecteDevices.Count == 0)
                        {
                            Console.WriteLine("No JTAG devices found");
                        }
                        else
                        {
                            Console.WriteLine("-- Connected JTAG devices --");

                            foreach (string deviceId in connecteDevices)
                            {
                                Console.WriteLine(deviceId);
                            }

                            Console.WriteLine("---------------------------");
                        }

                        // done here, this command has no further processing
                        _exitCode = ExitCodes.OK;
                    }
                    catch (Exception ex)
                    {
                        // exception with
                        _exitCode     = ExitCodes.E5000;
                        _extraMessage = ex.Message;
                    }

                    return;
                }

                if (!string.IsNullOrEmpty(o.DfuFile))
                {
                    // there is a DFU file argument, so follow DFU path
                    var dfuDevice = new StmDfuDevice(o.DfuDeviceId);

                    if (!dfuDevice.DevicePresent)
                    {
                        // no DFU device found

                        // done here, this command has no further processing
                        _exitCode = ExitCodes.E1000;

                        return;
                    }

                    if (verbosityLevel >= VerbosityLevel.Normal)
                    {
                        Console.WriteLine($"Connected to DFU device with ID { dfuDevice.DeviceId }");
                    }

                    // set verbosity
                    dfuDevice.Verbosity = verbosityLevel;

                    // get mass erase option
                    dfuDevice.DoMassErase = o.MassErase;

                    try
                    {
                        dfuDevice.FlashDfuFile(o.DfuFile);

                        // done here, this command has no further processing
                        _exitCode = ExitCodes.OK;

                        return;
                    }
                    catch (DfuFileDoesNotExistException)
                    {
                        // DFU file doesn't exist
                        _exitCode = ExitCodes.E1002;
                    }
                    catch (Exception ex)
                    {
                        // exception with DFU operation
                        _exitCode     = ExitCodes.E1003;
                        _extraMessage = ex.Message;
                    }
                }
                else if (
                    o.BinFile.Any() &&
                    o.HexFile.Any())
                {
                    // this has to be a JTAG connected device

                    #region STM32 JTAG options

                    try
                    {
                        var jtagDevice = new StmJtagDevice(o.JtagDeviceId);

                        if (!jtagDevice.DevicePresent)
                        {
                            // no JTAG device found

                            // done here, this command has no further processing
                            _exitCode = ExitCodes.E5001;

                            return;
                        }

                        if (verbosityLevel >= VerbosityLevel.Normal)
                        {
                            Console.WriteLine($"Connected to JTAG device with ID { jtagDevice.DeviceId }");
                        }

                        // set verbosity
                        jtagDevice.Verbosity = verbosityLevel;

                        // get mass erase option
                        jtagDevice.DoMassErase = o.MassErase;

                        if (o.HexFile.Any())
                        {
                            _exitCode = jtagDevice.FlashHexFiles(o.HexFile);

                            // done here
                            return;
                        }

                        if (o.BinFile.Any())
                        {
                            _exitCode = jtagDevice.FlashBinFiles(o.BinFile, o.FlashAddress);

                            // done here
                            return;
                        }
                    }
                    catch (CantConnectToJtagDeviceException)
                    {
                        // done here, this command has no further processing
                        _exitCode = ExitCodes.E5002;
                    }

                    #endregion
                }
                else if (!string.IsNullOrEmpty(o.TargetName))
                {
                    // update operation requested?
                    if (o.Update)
                    {
                        // this to update the device with fw from Bintray

                        // need to take care of flash address
                        string appFlashAddress = null;

                        if (o.FlashAddress.Any())
                        {
                            // take the first address, it should be the only one valid
                            appFlashAddress = o.FlashAddress.ElementAt(0);
                        }

                        _exitCode = await Stm32Operations.UpdateFirmwareAsync(
                            o.TargetName,
                            o.FwVersion,
                            o.Stable,
                            true,
                            o.DeploymentImage,
                            appFlashAddress,
                            o.DfuDeviceId,
                            o.JtagDeviceId,
                            verbosityLevel);

                        if (_exitCode != ExitCodes.OK)
                        {
                            // done here
                            return;
                        }
                    }

                    // it's OK to deploy after update
                    if (o.Deploy)
                    {
                        // this to flash a deployment image without updating the firmware

                        // need to take care of flash address
                        string appFlashAddress = null;

                        if (o.FlashAddress.Any())
                        {
                            // take the first address, it should be the only one valid
                            appFlashAddress = o.FlashAddress.ElementAt(0);
                        }
                        else
                        {
                            _exitCode = ExitCodes.E9009;
                            return;
                        }

                        _exitCode = await Stm32Operations.UpdateFirmwareAsync(
                            o.TargetName,
                            null,
                            false,
                            false,
                            o.DeploymentImage,
                            appFlashAddress,
                            o.DfuDeviceId,
                            o.JtagDeviceId,
                            verbosityLevel);

                        if (_exitCode != ExitCodes.OK)
                        {
                            // done here
                            return;
                        }
                    }

                    // reset MCU requested?
                    if (o.ResetMcu)
                    {
                        _exitCode = Stm32Operations.ResetMcu(
                            o.JtagDeviceId,
                            verbosityLevel);

                        if (_exitCode != ExitCodes.OK)
                        {
                            // done here
                            return;
                        }
                    }
                }
            }

            #endregion


            #region TI CC13x2 platform options

            if (o.Platform == "cc13x2")
            {
                if (!string.IsNullOrEmpty(o.TargetName))
                {
                    // update operation requested?
                    if (o.Update)
                    {
                        // this to update the device with fw from Bintray

                        // need to take care of flash address
                        string appFlashAddress = null;

                        if (o.FlashAddress.Any())
                        {
                            // take the first address, it should be the only one valid
                            appFlashAddress = o.FlashAddress.ElementAt(0);
                        }

                        _exitCode = await CC13x26x2Operations.UpdateFirmwareAsync(
                            o.TargetName,
                            o.FwVersion,
                            o.Stable,
                            true,
                            o.DeploymentImage,
                            appFlashAddress,
                            verbosityLevel);

                        if (_exitCode != ExitCodes.OK)
                        {
                            // done here
                            return;
                        }
                    }

                    // it's OK to deploy after update
                    if (o.Deploy)
                    {
                        // this to flash a deployment image without updating the firmware

                        // need to take care of flash address
                        string appFlashAddress = null;

                        if (o.FlashAddress.Any())
                        {
                            // take the first address, it should be the only one valid
                            appFlashAddress = o.FlashAddress.ElementAt(0);
                        }
                        else
                        {
                            _exitCode = ExitCodes.E9009;
                            return;
                        }

                        _exitCode = await CC13x26x2Operations.UpdateFirmwareAsync(
                            o.TargetName,
                            null,
                            false,
                            false,
                            o.DeploymentImage,
                            appFlashAddress,
                            verbosityLevel);

                        if (_exitCode != ExitCodes.OK)
                        {
                            // done here
                            return;
                        }
                    }

                    // reset MCU requested?
                    if (o.ResetMcu)
                    {
                        // can't reset CC13x2 device without configuration file
                        // would require to specify the exact target name and then had to try parsing that
                        _exitCode = ExitCodes.E9000;

                        // done here
                        return;
                    }
                }

                if (o.TIInstallXdsDrivers)
                {
                    _exitCode = CC13x26x2Operations.InstallXds110Drivers(verbosityLevel);

                    if (_exitCode != ExitCodes.OK)
                    {
                        // done here
                        return;
                    }
                }
            }

            #endregion
        }
Esempio n. 3
0
        public static ExitCodes BackupFlash(
            EspTool tool,
            EspTool.DeviceInfo device,
            string backupPath,
            string fileName,
            VerbosityLevel verbosity)
        {
            // check for backup file without backup path
            if (!string.IsNullOrEmpty(fileName) &&
                string.IsNullOrEmpty(backupPath))
            {
                // backup file without backup path
                return(ExitCodes.E9004);
            }

            // check if directory exists, if it doesn't, try to create
            if (!Directory.Exists(backupPath))
            {
                try
                {
                    Directory.CreateDirectory(backupPath);
                }
                catch
                {
                    return(ExitCodes.E9002);
                }
            }

            // file name specified
            if (string.IsNullOrEmpty(fileName))
            {
                fileName = $"{device.ChipName}_0x{device.MacAddress:X}_{DateTime.UtcNow.ToShortDateString()}.bin";
            }

            var backupFilePath = Path.Combine(backupPath, fileName);

            // check file existence
            if (File.Exists(fileName))
            {
                try
                {
                    File.Delete(backupFilePath);
                }
                catch
                {
                    return(ExitCodes.E9003);
                }
            }

            if (verbosity >= VerbosityLevel.Normal)
            {
                Console.WriteLine($"Backing up the firmware to \r\n{backupFilePath}...");
            }

            tool.BackupFlash(backupFilePath, device.FlashSize);

            if (verbosity > VerbosityLevel.Quiet)
            {
                Console.WriteLine($"Flash backup saved to {fileName}");
            }

            return(ExitCodes.OK);
        }