Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Storage Operation Commands #374

Merged
merged 14 commits into from
Mar 21, 2024
43 changes: 23 additions & 20 deletions USB Test App WPF/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,33 @@
<Button Content="Disconnect" HorizontalAlignment="Left" Margin="250,102,0,0" VerticalAlignment="Top" Width="98" Click="DisconnectDeviceButton_Click"/>
<Button Content="Ping" HorizontalAlignment="Left" Margin="250,129,0,0" VerticalAlignment="Top" Width="98" Click="PingButton_Click" />

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

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

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

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


</Grid>
Expand Down
41 changes: 41 additions & 0 deletions USB Test App WPF/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,5 +1092,46 @@ private void DeployFileTestButton_Click(object sender, RoutedEventArgs e)
// enable button
(sender as Button).IsEnabled = true;
}

private void UploadFileInternalStorage_Click(object sender, RoutedEventArgs e)
{
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" +
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " +
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
"2. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\r\n" +
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " +
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
"3. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\r\n" +
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " +
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
"4. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\r\n";
//string fileContent = "simple test file";
string fileName = "I:\\upload.txt";

// disable button
(sender as Button).IsEnabled = false;

var reply1 = (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.AddStorageFile(fileName, Encoding.UTF8.GetBytes(fileContent));
Debug.WriteLine($"File upload internal success: {reply1}");

// enable button
(sender as Button).IsEnabled = true;
}

private void RemoveFileInternalStorage_Click(object sender, RoutedEventArgs e)
{
string fileName = "I:\\upload.txt";
// disable button
(sender as Button).IsEnabled = false;

var reply1 = (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.DeleteStorageFile(fileName);
Debug.WriteLine($"File upload internal success: {reply1}");

// enable button
(sender as Button).IsEnabled = true;
}
}
}
174 changes: 173 additions & 1 deletion nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,45 @@ public enum AccessMemoryErrorCodes : uint
Unknown = 0xFFFF,
}

/// <summary>
/// Storage operation error codes.
/// </summary>
public enum StorageOperationErrorCode : uint
{
///////////////////////////////////////////////////////////////////////////////////////////
// NEED TO KEEP THESE IN SYNC WITH native 'StorageOperationErrorCode' enum in Debugger.h //
///////////////////////////////////////////////////////////////////////////////////////////

/// <summary>
/// No error.
/// </summary>
NoError = 0x0001,

/// <summary>
/// Write error.
/// </summary>
WriteError = 0x0010,

/// <summary>
/// Delete error.
/// </summary>
DeleteError = 0x0020,

/// <summary>
/// Platform dependent error.
/// </summary>
PlatformError = 0x0030,

/////////////////////////////////////////////////////////
// The following element is not present in native code //
/////////////////////////////////////////////////////////

/// <summary>
/// Target does not support storage operations.
/// </summary>
NotSupported = 0xFFFF,
}

