Naze32 clone with Frysky receiver
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

InterruptManager.h 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #ifndef MBED_INTERRUPTMANAGER_H
  2. #define MBED_INTERRUPTMANAGER_H
  3. #include "cmsis.h"
  4. #include "CallChain.h"
  5. #include <string.h>
  6. namespace mbed {
  7. /** Use this singleton if you need to chain interrupt handlers.
  8. *
  9. * Example (for LPC1768):
  10. * @code
  11. * #include "InterruptManager.h"
  12. * #include "mbed.h"
  13. *
  14. * Ticker flipper;
  15. * DigitalOut led1(LED1);
  16. * DigitalOut led2(LED2);
  17. *
  18. * void flip(void) {
  19. * led1 = !led1;
  20. * }
  21. *
  22. * void handler(void) {
  23. * led2 = !led1;
  24. * }
  25. *
  26. * int main() {
  27. * led1 = led2 = 0;
  28. * flipper.attach(&flip, 1.0);
  29. * InterruptManager::get()->add_handler(handler, TIMER3_IRQn);
  30. * }
  31. * @endcode
  32. */
  33. class InterruptManager {
  34. public:
  35. /** Return the only instance of this class
  36. */
  37. static InterruptManager* get();
  38. /** Destroy the current instance of the interrupt manager
  39. */
  40. static void destroy();
  41. /** Add a handler for an interrupt at the end of the handler list
  42. *
  43. * @param function the handler to add
  44. * @param irq interrupt number
  45. *
  46. * @returns
  47. * The function object created for 'function'
  48. */
  49. pFunctionPointer_t add_handler(void (*function)(void), IRQn_Type irq) {
  50. return add_common(function, irq);
  51. }
  52. /** Add a handler for an interrupt at the beginning of the handler list
  53. *
  54. * @param function the handler to add
  55. * @param irq interrupt number
  56. *
  57. * @returns
  58. * The function object created for 'function'
  59. */
  60. pFunctionPointer_t add_handler_front(void (*function)(void), IRQn_Type irq) {
  61. return add_common(function, irq, true);
  62. }
  63. /** Add a handler for an interrupt at the end of the handler list
  64. *
  65. * @param tptr pointer to the object that has the handler function
  66. * @param mptr pointer to the actual handler function
  67. * @param irq interrupt number
  68. *
  69. * @returns
  70. * The function object created for 'tptr' and 'mptr'
  71. */
  72. template<typename T>
  73. pFunctionPointer_t add_handler(T* tptr, void (T::*mptr)(void), IRQn_Type irq) {
  74. return add_common(tptr, mptr, irq);
  75. }
  76. /** Add a handler for an interrupt at the beginning of the handler list
  77. *
  78. * @param tptr pointer to the object that has the handler function
  79. * @param mptr pointer to the actual handler function
  80. * @param irq interrupt number
  81. *
  82. * @returns
  83. * The function object created for 'tptr' and 'mptr'
  84. */
  85. template<typename T>
  86. pFunctionPointer_t add_handler_front(T* tptr, void (T::*mptr)(void), IRQn_Type irq) {
  87. return add_common(tptr, mptr, irq, true);
  88. }
  89. /** Remove a handler from an interrupt
  90. *
  91. * @param handler the function object for the handler to remove
  92. * @param irq the interrupt number
  93. *
  94. * @returns
  95. * true if the handler was found and removed, false otherwise
  96. */
  97. bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq);
  98. private:
  99. InterruptManager();
  100. ~InterruptManager();
  101. // We declare the copy contructor and the assignment operator, but we don't
  102. // implement them. This way, if someone tries to copy/assign our instance,
  103. // he will get an error at compile time.
  104. InterruptManager(const InterruptManager&);
  105. InterruptManager& operator =(const InterruptManager&);
  106. template<typename T>
  107. pFunctionPointer_t add_common(T *tptr, void (T::*mptr)(void), IRQn_Type irq, bool front=false) {
  108. int irq_pos = get_irq_index(irq);
  109. bool change = must_replace_vector(irq);
  110. pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(tptr, mptr) : _chains[irq_pos]->add(tptr, mptr);
  111. if (change)
  112. NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper);
  113. return pf;
  114. }
  115. pFunctionPointer_t add_common(void (*function)(void), IRQn_Type irq, bool front=false);
  116. bool must_replace_vector(IRQn_Type irq);
  117. int get_irq_index(IRQn_Type irq);
  118. void irq_helper();
  119. void add_helper(void (*function)(void), IRQn_Type irq, bool front=false);
  120. static void static_irq_helper();
  121. CallChain* _chains[NVIC_NUM_VECTORS];
  122. static InterruptManager* _instance;
  123. };
  124. } // namespace mbed
  125. #endif