Renode SPI Connection crashing

62 views Asked by At

I'm trying to use the SPI connector from this commit in Renode. The connector itself is here. It hasn't been merged yet, so I have to include the files directly to get it to run. Here's my Renode script file, mostly taken directly from the tests in the commit:

include @SPISlaveModeController.cs
include @SPIMasterModeController.cs
include @SPIConnector.cs

emulation CreateSPIConnector "spi-con"

mach create "Peripheral"
machine LoadPlatformDescriptionFromString "spis: SPI.SPISlaveModeController @ sysbus 0x00000000"
connector Connect sysbus.spis "spi-con"

mach create "Controller"
machine LoadPlatformDescriptionFromString "spim: SPI.SPIMasterModeController @ sysbus 0x00000000"
connector Connect sysbus.spim "spi-con"

start

Now, using the SPIMasterModeController.cs from the example above everything works. My problem comes when I try to do anything with the Connector outside the constructor. I want to have the master call Transmit when I write to an address in it. Here's my minimal example code:

using Antmicro.Renode.Core;
using Antmicro.Renode.Core.Structure;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Time;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Peripherals.Timers;

namespace Antmicro.Renode.Peripherals.SPI
{
    public class SPIMasterModeController :
        NullRegistrationPointPeripheralContainer<ISPIPeripheral>,
        IBytePeripheral,
        IKnownSize
    {
        public SPIMasterModeController(Machine machine) : base(machine)
        {
            timer = new LimitTimer(machine.ClockSource, 1000, this,
                                   "master_clk", workMode: WorkMode.Periodic,
                                   eventEnabled: true, limit: 1, enabled: true);
            timer.LimitReached += () =>
            {
                var output = RegisteredPeripheral.Transmit(0xa5);
                this.Log(LogLevel.Info, "Master sent:{0} received:{1}", 0xa5,
                         output);
                RegisteredPeripheral.FinishTransmission();
                timer.Enabled = false;
            };
        }

        public byte ReadByte(long offset)
        {
            return 0x0;
        }

        public void WriteByte(long offset, byte value)
        {
            // if (offset == 0)
            // {
            //     timer.Enabled = true;
            // }
            // if (offset == 1)
            // {
            //     timer.Enabled = false;
            // }
            if (offset == 0)
            {
                RegisteredPeripheral.Transmit(value);
            }
            else
            {
                RegisteredPeripheral.FinishTransmission();
            }
        }

        public override void Reset()
        {
        }

        public long Size => 0x100;
        private LimitTimer timer;
    }
}

If I swap the implementation of WriteByte here, by uncommenting the commented code and commenting out the uncommented code, things work. I can send sysbus.spim WriteByte 0 0 and I get the messages from the slave about the transmission succeeding. However, as it is, when I send sysbus.spim WriteByte 0 0, Renode crashes with the following error.

[ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentException: Tried to obtain a virtual time stamp of an unregistered thread: 'Shell thread'/7
  at Antmicro.Renode.Time.TimeDomainsManager.get_VirtualTimeStamp () [0x0003c] in <b05710e063024506ba998245a09a24f0>:0 
  at Antmicro.Renode.Peripherals.SPI.SPIConnector.Transmit (System.Byte data) [0x0004d] in <df90037be0e74203ae6fcba2643fcb70>:0 
  at Antmicro.Renode.Peripherals.SPI.SPIMasterModeController.WriteByte (System.Int64 offset, System.Byte value) [0x00008] in <311068778e6543b9b3f5b2c22a93fb55>:0 
  at (wrapper dynamic-method) System.Object.CallSite.Target(System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object,object,object)
  at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3[T0,T1,T2] (System.Runtime.CompilerServices.CallSite site, T0 arg0, T1 arg1, T2 arg2) [0x00141] in <d22af090bceb4be792f53595cf074724>:0 
  at Dynamitey.Internal.Optimization.InvokeHelper.InvokeMemberAction (System.Runtime.CompilerServices.CallSite& callsite, System.Type binderType, System.Int32 knownType, Dynamitey.Internal.Optimization.InvokeHelper+LazyBinder binder, Dynamitey.InvokeMemberName name, System.Boolean staticContext, System.Type context, System.String[] argNames, System.Object target, System.Object[] args) [0x000df] in <1d0e1ef63ad2470a9ccec81105ee1302>:0 
  at Dynamitey.Internal.Optimization.InvokeHelper.InvokeMemberActionCallSite (System.Object target, Dynamitey.InvokeMemberName name, System.Object[] args, System.String[] tArgNames, System.Type tContext, System.Boolean tStaticContext, System.Runtime.CompilerServices.CallSite& callSite) [0x0004f] in <1d0e1ef63ad2470a9ccec81105ee1302>:0 
  at Dynamitey.Dynamic.InvokeMemberAction (System.Object target, Dynamitey.String_OR_InvokeMemberName name, System.Object[] args) [0x00018] in <1d0e1ef63ad2470a9ccec81105ee1302>:0 
  at Antmicro.Renode.UserInterface.Monitor.InvokeWithContext (Dynamitey.InvokeContext context, System.Reflection.MethodInfo method, System.Object[] parameters) [0x00023] in <11d556aecc3649618ce70f6971350082>:0 
  at Antmicro.Renode.UserInterface.Monitor.InvokeMethod (System.String name, System.Reflection.MethodInfo method, System.Collections.Generic.List`1[T] parameters) [0x0001a] in <11d556aecc3649618ce70f6971350082>:0 
  at Antmicro.Renode.UserInterface.Monitor.ExecuteDeviceAction (System.Type type, System.String name, System.Collections.Generic.IEnumerable`1[T] p) [0x00216] in <11d556aecc3649618ce70f6971350082>:0 
  at Antmicro.Renode.UserInterface.Monitor.ProcessDeviceAction (System.Type device, System.String name, System.Collections.Generic.IEnumerable`1[T] p, AntShell.Commands.ICommandInteraction writer) [0x00023] in <11d556aecc3649618ce70f6971350082>:0 
  at Antmicro.Renode.UserInterface.Monitor.ProcessDeviceActionByName (System.String name, System.Collections.Generic.IEnumerable`1[T] p, AntShell.Commands.ICommandInteraction writer) [0x00060] in <11d556aecc3649618ce70f6971350082>:0 
  at Antmicro.Renode.UserInterface.Monitor.ExecuteCommand (Antmicro.Renode.UserInterface.Tokenizer.Token[] com, AntShell.Commands.ICommandInteraction writer) [0x00165] in <11d556aecc3649618ce70f6971350082>:0 
  at Antmicro.Renode.UserInterface.Monitor.ParseTokens (System.Collections.Generic.IEnumerable`1[T] tokensToParse, AntShell.Commands.ICommandInteraction writer) [0x001df] in <11d556aecc3649618ce70f6971350082>:0 
  at Antmicro.Renode.UserInterface.Monitor.Parse (System.String cmd, AntShell.Commands.ICommandInteraction writer) [0x0019d] in <11d556aecc3649618ce70f6971350082>:0 
  at Antmicro.Renode.UserInterface.Monitor.HandleCommand (System.String cmd, AntShell.Commands.ICommandInteraction ci) [0x00000] in <11d556aecc3649618ce70f6971350082>:0 
  at AntShell.Shell.HandleCommand (System.String cmd, AntShell.Commands.ICommandInteraction ic) [0x000bd] in <12b5ceac888f4387a227ffd402a29e15>:0 
  at AntShell.CommandLine.HandleControlSequence (AntShell.Helpers.ControlSequence seq) [0x00aa1] in <12b5ceac888f4387a227ffd402a29e15>:0 
  at AntShell.Terminal.NavigableTerminalEmulator.HandleInput (System.Object input) [0x0002e] in <12b5ceac888f4387a227ffd402a29e15>:0 
  at AntShell.Terminal.NavigableTerminalEmulator.Run (System.Boolean stopOnError) [0x00017] in <12b5ceac888f4387a227ffd402a29e15>:0 
  at AntShell.Shell.Start (System.Boolean stopOnError) [0x00102] in <12b5ceac888f4387a227ffd402a29e15>:0 
  at Antmicro.Renode.UI.CommandLineInterface+<>c__DisplayClass0_1.<Run>b__3 (System.Object x) [0x00000] in <eb0d5c6c2ada4750b5c3a3c345d7e4f8>:0 
  at System.Threading.ThreadHelper.ThreadStart_Context (System.Object state) [0x0002c] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x0008d] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) [0x00031] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.ThreadHelper.ThreadStart (System.Object obj) [0x00012] in <12b418a7818c4ca0893feeaaf67f1e7f>:0

I'm not sufficiently familiar with C# in general or how Renode in particular works to know why this is happening. It seems like RegisteredPeripheral is only available in the constructor, but when I print it inside WriteByte it looks decidedly non-null.

0

There are 0 answers