irq.c 3.4 KB

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