Skip to content

Commit 8258d78

Browse files
authored
Improve update operation for ESP32 (#254)
1 parent 1f10419 commit 8258d78

File tree

4 files changed

+93
-2
lines changed

4 files changed

+93
-2
lines changed

nanoFirmwareFlasher.Library/Esp32Operations.cs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System;
77
using System.Collections.Generic;
88
using System.IO;
9+
using System.Text.RegularExpressions;
910

1011
namespace nanoFramework.Tools.FirmwareFlasher
1112
{
@@ -103,6 +104,7 @@ public static ExitCodes BackupFlash(
103104
/// <param name="deploymentAddress">Flash address to use when deploying an aplication.</param>
104105
/// <param name="clrFile">Path to CLR file to use for firmware update.</param>
105106
/// <param name="fitCheck"><see langword="true"/> to perform validation of update package against connected target.</param>
107+
/// <param name="massErase">If <see langword="true"/> perform mass erase on device before updating.</param>
106108
/// <param name="verbosity">Set verbosity level of progress and error messages.</param>
107109
/// <param name="partitionTableSize">Size of partition table.</param>
108110
/// <returns>The <see cref="ExitCodes"/> with the operation result.</returns>
@@ -117,6 +119,7 @@ public static async System.Threading.Tasks.Task<ExitCodes> UpdateFirmwareAsync(
117119
string deploymentAddress,
118120
string clrFile,
119121
bool fitCheck,
122+
bool massErase,
120123
VerbosityLevel verbosity,
121124
PartitionTableSize? partitionTableSize)
122125
{
@@ -403,16 +406,17 @@ public static async System.Threading.Tasks.Task<ExitCodes> UpdateFirmwareAsync(
403406
}
404407
}
405408

406-
if (updateFw)
409+
if (updateFw
410+
&& massErase)
407411
{
412+
// erase flash, if masse erase was requested
408413
// updating fw calls for a flash erase
409414
if (verbosity >= VerbosityLevel.Normal)
410415
{
411416
Console.ForegroundColor = ConsoleColor.White;
412417
Console.Write($"Erasing flash...");
413418
}
414419

415-
// erase flash
416420
operationResult = espTool.EraseFlash();
417421

418422
if (operationResult == ExitCodes.OK)
@@ -438,6 +442,39 @@ public static async System.Threading.Tasks.Task<ExitCodes> UpdateFirmwareAsync(
438442
Console.Write($"Flashing firmware...");
439443
}
440444

445+
int configPartitionAddress = 0;
446+
int configPartitionSize = 0;
447+
string configPartitionBackup = Path.GetTempFileName();
448+
449+
// if mass erase wasn't requested, backup config partitition
450+
if (!massErase)
451+
{
452+
// compose path to partition file
453+
string partitionCsvFile = Path.Combine(firmware.LocationPath, $"partitions_nanoclr_{Esp32DeviceInfo.GetFlashSizeAsString(esp32Device.FlashSize).ToLowerInvariant()}.csv");
454+
455+
var partitionDetails = File.ReadAllText(partitionCsvFile);
456+
457+
// grab details for the config partition
458+
string pattern = @"config,.*?(0x[0-9A-Fa-f]+),.*?(0x[0-9A-Fa-f]+),";
459+
Regex regex = new Regex(pattern);
460+
Match match = regex.Match(partitionDetails);
461+
462+
if (match.Success)
463+
{
464+
// just try to parse, ignore failures
465+
int.TryParse(match.Groups[1].Value.Substring(2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out configPartitionAddress);
466+
int.TryParse(match.Groups[2].Value.Substring(2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out configPartitionSize);
467+
}
468+
469+
// backup config partition
470+
operationResult = espTool.BackupConfigPartition(
471+
configPartitionBackup,
472+
configPartitionAddress,
473+
configPartitionSize);
474+
475+
firmware.FlashPartitions.Add(configPartitionAddress, configPartitionBackup);
476+
}
477+
441478
// write to flash
442479
operationResult = espTool.WriteFlash(firmware.FlashPartitions);
443480

@@ -469,6 +506,19 @@ public static async System.Threading.Tasks.Task<ExitCodes> UpdateFirmwareAsync(
469506
}
470507
}
471508

509+
// delete config partition backup
510+
try
511+
{
512+
if (File.Exists(configPartitionBackup))
513+
{
514+
File.Delete(configPartitionBackup);
515+
}
516+
}
517+
catch
518+
{
519+
// don't care
520+
}
521+
472522
Console.ForegroundColor = ConsoleColor.White;
473523
}
474524

nanoFirmwareFlasher.Library/EspTool.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,44 @@ internal void BackupFlash(string backupFilename,
393393
}
394394
}
395395

396+
/// <summary>
397+
/// Backup the entire flash into a bin file
398+
/// </summary>
399+
/// <param name="backupFilename">Backup file including full path</param>
400+
/// <param name="address">Start address of the config partition.</param>
401+
/// <param name="size">Size of the config partition.</param>
402+
/// <returns>true if successful</returns>
403+
internal ExitCodes BackupConfigPartition(
404+
string backupFilename,
405+
int address,
406+
int size)
407+
{
408+
// execute dump_mem command and parse the result; progress message can be found be searching for backspaces (ASCII code 8)
409+
if (!RunEspTool(
410+
$"read_flash 0x{address:X} 0x{size:X} \"{backupFilename}\"",
411+
false,
412+
true,
413+
false,
414+
null,
415+
out string messages))
416+
{
417+
throw new ReadEsp32FlashException(messages);
418+
}
419+
420+
var match = Regex.Match(messages, "(?<message>Read .*)(.*?\n)*");
421+
if (!match.Success)
422+
{
423+
throw new ReadEsp32FlashException(messages);
424+
}
425+
426+
if (Verbosity >= VerbosityLevel.Detailed)
427+
{
428+
Console.WriteLine(match.Groups["message"].ToString().Trim());
429+
}
430+
431+
return ExitCodes.OK;
432+
}
433+
396434
/// <summary>
397435
/// Erase the entire flash of the ESP32 chip.
398436
/// </summary>

nanoFirmwareFlasher.Library/FirmwarePackage.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ internal async Task<ExitCodes> DownloadAndExtractAsync()
293293
filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.hex").ToList());
294294
filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.s19").ToList());
295295
filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.dfu").ToList());
296+
filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.csv").ToList());
296297

297298
foreach (var file in filesToDelete)
298299
{

nanoFirmwareFlasher.Tool/Esp32Manager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ public async Task<ExitCodes> ProcessAsync()
145145
null,
146146
_options.ClrFile,
147147
!_options.FitCheck,
148+
_options.MassErase,
148149
_verbosityLevel,
149150
_options.Esp32PartitionTableSize);
150151

@@ -182,6 +183,7 @@ public async Task<ExitCodes> ProcessAsync()
182183
appFlashAddress,
183184
null,
184185
!_options.FitCheck,
186+
_options.MassErase,
185187
_verbosityLevel,
186188
_options.Esp32PartitionTableSize);
187189

0 commit comments

Comments
 (0)