Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Call Class Members from Interrupt Routine

Call Class Members from Interrupt Routine

Scheduled Pinned Locked Moved C / C++ / MFC
c++help
21 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Andy202
    wrote on last edited by
    #1

    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.

    J enhzflepE J 3 Replies Last reply
    0
    • A Andy202

      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.

      J Offline
      J Offline
      Jochen Arndt
      wrote on last edited by
      #2

      The best way to pass information from interrupt handlers to your application is to use user defined messages. This requires that you pass the handle of a window to the interrupt handler (usually the main window, but may be also a view or dialog window) and the handler then uses PostMessage(hWnd, WM_MY_APP_EVENT, wParam, lParam). The receiving window requires a handler for the WM_MY_APP_EVENT message: ON_MESSAGE(WM_MY_APP_EVENT, OnMyAppEvent). WM_MY_APP_EVENT is a place holder for a definition like #define WM_MY_APP_EVENT WM_APP+0. When not using your main window, you should use WM_USER as base rather than WM_APP.

      A 1 Reply Last reply
      0
      • J Jochen Arndt

        The best way to pass information from interrupt handlers to your application is to use user defined messages. This requires that you pass the handle of a window to the interrupt handler (usually the main window, but may be also a view or dialog window) and the handler then uses PostMessage(hWnd, WM_MY_APP_EVENT, wParam, lParam). The receiving window requires a handler for the WM_MY_APP_EVENT message: ON_MESSAGE(WM_MY_APP_EVENT, OnMyAppEvent). WM_MY_APP_EVENT is a place holder for a definition like #define WM_MY_APP_EVENT WM_APP+0. When not using your main window, you should use WM_USER as base rather than WM_APP.

        A Offline
        A Offline
        Andy202
        wrote on last edited by
        #3

        OK Jochen, thanks for the info. I remember using EVENTS a few years ago (this is similar?), but if you have a link or example that would be great as very out of date hear. Searching through old code to see what I did in the past regarding events. Andy

        J 1 Reply Last reply
        0
        • A Andy202

          OK Jochen, thanks for the info. I remember using EVENTS a few years ago (this is similar?), but if you have a link or example that would be great as very out of date hear. Searching through old code to see what I did in the past regarding events. Andy

          J Offline
          J Offline
          Jochen Arndt
          wrote on last edited by
          #4

          No, it has not to do with other events. I just choosed the word because it matches when using an interrupt routine. I can't give you a working example, because I don't know about your current implementation and requirements. But I can try to give you short implementation list:

          1. Decide where to handle the messages (main frame or other window).
          2. Pass the handle of the window to your interrupt service class using the m_hWnd member of your CWnd derived class. The service class should contain a member var for the handle.
          3. Add the message definition to a header file (project header file or those of the window class).
          4. Add the user message handler to your window class.
          5. Call PostMessage from your interrupt handler.
          1 Reply Last reply
          0
          • A Andy202

            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.

            enhzflepE Offline
            enhzflepE Offline
            enhzflep
            wrote on last edited by
            #5

            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.

            C A L 3 Replies Last reply
            0
            • enhzflepE enhzflep

              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.

              C Offline
              C Offline
              CPallini
              wrote on last edited by
              #6

              I suppose you are right.

              Veni, vidi, vici.

              1 Reply Last reply
              0
              • enhzflepE enhzflep

                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.

                A Offline
                A Offline
                Andy202
                wrote on last edited by
                #7

                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

                enhzflepE L J 3 Replies Last reply
                0
                • A Andy202

                  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

                  enhzflepE Offline
                  enhzflepE Offline
                  enhzflep
                  wrote on last edited by
                  #8

                  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. :)

                  L 1 Reply Last reply
                  0
                  • A Andy202

                    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

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #9

                    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

                    J 1 Reply Last reply
                    0
                    • L Lost User

                      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

                      J Offline
                      J Offline
                      Jochen Arndt
                      wrote on last edited by
                      #10

                      I assume he is using a driver kit for his device that provides a callback mechanism from the interrupt service.

                      A 1 Reply Last reply
                      0
                      • A Andy202

                        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

                        J Offline
                        J Offline
                        Jochen Arndt
                        wrote on last edited by
                        #11

                        Fine that you got it to work using the message mechanism and posting the solution.

                        1 Reply Last reply
                        0
                        • J Jochen Arndt

                          I assume he is using a driver kit for his device that provides a callback mechanism from the interrupt service.

                          A Offline
                          A Offline
                          Andy202
                          wrote on last edited by
                          #12

                          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

                          L 1 Reply Last reply
                          0
                          • enhzflepE enhzflep

                            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.

                            L Offline
                            L Offline
                            Lost User
                            wrote on last edited by
                            #13

                            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.

                            enhzflepE 1 Reply Last reply
                            0
                            • enhzflepE enhzflep

                              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. :)

                              L Offline
                              L Offline
                              Lost User
                              wrote on last edited by
                              #14

                              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.

                              enhzflepE 1 Reply Last reply
                              0
                              • A Andy202

                                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

                                L Offline
                                L Offline
                                Lost User
                                wrote on last edited by
                                #15

                                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 1 Reply Last reply
                                0
                                • L Lost User

                                  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.

                                  enhzflepE Offline
                                  enhzflepE Offline
                                  enhzflep
                                  wrote on last edited by
                                  #16

                                  Yeah, it is isn't it? I've had a play with the DDK. Written a couple of trivial drivers and had a toy with the concepts behind root-kits. I was scared before, but not anymore! :cool:

                                  1 Reply Last reply
                                  0
                                  • L Lost User

                                    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.

                                    enhzflepE Offline
                                    enhzflepE Offline
                                    enhzflep
                                    wrote on last edited by
                                    #17

                                    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!

                                    L 1 Reply Last reply
                                    0
                                    • enhzflepE enhzflep

                                      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!

                                      L Offline
                                      L Offline
                                      Lost User
                                      wrote on last edited by
                                      #18

                                      Yeah, Andy didnt describe it that well, but if you know the kernel its obvious how it is structured, it hasnt changed since NT3.5 that much.

                                      ============================== Nothing to say.

                                      1 Reply Last reply
                                      0
                                      • L Lost User

                                        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 Offline
                                        A Offline
                                        Andy202
                                        wrote on last edited by
                                        #19

                                        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

                                        L 1 Reply Last reply
                                        0
                                        • A Andy202

                                          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.

                                          J Offline
                                          J Offline
                                          JackDingler
                                          wrote on last edited by
                                          #20

                                          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.
                                          }

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups