Skip to content

Commit d0b9fbe

Browse files
authored
Add support for direct operations to nano devices (#151)
1 parent 832ce56 commit d0b9fbe

17 files changed

+1131
-160
lines changed

nanoFirmwareFlasher.Library/CC13x26x2Firmware.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ namespace nanoFramework.Tools.FirmwareFlasher
1313
/// </summary>
1414
internal class CC13x26x2Firmware : FirmwarePackage
1515
{
16-
public string nanoCLRFile { get; private set; }
17-
1816
public CC13x26x2Firmware(
1917
string targetName,
2018
string fwVersion,
@@ -26,17 +24,10 @@ public CC13x26x2Firmware(
2624
{
2725
}
2826

29-
internal new async System.Threading.Tasks.Task<ExitCodes> DownloadAndExtractAsync()
27+
internal new System.Threading.Tasks.Task<ExitCodes> DownloadAndExtractAsync()
3028
{
3129
// perform download and extract
32-
var executionResult = await base.DownloadAndExtractAsync();
33-
34-
if (executionResult == ExitCodes.OK)
35-
{
36-
nanoCLRFile = Directory.EnumerateFiles(LocationPath, "nanoCLR.hex").FirstOrDefault();
37-
}
38-
39-
return executionResult;
30+
return base.DownloadAndExtractAsync();
4031
}
4132
}
4233
}

nanoFirmwareFlasher.Library/CC13x26x2Operations.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public static async System.Threading.Tasks.Task<ExitCodes> UpdateFirmwareAsync(
6868

6969
if (updateFw)
7070
{
71-
filesToFlash.Add(firmware.nanoCLRFile);
71+
filesToFlash.Add(firmware.NanoClrFile);
7272
}
7373

7474
// need to include application file?
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System;
7+
using System.Runtime.Serialization;
8+
9+
namespace nanoFramework.Tools.FirmwareFlasher
10+
{
11+
/// <summary>
12+
/// Couldn't open the specified .NET nanoFramework device.
13+
/// </summary>
14+
[Serializable]
15+
public class CantConnectToNanoDeviceException : Exception
16+
{
17+
public CantConnectToNanoDeviceException()
18+
{
19+
}
20+
21+
public CantConnectToNanoDeviceException(string message) : base(message)
22+
{
23+
}
24+
25+
public CantConnectToNanoDeviceException(string message, Exception innerException) : base(message, innerException)
26+
{
27+
}
28+
29+
protected CantConnectToNanoDeviceException(SerializationInfo info, StreamingContext context) : base(info, context)
30+
{
31+
}
32+
}
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System;
7+
using System.Runtime.Serialization;
8+
9+
namespace nanoFramework.Tools.FirmwareFlasher
10+
{
11+
/// <summary>
12+
/// Verification of DFU write failed.
13+
/// </summary>
14+
[Serializable]
15+
public class NanoDeviceOperationFailedException : Exception
16+
{
17+
public NanoDeviceOperationFailedException()
18+
{
19+
}
20+
21+
public NanoDeviceOperationFailedException(string message) : base(message)
22+
{
23+
}
24+
25+
public NanoDeviceOperationFailedException(string message, Exception innerException) : base(message, innerException)
26+
{
27+
}
28+
29+
protected NanoDeviceOperationFailedException(SerializationInfo info, StreamingContext context) : base(info, context)
30+
{
31+
}
32+
}
33+
}

nanoFirmwareFlasher.Library/ExitCodes.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,28 @@ public enum ExitCodes
5656
[Display(Name = "Failed to start execition on the connected device.")]
5757
E1006 = 1006,
5858

59+
///////////////////////
60+
// nanoDevice Errors //
61+
///////////////////////
62+
63+
/// <summary>
64+
/// Error connecting to nano device.
65+
/// </summary>
66+
[Display(Name = "Error connecting to nano device.")]
67+
E2000 = 2000,
68+
69+
/// <summary>
70+
/// Error connecting to nano device.
71+
/// </summary>
72+
[Display(Name = "Error occurred with listing nano devices.")]
73+
E2001 = 2001,
74+
75+
/// <summary>
76+
/// Error executing operation with nano device.
77+
/// </summary>
78+
[Display(Name = "Error executing operation with nano device.")]
79+
E2002 = 2002,
80+
5981
////////////////////////
6082
// ESP32 tools Errors //
6183
////////////////////////
@@ -301,6 +323,5 @@ public enum ExitCodes
301323
/// </summary>
302324
[Display(Name = "Error occured when clearing the firmware cache location.")]
303325
E9014 = 9014,
304-
305326
}
306327
}

nanoFirmwareFlasher.Library/FirmwarePackage.cs

Lines changed: 163 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// See LICENSE file in the project root for full license information.
44
//
55

6+
using nanoFramework.Tools.Debugger;
7+
using nanoFramework.Tools.FirmwareFlasher;
68
using Newtonsoft.Json;
79
using System;
810
using System.Collections.Generic;
@@ -31,7 +33,7 @@ public abstract class FirmwarePackage : IDisposable
3133
private readonly bool _preview;
3234

3335
private const string _readmeContent = "This folder contains nanoFramework firmware files. Can safely be removed.";
34-
36+
3537
/// <summary>
3638
/// Path with the base location for firmware packages.
3739
/// </summary>
@@ -58,13 +60,58 @@ public static string LocationPathBase
5860

5961
public VerbosityLevel Verbosity { get; internal set; }
6062

63+
/// <summary>
64+
/// Path to nanoBooter file. Hex format.
65+
/// </summary>
66+
/// <remarks>For the binary file please use the <see cref="NanoBooterFileBinary"/> property.</remarks>
67+
public string NanoBooterFile { get; internal set; }
68+
69+
/// <summary>
70+
/// Path to nanoBooter file. Binary format.
71+
/// </summary>
72+
/// <remarks>For the HEX format file please use the <see cref="NanoBooterFile"/> property.</remarks>
73+
public string NanoBooterFileBinary => NanoBooterFile.Replace(".hex", ".bin");
74+
75+
/// <summary>
76+
/// Path to nanoCLR file. Hex format.
77+
/// </summary>
78+
/// <remarks>For the binary file please use the <see cref="NanoClrFileBinary"/> property.</remarks>
79+
public string NanoClrFile { get; internal set; }
80+
81+
/// <summary>
82+
/// Path to nanoCLR file. Binary format.
83+
/// </summary>
84+
/// <remarks>For the HEX format file please use the <see cref="NanoClrFile"/> property.</remarks>
85+
public string NanoClrFileBinary => NanoClrFile.Replace(".hex", ".bin");
86+
87+
/// <summary>
88+
/// The address of nanoCLR in flash.
89+
/// </summary>
90+
public uint ClrStartAddress { get; internal set; }
91+
92+
/// <summary>
93+
/// The address of nanoBooter in flash.
94+
/// </summary>
95+
public object BooterStartAddress { get; internal set; }
96+
6197
static FirmwarePackage()
6298
{
6399
_cloudsmithClient = new HttpClient();
64100
_cloudsmithClient.BaseAddress = new Uri("https://api.cloudsmith.io/v1/packages/net-nanoframework/");
65101
_cloudsmithClient.DefaultRequestHeaders.Add("Accept", "*/*");
66102
}
67103

104+
/// <summary>
105+
///
106+
/// </summary>
107+
/// <param name="nanoDevice"></param>
108+
protected FirmwarePackage(NanoDeviceBase nanoDevice)
109+
{
110+
_targetName = nanoDevice.TargetName;
111+
Version = "";
112+
_preview = false;
113+
}
114+
68115
/// <summary>
69116
/// Constructor
70117
/// </summary>
@@ -148,7 +195,7 @@ public static List<CloudSmithPackageDetail> GetTargetList(
148195
/// Download the firmware zip, extract this zip file, and get the firmware parts
149196
/// </summary>
150197
/// <returns>a dictionary which keys are the start addresses and the values are the complete filenames (the bin files)</returns>
151-
protected async Task<ExitCodes> DownloadAndExtractAsync()
198+
internal async Task<ExitCodes> DownloadAndExtractAsync()
152199
{
153200
string fwFileName = null;
154201

@@ -223,7 +270,7 @@ protected async Task<ExitCodes> DownloadAndExtractAsync()
223270
}
224271

225272
downloadUrl = downloadResult.Url;
226-
273+
227274
// update with version from package about to be downloaded
228275
Version = downloadResult.Version;
229276

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

430+
PostProcessDownloadAndExtract();
431+
383432
if (Verbosity >= VerbosityLevel.Normal)
384433
{
385434
Console.ForegroundColor = ConsoleColor.Yellow;
@@ -627,6 +676,117 @@ void IDisposable.Dispose()
627676
internal record struct DownloadUrlResult(string Url, string Version, ExitCodes Outcome)
628677
{
629678
}
679+
680+
private void FindBooterStartAddress()
681+
{
682+
uint address;
683+
684+
// find out what's the CLR block start
685+
686+
// do this by reading the HEX format file...
687+
var textLines = File.ReadAllLines(NanoBooterFile);
688+
689+
// ... and decoding the start address
690+
var addressRecord = textLines.FirstOrDefault();
691+
692+
// 1st line is an Extended Segment Address Records (HEX86)
693+
// format ":02000004FFFFFC"
694+
695+
// perform sanity checks
696+
if (addressRecord == null ||
697+
addressRecord.Length != 15 ||
698+
addressRecord.Substring(0, 9) != ":02000004")
699+
{
700+
// wrong format
701+
throw new FormatException("Wrong data in nanoBooter file");
702+
}
703+
704+
// looking good, grab the upper 16bits
705+
address = (uint)int.Parse(addressRecord.Substring(9, 4), System.Globalization.NumberStyles.HexNumber);
706+
address <<= 16;
707+
708+
// now the 2nd line to get the lower 16 bits of the address
709+
addressRecord = textLines.Skip(1).FirstOrDefault();
710+
711+
// 2nd line is a Data Record
712+
// format ":10246200464C5549442050524F46494C4500464C33"
713+
714+
// perform sanity checks
715+
if (addressRecord == null ||
716+
addressRecord.Substring(0, 1) != ":" ||
717+
addressRecord.Length < 7)
718+
{
719+
// wrong format
720+
throw new FormatException("Wrong data in nanoBooter file");
721+
}
722+
723+
// looking good, grab the lower 16bits
724+
address += (uint)int.Parse(addressRecord.Substring(3, 4), System.Globalization.NumberStyles.HexNumber);
725+
726+
BooterStartAddress = address;
727+
}
728+
729+
private void FindClrStartAddress()
730+
{
731+
uint address;
732+
733+
// find out what's the CLR block start
734+
735+
// do this by reading the HEX format file...
736+
var textLines = File.ReadAllLines(NanoClrFile);
737+
738+
// ... and decoding the start address
739+
var addressRecord = textLines.FirstOrDefault();
740+
741+
// 1st line is an Extended Segment Address Records (HEX86)
742+
// format ":02000004FFFFFC"
743+
744+
// perform sanity checks
745+
if (addressRecord == null ||
746+
addressRecord.Length != 15 ||
747+
addressRecord.Substring(0, 9) != ":02000004")
748+
{
749+
// wrong format
750+
throw new FormatException("Wrong data in nanoClr file");
751+
}
752+
753+
// looking good, grab the upper 16bits
754+
address = (uint)int.Parse(addressRecord.Substring(9, 4), System.Globalization.NumberStyles.HexNumber);
755+
address <<= 16;
756+
757+
// now the 2nd line to get the lower 16 bits of the address
758+
addressRecord = textLines.Skip(1).FirstOrDefault();
759+
760+
// 2nd line is a Data Record
761+
// format ":10246200464C5549442050524F46494C4500464C33"
762+
763+
// perform sanity checks
764+
if (addressRecord == null ||
765+
addressRecord.Substring(0, 1) != ":" ||
766+
addressRecord.Length < 7)
767+
{
768+
// wrong format
769+
throw new FormatException("Wrong data in nanoClr file");
770+
}
771+
772+
// looking good, grab the lower 16bits
773+
address += (uint)int.Parse(addressRecord.Substring(3, 4), System.Globalization.NumberStyles.HexNumber);
774+
775+
ClrStartAddress = address;
776+
}
777+
778+
internal void PostProcessDownloadAndExtract()
779+
{
780+
NanoBooterFile = Directory.EnumerateFiles(LocationPath, "nanoBooter.hex").FirstOrDefault();
781+
NanoClrFile = Directory.EnumerateFiles(LocationPath, "nanoCLR.hex").FirstOrDefault();
782+
783+
if (NanoBooterFile != null)
784+
{
785+
FindBooterStartAddress();
786+
}
787+
788+
FindClrStartAddress();
789+
}
630790
}
631791

632792
}

0 commit comments

Comments
 (0)