Welcome!

.NET Authors: Liz McMillan, Mark O'Neill, Peter Silva, Yakov Werde, Matthew Pollicove

Related Topics: .NET

.NET: Article

Making the .NET Micro Framework Work for You

The ultimate flashlight - building a device

AN INTERRUPT-HANDLER METHOD
Before we can create the delegate, we need to have a method that it can refer to. The method must have a particular construction because it is going to bind into part of the .NET Micro Framework system.

static void switchInterrupt_OnInterrupt( Cpu.Pin port, // the pin causing the interrupt
bool state, // the state of the pin
TimeSpan time) // the time of the interrupt
{
lampOutput.Write(state);
}

This is the method that we want to connect to the interrupt. This method has a specific signature, that is, a set of parameters, which is how the .NET Micro Framework delivers information to it. From the parameters, we can determine which port caused the interrupt, the state that it is now in, and the time at which the event was detected. This method ignores the port and time information and just uses the state value to control the output. Whenever the state of the input changes, the light will change to match it.

As far as the rest of the system is concerned, once our lamp and switch are tied together like this, there is no need for our program to do anything to keep track of the switch; whenever the input changes, our code is alerted and can behave appropriately. This behavior is directly analogous to the way in which a Windows Forms application is made to respond to user events such as button presses. When the user clicks a button on the screen, the window manager creates a thread that calls the event handler. Exactly the same thing happens in the .NET Micro Framework, making hardware components as easy to interact with as software components.

Note: That the .NET Micro Framework has quite a bit of work to do to create a thread and then invoke the interrupt handler does mean that there will be a time lag between the interrupt occurring and your code getting control. In most situations, this is not a problem, but it does mean that hard real-time applications (those applications that require a deterministic response time) may not be suitable for this Framework.

CONNECTING AN INTERRUPT HANDLER TO AN EVENT
Now that we have our InterruptPort instance and our handler method, we need to connect them together. An interrupt port instance contains an interrupt handler that maintains a list of delegates that have bound to its event. To get things to work, we just have to add our delegate to this handler. To make our lives easier, the creators of the .NET Micro Framework Library have overloaded the += operator:

switchInterrupt.OnInterrupt +=
new GPIOInterruptEventHandler(switchInterrupt_OnInterrupt);

OnInterrupt is the event handler for our interrupt port. This code makes a new instance of a GPIOInterruptEventHandler and then adds to the event handler a reference to this object. The constructor for GPIOInterruptEventHandler is passed the method that contains the code to be executed when the event occurs.

It is perfectly permissible to bind a single event-handler method to a number of different event generators. This is analogous to binding a single method to a button event, a menu event, and a keyboard shortcut event in Microsoft Windows Forms. Because the handler is told which CPU pin has caused the event, it is possible for the handler to respond appropriately.

It is also permissible to bind multiple event handlers to a single event source. If you do this, the handler methods are called in sequence, in the order in which they were bound to the event. Note that this means the first handler must complete before the second can be called, and so on down the chain.

Finally, the handler supports a -= operator that can be used to remove delegates from the event.

A Complete Program - A Flashlight Using Interrupts
We can now make a flashlight that operates under interrupt control (see Listing 2). When the Main method is called, it first creates the output port, as before, and then makes an interrupt port to monitor the switch. Next, it binds the interrupt handler to the input event. Having done this, the method has nothing further to do, so it enters a loop that repeatedly calls a Sleep method. This is given an infinite timeout, which means it should never return, so the loop is present just in case it ever does.
When the Sleep method is called, the .NET Micro Framework Library is informed that our program no longer wishes to run. This may result in the processor being placed in a lower power mode, thus saving the battery.

CLASSES AND DATA MEMBERS
If you compare Listing 2 to Listing 1, you will notice a few differences. The ports are now declared outside the body of the Main method. This is because methods other than Main require access to these variables; in the case of the flashlight, the switch interrupt-handling code needs to have access to the lamp output port so that it can control it. Within a class, data members are visible to all the methods inside that class.

You can also see that all the members of the class have been made static, which makes them part of the class rather than part of an instance of the class. This makes sense in that we never actually make an instance of the MicroFrameworkFlashlight class when our program runs. In effect, then, these members are shared among all instances of the class. In the case of this particular application, this scenario makes perfect sense, because there is no way we could possibly have multiple instances of these hardware components. However, in some situations you might want each instance of a class to hold information for you, and we will explore that later.

INHERITANCE AND PORTS
In the first program, we used an InputPort instance to read the switch. In the second program, we use an InterruptPort instance instead. An interrupt-enabled port has to be able to do everything that an input port can do, and has additional commands and properties concerned with interrupt management. It turns out that the object-oriented nature of C# makes this very easy, in that the implementation of InterruptPort is directly based on InputPort, that is, one class is an extension of the other. When designing your own programs, you can take advantage of this aspect of C# by extending a parent class to produce a child that has customized or additional behaviors.

OBJECTS AND DEVICES
All physical devices supported by the .NET Micro Framework are implemented as software objects. RS-232 serial ports, I2C interfaces, and the like are all accessed by means of an instance of the class that connects to the actual hardware. The class will contain the low-level drivers that actually do the work, but it will expose the abilities of the device in terms of methods that can be called and events that it can raise.


More Stories By Donald Thompson

Donald Thompson is responsible for overseeing the end-to-end design and day-to-day management of the developers, software, protocols, and technology strategy fueling the SPOT initiative. During the Internet boom, he built the centralized ad serving system used by all MSN Web properties, including Hotmail, MSNBC, and MSN.com. Prior to joining Microsoft, he developed an automated loan kiosk and decisioning system for Citibank, a cellular billing and management system for Bell South, and wrote AI and 3D graphics algorithms for commercial game companies. Before committing to a life of software, he was a professional child actor working in movies and television.

More Stories By Rob Miles

Rob Miles is a Microsoft Most Valuable Professional. He is a lecturer and Teaching Fellow in the Department of Computer Science at the University of Hull and is presently responsible for delivering the first year programming course and he also lectures on software development and virtual machine architectures. Visit his blog at www.robmiles.com

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.