Skip to content

Commit a28fd88

Browse files
authored
Merge pull request #4846 from fenghuijie/master
修改irq handle接口rt_hw_trap_irq,支持核间IPI中断处理
2 parents 7c00795 + 0015af0 commit a28fd88

File tree

8 files changed

+127
-24
lines changed

8 files changed

+127
-24
lines changed

include/rtdef.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,10 @@ typedef siginfo_t rt_siginfo_t;
567567
#define RT_SCHEDULE_IPI 0
568568
#endif
569569

570+
#ifndef RT_STOP_IPI
571+
#define RT_STOP_IPI 1
572+
#endif
573+
570574
/**
571575
* CPUs definitions
572576
*
@@ -659,6 +663,10 @@ struct rt_thread
659663
rt_ubase_t init_tick; /**< thread's initialized tick */
660664
rt_ubase_t remaining_tick; /**< remaining tick */
661665

666+
#ifdef RT_USING_CPU_USAGE
667+
rt_uint64_t duration_tick; /**< cpu usage tick */
668+
#endif
669+
662670
struct rt_timer thread_timer; /**< built-in thread timer */
663671

664672
void (*cleanup)(struct rt_thread *tid); /**< cleanup function when thread exit */

include/rtthread.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ rt_uint16_t rt_critical_level(void);
186186

187187
#ifdef RT_USING_HOOK
188188
void rt_scheduler_sethook(void (*hook)(rt_thread_t from, rt_thread_t to));
189+
void rt_scheduler_switch_sethook(void (*hook)(struct rt_thread *tid));
189190
#endif
190191

191192
#ifdef RT_USING_SMP

libcpu/arm/cortex-a/interrupt.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,20 @@ struct rt_irq_desc isr_table[MAX_HANDLERS];
2727
rt_uint32_t rt_interrupt_from_thread = 0;
2828
rt_uint32_t rt_interrupt_to_thread = 0;
2929
rt_uint32_t rt_thread_switch_interrupt_flag = 0;
30+
31+
#ifdef RT_USING_HOOK
32+
static void (*rt_interrupt_switch_hook)(void);
33+
34+
void rt_interrupt_switch_sethook(void (*hook)(void))
35+
{
36+
rt_interrupt_switch_hook = hook;
37+
}
38+
#endif
39+
40+
void rt_interrupt_hook(void)
41+
{
42+
RT_OBJECT_HOOK_CALL(rt_interrupt_switch_hook, ());
43+
}
3044
#endif
3145

3246
const unsigned int VECTOR_BASE = 0x00;

libcpu/arm/cortex-a/start_gcc.S

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@ rt_hw_context_switch_interrupt_do:
341341
ldr r6, [r6]
342342
ldr sp, [r6] @ get new task's stack pointer
343343