public class Commands
{
public const uint c_Monitor_Ping = 0x00000000; // The payload is empty, this command is used to let the other side know we are here...
Expand All @@ -58,6 +97,7 @@ public class Commands
public const uint c_Monitor_OemInfo = 0x0000000E;
public const uint c_Monitor_QueryConfiguration = 0x0000000F;
public const uint c_Monitor_UpdateConfiguration = 0x00000010;
public const uint c_Monitor_StorageOperation = 0x00000011;
public const uint c_Monitor_TargetInfo = 0x00000020;

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

/// <summary>
/// Perform storage operation on the target device.
/// </summary>
public class Monitor_StorageOperation : OverheadBase
{
/// <summary>
/// Storage operation to be performed.
/// </summary>
public uint Operation = (byte)StorageOperation.None;

/// <summary>
/// File name for the the storage operation.
/// </summary>
[IgnoreDataMember]
public string FileName = string.Empty;

/// <summary>
/// Length of the name of the file to be used in the operation.
/// </summary>
public uint NameLength = 0;

/// <summary>
/// Length of the data to be used in the operation.
/// </summary>
public uint DataLength = 0;

/// <summary>
/// Offset in the file data of the chunck in this operation.
/// </summary>
/// <remarks>
/// This is to be used by the target device to know where to start writing the chunk data.
/// </remarks>
public uint Offset = 0;

/// <summary>
/// Data buffer to be sent to the device.
/// </summary>
public byte[] Data;

public class Reply
{
public uint ErrorCode;
};

/// <summary>
/// Prepare for sending a storage operation to the target device.
/// </summary>
/// <param name="operation"><see cref="StorageOperation"/> to be performed.</param>
/// <param name="name">Name of the file to be used in the operation.</param>
public void SetupOperation(
StorageOperation operation,
string name)
{
Operation = (uint)operation;
FileName = name;
}

/// <summary>
/// Prepare for sending a storage operation to the target device.
/// </summary>
/// <param name="buffer">Data buffer to be sent to the device.</param>
/// <param name="offset">Offset in the <paramref name="buffer"/> to start copying data from.</param>
/// <param name="length">Length of the data to be copied from the <paramref name="buffer"/>.</param>
public override bool PrepareForSend(
byte[] buffer,
int length,
int offset = 0)
{
// setup the data payload
DataLength = (uint)length;
josesimoes marked this conversation as resolved.
Show resolved Hide resolved
Data = new byte[length + FileName.Length];

// add the file name to the data property buffer
var tempName = Encoding.UTF8.GetBytes(FileName);
NameLength = (uint)tempName.Length;
Array.Copy(tempName, 0, Data, 0, NameLength);

// copy the buffer data to the data property buffer
Array.Copy(buffer, offset, Data, NameLength, length);

return true;
}

internal void PrepareForSend()
{
// add the file name to the data property buffer
Data = Encoding.UTF8.GetBytes(FileName);
NameLength = (uint)FileName.Length;
}

//////////////////////////////////////////////////////////////////////////////////////
// !!! KEEP IN SYNC WITH typedef enum Monitor_StorageOperation (in native code) !!! //
//////////////////////////////////////////////////////////////////////////////////////

/// <summary>
/// Storage operation to be performed.
/// </summary>
public enum StorageOperation : byte
{
/// <summary>
/// Not specified.
/// </summary>
None = 0,

/// <summary>
/// Write to storage.
/// </summary>
/// <remarks>
/// If the file already exists, it will be overwritten.
/// </remarks>
Write = 1,

/// <summary>
/// Delete from storage.
/// </summary>
/// <remarks>
/// If the file doesn't exist, no action is taken.
/// </remarks>
Delete = 2,

/// <summary>
/// Append to a file.
/// </summary>
/// <remarks>
/// If the file doesn't exist, no action is taken.
/// </remarks>
Append = 3
}
}

public const uint c_Debugging_Execution_BasePtr = 0x00020000; // Returns the pointer for the ExecutionEngine object.
public const uint c_Debugging_Execution_ChangeConditions = 0x00020001; // Sets/resets the state of the debugger.
public const uint c_Debugging_Execution_SecurityKey = 0x00020002; // Sets security key.
Expand Down Expand Up @@ -1857,7 +2027,7 @@ internal static string GetZeroTerminatedString(byte[] buf, bool fUTF8)
while (len < num && buf[len] != 0) len++;

if (fUTF8) return Encoding.UTF8.GetString(buf, 0, len);
else return Encoding.UTF8.GetString(buf, 0, len);
else return Encoding.ASCII.GetString(buf, 0, len);
}

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

case c_Debugging_Execution_BasePtr: return new Debugging_Execution_BasePtr.Reply();
case c_Debugging_Execution_ChangeConditions: return new DebuggingExecutionChangeConditions.Reply();
Expand Down Expand Up @@ -1951,6 +2122,7 @@ public static object ResolveCommandToPayload(uint cmd, bool fReply, CLRCapabilit
case c_Monitor_DeploymentMap: return new Monitor_DeploymentMap();
case c_Monitor_FlashSectorMap: return new Monitor_FlashSectorMap();
case c_Monitor_QueryConfiguration: return new Monitor_QueryConfiguration();
case c_Monitor_StorageOperation: return new Monitor_StorageOperation();

case c_Debugging_Execution_BasePtr: return new Debugging_Execution_BasePtr();
case c_Debugging_Execution_ChangeConditions: return new DebuggingExecutionChangeConditions();
Expand Down
Loading