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 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #ifndef MBED_INTERRUPTMANAGER_H 00017 #define MBED_INTERRUPTMANAGER_H 00018 00019 #include "cmsis.h" 00020 #include "platform/CallChain.h" 00021 #include "platform/PlatformMutex.h" 00022 #include <string.h> 00023 00024 namespace mbed { 00025 /** \addtogroup drivers */ 00026 /** @{*/ 00027 00028 /** Use this singleton if you need to chain interrupt handlers. 00029 * 00030 * @Note Synchronization level: Thread safe 00031 * 00032 * Example (for LPC1768): 00033 * @code 00034 * #include "InterruptManager.h" 00035 * #include "mbed.h" 00036 * 00037 * Ticker flipper; 00038 * DigitalOut led1(LED1); 00039 * DigitalOut led2(LED2); 00040 * 00041 * void flip(void) { 00042 * led1 = !led1; 00043 * } 00044 * 00045 * void handler(void) { 00046 * led2 = !led1; 00047 * } 00048 * 00049 * int main() { 00050 * led1 = led2 = 0; 00051 * flipper.attach(&flip, 1.0); 00052 * InterruptManager::get()->add_handler(handler, TIMER3_IRQn); 00053 * } 00054 * @endcode 00055 */ 00056 class InterruptManager { 00057 public: 00058 /** Return the only instance of this class 00059 */ 00060 static InterruptManager* get(); 00061 00062 /** Destroy the current instance of the interrupt manager 00063 */ 00064 static void destroy(); 00065 00066 /** Add a handler for an interrupt at the end of the handler list 00067 * 00068 * @param function the handler to add 00069 * @param irq interrupt number 00070 * 00071 * @returns 00072 * The function object created for 'function' 00073 */ 00074 pFunctionPointer_t add_handler(void (*function)(void), IRQn_Type irq) { 00075 // Underlying call is thread safe 00076 return add_common(function, irq); 00077 } 00078 00079 /** Add a handler for an interrupt at the beginning of the handler list 00080 * 00081 * @param function the handler to add 00082 * @param irq interrupt number 00083 * 00084 * @returns 00085 * The function object created for 'function' 00086 */ 00087 pFunctionPointer_t add_handler_front(void (*function)(void), IRQn_Type irq) { 00088 // Underlying call is thread safe 00089 return add_common(function, irq, true); 00090 } 00091 00092 /** Add a handler for an interrupt at the end of the handler list 00093 * 00094 * @param tptr pointer to the object that has the handler function 00095 * @param mptr pointer to the actual handler function 00096 * @param irq interrupt number 00097 * 00098 * @returns 00099 * The function object created for 'tptr' and 'mptr' 00100 */ 00101 template<typename T> 00102 pFunctionPointer_t add_handler(T* tptr, void (T::*mptr)(void), IRQn_Type irq) { 00103 // Underlying call is thread safe 00104 return add_common(tptr, mptr, irq); 00105 } 00106 00107 /** Add a handler for an interrupt at the beginning of the handler list 00108 * 00109 * @param tptr pointer to the object that has the handler function 00110 * @param mptr pointer to the actual handler function 00111 * @param irq interrupt number 00112 * 00113 * @returns 00114 * The function object created for 'tptr' and 'mptr' 00115 */ 00116 template<typename T> 00117 pFunctionPointer_t add_handler_front(T* tptr, void (T::*mptr)(void), IRQn_Type irq) { 00118 // Underlying call is thread safe 00119 return add_common(tptr, mptr, irq, true); 00120 } 00121 00122 /** Remove a handler from an interrupt 00123 * 00124 * @param handler the function object for the handler to remove 00125 * @param irq the interrupt number 00126 * 00127 * @returns 00128 * true if the handler was found and removed, false otherwise 00129 */ 00130 bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq); 00131 00132 private: 00133 InterruptManager(); 00134 ~InterruptManager(); 00135 00136 void lock(); 00137 void unlock(); 00138 00139 // We declare the copy contructor and the assignment operator, but we don't 00140 // implement them. This way, if someone tries to copy/assign our instance, 00141 // he will get an error at compile time. 00142 InterruptManager(const InterruptManager&); 00143 InterruptManager& operator =(const InterruptManager&); 00144 00145 template<typename T> 00146 pFunctionPointer_t add_common(T *tptr, void (T::*mptr)(void), IRQn_Type irq, bool front=false) { 00147 _mutex.lock(); 00148 int irq_pos = get_irq_index(irq); 00149 bool change = must_replace_vector(irq); 00150 00151 pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(tptr, mptr) : _chains[irq_pos]->add(tptr, mptr); 00152 if (change) 00153 NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper); 00154 _mutex.unlock(); 00155 return pf; 00156 } 00157 00158 pFunctionPointer_t add_common(void (*function)(void), IRQn_Type irq, bool front=false); 00159 bool must_replace_vector(IRQn_Type irq); 00160 int get_irq_index(IRQn_Type irq); 00161 void irq_helper(); 00162 void add_helper(void (*function)(void), IRQn_Type irq, bool front=false); 00163 static void static_irq_helper(); 00164 00165 CallChain* _chains[NVIC_NUM_VECTORS]; 00166 static InterruptManager* _instance; 00167 PlatformMutex _mutex; 00168 }; 00169 00170 } // namespace mbed 00171 00172 #endif 00173 00174 00175 /** @}*/
Generated on Tue Jul 12 2022 10:59:56 by
