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