1

Committer:
valeyev
Date:
Tue Mar 13 07:17:50 2018 +0000
Revision:
0:e056ac8fecf8
looking for...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
valeyev 0:e056ac8fecf8 1 /* mbed Microcontroller Library
valeyev 0:e056ac8fecf8 2 * Copyright (c) 2006-2013 ARM Limited
valeyev 0:e056ac8fecf8 3 *
valeyev 0:e056ac8fecf8 4 * Licensed under the Apache License, Version 2.0 (the "License");
valeyev 0:e056ac8fecf8 5 * you may not use this file except in compliance with the License.
valeyev 0:e056ac8fecf8 6 * You may obtain a copy of the License at
valeyev 0:e056ac8fecf8 7 *
valeyev 0:e056ac8fecf8 8 * http://www.apache.org/licenses/LICENSE-2.0
valeyev 0:e056ac8fecf8 9 *
valeyev 0:e056ac8fecf8 10 * Unless required by applicable law or agreed to in writing, software
valeyev 0:e056ac8fecf8 11 * distributed under the License is distributed on an "AS IS" BASIS,
valeyev 0:e056ac8fecf8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
valeyev 0:e056ac8fecf8 13 * See the License for the specific language governing permissions and
valeyev 0:e056ac8fecf8 14 * limitations under the License.
valeyev 0:e056ac8fecf8 15 */
valeyev 0:e056ac8fecf8 16 #ifndef MBED_INTERRUPTMANAGER_H
valeyev 0:e056ac8fecf8 17 #define MBED_INTERRUPTMANAGER_H
valeyev 0:e056ac8fecf8 18
valeyev 0:e056ac8fecf8 19 #include "cmsis.h"
valeyev 0:e056ac8fecf8 20 #include "platform/CallChain.h"
valeyev 0:e056ac8fecf8 21 #include "platform/PlatformMutex.h"
valeyev 0:e056ac8fecf8 22 #include "platform/NonCopyable.h"
valeyev 0:e056ac8fecf8 23 #include <string.h>
valeyev 0:e056ac8fecf8 24
valeyev 0:e056ac8fecf8 25 namespace mbed {
valeyev 0:e056ac8fecf8 26 /** \addtogroup drivers */
valeyev 0:e056ac8fecf8 27
valeyev 0:e056ac8fecf8 28 /** Use this singleton if you need to chain interrupt handlers.
valeyev 0:e056ac8fecf8 29 *
valeyev 0:e056ac8fecf8 30 * @note Synchronization level: Thread safe
valeyev 0:e056ac8fecf8 31 *
valeyev 0:e056ac8fecf8 32 * Example (for LPC1768):
valeyev 0:e056ac8fecf8 33 * @code
valeyev 0:e056ac8fecf8 34 * #include "InterruptManager.h"
valeyev 0:e056ac8fecf8 35 * #include "mbed.h"
valeyev 0:e056ac8fecf8 36 *
valeyev 0:e056ac8fecf8 37 * Ticker flipper;
valeyev 0:e056ac8fecf8 38 * DigitalOut led1(LED1);
valeyev 0:e056ac8fecf8 39 * DigitalOut led2(LED2);
valeyev 0:e056ac8fecf8 40 *
valeyev 0:e056ac8fecf8 41 * void flip(void) {
valeyev 0:e056ac8fecf8 42 * led1 = !led1;
valeyev 0:e056ac8fecf8 43 * }
valeyev 0:e056ac8fecf8 44 *
valeyev 0:e056ac8fecf8 45 * void handler(void) {
valeyev 0:e056ac8fecf8 46 * led2 = !led1;
valeyev 0:e056ac8fecf8 47 * }
valeyev 0:e056ac8fecf8 48 *
valeyev 0:e056ac8fecf8 49 * int main() {
valeyev 0:e056ac8fecf8 50 * led1 = led2 = 0;
valeyev 0:e056ac8fecf8 51 * flipper.attach(&flip, 1.0);
valeyev 0:e056ac8fecf8 52 * InterruptManager::get()->add_handler(handler, TIMER3_IRQn);
valeyev 0:e056ac8fecf8 53 * }
valeyev 0:e056ac8fecf8 54 * @endcode
valeyev 0:e056ac8fecf8 55 * @ingroup drivers
valeyev 0:e056ac8fecf8 56 */
valeyev 0:e056ac8fecf8 57 class InterruptManager : private NonCopyable<InterruptManager> {
valeyev 0:e056ac8fecf8 58 public:
valeyev 0:e056ac8fecf8 59 /** Get the instance of InterruptManager Class
valeyev 0:e056ac8fecf8 60 *
valeyev 0:e056ac8fecf8 61 * @return the only instance of this class
valeyev 0:e056ac8fecf8 62 */
valeyev 0:e056ac8fecf8 63 MBED_DEPRECATED_SINCE("mbed-os-5.6", "This class is not part of the "
valeyev 0:e056ac8fecf8 64 "public API of mbed-os and is being removed in the future.")
valeyev 0:e056ac8fecf8 65 static InterruptManager* get();
valeyev 0:e056ac8fecf8 66
valeyev 0:e056ac8fecf8 67 /** Destroy the current instance of the interrupt manager
valeyev 0:e056ac8fecf8 68 */
valeyev 0:e056ac8fecf8 69 MBED_DEPRECATED_SINCE("mbed-os-5.6", "This class is not part of the "
valeyev 0:e056ac8fecf8 70 "public API of mbed-os and is being removed in the future.")
valeyev 0:e056ac8fecf8 71 static void destroy();
valeyev 0:e056ac8fecf8 72
valeyev 0:e056ac8fecf8 73 /** Add a handler for an interrupt at the end of the handler list
valeyev 0:e056ac8fecf8 74 *
valeyev 0:e056ac8fecf8 75 * @param function the handler to add
valeyev 0:e056ac8fecf8 76 * @param irq interrupt number
valeyev 0:e056ac8fecf8 77 *
valeyev 0:e056ac8fecf8 78 * @returns
valeyev 0:e056ac8fecf8 79 * The function object created for 'function'
valeyev 0:e056ac8fecf8 80 */
valeyev 0:e056ac8fecf8 81 MBED_DEPRECATED_SINCE("mbed-os-5.6", "This class is not part of the "
valeyev 0:e056ac8fecf8 82 "public API of mbed-os and is being removed in the future.")
valeyev 0:e056ac8fecf8 83 pFunctionPointer_t add_handler(void (*function)(void), IRQn_Type irq) {
valeyev 0:e056ac8fecf8 84 // Underlying call is thread safe
valeyev 0:e056ac8fecf8 85 return add_common(function, irq);
valeyev 0:e056ac8fecf8 86 }
valeyev 0:e056ac8fecf8 87
valeyev 0:e056ac8fecf8 88 /** Add a handler for an interrupt at the beginning of the handler list
valeyev 0:e056ac8fecf8 89 *
valeyev 0:e056ac8fecf8 90 * @param function the handler to add
valeyev 0:e056ac8fecf8 91 * @param irq interrupt number
valeyev 0:e056ac8fecf8 92 *
valeyev 0:e056ac8fecf8 93 * @returns
valeyev 0:e056ac8fecf8 94 * The function object created for 'function'
valeyev 0:e056ac8fecf8 95 */
valeyev 0:e056ac8fecf8 96 MBED_DEPRECATED_SINCE("mbed-os-5.6", "This class is not part of the "
valeyev 0:e056ac8fecf8 97 "public API of mbed-os and is being removed in the future.")
valeyev 0:e056ac8fecf8 98 pFunctionPointer_t add_handler_front(void (*function)(void), IRQn_Type irq) {
valeyev 0:e056ac8fecf8 99 // Underlying call is thread safe
valeyev 0:e056ac8fecf8 100 return add_common(function, irq, true);
valeyev 0:e056ac8fecf8 101 }
valeyev 0:e056ac8fecf8 102
valeyev 0:e056ac8fecf8 103 /** Add a handler for an interrupt at the end of the handler list
valeyev 0:e056ac8fecf8 104 *
valeyev 0:e056ac8fecf8 105 * @param tptr pointer to the object that has the handler function
valeyev 0:e056ac8fecf8 106 * @param mptr pointer to the actual handler function
valeyev 0:e056ac8fecf8 107 * @param irq interrupt number
valeyev 0:e056ac8fecf8 108 *
valeyev 0:e056ac8fecf8 109 * @returns
valeyev 0:e056ac8fecf8 110 * The function object created for 'tptr' and 'mptr'
valeyev 0:e056ac8fecf8 111 */
valeyev 0:e056ac8fecf8 112 template<typename T>
valeyev 0:e056ac8fecf8 113 MBED_DEPRECATED_SINCE("mbed-os-5.6", "This class is not part of the "
valeyev 0:e056ac8fecf8 114 "public API of mbed-os and is being removed in the future.")
valeyev 0:e056ac8fecf8 115 pFunctionPointer_t add_handler(T* tptr, void (T::*mptr)(void), IRQn_Type irq) {
valeyev 0:e056ac8fecf8 116 // Underlying call is thread safe
valeyev 0:e056ac8fecf8 117 return add_common(tptr, mptr, irq);
valeyev 0:e056ac8fecf8 118 }
valeyev 0:e056ac8fecf8 119
valeyev 0:e056ac8fecf8 120 /** Add a handler for an interrupt at the beginning of the handler list
valeyev 0:e056ac8fecf8 121 *
valeyev 0:e056ac8fecf8 122 * @param tptr pointer to the object that has the handler function
valeyev 0:e056ac8fecf8 123 * @param mptr pointer to the actual handler function
valeyev 0:e056ac8fecf8 124 * @param irq interrupt number
valeyev 0:e056ac8fecf8 125 *
valeyev 0:e056ac8fecf8 126 * @returns
valeyev 0:e056ac8fecf8 127 * The function object created for 'tptr' and 'mptr'
valeyev 0:e056ac8fecf8 128 */
valeyev 0:e056ac8fecf8 129 template<typename T>
valeyev 0:e056ac8fecf8 130 MBED_DEPRECATED_SINCE("mbed-os-5.6", "This class is not part of the "
valeyev 0:e056ac8fecf8 131 "public API of mbed-os and is being removed in the future.")
valeyev 0:e056ac8fecf8 132 pFunctionPointer_t add_handler_front(T* tptr, void (T::*mptr)(void), IRQn_Type irq) {
valeyev 0:e056ac8fecf8 133 // Underlying call is thread safe
valeyev 0:e056ac8fecf8 134 return add_common(tptr, mptr, irq, true);
valeyev 0:e056ac8fecf8 135 }
valeyev 0:e056ac8fecf8 136
valeyev 0:e056ac8fecf8 137 /** Remove a handler from an interrupt
valeyev 0:e056ac8fecf8 138 *
valeyev 0:e056ac8fecf8 139 * @param handler the function object for the handler to remove
valeyev 0:e056ac8fecf8 140 * @param irq the interrupt number
valeyev 0:e056ac8fecf8 141 *
valeyev 0:e056ac8fecf8 142 * @returns
valeyev 0:e056ac8fecf8 143 * true if the handler was found and removed, false otherwise
valeyev 0:e056ac8fecf8 144 */
valeyev 0:e056ac8fecf8 145 MBED_DEPRECATED_SINCE("mbed-os-5.6", "This class is not part of the "
valeyev 0:e056ac8fecf8 146 "public API of mbed-os and is being removed in the future.")
valeyev 0:e056ac8fecf8 147 bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq);
valeyev 0:e056ac8fecf8 148
valeyev 0:e056ac8fecf8 149 private:
valeyev 0:e056ac8fecf8 150 InterruptManager();
valeyev 0:e056ac8fecf8 151 ~InterruptManager();
valeyev 0:e056ac8fecf8 152
valeyev 0:e056ac8fecf8 153 void lock();
valeyev 0:e056ac8fecf8 154 void unlock();
valeyev 0:e056ac8fecf8 155
valeyev 0:e056ac8fecf8 156 template<typename T>
valeyev 0:e056ac8fecf8 157 pFunctionPointer_t add_common(T *tptr, void (T::*mptr)(void), IRQn_Type irq, bool front=false) {
valeyev 0:e056ac8fecf8 158 _mutex.lock();
valeyev 0:e056ac8fecf8 159 int irq_pos = get_irq_index(irq);
valeyev 0:e056ac8fecf8 160 bool change = must_replace_vector(irq);
valeyev 0:e056ac8fecf8 161
valeyev 0:e056ac8fecf8 162 pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(tptr, mptr) : _chains[irq_pos]->add(tptr, mptr);
valeyev 0:e056ac8fecf8 163 if (change)
valeyev 0:e056ac8fecf8 164 NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper);
valeyev 0:e056ac8fecf8 165 _mutex.unlock();
valeyev 0:e056ac8fecf8 166 return pf;
valeyev 0:e056ac8fecf8 167 }
valeyev 0:e056ac8fecf8 168
valeyev 0:e056ac8fecf8 169 pFunctionPointer_t add_common(void (*function)(void), IRQn_Type irq, bool front=false);
valeyev 0:e056ac8fecf8 170 bool must_replace_vector(IRQn_Type irq);
valeyev 0:e056ac8fecf8 171 int get_irq_index(IRQn_Type irq);
valeyev 0:e056ac8fecf8 172 void irq_helper();
valeyev 0:e056ac8fecf8 173 void add_helper(void (*function)(void), IRQn_Type irq, bool front=false);
valeyev 0:e056ac8fecf8 174 static void static_irq_helper();
valeyev 0:e056ac8fecf8 175
valeyev 0:e056ac8fecf8 176 CallChain* _chains[NVIC_NUM_VECTORS];
valeyev 0:e056ac8fecf8 177 static InterruptManager* _instance;
valeyev 0:e056ac8fecf8 178 PlatformMutex _mutex;
valeyev 0:e056ac8fecf8 179 };
valeyev 0:e056ac8fecf8 180
valeyev 0:e056ac8fecf8 181 } // namespace mbed
valeyev 0:e056ac8fecf8 182
valeyev 0:e056ac8fecf8 183 #endif