Call Class Members from Interrupt Routine
-
This looks good, but you have not shown how you get to register your app so the interrupt routine will call it.
Unrequited desire is character building. OriginalGriff I'm sitting here giving you a standing ovation - Len Goodman
I assume he is using a driver kit for his device that provides a callback mechanism from the interrupt service.
-
Thanks for the information and direction. I got it working now. My application was a MFC C++ Dialog based program using VS2008. The most difficult part was getting the first parameter in the PostMessage() call. This was the HWND hWnd of the main window. I used a global variable g_hMainHWND so that it was available in both the interrupt and main program. Code as follows:-
//In the header file
#define Digital_Event 1
// Message for 1553 interrupts
afx_msg LRESULT OnDigitalInterrupt(UINT wParam, LONG lParam);// In the Main MFC file of the application
const UINT WM_INTERRUPT_DIGITAL = WM_APP + 1;
HWND g_hMainHWND;BEGIN_MESSAGE_MAP(CDigitalPnPDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
// Interrupt for Digital
ON_MESSAGE(WM_INTERRUPT_DIGITAL, OnDigitalInterrupt)// In the Dialog Init routine
g_hMainHWND = this->GetSafeHwnd();LRESULT CDigitalPnPDlg::OnDigitalInterrupt(UINT wParam, LONG lParam)
{
/* This routine is called every 20 msec by the interrupt from the
board. */
if(wParam == Digital_Event)
manage_timers();
return 0;
}// In the interrupt routin
/* Arrange for the processing of the 20 msec interrupt in the main application */
PostMessage(g_hMainHWND, WM_INTERRUPT_DIGITAL, Digital_Event, NULL);Note I was using the interrupt to provide a timer facility as the card was providing this every 20 msec. Andy
Fine that you got it to work using the message mechanism and posting the solution.
-
I assume he is using a driver kit for his device that provides a callback mechanism from the interrupt service.
Yes, the card comes with a good API and I just need to install the interrupt handler at the start with a call-back routine and uninstall as the program ends. You do get a 'blue screen of death' from time to time; buts thats down to developing code and debugging - to be expected until the code is mature. Andy
-
Wauw! It's been a long, long, LONG time since I've written an interrupt handler. Perhaps 15 years or more - back when I started windows from the command prompt, since I didn't have win95 yet. I'm light-years away from being any kind of expert on the matter, however, the very fact that you want to call a software routine in response to a hardware event screams DEVICE DRIVER to me. In fact, one of the very reasons I avoided coding windows programs for quite a while was the fact that it was considerably more difficult to write code that would interact with hardware directly. My guess is that you'll have to download & use the windows DDK. :-\ I'll be waiting and watching this thread closely, in the hope that I'm wrong.
enhzflep wrote:
In fact, one of the very reasons I avoided coding windows programs for quite a while was the fact that it was considerably more difficult to write code that would interact with hardware directly.
Chieken! Working in the Kernel is SoOoOoO much fun! :) (Been doing it for 15 years or so)
============================== Nothing to say.
-
It's a pleasure. Brilliant! So glad it's worked for you. Thank-you also for the confirmation that this can be achieved just from user-mode. I've got the ddk somewhere, though felt disinclined to experiment too much. Your post has given me some fresh ideas too. :)
You cant pick up an interrupt from user mode. What Andy has is a card that comes with a driver and communicates with a dll over the IO manager, and that dll is imported into his app. So the driver completes an outstanding IOCTL sent down by the dll and on completion any registered 'interrupt' handlers are called. I dont know why an app would need notification every 20ms, the windows timer goes to about 10ms at the quickest, and if Andy is only using it as a timer then why not use the built in windows one? If it is for transfering data the driver should asemble it into meaningfull packets andx send big chunks to user mode. Andy is also going to get a massive performance hit switching contexts form kernel to user mode every 20ms.
============================== Nothing to say.
-
Yes, the card comes with a good API and I just need to install the interrupt handler at the start with a call-back routine and uninstall as the program ends. You do get a 'blue screen of death' from time to time; buts thats down to developing code and debugging - to be expected until the code is mature. Andy
Why do you need notificaiton every 20ms and why not use the windows timer? If in fact you are geting data every 20ms why isnt it packaged up and sentf less frequently? You are going to get a massive performance hit if you really are getting kernel to user transitions every 20ms.
============================== Nothing to say.
-
enhzflep wrote:
In fact, one of the very reasons I avoided coding windows programs for quite a while was the fact that it was considerably more difficult to write code that would interact with hardware directly.
Chieken! Working in the Kernel is SoOoOoO much fun! :) (Been doing it for 15 years or so)
============================== Nothing to say.
-
You cant pick up an interrupt from user mode. What Andy has is a card that comes with a driver and communicates with a dll over the IO manager, and that dll is imported into his app. So the driver completes an outstanding IOCTL sent down by the dll and on completion any registered 'interrupt' handlers are called. I dont know why an app would need notification every 20ms, the windows timer goes to about 10ms at the quickest, and if Andy is only using it as a timer then why not use the built in windows one? If it is for transfering data the driver should asemble it into meaningfull packets andx send big chunks to user mode. Andy is also going to get a massive performance hit switching contexts form kernel to user mode every 20ms.
============================== Nothing to say.
Yes indeed, reading some of the other posts filled in the details. I should have been less accepting - my suspicion-meter never did quite allow the idea to sit easily with me. I'd come at it from the angle that no such DLL was provided - it was certainly never mentioned until later in the discussion. Thanks for the quick primer!
-
Yes indeed, reading some of the other posts filled in the details. I should have been less accepting - my suspicion-meter never did quite allow the idea to sit easily with me. I'd come at it from the angle that no such DLL was provided - it was certainly never mentioned until later in the discussion. Thanks for the quick primer!
-
Why do you need notificaiton every 20ms and why not use the windows timer? If in fact you are geting data every 20ms why isnt it packaged up and sentf less frequently? You are going to get a massive performance hit if you really are getting kernel to user transitions every 20ms.
============================== Nothing to say.
A timing message needs to go out every 20 msec, thats why I wanted to use this interrupt facility on the PCI card. Most other data goes out at 100 msec or 300 msec, which wold be OK for Windows timers. I may be wrong but is not Windows limited to 55 msec accuracy? So do you think that this solution is poor? Andy
-
I have installed a PCI digital card which provides an interrupt every 20 msec. Now I would like to be able to call procedures within my MFC aplication from this routine. Are they any way I can call - exampe
CTest1::Timer1() // MFC Dialog is CTest1
from
DigitalInt();
I am not an expert on Namespace, but I think thats the problem. Andy.
In a callback, you can pass a static member function, and use a class pointer as the first parameter. When you register the callback, pass it the address of the static function and for the void * data member, pass the address of the object.
class CTest1
{
public:
// This is your callback routine
static void _DigitalInt(void * pData);public:
// This is the method that does the work.
void DigitalInt(void);
};void CTest1::_DigitalInt(void * pData)
{
((CTest1 *) pData)->DigitalInt();
}void CTest1::DigitalInt(void)
{
// Do Stuff here.
} -
A timing message needs to go out every 20 msec, thats why I wanted to use this interrupt facility on the PCI card. Most other data goes out at 100 msec or 300 msec, which wold be OK for Windows timers. I may be wrong but is not Windows limited to 55 msec accuracy? So do you think that this solution is poor? Andy
Windows timer resuloution is about 10 ms, so if you want a timer at 20 you can do ith with the windows timer. Less than this you have to go to specific HW, or, on later windows OSs, apparently you can change the timer, but it is apparently illadvised. So yes, your solution will incur a performance hit because of the kernel to user transition. I took over a sw and driver design once that wrote data byte by byte to a RAM pack. It took 30 seconds to fill the thing with data. I changed it to writing 2 k packets at a time. It too 250 ms to fill it with data. Thats the cost of switching form user to kernel to user every byte, as oposed to evert 2k bytes. Heavy eh?
============================== Nothing to say.