Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
InterruptManager.h
00001 #ifndef MBED_INTERRUPTMANAGER_H 00002 #define MBED_INTERRUPTMANAGER_H 00003 00004 #include "cmsis.h" 00005 #include "CallChain.h" 00006 #include "PlatformMutex.h" 00007 #include <string.h> 00008 00009 namespace mbed { 00010 00011 /** Use this singleton if you need to chain interrupt handlers. 00012 * 00013 * @Note Synchronization level: Thread safe 00014 * 00015 * Example (for LPC1768): 00016 * @code 00017 * #include "InterruptManager.h" 00018 * #include "mbed.h" 00019 * 00020 * Ticker flipper; 00021 * DigitalOut led1(LED1); 00022 * DigitalOut led2(LED2); 00023 * 00024 * void flip(void) { 00025 * led1 = !led1; 00026 * } 00027 * 00028 * void handler(void) { 00029 * led2 = !led1; 00030 * } 00031 * 00032 * int main() { 00033 * led1 = led2 = 0; 00034 * flipper.attach(&flip, 1.0); 00035 * InterruptManager::get()->add_handler(handler, TIMER3_IRQn); 00036 * } 00037 * @endcode 00038 */ 00039 class InterruptManager { 00040 public: 00041 /** Return the only instance of this class 00042 */ 00043 static InterruptManager* get(); 00044 00045 /** Destroy the current instance of the interrupt manager 00046 */ 00047 static void destroy(); 00048 00049 /** Add a handler for an interrupt at the end of the handler list 00050 * 00051 * @param function the handler to add 00052 * @param irq interrupt number 00053 * 00054 * @returns 00055 * The function object created for 'function' 00056 */ 00057 pFunctionPointer_t add_handler(void (*function)(void), IRQn_Type irq) { 00058 // Underlying call is thread safe 00059 return add_common(function, irq); 00060 } 00061 00062 /** Add a handler for an interrupt at the beginning of the handler list 00063 * 00064 * @param function the handler to add 00065 * @param irq interrupt number 00066 * 00067 * @returns 00068 * The function object created for 'function' 00069 */ 00070 pFunctionPointer_t add_handler_front(void (*function)(void), IRQn_Type irq) { 00071 // Underlying call is thread safe 00072 return add_common(function, irq, true); 00073 } 00074 00075 /** Add a handler for an interrupt at the end of the handler list 00076 * 00077 * @param tptr pointer to the object that has the handler function 00078 * @param mptr pointer to the actual handler function 00079 * @param irq interrupt number 00080 * 00081 * @returns 00082 * The function object created for 'tptr' and 'mptr' 00083 */ 00084 template<typename T> 00085 pFunctionPointer_t add_handler(T* tptr, void (T::*mptr)(void), IRQn_Type irq) { 00086 // Underlying call is thread safe 00087 return add_common(tptr, mptr, irq); 00088 } 00089 00090 /** Add a handler for an interrupt at the beginning of the handler list 00091 * 00092 * @param tptr pointer to the object that has the handler function 00093 * @param mptr pointer to the actual handler function 00094 * @param irq interrupt number 00095 * 00096 * @returns 00097 * The function object created for 'tptr' and 'mptr' 00098 */ 00099 template<typename T> 00100 pFunctionPointer_t add_handler_front(T* tptr, void (T::*mptr)(void), IRQn_Type irq) { 00101 // Underlying call is thread safe 00102 return add_common(tptr, mptr, irq, true); 00103 } 00104 00105 /** Remove a handler from an interrupt 00106 * 00107 * @param handler the function object for the handler to remove 00108 * @param irq the interrupt number 00109 * 00110 * @returns 00111 * true if the handler was found and removed, false otherwise 00112 */ 00113 bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq); 00114 00115 private: 00116 InterruptManager(); 00117 ~InterruptManager(); 00118 00119 void lock(); 00120 void unlock(); 00121 00122 // We declare the copy contructor and the assignment operator, but we don't 00123 // implement them. This way, if someone tries to copy/assign our instance, 00124 // he will get an error at compile time. 00125 InterruptManager(const InterruptManager&); 00126 InterruptManager& operator =(const InterruptManager&); 00127 00128 template<typename T> 00129 pFunctionPointer_t add_common(T *tptr, void (T::*mptr)(void), IRQn_Type irq, bool front=false) { 00130 _mutex.lock(); 00131 int irq_pos = get_irq_index(irq); 00132 bool change = must_replace_vector(irq); 00133 00134 pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(tptr, mptr) : _chains[irq_pos]->add(tptr, mptr); 00135 if (change) 00136 NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper); 00137 _mutex.unlock(); 00138 return pf; 00139 } 00140 00141 pFunctionPointer_t add_common(void (*function)(void), IRQn_Type irq, bool front=false); 00142 bool must_replace_vector(IRQn_Type irq); 00143 int get_irq_index(IRQn_Type irq); 00144 void irq_helper(); 00145 void add_helper(void (*function)(void), IRQn_Type irq, bool front=false); 00146 static void static_irq_helper(); 00147 00148 CallChain* _chains[NVIC_NUM_VECTORS]; 00149 static InterruptManager* _instance; 00150 PlatformMutex _mutex; 00151 }; 00152 00153 } // namespace mbed 00154 00155 #endif 00156
Generated on Tue Jul 12 2022 22:19:20 by
