NOTICE: The Processors Wiki will End-of-Life in December of 2020. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.

Invoke a C++ Class Member Function from an Interrupt

From Texas Instruments Wiki
Jump to: navigation, search

Problem Statement[edit]

How do you have an interrupt call a function that is a member of a C++ class?

Why Its Tricky[edit]

An interrupt function can take no arguments and return no result. A C++ class member function, however, is always passed an implicit "this" pointer argument. So, a C++ class member function cannot be directly invoked from an interrupt.

Solutions[edit]

One solution could look like this:

class myclass { public: void member_fxn(); ... };  // define myclass
myclass g;                                         // myclass global object
interrupt void called_from_interrupt()  // problem here addressed later
   { g.member_fxn(); }

Notice the class member function is not called directly, but from another function entirely outside the class. Also notice how you must invoke the member function on an actual object of that class, "g" in this case. Here is an attempt to fix these issues.

// doesn't quite work!
class myclass { public: static interrupt void called_from_interrupt(); ...};

Static member functions do not require a object on which to be invoked. They are not passed a "this" pointer. But there is another problem here. How do you associate this function with the interrupt? Details vary by system. One simple scenario is the function name is entered in a table in assembly language:

.sect "vectors"
.word myclass::called_from_interrupt        ; doesn't work!

Is the problem clear now? This solution comes closer.

// still not quite right!
class myclass { public: static void member_fxn(); ... };
interrupt void called_from_interrupt()
   { myclass::member_fxn(); }

The problem here is that you still can't associate the function "called_from_interrupt" with the interrupt. Note the first example also has this problem. Why? By C++ convention, all function names are mangled. An internet search on "C++ name mangling" gives more detail. To defeat the name mangling:

// this works!
class myclass { public: static void member_fxn(); ... };
extern "C" void called_from_interrupt();                  // new stuff here
interrupt void called_from_interrupt()
   { myclass::member_fxn(); }

Now you can enter the name "_called_from_interrupt" in the interrupt vector table. Note you may not need that leading underscore. Consult your compiler manual.

Limitations of Static Member Functions[edit]

The main limitation is that static member functions cannot access ordinary data members, but only static data members. There are other limitations which are less likely to cause any issues. If you are affected by this limitation, then your interrupt handling function must invoke the class member function on an actual object of the class, like the first example does.

About the Keyword interrupt[edit]

The above examples use the interrupt keyword. This is an extension to C++ supported by the TI compilers. It changes conventions on saving registers and function return. If the affected function is directly invoked by the interrupt, then you must use the interrupt keyword for correct operation. Note this is not the case with BIOS interrupts. BIOS interrupts are handled differently. It is an error to use the interrupt keyword on a function invoked by a BIOS interrupt.

Make it Fast[edit]

The key to good performance in this situation is to inline the call to the class member_fxn(). Two steps are required: 1) Request inlining when defining the member_fxn() 2) Build with optimization. There are two ways to request inlining. You can use the inline keyword, or you can supply the definition of member_fxn() within the definition of myclass. Consult your favorite C++ book for details. Even though inlining is requested, the compiler does not actually inline the function unless optimization options (--opt_level=2 or higher) are used.

E2e.jpg {{
  1. switchcategory:MultiCore=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article Invoke a C++ Class Member Function from an Interrupt here.

Keystone=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article Invoke a C++ Class Member Function from an Interrupt here.

C2000=For technical support on the C2000 please post your questions on The C2000 Forum. Please post only comments about the article Invoke a C++ Class Member Function from an Interrupt here. DaVinci=For technical support on DaVincoplease post your questions on The DaVinci Forum. Please post only comments about the article Invoke a C++ Class Member Function from an Interrupt here. MSP430=For technical support on MSP430 please post your questions on The MSP430 Forum. Please post only comments about the article Invoke a C++ Class Member Function from an Interrupt here. OMAP35x=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article Invoke a C++ Class Member Function from an Interrupt here. OMAPL1=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article Invoke a C++ Class Member Function from an Interrupt here. MAVRK=For technical support on MAVRK please post your questions on The MAVRK Toolbox Forum. Please post only comments about the article Invoke a C++ Class Member Function from an Interrupt here. For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article Invoke a C++ Class Member Function from an Interrupt here.

}}

Hyperlink blue.png Links

Amplifiers & Linear
Audio
Broadband RF/IF & Digital Radio
Clocks & Timers
Data Converters

DLP & MEMS
High-Reliability
Interface
Logic
Power Management

Processors

Switches & Multiplexers
Temperature Sensors & Control ICs
Wireless Connectivity