Skip to content

Commit e9212f7

Browse files
authored
Add Storage Operation Commands (#374)
1 parent 3299eee commit e9212f7

File tree

4 files changed

+460
-21
lines changed

4 files changed

+460
-21
lines changed

USB Test App WPF/MainWindow.xaml

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,33 @@
2727
<Button Content="Disconnect" HorizontalAlignment="Left" Margin="250,102,0,0" VerticalAlignment="Top" Width="98" Click="DisconnectDeviceButton_Click"/>
2828
<Button Content="Ping" HorizontalAlignment="Left" Margin="250,129,0,0" VerticalAlignment="Top" Width="98" Click="PingButton_Click" />
2929

30-
<Button Content="Get Execution" HorizontalAlignment="Left" Margin="250,195,0,0" VerticalAlignment="Top" Width="98" Click="GetExecutionModeButton_Click"/>
31-
<Button Content="Deploy Test" HorizontalAlignment="Left" Margin="162,235,0,0" VerticalAlignment="Top" Width="75" Click="DeployTestButton_Click" />
32-
<Button Content="Get Deployment Map" HorizontalAlignment="Left" Margin="162,275,0,0" VerticalAlignment="Top" Width="75" Click="GetDeploymentMapButton_Click" />
30+
<Button Content="Get Execution" HorizontalAlignment="Left" Margin="250,187,0,0" VerticalAlignment="Top" Width="98" Click="GetExecutionModeButton_Click"/>
31+
<Button Content="Deploy Test" HorizontalAlignment="Left" Margin="162,216,0,0" VerticalAlignment="Top" Width="75" Click="DeployTestButton_Click" />
32+
<Button Content="Get Deployment Map" HorizontalAlignment="Left" Margin="162,245,0,0" VerticalAlignment="Top" Width="75" Click="GetDeploymentMapButton_Click" />
3333

34-
<Button Content="Device Capabilites" HorizontalAlignment="Left" Margin="39,195,0,0" VerticalAlignment="Top" Width="110" Click="DeviceCapabilitesButton_Click" />
35-
<Button Content="Flash Map" HorizontalAlignment="Left" Margin="39,275,0,0" VerticalAlignment="Top" Width="110" Click="FlashMapButton_Click" />
36-
<Button Content="Resolve Assemblies" HorizontalAlignment="Left" Margin="39,235,0,0" VerticalAlignment="Top" Width="110" Click="ResolveAssembliesButton_Click" />
34+
<Button Content="Device Capabilites" HorizontalAlignment="Left" Margin="39,187,0,0" VerticalAlignment="Top" Width="110" Click="DeviceCapabilitesButton_Click" />
35+
<Button Content="Flash Map" HorizontalAlignment="Left" Margin="39,245,0,0" VerticalAlignment="Top" Width="110" Click="FlashMapButton_Click" />
36+
<Button Content="Resolve Assemblies" HorizontalAlignment="Left" Margin="39,216,0,0" VerticalAlignment="Top" Width="110" Click="ResolveAssembliesButton_Click" />
3737

38-
<Button Content="Pause Execution" HorizontalAlignment="Left" Margin="250,235,0,0" VerticalAlignment="Top" Width="98" Click="PauseExecutionButton_Click" />
39-
<Button Content="Resume Execution" HorizontalAlignment="Left" Margin="250,275,0,0" VerticalAlignment="Top" Width="98" Click="ResumeExecutionButton_Click" />
38+
<Button Content="Pause Execution" HorizontalAlignment="Left" Margin="250,216,0,0" VerticalAlignment="Top" Width="98" Click="PauseExecutionButton_Click" />
39+
<Button Content="Resume Execution" HorizontalAlignment="Left" Margin="250,245,0,0" VerticalAlignment="Top" Width="98" Click="ResumeExecutionButton_Click" />
4040

41-
<Button Content="Reboot CLR" HorizontalAlignment="Left" Margin="378,77,0,0" VerticalAlignment="Top" Width="121" Click="RebootDeviceButton_Click"/>
42-
<Button Content="Soft Reboot" HorizontalAlignment="Left" Margin="378,102,0,0" VerticalAlignment="Top" Width="121" Click="SoftRebootDeviceButton_Click"/>
43-
<Button Content="Reboot to bootloader" HorizontalAlignment="Left" Margin="378,129,0,0" VerticalAlignment="Top" Width="121" Click="RebootToBootloaderButton_Click"/>
44-
<Button Content="Stop Processing" HorizontalAlignment="Left" Margin="378,195,0,0" VerticalAlignment="Top" Width="121" Click="StopProcessingButton_Click"/>
45-
<Button Content="Erase Deployment" HorizontalAlignment="Left" Margin="378,235,0,0" VerticalAlignment="Top" Width="121" Click="EraseDeploymentButton_Click" />
46-
<Button Content="Is Init State" HorizontalAlignment="Left" Margin="162,195,0,0" VerticalAlignment="Top" Width="75" Click="IsInitStateButton_Click" />
47-
<Button Content="Get Device Config" HorizontalAlignment="Left" Margin="378,275,0,0" VerticalAlignment="Top" Width="121" Click="GetDeviceConfigButton_Click" />
48-
<Button Content="Set Device Config" HorizontalAlignment="Left" Margin="378,313,0,0" VerticalAlignment="Top" Width="121" Click="SetDeviceConfigButton_Click" />
41+
<Button Content="Reboot CLR" HorizontalAlignment="Left" Margin="364,77,0,0" VerticalAlignment="Top" Width="121" Click="RebootDeviceButton_Click"/>
42+
<Button Content="Soft Reboot" HorizontalAlignment="Left" Margin="364,102,0,0" VerticalAlignment="Top" Width="121" Click="SoftRebootDeviceButton_Click"/>
43+
<Button Content="Reboot to bootloader" HorizontalAlignment="Left" Margin="364,129,0,0" VerticalAlignment="Top" Width="121" Click="RebootToBootloaderButton_Click"/>
44+
<Button Content="Stop Processing" HorizontalAlignment="Left" Margin="364,187,0,0" VerticalAlignment="Top" Width="121" Click="StopProcessingButton_Click"/>
45+
<Button Content="Erase Deployment" HorizontalAlignment="Left" Margin="364,216,0,0" VerticalAlignment="Top" Width="121" Click="EraseDeploymentButton_Click" />
46+
<Button Content="Is Init State" HorizontalAlignment="Left" Margin="162,187,0,0" VerticalAlignment="Top" Width="75" Click="IsInitStateButton_Click" />
47+
<Button Content="Get Device Config" HorizontalAlignment="Left" Margin="364,245,0,0" VerticalAlignment="Top" Width="121" Click="GetDeviceConfigButton_Click" />
48+
<Button Content="Set Device Config" HorizontalAlignment="Left" Margin="364,275,0,0" VerticalAlignment="Top" Width="121" Click="SetDeviceConfigButton_Click" />
4949
<Button Content="ReScan devices" HorizontalAlignment="Left" Margin="250,157,0,0" VerticalAlignment="Top" Width="98" Click="ReScanDevices_Click" />
50-
<Button Content="Read Test" HorizontalAlignment="Left" Margin="250,313,0,0" VerticalAlignment="Top" Width="98" Click="ReadTestButton_Click" />
51-
<Button Content="Target Info" HorizontalAlignment="Left" Margin="39,313,0,0" VerticalAlignment="Top" Width="110" Click="TargetInfoButton_Click" />
52-
<Button Content="Reboot to nanoBooter" HorizontalAlignment="Left" Margin="378,157,0,0" VerticalAlignment="Top" Width="121" Click="RebootToNanoBooterButton_Click"/>
53-
<Button Content="Deploy File" HorizontalAlignment="Left" Margin="162,313,0,0" VerticalAlignment="Top" Width="75" Click="DeployFileTestButton_Click" />
50+
<Button Content="Read Test" HorizontalAlignment="Left" Margin="250,275,0,0" VerticalAlignment="Top" Width="98" Click="ReadTestButton_Click" />
51+
<Button Content="Target Info" HorizontalAlignment="Left" Margin="39,275,0,0" VerticalAlignment="Top" Width="110" Click="TargetInfoButton_Click" />
52+
<Button Content="Reboot to nanoBooter" HorizontalAlignment="Left" Margin="364,157,0,0" VerticalAlignment="Top" Width="121" Click="RebootToNanoBooterButton_Click"/>
53+
<Button Content="Deploy File" HorizontalAlignment="Left" Margin="162,275,0,0" VerticalAlignment="Top" Width="75" Click="DeployFileTestButton_Click" />
54+
<Button Content="Reboot CLR" HorizontalAlignment="Left" Margin="364,77,0,0" VerticalAlignment="Top" Width="121" Click="RebootDeviceButton_Click"/>
55+
<Button Content="Upload File I:\" HorizontalAlignment="Left" Margin="39,306,0,0" VerticalAlignment="Top" Width="110" Click="UploadFileInternalStorage_Click"/>
56+
<Button Content="Rm file I:\" HorizontalAlignment="Left" Margin="162,306,0,0" VerticalAlignment="Top" Width="75" Click="RemoveFileInternalStorage_Click"/>
5457

5558

5659
</Grid>

USB Test App WPF/MainWindow.xaml.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,5 +1092,46 @@ private void DeployFileTestButton_Click(object sender, RoutedEventArgs e)
10921092
// enable button
10931093
(sender as Button).IsEnabled = true;
10941094
}
1095+
1096+
private void UploadFileInternalStorage_Click(object sender, RoutedEventArgs e)
1097+
{
1098+
string fileContent = "1. This is a test file to upload in internal storage. A long message to test more than just a line.\r\n" +
1099+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
1100+
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " +
1101+
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
1102+
"2. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\r\n" +
1103+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
1104+
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " +
1105+
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
1106+
"3. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\r\n" +
1107+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
1108+
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " +
1109+
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
1110+
"4. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\r\n";
1111+
//string fileContent = "simple test file";
1112+
string fileName = "I:\\upload.txt";
1113+
1114+
// disable button
1115+
(sender as Button).IsEnabled = false;
1116+
1117+
var reply1 = (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.AddStorageFile(fileName, Encoding.UTF8.GetBytes(fileContent));
1118+
Debug.WriteLine($"File upload internal success: {reply1}");
1119+
1120+
// enable button
1121+
(sender as Button).IsEnabled = true;
1122+
}
1123+
1124+
private void RemoveFileInternalStorage_Click(object sender, RoutedEventArgs e)
1125+
{
1126+
string fileName = "I:\\upload.txt";
1127+
// disable button
1128+
(sender as Button).IsEnabled = false;
1129+
1130+
var reply1 = (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.DeleteStorageFile(fileName);
1131+
Debug.WriteLine($"File upload internal success: {reply1}");
1132+
1133+
// enable button
1134+
(sender as Button).IsEnabled = true;
1135+
}
10951136
}
10961137
}

nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Commands.cs

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,45 @@ public enum AccessMemoryErrorCodes : uint
4141
Unknown = 0xFFFF,
4242
}
4343

44+
/// <summary>
45+
/// Storage operation error codes.
46+
/// </summary>
47+
public enum StorageOperationErrorCode : uint
48+
{
49+
///////////////////////////////////////////////////////////////////////////////////////////
50+
// NEED TO KEEP THESE IN SYNC WITH native 'StorageOperationErrorCode' enum in Debugger.h //
51+
///////////////////////////////////////////////////////////////////////////////////////////
52+
53+
/// <summary>
54+
/// No error.
55+
/// </summary>
56+
NoError = 0x0001,
57+
58+
/// <summary>
59+
/// Write error.
60+
/// </summary>
61+
WriteError = 0x0010,
62+
63+
/// <summary>
64+
/// Delete error.
65+
/// </summary>
66+
DeleteError = 0x0020,
67+
68+
/// <summary>
69+
/// Platform dependent error.
70+
/// </summary>
71+
PlatformError = 0x0030,
72+
73+
/////////////////////////////////////////////////////////
74+
// The following element is not present in native code //
75+
/////////////////////////////////////////////////////////
76+
77+
/// <summary>
78+
/// Target does not support storage operations.
79+
/// </summary>
80+
NotSupported = 0xFFFF,
81+
}
82+
4483
public class Commands
4584
{
4685
public const uint c_Monitor_Ping = 0x00000000; // The payload is empty, this command is used to let the other side know we are here...
@@ -58,6 +97,7 @@ public class Commands
5897
public const uint c_Monitor_OemInfo = 0x0000000E;
5998
public const uint c_Monitor_QueryConfiguration = 0x0000000F;
6099
public const uint c_Monitor_UpdateConfiguration = 0x00000010;
100+
public const uint c_Monitor_StorageOperation = 0x00000011;
61101
public const uint c_Monitor_TargetInfo = 0x00000020;
62102

63103
public class Monitor_Message : IConverter
@@ -529,6 +569,136 @@ public override bool PrepareForSend(byte[] data, int length, int offset = 0)
529569
}
530570
}
531571