344+
bl rt_interrupt_hook
345+
344346
#ifdef RT_USING_FPU
345347
/* fpu context */
346348
ldmfd sp!, {r6}
@@ -373,9 +375,18 @@ rt_hw_context_switch_interrupt_do:
373375
mrs r6, spsr @/* Save CPSR */
374376
str lr, [r0, #15*4] @/* Push PC */
375377
str r6, [r0, #16*4] @/* Push CPSR */
376-
cps #Mode_SVC
378+
mrs r5, cpsr @/* Save CPSR */
379+
380+
and r4, r6, #0x1F
381+
cmp r4, #Mode_USR
382+
moveq r6, #Mode_SYS
383+
384+
orr r6, r6, #0x80 @/* Switch to previous mode, then save SP & PC */
385+
msr cpsr_c, r6
377386
str sp, [r0, #13*4] @/* Save calling SP */
378387
str lr, [r0, #14*4] @/* Save calling PC */
388+
389+
msr cpsr_c, r5 @/* Switch back to current mode */
379390
.endm
380391

381392
.align 5
@@ -482,6 +493,8 @@ secondary_cpu_start:
482493
.bss
483494
.align 2 //align to 2~2=4
484495

496+
.global sub_stack_top /* used for backtrace to calculate stack top of irq mode */
497+
485498
sub_stack_start:
486499
.space (SUB_ISR_Stack_Size * (RT_CPUS_NR-1))
487500
sub_stack_top:

libcpu/arm/cortex-a/trap.c

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ void rt_hw_show_register(struct rt_hw_exp_stack *regs)
3535
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
3636
}
3737

38+
void (*rt_trap_hook)(struct rt_hw_exp_stack *regs, const char *ex, unsigned int exception_type);
39+
40+
/**
41+
* This function will set a hook function to trap handler.
42+
*
43+
* @param hook the hook function
44+
*/
45+
void rt_hw_trap_set_hook(void (*hook)(struct rt_hw_exp_stack *regs, const char *ex, unsigned int exception_type))
46+
{
47+
rt_trap_hook = hook;
48+
}
49+
3850
/**
3951
* When comes across an instruction which it cannot handle,
4052
* it takes the undefined instruction trap.
@@ -72,12 +84,20 @@ void rt_hw_trap_undef(struct rt_hw_exp_stack *regs)
7284
}
7385
}
7486
#endif
75-
rt_kprintf("undefined instruction:\n");
76-
rt_hw_show_register(regs);
87+
88+
if (rt_trap_hook == RT_NULL)
89+
{
90+
rt_kprintf("undefined instruction:\n");
91+
rt_hw_show_register(regs);
7792
#ifdef RT_USING_FINSH
78-
list_thread();
93+
list_thread();
7994
#endif
80-
rt_hw_cpu_shutdown();
95+
rt_hw_cpu_shutdown();
96+
}
97+
else
98+
{
99+
rt_trap_hook(regs, "undefined instruction", UND_EXCEPTION);
100+
}
81101
}
82102

83103
/**
@@ -91,12 +111,19 @@ void rt_hw_trap_undef(struct rt_hw_exp_stack *regs)
91111
*/
92112
void rt_hw_trap_swi(struct rt_hw_exp_stack *regs)
93113
{
94-
rt_kprintf("software interrupt:\n");
95-
rt_hw_show_register(regs);
114+
if (rt_trap_hook == RT_NULL)
115+
{
116+
rt_kprintf("software interrupt:\n");
117+
rt_hw_show_register(regs);
96118
#ifdef RT_USING_FINSH
97-
list_thread();
119+
list_thread();
98120
#endif
99-
rt_hw_cpu_shutdown();
121+
rt_hw_cpu_shutdown();
122+
}
123+
else
124+
{
125+
rt_trap_hook(regs, "software instruction", SWI_EXCEPTION);
126+
}
100127
}
101128

102129
/**
@@ -109,12 +136,19 @@ void rt_hw_trap_swi(struct rt_hw_exp_stack *regs)
109136
*/
110137
void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs)
111138
{
112-
rt_kprintf("prefetch abort:\n");
113-
rt_hw_show_register(regs);
139+
if (rt_trap_hook == RT_NULL)
140+
{
141+
rt_kprintf("prefetch abort:\n");
142+
rt_hw_show_register(regs);
114143
#ifdef RT_USING_FINSH
115-
list_thread();
144+
list_thread();
116145
#endif
117-
rt_hw_cpu_shutdown();
146+
rt_hw_cpu_shutdown();
147+
}
148+
else
149+
{
150+
rt_trap_hook(regs, "prefetch abort", PABT_EXCEPTION);
151+
}
118152
}
119153

120154
/**
@@ -127,12 +161,19 @@ void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs)
127161
*/
128162
void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs)
129163
{
130-
rt_kprintf("data abort:");
131-
rt_hw_show_register(regs);
164+
if (rt_trap_hook == RT_NULL)
165+
{
166+
rt_kprintf("data abort:");
167+
rt_hw_show_register(regs);
132168
#ifdef RT_USING_FINSH
133-
list_thread();
169+
list_thread();
134170
#endif
135-
rt_hw_cpu_shutdown();
171+
rt_hw_cpu_shutdown();
172+
}
173+
else
174+
{
175+
rt_trap_hook(regs, "data abort", DABT_EXCEPTION);
176+
}
136177
}
137178

138179
/**
@@ -144,23 +185,32 @@ void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs)
144185
*/
145186
void rt_hw_trap_resv(struct rt_hw_exp_stack *regs)
146187
{
147-
rt_kprintf("reserved trap:\n");
148-
rt_hw_show_register(regs);
188+
if (rt_trap_hook == RT_NULL)
189+
{
190+
rt_kprintf("reserved trap:\n");
191+
rt_hw_show_register(regs);
149192
#ifdef RT_USING_FINSH
150-
list_thread();
193+
list_thread();
151194
#endif
152-
rt_hw_cpu_shutdown();
195+
rt_hw_cpu_shutdown();
196+
}
197+
else
198+
{
199+
rt_trap_hook(regs, "reserved trap", RESV_EXCEPTION);
200+
}
153201
}
154202

155203
void rt_hw_trap_irq(void)
156204
{
157205
void *param;
206+
int int_ack;
158207
int ir;
159208
rt_isr_handler_t isr_func;
160209
extern struct rt_irq_desc isr_table[];
161210

162-
ir = rt_hw_interrupt_get_irq();
211+
int_ack = rt_hw_interrupt_get_irq();
163212

213+
ir = int_ack & GIC_ACK_INTID_MASK;
164214
if (ir == 1023)
165215
{
166216
/* Spurious interrupt */
@@ -181,7 +231,7 @@ void rt_hw_trap_irq(void)
181231
}
182232

183233
/* end of interrupt */
184-
rt_hw_interrupt_ack(ir);
234+
rt_hw_interrupt_ack(int_ack);
185235
}
186236

187237
void rt_hw_trap_fiq(void)

src/irq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ void rt_interrupt_leave(void)
8989
rt_interrupt_nest));
9090

