Skip to content

Commit

Permalink
Add support for direct operations to nano devices (#151)
Browse files Browse the repository at this point in the history
  • Loading branch information
josesimoes authored Aug 22, 2022
1 parent 832ce56 commit d0b9fbe
Show file tree
Hide file tree
Showing 17 changed files with 1,131 additions and 160 deletions.
13 changes: 2 additions & 11 deletions nanoFirmwareFlasher.Library/CC13x26x2Firmware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ namespace nanoFramework.Tools.FirmwareFlasher
/// </summary>
internal class CC13x26x2Firmware : FirmwarePackage
{
public string nanoCLRFile { get; private set; }

public CC13x26x2Firmware(
string targetName,
string fwVersion,
Expand All @@ -26,17 +24,10 @@ public CC13x26x2Firmware(
{
}

internal new async System.Threading.Tasks.Task<ExitCodes> DownloadAndExtractAsync()
internal new System.Threading.Tasks.Task<ExitCodes> DownloadAndExtractAsync()
{
// perform download and extract
var executionResult = await base.DownloadAndExtractAsync();

if (executionResult == ExitCodes.OK)
{
nanoCLRFile = Directory.EnumerateFiles(LocationPath, "nanoCLR.hex").FirstOrDefault();
}

return executionResult;
return base.DownloadAndExtractAsync();
}
}
}
2 changes: 1 addition & 1 deletion nanoFirmwareFlasher.Library/CC13x26x2Operations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public static async System.Threading.Tasks.Task<ExitCodes> UpdateFirmwareAsync(

if (updateFw)
{
filesToFlash.Add(firmware.nanoCLRFile);
filesToFlash.Add(firmware.NanoClrFile);
}

// need to include application file?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

using System;
using System.Runtime.Serialization;

namespace nanoFramework.Tools.FirmwareFlasher
{
/// <summary>
/// Couldn't open the specified .NET nanoFramework device.
/// </summary>
[Serializable]
public class CantConnectToNanoDeviceException : Exception
{
public CantConnectToNanoDeviceException()
{
}

public CantConnectToNanoDeviceException(string message) : base(message)
{
}

public CantConnectToNanoDeviceException(string message, Exception innerException) : base(message, innerException)
{
}

protected CantConnectToNanoDeviceException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

using System;
using System.Runtime.Serialization;

namespace nanoFramework.Tools.FirmwareFlasher
{
/// <summary>
/// Verification of DFU write failed.
/// </summary>
[Serializable]
public class NanoDeviceOperationFailedException : Exception
{
public NanoDeviceOperationFailedException()
{
}

public NanoDeviceOperationFailedException(string message) : base(message)
{
}

public NanoDeviceOperationFailedException(string message, Exception innerException) : base(message, innerException)
{
}

protected NanoDeviceOperationFailedException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
23 changes: 22 additions & 1 deletion nanoFirmwareFlasher.Library/ExitCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,28 @@ public enum ExitCodes
[Display(Name = "Failed to start execition on the connected device.")]
E1006 = 1006,

///////////////////////
// nanoDevice Errors //
///////////////////////

/// <summary>
/// Error connecting to nano device.
/// </summary>
[Display(Name = "Error connecting to nano device.")]
E2000 = 2000,

/// <summary>
/// Error connecting to nano device.
/// </summary>
[Display(Name = "Error occurred with listing nano devices.")]
E2001 = 2001,

/// <summary>
/// Error executing operation with nano device.
/// </summary>
[Display(Name = "Error executing operation with nano device.")]
E2002 = 2002,

////////////////////////
// ESP32 tools Errors //
////////////////////////
Expand Down Expand Up @@ -301,6 +323,5 @@ public enum ExitCodes
/// </summary>
[Display(Name = "Error occured when clearing the firmware cache location.")]
E9014 = 9014,

}
}
166 changes: 163 additions & 3 deletions nanoFirmwareFlasher.Library/FirmwarePackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// See LICENSE file in the project root for full license information.
//

using nanoFramework.Tools.Debugger;
using nanoFramework.Tools.FirmwareFlasher;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -31,7 +33,7 @@ public abstract class FirmwarePackage : IDisposable
private readonly bool _preview;

private const string _readmeContent = "This folder contains nanoFramework firmware files. Can safely be removed.";

/// <summary>
/// Path with the base location for firmware packages.
/// </summary>
Expand All @@ -58,13 +60,58 @@ public static string LocationPathBase

public VerbosityLevel Verbosity { get; internal set; }

/// <summary>
/// Path to nanoBooter file. Hex format.
/// </summary>
/// <remarks>For the binary file please use the <see cref="NanoBooterFileBinary"/> property.</remarks>
public string NanoBooterFile { get; internal set; }

/// <summary>
/// Path to nanoBooter file. Binary format.
/// </summary>
/// <remarks>For the HEX format file please use the <see cref="NanoBooterFile"/> property.</remarks>
public string NanoBooterFileBinary => NanoBooterFile.Replace(".hex", ".bin");

/// <summary>
/// Path to nanoCLR file. Hex format.
/// </summary>
/// <remarks>For the binary file please use the <see cref="NanoClrFileBinary"/> property.</remarks>
public string NanoClrFile { get; internal set; }

/// <summary>
/// Path to nanoCLR file. Binary format.
/// </summary>
/// <remarks>For the HEX format file please use the <see cref="NanoClrFile"/> property.</remarks>
public string NanoClrFileBinary => NanoClrFile.Replace(".hex", ".bin");

/// <summary>
/// The address of nanoCLR in flash.
/// </summary>
public uint ClrStartAddress { get; internal set; }

/// <summary>
/// The address of nanoBooter in flash.
/// </summary>
public object BooterStartAddress { get; internal set; }

static FirmwarePackage()
{
_cloudsmithClient = new HttpClient();
_cloudsmithClient.BaseAddress = new Uri("https://api.cloudsmith.io/v1/packages/net-nanoframework/");
_cloudsmithClient.DefaultRequestHeaders.Add("Accept", "*/*");
}

/// <summary>
///
/// </summary>
/// <param name="nanoDevice"></param>
protected FirmwarePackage(NanoDeviceBase nanoDevice)
{
_targetName = nanoDevice.TargetName;
Version = "";
_preview = false;
}

/// <summary>
/// Constructor
/// </summary>
Expand Down Expand Up @@ -148,7 +195,7 @@ public static List<CloudSmithPackageDetail> GetTargetList(
/// Download the firmware zip, extract this zip file, and get the firmware parts
/// </summary>
/// <returns>a dictionary which keys are the start addresses and the values are the complete filenames (the bin files)</returns>
protected async Task<ExitCodes> DownloadAndExtractAsync()
internal async Task<ExitCodes> DownloadAndExtractAsync()
{
string fwFileName = null;

Expand Down Expand Up @@ -223,7 +270,7 @@ protected async Task<ExitCodes> DownloadAndExtractAsync()
}

downloadUrl = downloadResult.Url;

// update with version from package about to be downloaded
Version = downloadResult.Version;

Expand Down Expand Up @@ -380,6 +427,8 @@ protected async Task<ExitCodes> DownloadAndExtractAsync()
.ToList()
.ForEach(f => f.Delete());

PostProcessDownloadAndExtract();

if (Verbosity >= VerbosityLevel.Normal)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Expand Down Expand Up @@ -627,6 +676,117 @@ void IDisposable.Dispose()
internal record struct DownloadUrlResult(string Url, string Version, ExitCodes Outcome)
{
}

private void FindBooterStartAddress()
{
uint address;

// find out what's the CLR block start

// do this by reading the HEX format file...
var textLines = File.ReadAllLines(NanoBooterFile);

// ... and decoding the start address
var addressRecord = textLines.FirstOrDefault();

// 1st line is an Extended Segment Address Records (HEX86)
// format ":02000004FFFFFC"

// perform sanity checks
if (addressRecord == null ||
addressRecord.Length != 15 ||
addressRecord.Substring(0, 9) != ":02000004")
{
// wrong format
throw new FormatException("Wrong data in nanoBooter file");
}

// looking good, grab the upper 16bits
address = (uint)int.Parse(addressRecord.Substring(9, 4), System.Globalization.NumberStyles.HexNumber);
address <<= 16;

// now the 2nd line to get the lower 16 bits of the address
addressRecord = textLines.Skip(1).FirstOrDefault();

// 2nd line is a Data Record
// format ":10246200464C5549442050524F46494C4500464C33"

// perform sanity checks
if (addressRecord == null ||
addressRecord.Substring(0, 1) != ":" ||
addressRecord.Length < 7)
{
// wrong format
throw new FormatException("Wrong data in nanoBooter file");
}

// looking good, grab the lower 16bits
address += (uint)int.Parse(addressRecord.Substring(3, 4), System.Globalization.NumberStyles.HexNumber);

BooterStartAddress = address;
}

private void FindClrStartAddress()
{
uint address;

// find out what's the CLR block start

// do this by reading the HEX format file...
var textLines = File.ReadAllLines(NanoClrFile);

// ... and decoding the start address
var addressRecord = textLines.FirstOrDefault();

// 1st line is an Extended Segment Address Records (HEX86)
// format ":02000004FFFFFC"

// perform sanity checks
if (addressRecord == null ||
addressRecord.Length != 15 ||
addressRecord.Substring(0, 9) != ":02000004")
{
// wrong format
throw new FormatException("Wrong data in nanoClr file");
}

// looking good, grab the upper 16bits
address = (uint)int.Parse(addressRecord.Substring(9, 4), System.Globalization.NumberStyles.HexNumber);
address <<= 16;

// now the 2nd line to get the lower 16 bits of the address
addressRecord = textLines.Skip(1).FirstOrDefault();

// 2nd line is a Data Record
// format ":10246200464C5549442050524F46494C4500464C33"

// perform sanity checks
if (addressRecord == null ||
addressRecord.Substring(0, 1) != ":" ||
addressRecord.Length < 7)
{
// wrong format
throw new FormatException("Wrong data in nanoClr file");
}

// looking good, grab the lower 16bits
address += (uint)int.Parse(addressRecord.Substring(3, 4), System.Globalization.NumberStyles.HexNumber);

ClrStartAddress = address;
}

internal void PostProcessDownloadAndExtract()
{
NanoBooterFile = Directory.EnumerateFiles(LocationPath, "nanoBooter.hex").FirstOrDefault();
NanoClrFile = Directory.EnumerateFiles(LocationPath, "nanoCLR.hex").FirstOrDefault();

if (NanoBooterFile != null)
{
FindBooterStartAddress();
}

FindClrStartAddress();
}
}

}
Loading

0 comments on commit d0b9fbe

Please sign in to comment.