572+
/// <summary>
573+
/// Perform storage operation on the target device.
574+
/// </summary>
575+
public class Monitor_StorageOperation : OverheadBase
576+
{
577+
/// <summary>
578+
/// Storage operation to be performed.
579+
/// </summary>
580+
public uint Operation = (byte)StorageOperation.None;
581+
582+
/// <summary>
583+
/// File name for the the storage operation.
584+
/// </summary>
585+
[IgnoreDataMember]
586+
public string FileName = string.Empty;
587+
588+
/// <summary>
589+
/// Length of the name of the file to be used in the operation.
590+
/// </summary>
591+
public uint NameLength = 0;
592+
593+
/// <summary>
594+
/// Length of the data to be used in the operation.
595+
/// </summary>
596+
public uint DataLength = 0;
597+
598+
/// <summary>
599+
/// Offset in the file data of the chunck in this operation.
600+
/// </summary>
601+
/// <remarks>
602+
/// This is to be used by the target device to know where to start writing the chunk data.
603+
/// </remarks>
604+
public uint Offset = 0;
605+
606+
/// <summary>
607+
/// Data buffer to be sent to the device.
608+
/// </summary>
609+
public byte[] Data;
610+
611+
public class Reply
612+
{
613+
public uint ErrorCode;
614+
};
615+
616+
/// <summary>
617+
/// Prepare for sending a storage operation to the target device.
618+
/// </summary>
619+
/// <param name="operation"><see cref="StorageOperation"/> to be performed.</param>
620+
/// <param name="name">Name of the file to be used in the operation.</param>
621+
public void SetupOperation(
622+
StorageOperation operation,
623+
string name)
624+
{
625+
Operation = (uint)operation;
626+
FileName = name;
627+
}
628+
629+
/// <summary>
630+
/// Prepare for sending a storage operation to the target device.
631+
/// </summary>
632+
/// <param name="buffer">Data buffer to be sent to the device.</param>
633+
/// <param name="offset">Offset in the <paramref name="buffer"/> to start copying data from.</param>
634+
/// <param name="length">Length of the data to be copied from the <paramref name="buffer"/>.</param>
635+
public override bool PrepareForSend(
636+
byte[] buffer,
637+
int length,
638+
int offset = 0)
639+
{
640+
// setup the data payload
641+
DataLength = (uint)length;
642+
Data = new byte[length + FileName.Length];
643+
644+
// add the file name to the data property buffer
645+
var tempName = Encoding.UTF8.GetBytes(FileName);
646+
NameLength = (uint)tempName.Length;
647+
Array.Copy(tempName, 0, Data, 0, NameLength);
648+
649+
// copy the buffer data to the data property buffer
650+
Array.Copy(buffer, offset, Data, NameLength, length);
651+
652+
return true;
653+
}
654+
655+
internal void PrepareForSend()
656+
{
657+
// add the file name to the data property buffer
658+
Data = Encoding.UTF8.GetBytes(FileName);
659+
NameLength = (uint)FileName.Length;
660+
}
661+
662+
//////////////////////////////////////////////////////////////////////////////////////
663+
// !!! KEEP IN SYNC WITH typedef enum Monitor_StorageOperation (in native code) !!! //
664+
//////////////////////////////////////////////////////////////////////////////////////
665+
666+
/// <summary>
667+
/// Storage operation to be performed.
668+
/// </summary>
669+
public enum StorageOperation : byte
670+
{
671+
/// <summary>
672+
/// Not specified.
673+
/// </summary>
674+
None = 0,
675+
676+
/// <summary>
677+
/// Write to storage.
678+
/// </summary>
679+
/// <remarks>
680+
/// If the file already exists, it will be overwritten.
681+
/// </remarks>
682+
Write = 1,
683+
684+
/// <summary>
685+
/// Delete from storage.
686+
/// </summary>
687+
/// <remarks>
688+
/// If the file doesn't exist, no action is taken.
689+
/// </remarks>
690+
Delete = 2,
691+
692+
/// <summary>
693+
/// Append to a file.
694+
/// </summary>
695+
/// <remarks>
696+
/// If the file doesn't exist, no action is taken.
697+
/// </remarks>
698+
Append = 3
699+
}
700+
}
701+
532702
public const uint c_Debugging_Execution_BasePtr = 0x00020000; // Returns the pointer for the ExecutionEngine object.
533703
public const uint c_Debugging_Execution_ChangeConditions = 0x00020001; // Sets/resets the state of the debugger.
534704
public const uint c_Debugging_Execution_SecurityKey = 0x00020002; // Sets security key.
@@ -1857,7 +2027,7 @@ internal static string GetZeroTerminatedString(byte[] buf, bool fUTF8)
18572027
while (len < num && buf[len] != 0) len++;
18582028

