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

Document how to debug C# modules #15

Open
xobs opened this issue Oct 16, 2020 · 4 comments
Open

Document how to debug C# modules #15

xobs opened this issue Oct 16, 2020 · 4 comments

Comments

@xobs
Copy link

xobs commented Oct 16, 2020

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:

  1. What properties there are on machine
  2. Where Machine is defined (which package does it come from?)
  3. What do each of the parameters in that function mean?
  4. What is a ClockSource and how does it work?
  5. What other properties are there in Antmicro.Renode.Peripherals?
  6. What is the interface required to implement IDoubleWordPeripheral?
  7. 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.

@xobs
Copy link
Author

xobs commented Oct 27, 2020

I'm starting to understand how to integrate this with Omnisharp.

I now have this:

image

Note the gray up top, indicating I'm not using particular modules. Also, note that mouseover gives information on arguments.

I get full autocomplete:
image

And if I control-click on a symbol, it brings me to a useful screen describing it:

image

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.

@xobs
Copy link
Author

xobs commented Oct 27, 2020

Also, one can mouseover the arguments to figure out which package they come from. For example, now I know that Machine comes from Antmicro.Renode.Core:

image

@xobs
Copy link
Author

xobs commented Oct 27, 2020

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.

@PiotrZierhoffer
Copy link
Member

PiotrZierhoffer commented Oct 27, 2020

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants