@@ -180,12 +180,6 @@ public byte[] Upload(ushort blockNumber, uint length)
180
180
ControlTransfer ( Request . Upload , blockNumber , ref block ) ;
181
181
return block ;
182
182
}
183
- public void Upload ( ushort blockNumber , ref byte [ ] data , int startIndex , int length )
184
- {
185
- byte [ ] block = new byte [ length ] ;
186
- ControlTransfer ( Request . Upload , blockNumber , ref block ) ;
187
- Array . Copy ( block , 0 , data , startIndex , length ) ;
188
- }
189
183
190
184
public State GetState ( )
191
185
{
@@ -450,6 +444,52 @@ private void VerifyState(Status status, State expectedState)
450
444
}
451
445
}
452
446
447
+ /// <summary>
448
+ /// Upload a block of firmware from the reconfigured DFU device.
449
+ /// </summary>
450
+ /// <param name="length">The (maximum) size of memory to upload from the device.</param>
451
+ /// <param name="blockNr">The starting block number of memory reading.</param>
452
+ /// <returns>The memory dump from the device</returns>
453
+ public byte [ ] UploadBlock ( uint length , ushort blockNr = 0 )
454
+ {
455
+ if ( ! DfuDescriptor . CanUpload )
456
+ {
457
+ throw new InvalidOperationException ( "The device doesn't support the upload operation." ) ;
458
+ }
459
+ ResetToIdle ( ) ;
460
+ byte [ ] block = new byte [ length ] ;
461
+ uint transferred = 0 ;
462
+ while ( transferred < length )
463
+ {
464
+ uint transferLen ;
465
+ if ( ( transferred + DfuDescriptor . TransferSize ) > length )
466
+ {
467
+ transferLen = length - transferred ;
468
+ }
469
+ else
470
+ {
471
+ transferLen = ( uint ) DfuDescriptor . TransferSize ;
472
+ }
473
+
474
+ var b = Upload ( blockNr , transferLen ) ;
475
+ Array . Copy ( b , 0 , block , transferred , transferLen ) ;
476
+ transferred += ( uint ) b . Length ;
477
+ blockNr ++ ;
478
+
479
+ if ( b . Length < transferLen )
480
+ {
481
+ Array . Resize ( ref block , ( int ) transferred ) ;
482
+ break ;
483
+ }
484
+ }
485
+ // if the last transfer was also TransferSize, add a 0 length transfer to terminate the upload
486
+ if ( GetState ( ) == State . UploadIdle )
487
+ {
488
+ Upload ( blockNr , 0 ) ;
489
+ }
490
+ return block ;
491
+ }
492
+
453
493
/// <summary>
454
494
/// Download a contiguous memory segment to the idling DFU device. (DFU spec 1.1)
455
495
/// </summary>
@@ -571,6 +611,16 @@ private Status SeErase(uint address)
571
611
/(\d+)\*(\d+)([\x20KM]{1})([a-g]{1})(?:,(\d+)\*(\d+)([\x20KM]{1})([a-g]{1}))*$" ,
572
612
RegexOptions . Compiled | RegexOptions . IgnorePatternWhitespace ) ;
573
613
614
+ /// <summary>
615
+ /// Parses the string description of a DFU alternate setting into a memory layout.
616
+ /// </summary>
617
+ /// <param name="altSel">DFU alternate setting index</param>
618
+ /// <returns>The parsed memory layout</returns>
619
+ private NamedLayout ParseLayout ( byte altSel )
620
+ {
621
+ return ParseLayout ( GetString ( iAlternateSetting ( altSel ) ) ) ;
622
+ }
623
+
574
624
/// <summary>
575
625
/// Parses the string description of a DFU alternate setting into a memory layout.
576
626
/// </summary>
@@ -640,8 +690,7 @@ private void Download(Dictionary<byte, NamedMemory> sortedMemory)
640
690
byte altSel = memoryWithAltSel . Key ;
641
691
var memory = memoryWithAltSel . Value ;
642
692
643
- string ml = GetString ( iAlternateSetting ( altSel ) ) ;
644
- var layout = ParseLayout ( ml ) ;
693
+ var layout = ParseLayout ( altSel ) ;
645
694
int segNo = 0 ;
646
695
int lastSeg = memory . Segments . Count - 1 ;
647
696
@@ -776,8 +825,7 @@ private Dictionary<byte, NamedMemory> SortMemoryByAltSetting(RawMemory memory)
776
825
// go through the available memories (each of which is an alternate setting)
777
826
for ( altSel = 0 ; altSel < NumberOfAlternateSettings ; altSel ++ )
778
827
{
779
- string ml = GetString ( iAlternateSetting ( altSel ) ) ;
780
- var layout = ParseLayout ( ml ) ;
828
+ var layout = ParseLayout ( altSel ) ;
781
829
int segCount = 0 ;
782
830
var newMem = new NamedMemory ( layout . Name ) ;
783
831
@@ -814,6 +862,56 @@ private Dictionary<byte, NamedMemory> SortMemoryByAltSetting(RawMemory memory)
814
862
815
863
return sortedMemory ;
816
864
}
865
+
866
+ /// <summary>
867
+ /// Upload part of the firmware image from the reconfigured DFU device.
868
+ /// </summary>
869
+ /// <param name="mblock">Memory block to read from</param>
870
+ /// <returns>The memory segment provided by the device</returns>
871
+ public Segment UploadBlock ( Block mblock )
872
+ {
873
+ // perform a bunch of tests first
874
+ if ( DfuDescriptor . DfuVersion != Protocol . SeVersion )
875
+ {
876
+ throw new InvalidOperationException ( "The device doesn't support the DFUSE protocol." ) ;
877
+ }
878
+
879
+ byte altSel = 0 ;
880
+ for ( ; altSel < NumberOfAlternateSettings ; altSel ++ )
881
+ {
882
+ var layout = ParseLayout ( altSel ) ;
883
+ if ( ( mblock . StartAddress >= layout . StartAddress ) && ( mblock . EndAddress <= layout . EndAddress ) )
884
+ {
885
+ foreach ( var block in layout . Blocks )
886
+ {
887
+ if ( block . Overlaps ( mblock ) && ! block . Permissions . IsReadable ( ) )
888
+ {
889
+ throw new ArgumentOutOfRangeException ( "mblock" , mblock , "The provided memory block is not readable on the target device." ) ;
890
+ }
891
+ }
892
+ break ;
893
+ }
894
+ }
895
+ if ( altSel == NumberOfAlternateSettings )
896
+ {
897
+ throw new ArgumentOutOfRangeException ( "mblock" , mblock , "The provided memory block is not available on the target device." ) ;
898
+ }
899
+
900
+ // select this memory layout for upload
901
+ AlternateSetting = altSel ;
902
+
903
+ // select start address
904
+ ResetToIdle ( ) ;
905
+
906
+ Status status = SeSetAddress ( ( uint ) mblock . StartAddress ) ;
907
+ VerifyState ( status , State . DnloadIdle ) ;
908
+
909
+ // perform memory dump
910
+ // TODO: ensure block number doesn't overflow
911
+ byte [ ] memory = UploadBlock ( ( uint ) mblock . Size , 2 ) ;
912
+
913
+ return new Segment ( mblock . StartAddress , memory ) ;
914
+ }
817
915
#endregion
818
916
}
819
917
}
0 commit comments