18592029
if (fUTF8) return Encoding.UTF8.GetString(buf, 0, len);
1860-
else return Encoding.UTF8.GetString(buf, 0, len);
2030+
else return Encoding.ASCII.GetString(buf, 0, len);
18612031
}
18622032

18632033
public static object ResolveCommandToPayload(uint cmd, bool fReply, CLRCapabilities capabilities)
@@ -1878,6 +2048,7 @@ public static object ResolveCommandToPayload(uint cmd, bool fReply, CLRCapabilit
18782048
case c_Monitor_FlashSectorMap: return new Monitor_FlashSectorMap.Reply();
18792049
case c_Monitor_QueryConfiguration: return new Monitor_QueryConfiguration.Reply();
18802050
case c_Monitor_UpdateConfiguration: return new Monitor_UpdateConfiguration.Reply();
2051+
case c_Monitor_StorageOperation: return new Monitor_StorageOperation.Reply();
18812052

18822053
case c_Debugging_Execution_BasePtr: return new Debugging_Execution_BasePtr.Reply();
18832054
case c_Debugging_Execution_ChangeConditions: return new DebuggingExecutionChangeConditions.Reply();
@@ -1951,6 +2122,7 @@ public static object ResolveCommandToPayload(uint cmd, bool fReply, CLRCapabilit
19512122
case c_Monitor_DeploymentMap: return new Monitor_DeploymentMap();
19522123
case c_Monitor_FlashSectorMap: return new Monitor_FlashSectorMap();
19532124
case c_Monitor_QueryConfiguration: return new Monitor_QueryConfiguration();
2125+
case c_Monitor_StorageOperation: return new Monitor_StorageOperation();
19542126

19552127
case c_Debugging_Execution_BasePtr: return new Debugging_Execution_BasePtr();
19562128
case c_Debugging_Execution_ChangeConditions: return new DebuggingExecutionChangeConditions();

0 commit comments

Comments
 (0)