Document how to debug C# modules
xobs opened this issue · 4 comments
Writing C# modules unlocks a lot of functionality in Renode, however it's very difficult to debug these modules.
For example, in this module:
using System;
using Antmicro.Renode.Core;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Time;
using Antmicro.Renode.Logging;
using System.Threading;
namespace Antmicro.Renode.Peripherals.Timers
{
public class SimpleTicker : IDoubleWordPeripheral
{
public SimpleTicker(ulong periodInMs, Machine machine)
{
machine.ClockSource.AddClockEntry(new ClockEntry(periodInMs, ClockEntry.FrequencyToRatio(this, 1000), OnTick, this, String.Empty));
}
// ...
}
}
It's difficult to know:
- What properties there are on
machine
- Where
Machine
is defined (which package does it come from?) - What do each of the parameters in that function mean?
- What is a
ClockSource
and how does it work? - What other properties are there in
Antmicro.Renode.Peripherals
? - What is the interface required to implement
IDoubleWordPeripheral
? - Does this even compile?
Many of these questions could be answered by connecting this .cs
file to an IDE of some sort. I'm not sure how 2
could be answered, because I gather that's a feature of C#. 7
can only be answered by restarting Renode.
With C# modules being documented, it would also be nice to know how to implement modules and debug issues within them.
I'm starting to understand how to integrate this with Omnisharp.
I now have this:
Note the gray up top, indicating I'm not using particular modules. Also, note that mouseover gives information on arguments.
And if I control-click on a symbol, it brings me to a useful screen describing it:
In order to get this, create a .csproj
file somewhere in the directory and point it to Renode. In my case, this file looks like:
Click to show `peripherals.csproj`
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PlatformTarget>AMD64</PlatformTarget>
<RenodePath>..\..\..\..\Software\Renode\bin</RenodePath>
</PropertyGroup>
<ItemGroup>
<Reference Include="AdvancedLoggerViewerPlugin">
<HintPath>$(RenodePath)/AdvancedLoggerViewerPlugin.dll</HintPath>
</Reference>
<Reference Include="AntShell">
<HintPath>$(RenodePath)/AntShell.dll</HintPath>
</Reference>
<Reference Include="AsyncIO">
<HintPath>$(RenodePath)/AsyncIO.dll</HintPath>
</Reference>
<Reference Include="CookComputing.XmlRpcV2">
<HintPath>$(RenodePath)/CookComputing.XmlRpcV2.dll</HintPath>
</Reference>
<Reference Include="cores-arm">
<HintPath>$(RenodePath)/cores-arm.dll</HintPath>
</Reference>
<Reference Include="cores-arm-m">
<HintPath>$(RenodePath)/cores-arm-m.dll</HintPath>
</Reference>
<Reference Include="cores-i386">
<HintPath>$(RenodePath)/cores-i386.dll</HintPath>
</Reference>
<Reference Include="cores-ppc">
<HintPath>$(RenodePath)/cores-ppc.dll</HintPath>
</Reference>
<Reference Include="cores-ppc64">
<HintPath>$(RenodePath)/cores-ppc64.dll</HintPath>
</Reference>
<Reference Include="cores-riscv">
<HintPath>$(RenodePath)/cores-riscv.dll</HintPath>
</Reference>
<Reference Include="cores-riscv64">
<HintPath>$(RenodePath)/cores-riscv64.dll</HintPath>
</Reference>
<Reference Include="cores-sparc">
<HintPath>$(RenodePath)/cores-sparc.dll</HintPath>
</Reference>
<Reference Include="CxxDemangler">
<HintPath>$(RenodePath)/CxxDemangler.dll</HintPath>
</Reference>
<Reference Include="Dynamitey">
<HintPath>$(RenodePath)/Dynamitey.dll</HintPath>
</Reference>
<Reference Include="ELFSharp">
<HintPath>$(RenodePath)/ELFSharp.dll</HintPath>
</Reference>
<Reference Include="Emulator">
<HintPath>$(RenodePath)/Emulator.dll</HintPath>
</Reference>
<Reference Include="Extensions">
<HintPath>$(RenodePath)/Extensions.dll</HintPath>
</Reference>
<Reference Include="FdtSharp">
<HintPath>$(RenodePath)/FdtSharp.dll</HintPath>
</Reference>
<Reference Include="IronPython">
<HintPath>$(RenodePath)/IronPython.dll</HintPath>
</Reference>
<Reference Include="IronPython.Modules">
<HintPath>$(RenodePath)/IronPython.Modules.dll</HintPath>
</Reference>
<Reference Include="libtftp">
<HintPath>$(RenodePath)/libtftp.dll</HintPath>
</Reference>
<Reference Include="LLVMDisassembler">
<HintPath>$(RenodePath)/LLVMDisassembler.dll</HintPath>
</Reference>
<Reference Include="Lucene.Net">
<HintPath>$(RenodePath)/Lucene.Net.dll</HintPath>
</Reference>
<Reference Include="LZ4">
<HintPath>$(RenodePath)/LZ4.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Dynamic">
<HintPath>$(RenodePath)/Microsoft.Dynamic.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Scripting">
<HintPath>$(RenodePath)/Microsoft.Scripting.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Scripting.Metadata">
<HintPath>$(RenodePath)/Microsoft.Scripting.Metadata.dll</HintPath>
</Reference>
<Reference Include="Migrant">
<HintPath>$(RenodePath)/Migrant.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil">
<HintPath>$(RenodePath)/Mono.Cecil.dll</HintPath>
</Reference>
<Reference Include="NetMQ">
<HintPath>$(RenodePath)/NetMQ.dll</HintPath>
</Reference>
<Reference Include="Nini">
<HintPath>$(RenodePath)/Nini.dll</HintPath>
</Reference>
<Reference Include="OptionsParser">
<HintPath>$(RenodePath)/OptionsParser.dll</HintPath>
</Reference>
<Reference Include="PacketDotNet">
<HintPath>$(RenodePath)/PacketDotNet.dll</HintPath>
</Reference>
<Reference Include="Renode">
<HintPath>$(RenodePath)/Renode.exe</HintPath>
</Reference>
<Reference Include="Renode-peripherals">
<HintPath>$(RenodePath)/Renode-peripherals.dll</HintPath>
</Reference>
<Reference Include="SampleCommandPlugin">
<HintPath>$(RenodePath)/SampleCommandPlugin.dll</HintPath>
</Reference>
<Reference Include="Sprache">
<HintPath>$(RenodePath)/Sprache.dll</HintPath>
</Reference>
<Reference Include="TermSharp">
<HintPath>$(RenodePath)/TermSharp.dll</HintPath>
</Reference>
<Reference Include="TracePlugin">
<HintPath>$(RenodePath)/TracePlugin.dll</HintPath>
</Reference>
<Reference Include="UI">
<HintPath>$(RenodePath)/UI.dll</HintPath>
</Reference>
<Reference Include="VerilatorPlugin">
<HintPath>$(RenodePath)/VerilatorPlugin.dll</HintPath>
</Reference>
<Reference Include="WiresharkPlugin">
<HintPath>$(RenodePath)/WiresharkPlugin.dll</HintPath>
</Reference>
<Reference Include="Xwt">
<HintPath>$(RenodePath)/Xwt.dll</HintPath>
</Reference>
<Reference Include="Xwt.WPF">
<HintPath>$(RenodePath)/Xwt.WPF.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
This obviously has a lot of platform-specific cruft. And I'm not sure on the <TargetFramework>netstandard2.0</TargetFramework>
value -- isn't it a different version on Windows?
At any rate, this gives me syntax checking, autocomplete, and rudimentary documentation. It also doesn't require me to compile Renode, since I'm just using the binaries directly.
Edit: The csproj
file was updated to parameterize it to include RenodePath
as a build variable, and to add forward slashes. I'd appreciate seeing if this works on non-Windows platforms, and if so perhaps this could be put forward as an official solution to the issue.
I updated the peripherals.csproj
file in original comment to make it more cross-platform and less unwieldy. I'd appreciate someone else giving it a try to see if it works for them.
Hey @xobs, this is really cool.
We'll take a look internally and then maybe we'd be able to somehow include it in our packages, so that everyone can use it with simple instructions (like cp this file to your dir, start vscode, install omnisharp, voila
)