Creating the equivalent of a 10ms interrupt timer
-
I have 20 years plus embedded experience but am new to C# and Windows CE so this will be a basic question... I am developing a C# ap that requires some interface housekeeping to be done every 10ms. This ap is being tested on XP pro but will eventually go to an embedded device running Windows CE 6. In normal embedded environments I would set up a hardware timer in the cpu and put the function in an interrupt routine. We will have a small number of threads running that will be doing inbound message handling, MMI and some other functions. I think I need to have a "timer" thread called every 10ms to do this housekeeping so I have been looking at the various timer options. From Luc's excellent article on timers I see that the resolution of all timers except the multimedia timer will not be good enough. So, am I barking up the right tree? Is there a better way? (Note that the housekeeping function varies in length) Your input would be very much appreciated. Many thanks Bruce :confused:
-
I have 20 years plus embedded experience but am new to C# and Windows CE so this will be a basic question... I am developing a C# ap that requires some interface housekeeping to be done every 10ms. This ap is being tested on XP pro but will eventually go to an embedded device running Windows CE 6. In normal embedded environments I would set up a hardware timer in the cpu and put the function in an interrupt routine. We will have a small number of threads running that will be doing inbound message handling, MMI and some other functions. I think I need to have a "timer" thread called every 10ms to do this housekeeping so I have been looking at the various timer options. From Luc's excellent article on timers I see that the resolution of all timers except the multimedia timer will not be good enough. So, am I barking up the right tree? Is there a better way? (Note that the housekeeping function varies in length) Your input would be very much appreciated. Many thanks Bruce :confused:
The majority of time I see requests requiring that sort of resolution it is because of a flawed approach. I don't want to suggest that your need is inherently flawed but maybe looking at the problem from another angle may device a solution that does not require 10ms housekeeping intervals, or even intervals at all. Events can work wonders if used correctly.
Need custom software developed? I do C# development and consulting all over the United States.
If you don't ask questions the answers won't stand in your way.
Doing a job is like selecting a mule, you can't choose just the front half xor the back half so when you ask me to do a job don't expect me to do it half-assed. -
I have 20 years plus embedded experience but am new to C# and Windows CE so this will be a basic question... I am developing a C# ap that requires some interface housekeeping to be done every 10ms. This ap is being tested on XP pro but will eventually go to an embedded device running Windows CE 6. In normal embedded environments I would set up a hardware timer in the cpu and put the function in an interrupt routine. We will have a small number of threads running that will be doing inbound message handling, MMI and some other functions. I think I need to have a "timer" thread called every 10ms to do this housekeeping so I have been looking at the various timer options. From Luc's excellent article on timers I see that the resolution of all timers except the multimedia timer will not be good enough. So, am I barking up the right tree? Is there a better way? (Note that the housekeeping function varies in length) Your input would be very much appreciated. Many thanks Bruce :confused:
You'll need to add a reference at the top of your code for using System.Threading; Then in your code just add a sleep with: Thread.Sleep(10); // Time in milliseconds Hope this helps
Tom
-
I have 20 years plus embedded experience but am new to C# and Windows CE so this will be a basic question... I am developing a C# ap that requires some interface housekeeping to be done every 10ms. This ap is being tested on XP pro but will eventually go to an embedded device running Windows CE 6. In normal embedded environments I would set up a hardware timer in the cpu and put the function in an interrupt routine. We will have a small number of threads running that will be doing inbound message handling, MMI and some other functions. I think I need to have a "timer" thread called every 10ms to do this housekeeping so I have been looking at the various timer options. From Luc's excellent article on timers I see that the resolution of all timers except the multimedia timer will not be good enough. So, am I barking up the right tree? Is there a better way? (Note that the housekeeping function varies in length) Your input would be very much appreciated. Many thanks Bruce :confused:
Hello, Remeber that when working on Windows, you have to face that your threads will be scheduled by OS, so sometimes getting exact timing is not possible. If you need about 10ms resolution, considering fact that threads gets about 10ms every time they are executed (that's simplified truth), I would try fe. such approach: 1. Check how much time has elapsed since last update. 2. If not enough, yield. 2. Set new "last update" to now. 3. Do some stuff. 4. Yield. For timing you could use System.Diagnostics.Stopwatch timer. This one will use Query.. mechanism if possible to measure time, and that means even about 0.1ms resolution afair. This is the better timer you can get. For yielding you could use fe. Sleep(0). I don't know if this idea would work as expected, but maybe it's worth trying out.
-
I have 20 years plus embedded experience but am new to C# and Windows CE so this will be a basic question... I am developing a C# ap that requires some interface housekeeping to be done every 10ms. This ap is being tested on XP pro but will eventually go to an embedded device running Windows CE 6. In normal embedded environments I would set up a hardware timer in the cpu and put the function in an interrupt routine. We will have a small number of threads running that will be doing inbound message handling, MMI and some other functions. I think I need to have a "timer" thread called every 10ms to do this housekeeping so I have been looking at the various timer options. From Luc's excellent article on timers I see that the resolution of all timers except the multimedia timer will not be good enough. So, am I barking up the right tree? Is there a better way? (Note that the housekeeping function varies in length) Your input would be very much appreciated. Many thanks Bruce :confused:
Hi Bruce,
Bruce Coward wrote:
From Luc's excellent article on timers ...
Thanks for that. I don't know how timers behave on WinCE, however you can easily find out using my or similar test code. If 16msec is good enough, then chances are any kind of timer would do. If not, multimedia timers are the only standard way I know to generate periodic events at a rather high frequency; I don't know whether they are available on WinCE, I hope they are. If you are running .NET 2.0 or later, there is the StopWatch class which measures time with 1 msec accuracy (again, unsure about WinCE though); but it does not trigger events... (if everything else fails you could have a very low priority thread looping and reading a StopWatch, then sending an event to another thread working at normal priority; I would not try and switch thread priorities all the time!) The desktop versions of Windows are not real-time oriented at all, as you are probably aware of; I don't expect WinCE to be much better at consistently reacting with a reasonable latency. Therefore, when attaching lab equipment and the like, I used to leave the initiative to the central PC as much as possible; you may call that a polling architecture, I don't care, it often looks as the one way to get things working as reliable as can be achieved when Windows is part of the game. Warning: .NET having garbage collection makes things worse as far as real-time goes: when a process needs free memory due to some object being created, and there isn't sufficient free memory available, the gc kicks in, temporarily stops all threads, scans the data structures to find the live objects, then releases the threads and lets a gc thread collect the dead objects. In my experience it is worthwhile to help a little by: - not creating any more objects than really necessary during the critical parts of the app; part of that is reusing objects rather than replacing them (strings pose a problem here!) - possibly, it depends, calling GC explicitly once a critical part is done. A totally different approach may be to add lots of buffering to the peripherals, that is assuming you only need to protect the distributed system against data overruns at the PC side. It would not help when latency is critical. :)
Luc Pattyn [Forum Guidelines]
-
Hi Bruce,
Bruce Coward wrote:
From Luc's excellent article on timers ...
Thanks for that. I don't know how timers behave on WinCE, however you can easily find out using my or similar test code. If 16msec is good enough, then chances are any kind of timer would do. If not, multimedia timers are the only standard way I know to generate periodic events at a rather high frequency; I don't know whether they are available on WinCE, I hope they are. If you are running .NET 2.0 or later, there is the StopWatch class which measures time with 1 msec accuracy (again, unsure about WinCE though); but it does not trigger events... (if everything else fails you could have a very low priority thread looping and reading a StopWatch, then sending an event to another thread working at normal priority; I would not try and switch thread priorities all the time!) The desktop versions of Windows are not real-time oriented at all, as you are probably aware of; I don't expect WinCE to be much better at consistently reacting with a reasonable latency. Therefore, when attaching lab equipment and the like, I used to leave the initiative to the central PC as much as possible; you may call that a polling architecture, I don't care, it often looks as the one way to get things working as reliable as can be achieved when Windows is part of the game. Warning: .NET having garbage collection makes things worse as far as real-time goes: when a process needs free memory due to some object being created, and there isn't sufficient free memory available, the gc kicks in, temporarily stops all threads, scans the data structures to find the live objects, then releases the threads and lets a gc thread collect the dead objects. In my experience it is worthwhile to help a little by: - not creating any more objects than really necessary during the critical parts of the app; part of that is reusing objects rather than replacing them (strings pose a problem here!) - possibly, it depends, calling GC explicitly once a critical part is done. A totally different approach may be to add lots of buffering to the peripherals, that is assuming you only need to protect the distributed system against data overruns at the PC side. It would not help when latency is critical. :)
Luc Pattyn [Forum Guidelines]
Hi Guys, Many thanks for all your inputs. Very valuable to a Windows newbie! What I think I will do is run a thread with normal priority that tests the stopwatch elapsed ticks value and do my 10ms tasks when it trips over frequency / 100 to give me ticks per 10ms. I have set the code to relinquish the cpu if the stopwatch tick count hasn't incremented sufficiently this cpu time slice. I am assuming the time slices are about every ms. Here is the code. Any comments or anything I am doing wrong?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;namespace WFSO
{
class Program
{static void Main() { Thread t = new Thread(Tick); t.Start(); Console.ReadLine(); // Stop to view results t.Abort(); Console.ReadLine(); } static void Tick() { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); long tickcount = Stopwatch.Frequency / 100; // Calc 10ms tickcount while (true) { if (stopWatch.ElapsedTicks > tickcount) { stopWatch.Reset(); // Stop and zero stopwatch stopWatch.Start(); // Restart for next 10ms // Here we do the housekeeping work } Thread.Sleep(0); } } }
}
Thank you once again. Bruce
-
Hi Guys, Many thanks for all your inputs. Very valuable to a Windows newbie! What I think I will do is run a thread with normal priority that tests the stopwatch elapsed ticks value and do my 10ms tasks when it trips over frequency / 100 to give me ticks per 10ms. I have set the code to relinquish the cpu if the stopwatch tick count hasn't incremented sufficiently this cpu time slice. I am assuming the time slices are about every ms. Here is the code. Any comments or anything I am doing wrong?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;namespace WFSO
{
class Program
{static void Main() { Thread t = new Thread(Tick); t.Start(); Console.ReadLine(); // Stop to view results t.Abort(); Console.ReadLine(); } static void Tick() { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); long tickcount = Stopwatch.Frequency / 100; // Calc 10ms tickcount while (true) { if (stopWatch.ElapsedTicks > tickcount) { stopWatch.Reset(); // Stop and zero stopwatch stopWatch.Start(); // Restart for next 10ms // Here we do the housekeeping work } Thread.Sleep(0); } } }
}
Thank you once again. Bruce
Hi Bruce,
Bruce Coward wrote:
I am assuming the time slices are about every ms.
Where do you get that idea? The scheduler runs based on the system clock, that is around 16 msec on modern hardware (it used to be 55 msec on Pentium 3 running Win95), and it corresponds to the base frequency of regular timers, see my timers article. It could be better on PDAs running WinCE, I don't know (and don't expect it to be). Hence, your code will approximately run at 16 msec intervals, each Thread.Sleep(0) will make it wait for the next tick; the StopWatch is not going to do anything useful in that code. BTW: why aren't you using a multimedia timer (assuming it exists on WinCE)? :)
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google - the quality and detail of your question reflects on the effectiveness of the help you are likely to get - use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
modified on Sunday, June 12, 2011 8:04 AM
-
Hi Bruce,
Bruce Coward wrote:
I am assuming the time slices are about every ms.
Where do you get that idea? The scheduler runs based on the system clock, that is around 16 msec on modern hardware (it used to be 55 msec on Pentium 3 running Win95), and it corresponds to the base frequency of regular timers, see my timers article. It could be better on PDAs running WinCE, I don't know (and don't expect it to be). Hence, your code will approximately run at 16 msec intervals, each Thread.Sleep(0) will make it wait for the next tick; the StopWatch is not going to do anything useful in that code. BTW: why aren't you using a multimedia timer (assuming it exists on WinCE)? :)
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google - the quality and detail of your question reflects on the effectiveness of the help you are likely to get - use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
modified on Sunday, June 12, 2011 8:04 AM
"Time slice every 1ms" I think I read that in the embedded training but I am now checking again. Many thanks, Bruce