33// See LICENSE file in the project root for full license information.
44//
55
6+ using nanoFramework . Tools . Debugger ;
7+ using nanoFramework . Tools . FirmwareFlasher ;
68using Newtonsoft . Json ;
79using System ;
810using 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