Accurate Timer in WinCE

  • Hello all
    I need an accurate timer in windows CE.
    for testing WinCE timers, I wrote a tiny program, that sets two timer.
    One of them 1 milisec and another 5000 milisec and I set the pariority of current thread to Time_Critical.
    In first timer tick I increment a counter and in second timer tick(every 5 sec) I show the value of counter. but the value is not correct and it is the half of that I expect!!



    How can set an accurate timer in WinCE?
    Is my code wrong?
    Thanks


    [edit HK: code tags for program]

  • Even if the task switching is in the region of below a millisecond, you have to consider that there are quite a lot threads running in the kernel that have higher priority than your application, even with priority "time_critical". Therefore there may not only be one, but quite a few task switches until your program gets the response to the timer. Therefore you are most probably in the region of about 1ms of accuracy, sometimes lower, sometimes higher. Adding the time of the timer function itself, this may lead to missing some timer events, because the previous timer event was not finished when the timer ticks the next time.


    Lets assume that your 1ms timer function takes 700µs to run and a task switch takes 100µs. You would assume that this is fast enough to get each timer. But it is not. Let's see why.


    The timer triggers an interrupt which in turn calls the scheduler to reschedule the threads (first task switch). The scheduler sees that your thread can run now and switches to it (second task switch). After your timer function is done, it returns, which means the scheduler is called again (third task switch). Then some other thread, e.g. the one running before the timer interrupt occured, is resumed (fourth task switch). This sums up to 1100µs. Somewhere here, the interrupt is acknowledged and can occur again. You can easily see that you might miss the timer tick that was exactly 1000µs after the previous one.


    Maybe the times are smaller in reality and you get most of the 1ms ticks. But this example shows how time critical everything is. Just one more thread with high priority, running at the wrong time, and you miss a tick here and there.


    In addition the output of your 5000ms timer will slow down everything two, as it will need quite some time during which the 1ms timer will not be triggered. By looking at the code I expect that the first number output is significantly higher than the remaining numbers after that.


    You have to make sure that your measuring technique does not have too much influence on the measurement itself. In your example, the 5000ms timer has much influence on the timing. If you would store the count values in a data array instead of printing them directly, and then after some iterations you would stop and then print the results assembled in the array in one go, the output process itself would have no influence on the measurement anymore. This would result in much better accuracy.


    And, finally, you can increase the priority of your thread with CeSetThreadPriority(). The value "time_critical" implies that you are only using SetThreadPriority() (without "Ce"), because this value has no meaning with CeSetThreadPriority().


    PS: You can use "[ code ]" and "[ /code ]" for code samples. Then they are better formatted than just inserting them in the normal text. Example:


    Code
    1. #include <stdio>
    2. int main(void)
    3. {
    4. printf("Hello world\r\n");
    5. }


    I have edited your posting in this aspect to make it more readable.


    Regards,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Dear Mr. Keller
    Thank you for your description.
    If I underestand you, you told that I can not get timer event in 1 milisec or less than that and I can not insure about time of receiving WM_TIMER message because Windows timer uses message queue and it dependent to the other windows message.


    Now how can I set an accurate timer in WinCE?


    I think I need a "message queue free" timer like Multimedia timer but unfortunately I can not find "WinMM.Lib" in NetDCU SDK.
    How can I use Multimedia timer in WinCE?


    Thanks

  • Quote

    If I underestand you, you told that I can not get timer event in 1 milisec or less than that and I can not insure about time of receiving WM_TIMER message because Windows timer uses message queue and it dependent to the other windows message.


    I didn't say anything about messages, just about task switching between all the threads and processes in the system. But you're right, the message queue takes another part of the time.


    Quote

    Now how can I set an accurate timer in WinCE?


    Well, do you really need a function that is triggered every millisecond? Or do you just need some exact timing? Because then you could use GetTickCount(). This value is accurate and does not skip *any* tick. This is a good way of measuring the time in milliseconds. And if you need even more precise measurement, you can use the Performance Counter.


    For example you could write some scheduling function that runs in a loop and when the time has elapsed, calls the appropriate functions. Here is a template of how this can be done.



    Of course you can add more features, like adding or removing new tasks to the list at runtime. You can also do some optimization, for example during the inner loop compute the minimum time x until the next task must be run and add a Sleep(x-1) to reduce the process load.


    The advantage of this own scheduling is that you do not depend on any call back functions of the system. And as the tick count is always accurate, you'll get as accurate as possible.


    Quote

    I think I need a "message queue free" timer like Multimedia timer but unfortunately I can not find "WinMM.Lib" in NetDCU SDK.
    How can I use Multimedia timer in WinCE?


    I don't know if this kind of timer is available in Windows CE. You'll have to look for that yourself or maybe someone else can help here.


    Best regards,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Under WindowsCE you can use multimedia timers. The interface is defined in file mmsystem.h.
    With this timer you should get accurate results. But the lowest resolution is 1 ms.
    Please take a look at the following sample.


    Regards
    Holger

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.