App Notes

Samraksh eMote is built on Microsoft's .NET Micro Framework (MF), a subset of .NET that's scaled to embeded devices. The MF scheduler is not real-time. Each thread, when enabled, is allocated a quantum of 20 ms, yielding when the quantum expires or the thread blocks on an event. Every thread has to wait its turn, so the delay can be substantial. Event callbacks, such as a timer expiration, take precedence over threads but do not interrupt them, so the delay can be 20 ms.

Some applications such as controlling a motor or sensing the environment and responding must happen at precise intervals. MF can only give loose boundaries on the invocation times of this kind of application thread and hence is unsuitable. We address the limitation by introducing a real-time timer class. A RealTime timer will interrupt any running thread with little delay and execute the specified callback method, providing low latency and low jitter.

For an example of how to use the RealTime timer, see the Low-Jitter RealTime Timer app note description. As that article observes, a RealTime timer has very low latency and jitter. The callback to the RealTime timer should

  • Be short.
  • Not create any heap objects.

It should be short for two reasons. First, it must complete before the next timer callback occurs. Second, it is blocking other threads while it is running and if it takes too long, events such as ADC callback can stack up, causing unexpected problems.

It should not create heap objects as doing so can cause the garbage collector (GC) to run, interfering with the performance requirements of the callback. Heap objects include things like strings, arrays: any object created with C# "new". When GC runs it is blocking — nothing else can happen — and it can take a relatively long amount of time.

The RealTime timer will interrupt any running thread but it will not interrupt the GC if it's running. Since the GC can cause so much interference it is best to design the program so that objects are created only when doing so allows enough time for the GC to run without interfering with the RealTime timer. As much as possible, preallocate the heap objects you're going to need. You can also force the GC to run at a time of your choosing so as to avoid the possibility of a later conflict.