Dave_911
asked on
How to obtain accurate 20 ms Timer callback without Multimedia Timers VS2003 MFC
I'm writing a DLL that is used with an existing application to interface some RS232 devices (up to 6) that must be fed data about every 50 ms. The devices cannot starve of data, if so they go into stop mode and a graceful recovery is impossible. In order to feed them data at the proper time the program must poll the devices about every 20-24 ms ms asking if they have space for additional data. I have this working in a limited fashion now talking to only one device with a worker thread. The worker thread monitors the buffer level in the RS232 device and sends data to the device if it has room available. However when other simple windows events occur, windows resize, etc, the thread scheduling changes and I am getting thread latencies which prevent the polling to occur on time, or else the thread is interrupted during the data send routines and the device runs out of data. I tried increasing the thread priority but I am limited to I believe two levels above main process threads priority and that is not sufficient. It helps but it is not enough to ensure reliable operation.
I decided to try using a Multimedia timer ( timeSetEvent) with a callback to run the RS232 data handling routine. Using DebugView I could see that the timer was working well and that windows events have little effect on the callback function execution due to its high priority. But when I tried this setup with my application (parent) program and I found out that my use of the Multimedia timers in my DLL had affected the operation of the parent (.exe) program.
It's timing is now way off, even though I was able to sucessully create the MM timer in the DLL. By doing some testing I was able to create a total of 6 more MM timers before the parent program developed a serious fault so this is not an issue of the number of MM timer limits.
So this is my dilemma. A worker thread gets pre-empted and the device runs out of data, a MM timer interferes with the .exe application.
My thoughts at this point are to find another timing mechanism that I can use to fire a callback?
Perhaps a sound system timer? or ?
Somehow hook the system timer interrupt which occurs about every 15 ms (plenty fast) or ?
I've looked for code to hook the system timer interrupt and haven't found anything yet. I have no problem putting asm code into this application if it gets me what I need.
I'm using VS2003 MFC.
I decided to try using a Multimedia timer ( timeSetEvent) with a callback to run the RS232 data handling routine. Using DebugView I could see that the timer was working well and that windows events have little effect on the callback function execution due to its high priority. But when I tried this setup with my application (parent) program and I found out that my use of the Multimedia timers in my DLL had affected the operation of the parent (.exe) program.
It's timing is now way off, even though I was able to sucessully create the MM timer in the DLL. By doing some testing I was able to create a total of 6 more MM timers before the parent program developed a serious fault so this is not an issue of the number of MM timer limits.
So this is my dilemma. A worker thread gets pre-empted and the device runs out of data, a MM timer interferes with the .exe application.
My thoughts at this point are to find another timing mechanism that I can use to fire a callback?
Perhaps a sound system timer? or ?
Somehow hook the system timer interrupt which occurs about every 15 ms (plenty fast) or ?
I've looked for code to hook the system timer interrupt and haven't found anything yet. I have no problem putting asm code into this application if it gets me what I need.
I'm using VS2003 MFC.
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
"you can set priority level to realtime for yur entire application."
in the process tab, right click you process
of course it's not 'real' real time, but try it out
and remember debug code takes a few "watts", off your code VS insert a lot of check code, try to run a release build .
Dbgview is also taking some power
in the process tab, right click you process
of course it's not 'real' real time, but try it out
and remember debug code takes a few "watts", off your code VS insert a lot of check code, try to run a release build .
Dbgview is also taking some power
sorry repeating myself ,,,
I agree with lhl60 that that must be a seriously-flawed device. I'm sure you would not be going this direction unless you were sure that there was no alternative, but I still recommend that you pore over the documentation for any other options.
For the device to shut down within a few milliseconds because it is starved for data is very unusual. There should be a way to either wake it up OR set its critical period to a longer, more convenient interval.
A worker thread using CreateEvent and WaitForSingleObject (as described in http:#a23905801) should get a timeslice often enough, most of the time. Modern CPUs running recent versions of Windows are likely to give a thread a timeslice often enough. Use
timeGetDevCaps
http://msdn.microsoft.com/en-us/library/ms713416(VS.85).aspx
to learn the timer resolution for your computer.
One other thought: I can think of no reason why a properly-implemented MM timer in a DLL should "interfere with the .exe application." Check your code and make sure that you are not doing anything foolish such as blocking execution when you should be sleeping, or spending more time in your timer event handler than the timer interval allows.
For the device to shut down within a few milliseconds because it is starved for data is very unusual. There should be a way to either wake it up OR set its critical period to a longer, more convenient interval.
A worker thread using CreateEvent and WaitForSingleObject (as described in http:#a23905801) should get a timeslice often enough, most of the time. Modern CPUs running recent versions of Windows are likely to give a thread a timeslice often enough. Use
timeGetDevCaps
http://msdn.microsoft.com/en-us/library/ms713416(VS.85).aspx
to learn the timer resolution for your computer.
One other thought: I can think of no reason why a properly-implemented MM timer in a DLL should "interfere with the .exe application." Check your code and make sure that you are not doing anything foolish such as blocking execution when you should be sleeping, or spending more time in your timer event handler than the timer interval allows.
ASKER
Sorry for the delay I was out of town yesterday...
Thanks for the followups... I was really hoping for a clear cut solution to be able to obtain another timer mechanism that I could use for a timer that is attached to a CPU timer someplace - I don't care if it is the CPU or a sound timer chip etc.
Yes, this device is not quite right software wise. The buffer is too small. I've discussed the situation with the manufacturers software engineer responsible for the product and it is what it is. I'm not missing anything. IMO the buffer should be 10 times larger.
I'm afraid that the create event is not going to be any more reliable than a standard windows system timer (already tried that also...).
I forgot about trying to up the entire process to realtime ... good suggestion, I can try that easily enough.. I don't know how I missed that......
I guess I need to go back to the software author and see if he can fix the MM timer functions in the application so I can use one of them. He is swamped with work fixing other problems so I'm hesitant to do that.
The current state of the application is that I can get this to function for probably an hour or more without problems, but if I trigger any other windows events by resizing a window etc, the threads are interrupted long enough to cause the device to run out of data. So this is truly a windows thread handling issue IMO. I thought the MM timer would get around this, but that didn't work out.
I'm certain that the MM timer I tried was setup properly. It was a bare minimum test and it worked great in the DLL, but it really screwed with the main .exe app which makes me think that the .exe has a bug in it regarding the MM timers that it utilizes.
I'll leave this open for a couple more days as I pray to the software gods for some revelation so I can truly solve this issue.
I do want to tell you guys that I truly, truly appreciate any and all comments regarding this problem.. THANKS!!!
do your know that in the task explorer ( or what it's called in English, my windows speak Danish), right click the task bar.
you can set priority level to realtime for yur entire application.
and remember when you run with debug code you application is slower due to all the check code inserted by VS. Try a run with release code.
And Dbgview also take a few watts from your system.