Welcome!

.NET Authors: Liz McMillan, Yakov Werde, Matthew Pollicove , Kevin Benedict

Related Topics: .NET

.NET: Article

Making the .NET Micro Framework Work for You

The ultimate flashlight - building a device

Implementing a Flashlight-Finder Feature Using Threads
Next, we are going to improve our flashlight by adding a finder feature. This is to help users who have problems finding the flashlight in the dark (which is hardly surprising). The addition to the flashlight will cause the lamp to flash for half a second every two minutes. If we need to find the flashlight in the dark, we now just have to wait for a little while until it signals where it is.

FOREGROUND AND BACKGROUND THREADS
At the moment, our program contains multiple threads of execution. A thread is created each time an interrupt is required. In addition, we have the original foreground thread that forms the body of the Main method. We can add our flashlight-finder feature by making use of this thread. Because we attached the on/off behavior to interrupts, the main thread now has nothing to do and contains just a call to the Sleep method. Instead of this, we can create a loop that waits for a while and then flashes the lamp for half a second.

while (true)
{
// Wait for 5 seconds
System.Threading.Thread.Sleep(5000);
if (switchInterrupt.Read())
// go round again if the switch is on
continue;
// Switch on the lamp
lampOutput.Write(true);
// Wait for a 10th of a second
System.Threading.Thread.Sleep(100);
// if the switch is not on, turn the lamp off
if (!switchInterrupt.Read())
{
lampOutput.Write(false);
}
}

This loop performs a timed sleep. It then checks to see whether the switch is on, that is, the flashlight is lit. If it is, the continue will cause the loop to go back to the top and wait another five seconds. Otherwise, the lamp is turned on, the program sleeps for a tenth of a second, and then the lamp is turned off. This will cause the lamp to flash briefly every five seconds. At the end of the flash, if the switch has not been turned on, the program turns the lamp off.

This code seems to work well, but when the customers start using the super flashlight, they report problems. They claim that every now and then the flashlight does not switch on when they press the button.

The problem is caused by an interaction between the two threads that are sharing the same inputs and outputs. If the user manages to turn the flashlight on just at the end of a finder flash - that is, in the time between the test to see whether the switch is on and the line that turns the lamp off - the code will turn the lamp off even though the user has closed the switch.

if (!switchInterrupt.Read())
{
System.Threading.Sleep(500);
lampOutput.Write(false);
}

The Sleep statement is where the glitch occurs, and it very easily causes the problem; all the user has to do is wait for the finder flash and then close the switch. When the flash ends, the flashlight is turned off, giving the fault as reported by our users.

THREAD SYNCHRONIZATION
What is needed is a way of ensuring that it is not possible for the interrupt handler to change the lamp state until the test and set have been performed. Fortunately, the .NET Framework provides this facility in the form of Monitors. The monitor mechanism uses a synchronization object that is shared between the threads that need to synchronize. The object can be an instance of any C# class, so we can use the switchInterrupt item.

System.Threading.Monitor.Enter(switchInterrupt);
if (!switchInterrupt.Read())
{
lampOutput.Write(false);
}
System.Threading.Monitor.Exit(switchInterrupt);

Once the code has performed the Enter method, it has control of the synchronization object, and any other thread calling the Enter method on this object will be held until the Exit method is called. If the interrupt handler has corresponding behavior, the two threads have no chance of conflicting.

static void switchInterrupt_OnInterrupt(Cpu.Pin port, bool state, TimeSpan time)
{
Monitor.Enter(switchInterrupt);
lampOutput.Write(state);
Monitor.Exit(switchInterrupt);
}

Now, it is impossible for the interrupt handler to run in between the test for the switch state and the act of turning the light off. So, if an interrupt occurs during that time, the handler will be held until the lamp has been switched off. Then, when the handler runs, it will switch it on again, removing the glitch.

Note: It is important to remember that while a thread has a lock on a synchronization object, it may be blocking other threads from running. For this reason, make sure you release locks as quickly as possible.


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.