irq.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. #define DBG_TAG "kernel.irq"
  19. #define DBG_LVL DBG_INFO
  20. #include <rtdbg.h>
  21. #ifndef __on_rt_interrupt_enter_hook
  22. #define __on_rt_interrupt_enter_hook() __ON_HOOK_ARGS(rt_interrupt_enter_hook, ())
  23. #endif
  24. #ifndef __on_rt_interrupt_leave_hook
  25. #define __on_rt_interrupt_leave_hook() __ON_HOOK_ARGS(rt_interrupt_leave_hook, ())
  26. #endif
  27. #if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
  28. static void (*rt_interrupt_enter_hook)(void);
  29. static void (*rt_interrupt_leave_hook)(void);
  30. /**
  31. * @ingroup Hook
  32. *
  33. * @brief This function set a hook function when the system enter a interrupt
  34. *
  35. * @note The hook function must be simple and never be blocked or suspend.
  36. *
  37. * @param hook the function point to be called
  38. */
  39. void rt_interrupt_enter_sethook(void (*hook)(void))
  40. {
  41. rt_interrupt_enter_hook = hook;
  42. }
  43. /**
  44. * @ingroup Hook
  45. *
  46. * @brief This function set a hook function when the system exit a interrupt.
  47. *
  48. * @note The hook function must be simple and never be blocked or suspend.
  49. *
  50. * @param hook the function point to be called
  51. */
  52. void rt_interrupt_leave_sethook(void (*hook)(void))
  53. {
  54. rt_interrupt_leave_hook = hook;
  55. }
  56. #endif /* RT_USING_HOOK */
  57. /**
  58. * @addtogroup Kernel
  59. */
  60. /**@{*/
  61. #ifdef RT_USING_SMP
  62. #define rt_interrupt_nest rt_cpu_self()->irq_nest
  63. #else
  64. volatile rt_uint8_t rt_interrupt_nest = 0;
  65. #endif /* RT_USING_SMP */
  66. /**
  67. * @brief This function will be invoked by BSP, when enter interrupt service routine
  68. *
  69. * @note Please don't invoke this routine in application
  70. *
  71. * @see rt_interrupt_leave
  72. */
  73. rt_weak void rt_interrupt_enter(void)
  74. {
  75. rt_base_t level;
  76. level = rt_hw_interrupt_disable();
  77. rt_interrupt_nest ++;
  78. RT_OBJECT_HOOK_CALL(rt_interrupt_enter_hook,());
  79. rt_hw_interrupt_enable(level);
  80. LOG_D("irq has come..., irq current nest:%d",
  81. (rt_int32_t)rt_interrupt_nest);
  82. }
  83. RTM_EXPORT(rt_interrupt_enter);
  84. /**
  85. * @brief This function will be invoked by BSP, when leave interrupt service routine
  86. *
  87. * @note Please don't invoke this routine in application
  88. *
  89. * @see rt_interrupt_enter
  90. */
  91. rt_weak void rt_interrupt_leave(void)
  92. {
  93. rt_base_t level;
  94. LOG_D("irq is going to leave, irq current nest:%d",
  95. (rt_int32_t)rt_interrupt_nest);
  96. level = rt_hw_interrupt_disable();
  97. RT_OBJECT_HOOK_CALL(rt_interrupt_leave_hook,());
  98. rt_interrupt_nest --;
  99. rt_hw_interrupt_enable(level);
  100. }
  101. RTM_EXPORT(rt_interrupt_leave);
  102. /**
  103. * @brief This function will return the nest of interrupt.
  104. *
  105. * User application can invoke this function to get whether current
  106. * context is interrupt context.
  107. *
  108. * @return the number of nested interrupts.
  109. */
  110. rt_weak rt_uint8_t rt_interrupt_get_nest(void)
  111. {
  112. rt_uint8_t ret;
  113. rt_base_t level;
  114. level = rt_hw_interrupt_disable();
  115. ret = rt_interrupt_nest;
  116. rt_hw_interrupt_enable(level);
  117. return ret;
  118. }
  119. RTM_EXPORT(rt_interrupt_get_nest);
  120. RTM_EXPORT(rt_hw_interrupt_disable);
  121. RTM_EXPORT(rt_hw_interrupt_enable);
  122. rt_weak rt_bool_t rt_hw_interrupt_is_disabled(void)
  123. {
  124. return RT_FALSE;
  125. }
  126. RTM_EXPORT(rt_hw_interrupt_is_disabled);
  127. /**@}*/