TinyCore Exception (4.1)

I have a thread monitoring the Joystick that seems to be killing TinyCore for some reason. I can confirm it is exactly this method, since it is a small app and removing this removes the problem.

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            new Thread(MonitorJoystick).Start();
        }

        void MonitorJoystick()
        {
            RetroConsole.Buttons md;
            long lNextOccur = 0;
            long[] Delays = new long[] { 750 * TimeSpan.TicksPerMillisecond, 500 * TimeSpan.TicksPerMillisecond, 300 * TimeSpan.TicksPerMillisecond, 150 * TimeSpan.TicksPerMillisecond, 75 * TimeSpan.TicksPerMillisecond, 25 * TimeSpan.TicksPerMillisecond, 10 * TimeSpan.TicksPerMillisecond };
            int DelayIndex = 0;

            while (true)
            {
                md = RetroConsole.Buttons.None;
                Joystick.Position jp = joystick.GetJoystickPosition();
                if (jp.X < 0.4)
                    md = RetroConsole.Buttons.Left;
                else if (jp.X > 0.6)
                    md = RetroConsole.Buttons.Right;
                else if (jp.Y < 0.4 && jp.Y < jp.X)
                    md = RetroConsole.Buttons.Down;
                else if (jp.Y > 0.6 && jp.Y > jp.X)
                    md = RetroConsole.Buttons.Up;

                if (_jMD != md)
                {
                    if (_jMD != RetroConsole.Buttons.None)
                        RC.SendButtonPress(md);
                    else
                        RC.SendButtonPress(_jMD);
                    _jMD = md;
                    DelayIndex = 0;
                    lNextOccur = DateTime.Now.Ticks + Delays[DelayIndex];
                }
                else if (md != RetroConsole.Buttons.None && DateTime.Now.Ticks >= lNextOccur)
                {
                    RC.SendButtonPress(_jMD);
                    if (DelayIndex < Delays.Length - 1)
                        DelayIndex++;
                    lNextOccur = DateTime.Now.Ticks + Delays[DelayIndex];
                }

                Thread.Sleep(250);
            }
        }

Resultant error:

    #### Exception System.NullReferenceException - CLR_E_NULL_REFERENCE (6) ####
    #### Message: 
    #### Microsoft.SPOT.Application::OnEvent [IP: 0098] ####
    #### Microsoft.SPOT.EventSink::ProcessEvent [IP: 0023] ####
    #### Microsoft.SPOT.EventSink::EventDispatchCallback [IP: 0014] ####
A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.SPOT.TinyCore.dll

Any clue here? It tells me not to use blocking While/Trues but I’m inside a new thread and I sleep, so where’s the issue?

Is _jMD initialized?

It’s an enum defaults to a value of .None, I’ve tried setting an initial value as well, no difference.

Putting in a break & stepping through it doesn’t reveal anything?

The error occurs in TinyCore not my code. Breakpoints do nothing. I’m going to try using a timer instead of a thread, but it’d be nice to know what the issue is.

So, it happens when you are deploying or can you step into ProgramStarted() up to the point where the new thread is created?

It happens at a random point after program started. No break is brought up on the error, it instantly tries to step inside TinyCore which it doesn’t have the source for.

I’ve removed everything else from the code, put it inside a timer, removed the lines of code that reference any other object, still blows up. I’m wondering if it isn’t happening on .GetJoystickPosition somewhere inside the module driver.

I have found this ONLY happens with the T35 connected. Remove that and the problem disappears as well. Analog/Touch conflict?

Initializing Touch handling removes the error. Odd stuff, but as long as it works now. :slight_smile:

Still want to know why it fails without touch handling

Try to use a timer instead of a thread. Does it work?

I am thinking the thread got going too early before gadgeteer core is ready.

I already tried using a timer, see above :wink:

It’s touch related. Exact same code works as long as I initialize touch.

I think you are correct, when I moved my game engine over to the Hydra I would sporadically get these exceptions. I also concluded that it was related to the touch interface, I found that wiring the touch events seems to eliminate the problem.


void ProgramStarted()
{
  // Wire touch events to eliminate the sporadic exceptions which seem to be related to the touch interface.
  display_T35.WPFWindow.TouchDown += (a, b) => { };
  display_T35.WPFWindow.TouchUp += (a, b) => { };
  display_T35.WPFWindow.TouchMove += (a, b) => { };

  _game = new RallyXGame();
  _game.InputManager.AddInputProvider(new GhiJoystickInputProvider(joystick));
  _game.Initialize();

  Debug.Print("Program Started");
}

The game loop is running in a thread and reading the joystick, so structurally what we are doing is very similar. I would be interested to know, just to confirm that it was not coincidence that the issues seemed to disappear when the events are wired.