Main Site Documentation

GC exception when input port does not support interrupts


#1

Hi!

I am using FEZ Panda II with the latest firmware and .NET MF 4.1 SDK. My code is as follows:

try
{
  // Try to create an interrupt port
  m_inputPort = new InterruptPort(signalPin, true, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth);
}
catch (Exception e)
{
  // Failed to create interrupt port (not supported on this pin?), use default input port instead
  m_inputPort = new InputPort(signalPin, false, Port.ResistorMode.PullDown);
}

If the signalPin specified by the user does not support interrupts, the exception handler is called and a normal InputPort is created successfully. However, on the next garbage collector invocation, the following exception is thrown:

GC: 3msec 25716 bytes used, 38664 bytes available
...
 #### Exception System.Exception - CLR_E_WRONG_TYPE (4) ####
 #### Message: 
 #### Microsoft.SPOT.Hardware.Port::Dispose [IP: 0000] ####
 #### Microsoft.SPOT.Hardware.NativeEventDispatcher::Finalize [IP: 0005] ####

It appears that the GC is trying to dispose the originally created InterruptPort (of which the constructor failed with an exception), but something is going wrong then. As I have not yet found a different way of dealing with GPIO pins that do not support interrupts (except for hard-coding all these pins), I’m wondering if this is a bug in the runtime or in my code.

Thanks for your help :)!


#2

Maybe try adding a m_inputPort.Dispose() as the first line in your catch. Although, if it’s doing what you say then I wouldn’t really expect there to be anything to dispose…


#3

I am not sure what is happening, but this is a situation which would never be covered in normal testing of .NET MF.

Why would anyone, doing an imbedded system, try to initialize a pin as an interrupt port, and if it did not support interrupts, then try to initialize as an input port? ???

Once the first exception occurred, I would say any further references to the pin could produce unexpected results. :o


#4

@ Ian: I tried that, but it didn’t change anything.

@ Mike: This is part of a button class for students to work with. If the particular pin does not support interrupts, the class should fall back to using a timer to periodically poll the button (such that the students don’t have to care about interrupt capabilities). But as there is apparently no way of finding out if a particular pin supports interrupts or not, I first attempt to create an InterruptPort, and then an InputPort as an alternative if the former fails.

While of course it is right that creating an InterruptPort on a non-interrupt-capable pin should result in an exception, this should not put the system into an invalid state in my opinion, causing other things to break. I, however, admit that this might not be the first thing you’d look for while testing.


#5

I have to disagree. ;D

When working with an embedded system, all the information is available to know which pins support interrupts. In order to fit .NET onto very small platforms, many compromises had to be made. It would be wasteful to add the code to recover from a unsupported exception.

I am not sure what your students would learn by handling the exception, since it represents a scenario which should not occur in good embedded programming practice. Perhaps passing a parameter in the class constructor, which says whether the pin supports interrupts, would be a better approach.

FYI, from the MS documentation for InterruptPort: