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 "platform/NonCopyable.h" 00023 #include <string.h> 00024 00025 namespace mbed { 00026 /** \addtogroup drivers */ 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 * @ingroup drivers 00056 */ 00057 class InterruptManager : private NonCopyable<InterruptManager> { 00058 public: 00059 /** Get the instance of InterruptManager Class 00060 * 00061 * @return the only instance of this class 00062 */ 00063 static InterruptManager* get(); 00064 00065 /** Destroy the current instance of the interrupt manager 00066 */ 00067 static void destroy(); 00068 00069 /** Add a handler for an interrupt at the end of the handler list 00070 * 00071 * @param function the handler to add 00072 * @param irq interrupt number 00073 * 00074 * @returns 00075 * The function object created for 'function' 00076 */ 00077 pFunctionPointer_t add_handler(void (*function)(void), IRQn_Type irq) { 00078 // Underlying call is thread safe 00079 return add_common(function, irq); 00080 } 00081 00082 /** Add a handler for an interrupt at the beginning of the handler list 00083 * 00084 * @param function the handler to add 00085 * @param irq interrupt number 00086 * 00087 * @returns 00088 * The function object created for 'function' 00089 */ 00090 pFunctionPointer_t add_handler_front(void (*function)(void), IRQn_Type irq) { 00091 // Underlying call is thread safe 00092 return add_common(function, irq, true); 00093 } 00094 00095 /** Add a handler for an interrupt at the end of the handler list 00096 * 00097 * @param tptr pointer to the object that has the handler function 00098 * @param mptr pointer to the actual handler function 00099 * @param irq interrupt number 00100 * 00101 * @returns 00102 * The function object created for 'tptr' and 'mptr' 00103 */ 00104 template<typename T> 00105 pFunctionPointer_t add_handler(T* tptr, void (T::*mptr)(void), IRQn_Type irq) { 00106 // Underlying call is thread safe 00107 return add_common(tptr, mptr, irq); 00108 } 00109 00110 /** Add a handler for an interrupt at the beginning of the handler list 00111 * 00112 * @param tptr pointer to the object that has the handler function 00113 * @param mptr pointer to the actual handler function 00114 * @param irq interrupt number 00115 * 00116 * @returns 00117 * The function object created for 'tptr' and 'mptr' 00118 */ 00119 template<typename T> 00120 pFunctionPointer_t add_handler_front(T* tptr, void (T::*mptr)(void), IRQn_Type irq) { 00121 // Underlying call is thread safe 00122 return add_common(tptr, mptr, irq, true); 00123 } 00124 00125 /** Remove a handler from an interrupt 00126 * 00127 * @param handler the function object for the handler to remove 00128 * @param irq the interrupt number 00129 * 00130 * @returns 00131 * true if the handler was found and removed, false otherwise 00132 */ 00133 bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq); 00134 00135 private: 00136 InterruptManager(); 00137 ~InterruptManager(); 00138 00139 void lock(); 00140 void unlock(); 00141 00142 template<typename T> 00143 pFunctionPointer_t add_common(T *tptr, void (T::*mptr)(void), IRQn_Type irq, bool front=false) { 00144 _mutex.lock(); 00145 int irq_pos = get_irq_index(irq); 00146 bool change = must_replace_vector(irq); 00147 00148 pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(tptr, mptr) : _chains[irq_pos]->add(tptr, mptr); 00149 if (change) 00150 NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper); 00151 _mutex.unlock(); 00152 return pf; 00153 } 00154 00155 pFunctionPointer_t add_common(void (*function)(void), IRQn_Type irq, bool front=false); 00156 bool must_replace_vector(IRQn_Type irq); 00157 int get_irq_index(IRQn_Type irq); 00158 void irq_helper(); 00159 void add_helper(void (*function)(void), IRQn_Type irq, bool front=false); 00160 static void static_irq_helper(); 00161 00162 CallChain* _chains[NVIC_NUM_VECTORS]; 00163 static InterruptManager* _instance; 00164 PlatformMutex _mutex; 00165 }; 00166 00167 } // namespace mbed 00168 00169 #endif
Generated on Tue Jul 12 2022 20:03:19 by