9191
level = rt_hw_interrupt_disable();
92-
rt_interrupt_nest --;
9392
RT_OBJECT_HOOK_CALL(rt_interrupt_leave_hook,());
93+
rt_interrupt_nest --;
9494
rt_hw_interrupt_enable(level);
9595
}
9696
RTM_EXPORT(rt_interrupt_leave);

src/scheduler.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ rt_uint8_t rt_current_priority;
4949

5050
#ifdef RT_USING_HOOK
5151
static void (*rt_scheduler_hook)(struct rt_thread *from, struct rt_thread *to);
52+
static void (*rt_scheduler_switch_hook)(struct rt_thread *tid);
5253

5354
/**
5455
* @addtogroup Hook
@@ -68,6 +69,12 @@ rt_scheduler_sethook(void (*hook)(struct rt_thread *from, struct rt_thread *to))
6869
rt_scheduler_hook = hook;
6970
}
7071

72+
void
73+
rt_scheduler_switch_sethook(void (*hook)(struct rt_thread *tid))
74+
{
75+
rt_scheduler_switch_hook = hook;
76+
}
77+
7178
/**@}*/
7279
#endif /* RT_USING_HOOK */
7380

@@ -364,6 +371,8 @@ void rt_schedule(void)
364371
_rt_scheduler_stack_check(to_thread);
365372
#endif /* RT_USING_OVERFLOW_CHECK */
366373

374+
RT_OBJECT_HOOK_CALL(rt_scheduler_switch_hook, (current_thread));
375+
367376
rt_hw_context_switch((rt_ubase_t)&current_thread->sp,
368377
(rt_ubase_t)&to_thread->sp, to_thread);
369378
}
@@ -473,6 +482,8 @@ void rt_schedule(void)
473482
{
474483
extern void rt_thread_handle_sig(rt_bool_t clean_state);
475484

485+
RT_OBJECT_HOOK_CALL(rt_scheduler_switch_hook, (from_thread));
486+
476487
rt_hw_context_switch((rt_ubase_t)&from_thread->sp,
477488
(rt_ubase_t)&to_thread->sp);
478489

@@ -609,6 +620,8 @@ void rt_scheduler_do_irq_switch(void *context)
609620
current_thread->cpus_lock_nest--;
610621
current_thread->scheduler_lock_nest--;
611622

623+
RT_OBJECT_HOOK_CALL(rt_scheduler_switch_hook, (current_thread));
624+
612625
rt_hw_context_switch_interrupt(context, (rt_ubase_t)&current_thread->sp,
613626
(rt_ubase_t)&to_thread->sp, to_thread);
614627
}

src/thread.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ static rt_err_t _rt_thread_init(struct rt_thread *thread,
228228
thread->lwp = RT_NULL;
229229
#endif /* RT_USING_LWP */
230230

231+
#ifdef RT_USING_CPU_USAGE
232+
thread->duration_tick = 0;
233+
#endif
234+
231235
RT_OBJECT_HOOK_CALL(rt_thread_inited_hook, (thread));
232236

233237
return RT_EOK;

0 commit comments

Comments
 (0)