irq.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2006-02-24 Bernard first version
  9. * 2006-05-03 Bernard add IRQ_DEBUG
  10. * 2016-08-09 ArdaFu add interrupt enter and leave hook.
  11. * 2018-11-22 Jesven rt_interrupt_get_nest function add disable irq
  12. * 2021-08-15 Supperthomas fix the comment
  13. * 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to irq.c
  14. * 2022-07-04 Yunjie fix RT_DEBUG_LOG
  15. */
  16. #include <rthw.h>
  17. #include <rtthread.h>
  18. #ifndef __on_rt_interrupt_enter_hook
  19. #define __on_rt_interrupt_enter_hook() __ON_HOOK_ARGS(rt_interrupt_enter_hook, ())
  20. #endif
  21. #ifndef __on_rt_interrupt_leave_hook
  22. #define __on_rt_interrupt_leave_hook() __ON_HOOK_ARGS(rt_interrupt_leave_hook, ())
  23. #endif
  24. #if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
  25. static void (*rt_interrupt_enter_hook)(void);
  26. static void (*rt_interrupt_leave_hook)(void);
  27. /**
  28. * @ingroup Hook
  29. *
  30. * @brief This function set a hook function when the system enter a interrupt
  31. *
  32. * @note The hook function must be simple and never be blocked or suspend.
  33. *
  34. * @param hook the function point to be called
  35. */
  36. void rt_interrupt_enter_sethook(void (*hook)(void))
  37. {
  38. rt_interrupt_enter_hook = hook;
  39. }
  40. /**
  41. * @ingroup Hook
  42. *
  43. * @brief This function set a hook function when the system exit a interrupt.
  44. *
  45. * @note The hook function must be simple and never be blocked or suspend.
  46. *
  47. * @param hook the function point to be called
  48. */
  49. void rt_interrupt_leave_sethook(void (*hook)(void))
  50. {
  51. rt_interrupt_leave_hook = hook;
  52. }
  53. #endif /* RT_USING_HOOK */
  54. /**
  55. * @addtogroup Kernel
  56. */
  57. /**@{*/
  58. #ifdef RT_USING_SMP
  59. #define rt_interrupt_nest rt_cpu_self()->irq_nest
  60. #else
  61. volatile rt_uint8_t rt_interrupt_nest = 0;
  62. #endif /* RT_USING_SMP */
  63. /**
  64. * @brief This function will be invoked by BSP, when enter interrupt service routine
  65. *
  66. * @note Please don't invoke this routine in application
  67. *
  68. * @see rt_interrupt_leave
  69. */
  70. rt_weak void rt_interrupt_enter(void)
  71. {
  72. rt_base_t level;
  73. level = rt_hw_interrupt_disable();
  74. rt_interrupt_nest ++;
  75. RT_OBJECT_HOOK_CALL(rt_interrupt_enter_hook,());
  76. rt_hw_interrupt_enable(level);
  77. RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq has come..., irq current nest:%d\n",
  78. (rt_int32_t)rt_interrupt_nest));
  79. }
  80. RTM_EXPORT(rt_interrupt_enter);
  81. /**
  82. * @brief This function will be invoked by BSP, when leave interrupt service routine
  83. *
  84. * @note Please don't invoke this routine in application
  85. *
  86. * @see rt_interrupt_enter
  87. */
  88. rt_weak void rt_interrupt_leave(void)
  89. {
  90. rt_base_t level;
  91. RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq is going to leave, irq current nest:%d\n",
  92. (rt_int32_t)rt_interrupt_nest));
  93. level = rt_hw_interrupt_disable();
  94. RT_OBJECT_HOOK_CALL(rt_interrupt_leave_hook,());
  95. rt_interrupt_nest --;
  96. rt_hw_interrupt_enable(level);
  97. }
  98. RTM_EXPORT(rt_interrupt_leave);
  99. /**
  100. * @brief This function will return the nest of interrupt.
  101. *
  102. * User application can invoke this function to get whether current
  103. * context is interrupt context.
  104. *
  105. * @return the number of nested interrupts.
  106. */
  107. rt_weak rt_uint8_t rt_interrupt_get_nest(void)
  108. {
  109. rt_uint8_t ret;
  110. rt_base_t level;
  111. level = rt_hw_interrupt_disable();
  112. ret = rt_interrupt_nest;
  113. rt_hw_interrupt_enable(level);
  114. return ret;
  115. }
  116. RTM_EXPORT(rt_interrupt_get_nest);
  117. RTM_EXPORT(rt_hw_interrupt_disable);
  118. RTM_EXPORT(rt_hw_interrupt_enable);
  119. /**@}*/