mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-23 04:04:15 +08:00
[bsp][c28x] add support to not disable global interrupt in context-switch to enable zero-latency isr for critical interrupts.
This commit is contained in:
+251
-179
@@ -11,37 +11,208 @@
|
||||
; 2019-12-05 xiaolifan add support for hardware fpu32
|
||||
; 2022-06-21 guyunjie trim pendsv (RTOSINT_Handler)
|
||||
; 2022-08-24 guyunjie fix bugs in context switching
|
||||
; 2022-10-15 guyunjie add zero-latency interrupt
|
||||
|
||||
.ref _rt_interrupt_to_thread
|
||||
.ref _rt_interrupt_from_thread
|
||||
.ref _rt_thread_switch_interrupt_flag
|
||||
.ref rt_interrupt_to_thread
|
||||
.ref rt_interrupt_from_thread
|
||||
.ref rt_thread_switch_interrupt_flag
|
||||
|
||||
.def _RTOSINT_Handler
|
||||
.def _rt_hw_get_st0
|
||||
.def _rt_hw_get_st1
|
||||
.def _rt_hw_calc_csb
|
||||
.def _rt_hw_context_switch_interrupt
|
||||
.def _rt_hw_context_switch
|
||||
.def _rt_hw_context_switch_to
|
||||
.def _rt_hw_interrupt_thread_switch
|
||||
.def _rt_hw_interrupt_disable
|
||||
.def _rt_hw_interrupt_enable
|
||||
.def rtosint_handler
|
||||
.def rt_hw_get_st0
|
||||
.def rt_hw_get_st1
|
||||
.def rt_hw_calc_csb
|
||||
.def rt_hw_context_switch_interrupt
|
||||
.def rt_hw_context_switch
|
||||
.def rt_hw_context_switch_to
|
||||
.def rt_hw_interrupt_thread_switch
|
||||
.def rt_hw_interrupt_disable
|
||||
.def rt_hw_interrupt_enable
|
||||
|
||||
;workaround for importing fpu settings from the compiler
|
||||
;importing settings from compiler and config
|
||||
.cdecls C,NOLIST
|
||||
%{
|
||||
#include <rtconfig.h>
|
||||
|
||||
#ifdef __TMS320C28XX_FPU32__
|
||||
#define __FPU32__ 1
|
||||
#else
|
||||
#define __FPU32__ 0
|
||||
#endif
|
||||
|
||||
#ifdef __TMS320C28XX_FPU64__
|
||||
#define __FPU64__ 1
|
||||
#else
|
||||
#define __FPU64__ 0
|
||||
#endif
|
||||
|
||||
#ifdef __TMS320C28XX_VCRC__
|
||||
#define __VCRC__ 1
|
||||
#else
|
||||
#define __VCRC__ 0
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_ZERO_LATENCY
|
||||
#define ZERO_LATENCY 1
|
||||
#ifndef ZERO_LATENCY_INT_MASK
|
||||
#error ZERO_LATENCY_INT_MASK must be defined for zero latency interrupt
|
||||
#elif ZERO_LATENCY_INT_MASK & 0x8000
|
||||
#error RTOS bit (0x8000) must not be set in ZERO_LATENCY_INT_MASK
|
||||
#endif
|
||||
#else
|
||||
#define ZERO_LATENCY 0
|
||||
#endif
|
||||
%}
|
||||
|
||||
|
||||
RT_CTX_SAVE .macro
|
||||
.text
|
||||
.newblock
|
||||
|
||||
;
|
||||
; rt_base_t rt_hw_interrupt_disable();
|
||||
;
|
||||
.asmfunc
|
||||
rt_hw_interrupt_disable:
|
||||
.if ZERO_LATENCY
|
||||
MOV AL, IER
|
||||
AND IER, #ZERO_LATENCY_INT_MASK
|
||||
.else
|
||||
PUSH ST1
|
||||
SETC INTM
|
||||
POP AL
|
||||
.endif
|
||||
MOV AH, #0
|
||||
LRETR
|
||||
.endasmfunc
|
||||
|
||||
;
|
||||
; void rt_hw_interrupt_enable(rt_base_t level);
|
||||
;
|
||||
.asmfunc
|
||||
rt_hw_interrupt_enable:
|
||||
.if ZERO_LATENCY
|
||||
MOV IER, AL
|
||||
.else
|
||||
PUSH AL
|
||||
POP ST1
|
||||
.endif
|
||||
LRETR
|
||||
.endasmfunc
|
||||
|
||||
;
|
||||
; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
||||
; ACC --> from
|
||||
; SP[4] --> to
|
||||
;
|
||||
.asmfunc
|
||||
rt_hw_context_switch_interrupt:
|
||||
|
||||
; ACC, XAR4-7 are "save on call" following TI C28x C/C++ compiler convention
|
||||
; and therefore can be used in a function without being saved on stack first
|
||||
; (the compiler has already saved it before the call).
|
||||
; Reference: TMS320C28x Optimizing CC++ Compiler
|
||||
; note this convention is only applicable to normal functions not to isrs
|
||||
|
||||
MOVL XAR6, ACC
|
||||
MOVL XAR4, *-SP[4]
|
||||
; set rt_thread_switch_interrupt_flag to 1
|
||||
MOVL XAR5, #rt_thread_switch_interrupt_flag
|
||||
MOVL ACC, *XAR5
|
||||
BF reswitch2, NEQ ; ACC!=0
|
||||
MOVB ACC, #1
|
||||
MOVL *XAR5, ACC
|
||||
|
||||
MOVL XAR5, #rt_interrupt_from_thread ; set rt_interrupt_from_thread
|
||||
MOVL *XAR5, XAR6
|
||||
|
||||
reswitch2:
|
||||
MOVL XAR5, #rt_interrupt_to_thread ; set rt_interrupt_to_thread
|
||||
MOVL *XAR5, XAR4
|
||||
LRETR
|
||||
.endasmfunc
|
||||
|
||||
;
|
||||
; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
||||
; ACC --> from
|
||||
; SP[4] --> to
|
||||
;
|
||||
.asmfunc
|
||||
rt_hw_context_switch:
|
||||
|
||||
MOVL XAR6, ACC
|
||||
MOVL XAR4, *-SP[4]
|
||||
; set rt_thread_switch_interrupt_flag to 1
|
||||
MOVL XAR5, #rt_thread_switch_interrupt_flag
|
||||
MOVL ACC, *XAR5
|
||||
BF reswitch1, NEQ ; ACC!=0
|
||||
MOVB ACC, #1
|
||||
MOVL *XAR5, ACC
|
||||
|
||||
MOVL XAR5, #rt_interrupt_from_thread ; set rt_interrupt_from_thread
|
||||
MOVL *XAR5, XAR6
|
||||
|
||||
reswitch1:
|
||||
MOVL XAR5, #rt_interrupt_to_thread ; set rt_interrupt_to_thread
|
||||
MOVL *XAR5, XAR4
|
||||
OR IFR, #0x8000
|
||||
LRETR
|
||||
.endasmfunc
|
||||
;
|
||||
; * void rt_hw_context_switch_to(rt_uint32 to);
|
||||
; * ACC --> to
|
||||
;
|
||||
.asmfunc
|
||||
rt_hw_context_switch_to:
|
||||
; get to thread
|
||||
MOVL XAR5, #rt_interrupt_to_thread
|
||||
MOVL *XAR5, ACC
|
||||
|
||||
; set from thread to 0
|
||||
MOVL XAR5, #rt_interrupt_from_thread
|
||||
MOVL XAR4, #0
|
||||
MOVL *XAR5, XAR4
|
||||
|
||||
; set interrupt flag to 1
|
||||
MOVL XAR5, #rt_thread_switch_interrupt_flag
|
||||
MOVL XAR4, #1
|
||||
MOVL *XAR5, XAR4
|
||||
|
||||
; trigger rtos interrupt
|
||||
OR IFR, #0x8000
|
||||
OR IER, #0x8000
|
||||
CLRC INTM
|
||||
|
||||
; never reach here!
|
||||
.endasmfunc
|
||||
|
||||
.asmfunc
|
||||
rtosint_handler:
|
||||
|
||||
.if ZERO_LATENCY
|
||||
; mask out non-critical interrupts and enable global interrupt
|
||||
; so rtosint_handler won't block critical interrupts
|
||||
AND IER, #ZERO_LATENCY_INT_MASK
|
||||
CLRC INTM
|
||||
.endif
|
||||
|
||||
MOVL ACC, *-SP[4]
|
||||
MOV AR0, AL ; save original IER
|
||||
|
||||
PUSH AR1H:AR0H
|
||||
PUSH XAR2
|
||||
|
||||
; get rt_thread_switch_interrupt_flag
|
||||
MOVL XAR1, #rt_thread_switch_interrupt_flag
|
||||
MOVL ACC, *XAR1
|
||||
BF rtosint_exit, EQ ; rtos_int already handled
|
||||
|
||||
; clear rt_thread_switch_interrupt_flag to 0
|
||||
MOVL XAR2, #0
|
||||
MOVL *XAR1, XAR2
|
||||
|
||||
MOVL XAR1, #rt_interrupt_from_thread
|
||||
MOVL ACC, *XAR1
|
||||
BF switch_to_thread, EQ ; skip register save at the first time
|
||||
|
||||
PUSH XAR3
|
||||
PUSH XAR4
|
||||
PUSH XAR5
|
||||
@@ -63,20 +234,63 @@ RT_CTX_SAVE .macro
|
||||
MOV32 *SP++, R7H
|
||||
.endif
|
||||
|
||||
.endm
|
||||
.if __FPU64__
|
||||
MOV32 *SP++, R0L
|
||||
MOV32 *SP++, R1L
|
||||
MOV32 *SP++, R2L
|
||||
MOV32 *SP++, R3L
|
||||
MOV32 *SP++, R4L
|
||||
MOV32 *SP++, R5L
|
||||
MOV32 *SP++, R6L
|
||||
MOV32 *SP++, R7L
|
||||
.endif
|
||||
|
||||
.if __VCRC__
|
||||
VMOV32 *SP++, VCRC
|
||||
VMOV32 *SP++, VSTATUS
|
||||
VMOV32 *SP++, VCRCPOLY
|
||||
VMOV32 *SP++, VCRCSIZE
|
||||
.endif
|
||||
|
||||
RT_CTX_RESTORE .macro
|
||||
MOVL ACC, *XAR1
|
||||
MOVL XAR1, ACC
|
||||
MOVZ AR2, @SP ; get from thread stack pointer
|
||||
MOVL *XAR1, XAR2 ; update from thread stack pointer
|
||||
|
||||
switch_to_thread:
|
||||
MOVL XAR1, #rt_interrupt_to_thread
|
||||
MOVL ACC, *XAR1
|
||||
MOVL XAR1, ACC
|
||||
MOVL ACC, *XAR1
|
||||
MOV @SP, AL ; load thread stack pointer
|
||||
|
||||
.if __VCRC__
|
||||
VMOV32 VCRCSIZE, *--SP
|
||||
VMOV32 VCRCPOLY, *--SP
|
||||
VMOV32 VSTATUS, *--SP
|
||||
VMOV32 VCRC, *--SP
|
||||
.endif
|
||||
|
||||
.if __FPU64__
|
||||
MOV32 R7L, *--SP
|
||||
MOV32 R6L, *--SP
|
||||
MOV32 R5L, *--SP
|
||||
MOV32 R4L, *--SP
|
||||
MOV32 R3L, *--SP
|
||||
MOV32 R2L, *--SP
|
||||
MOV32 R1L, *--SP
|
||||
MOV32 R0L, *--SP
|
||||
.endif
|
||||
|
||||
.if __FPU32__
|
||||
MOV32 R7H, *--SP, UNCF
|
||||
MOV32 R6H, *--SP, UNCF
|
||||
MOV32 R5H, *--SP, UNCF
|
||||
MOV32 R4H, *--SP, UNCF
|
||||
MOV32 R3H, *--SP, UNCF
|
||||
MOV32 R2H, *--SP, UNCF
|
||||
MOV32 R1H, *--SP, UNCF
|
||||
MOV32 R0H, *--SP, UNCF
|
||||
MOV32 R7H, *--SP
|
||||
MOV32 R6H, *--SP
|
||||
MOV32 R5H, *--SP
|
||||
MOV32 R4H, *--SP
|
||||
MOV32 R3H, *--SP
|
||||
MOV32 R2H, *--SP
|
||||
MOV32 R1H, *--SP
|
||||
MOV32 R0H, *--SP
|
||||
MOV32 STF, *--SP
|
||||
POP RB
|
||||
.endif
|
||||
@@ -88,172 +302,30 @@ RT_CTX_RESTORE .macro
|
||||
POP XAR5
|
||||
POP XAR4
|
||||
POP XAR3
|
||||
POP XAR2
|
||||
|
||||
MOVZ AR0 , @SP
|
||||
SUBB XAR0, #6
|
||||
MOVL ACC , *XAR0
|
||||
AND ACC, #0xFFFF << 16
|
||||
MOV AL, IER
|
||||
MOVL *XAR0, ACC
|
||||
|
||||
POP AR1H:AR0H
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.text
|
||||
.newblock
|
||||
|
||||
;
|
||||
; rt_base_t rt_hw_interrupt_disable();
|
||||
;
|
||||
.asmfunc
|
||||
_rt_hw_interrupt_disable:
|
||||
PUSH ST1
|
||||
SETC INTM,DBGM
|
||||
MOV AL, *--SP
|
||||
LRETR
|
||||
.endasmfunc
|
||||
|
||||
;
|
||||
; void rt_hw_interrupt_enable(rt_base_t level);
|
||||
;
|
||||
.asmfunc
|
||||
_rt_hw_interrupt_enable:
|
||||
MOV *SP++, AL
|
||||
POP ST1
|
||||
LRETR
|
||||
.endasmfunc
|
||||
|
||||
;
|
||||
; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
||||
; ACC --> from
|
||||
; SP[4] --> to
|
||||
;
|
||||
.asmfunc
|
||||
_rt_hw_context_switch_interrupt:
|
||||
MOVL XAR0, ACC
|
||||
MOVL XAR4, *-SP[4]
|
||||
; set rt_thread_switch_interrupt_flag to 1
|
||||
MOVL XAR5, #_rt_thread_switch_interrupt_flag
|
||||
MOVL ACC, *XAR5
|
||||
BF _reswitch, NEQ ; ACC!=0
|
||||
MOVB ACC, #1
|
||||
MOVL *XAR5, ACC
|
||||
|
||||
MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread
|
||||
MOVL *XAR5, XAR0
|
||||
|
||||
_reswitch:
|
||||
MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread
|
||||
MOVL *XAR5, XAR4
|
||||
|
||||
LRETR
|
||||
.endasmfunc
|
||||
|
||||
;
|
||||
; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
||||
; ACC --> from
|
||||
; SP[4] --> to
|
||||
;
|
||||
.asmfunc
|
||||
_rt_hw_context_switch:
|
||||
MOVL XAR0, ACC
|
||||
MOVL XAR4, *-SP[4]
|
||||
; set rt_thread_switch_interrupt_flag to 1
|
||||
MOVL XAR5, #_rt_thread_switch_interrupt_flag
|
||||
MOVL ACC, *XAR5
|
||||
BF _reswitch2, NEQ ; ACC!=0
|
||||
MOVB ACC, #1
|
||||
MOVL *XAR5, ACC
|
||||
|
||||
MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread
|
||||
MOVL *XAR5, XAR0
|
||||
|
||||
_reswitch2:
|
||||
MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread
|
||||
MOVL *XAR5, XAR4
|
||||
|
||||
TRAP #16
|
||||
LRETR
|
||||
.endasmfunc
|
||||
|
||||
;
|
||||
; * void rt_hw_context_switch_to(rt_uint32 to);
|
||||
; * ACC --> to
|
||||
;
|
||||
.asmfunc
|
||||
_rt_hw_context_switch_to:
|
||||
; get to thread
|
||||
MOVL XAR1, #_rt_interrupt_to_thread
|
||||
MOVL *XAR1, ACC
|
||||
|
||||
; set from thread to 0
|
||||
MOVL XAR1, #_rt_interrupt_from_thread
|
||||
MOVL XAR0, #0
|
||||
MOVL *XAR1, XAR0
|
||||
|
||||
; set interrupt flag to 1
|
||||
MOVL XAR1, #_rt_thread_switch_interrupt_flag
|
||||
MOVL XAR0, #1
|
||||
MOVL *XAR1, XAR0
|
||||
|
||||
TRAP #16
|
||||
|
||||
; never reach here!
|
||||
.endasmfunc
|
||||
|
||||
.asmfunc
|
||||
_RTOSINT_Handler:
|
||||
; disable interrupt to protect context switch
|
||||
; DINT ;this is done by hardware so not needed
|
||||
|
||||
; get rt_thread_switch_interrupt_flag
|
||||
MOVL XAR0, #_rt_thread_switch_interrupt_flag
|
||||
MOVL ACC, *XAR0
|
||||
BF rtosint_exit, EQ ; pendsv already handled
|
||||
|
||||
; clear rt_thread_switch_interrupt_flag to 0
|
||||
MOVL XAR1, #0
|
||||
MOVL *XAR0, XAR1
|
||||
|
||||
MOVL XAR0, #_rt_interrupt_from_thread
|
||||
MOVL ACC, *XAR0
|
||||
BF switch_to_thread, EQ ; skip register save at the first time
|
||||
|
||||
RT_CTX_SAVE ; push cpu registers
|
||||
|
||||
MOVL ACC, *XAR0
|
||||
MOVL XAR0, ACC
|
||||
MOVZ AR1, @SP ; get from thread stack pointer
|
||||
MOVL *XAR0, XAR1 ; update from thread stack pointer
|
||||
|
||||
switch_to_thread:
|
||||
MOVL XAR1, #_rt_interrupt_to_thread
|
||||
MOVL ACC, *XAR1
|
||||
MOVL XAR1, ACC
|
||||
MOVL ACC, *XAR1
|
||||
MOV @SP, AL ; load thread stack pointer
|
||||
|
||||
RT_CTX_RESTORE ; pop cpu registers
|
||||
|
||||
rtosint_exit:
|
||||
; do not restore interrupt here: to be restored according to the
|
||||
; switched-to context during IRET (automaticlly by hardware)
|
||||
|
||||
POP XAR2
|
||||
POP AR1H:AR0H
|
||||
|
||||
MOVL ACC , *-SP[4]
|
||||
MOV AL, AR0
|
||||
MOVL *-SP[4], ACC
|
||||
|
||||
IRET
|
||||
.endasmfunc
|
||||
|
||||
.asmfunc
|
||||
_rt_hw_get_st0:
|
||||
rt_hw_get_st0:
|
||||
PUSH ST0
|
||||
POP AL
|
||||
LRETR
|
||||
.endasmfunc
|
||||
|
||||
.asmfunc
|
||||
_rt_hw_get_st1:
|
||||
rt_hw_get_st1:
|
||||
PUSH ST1
|
||||
POP AL
|
||||
LRETR
|
||||
@@ -269,18 +341,18 @@ _rt_hw_get_st1:
|
||||
; 0x000001FF 22 8
|
||||
; 0x000001F0 22 8
|
||||
.asmfunc
|
||||
_rt_hw_calc_csb:
|
||||
rt_hw_calc_csb:
|
||||
MOV AH, #0
|
||||
CSB ACC ; T = no. of sign bits - 1
|
||||
MOVU ACC, T ; ACC = no. of sign bits - 1
|
||||
SUBB ACC, #30 ; ACC = ACC - 30
|
||||
ABS ACC ; ACC = |ACC|
|
||||
lretr
|
||||
LRETR
|
||||
.endasmfunc
|
||||
|
||||
; compatible with old version
|
||||
.asmfunc
|
||||
_rt_hw_interrupt_thread_switch:
|
||||
rt_hw_interrupt_thread_switch:
|
||||
LRETR
|
||||
NOP
|
||||
.endasmfunc
|
||||
|
||||
@@ -8,9 +8,12 @@
|
||||
* 2018-09-01 xuzhuoyi the first version.
|
||||
* 2019-07-03 zhaoxiaowei add support for __rt_ffs.
|
||||
* 2019-12-05 xiaolifan add support for hardware fpu32
|
||||
* 2022-10-17 guyunjie add support for hardware fpu64 and vcrc
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
extern volatile rt_uint8_t rt_interrupt_nest;
|
||||
|
||||
/* exception and interrupt handler table */
|
||||
rt_uint32_t rt_interrupt_from_thread;
|
||||
@@ -64,6 +67,24 @@ struct stack_frame
|
||||
rt_uint32_t r7h;
|
||||
#endif
|
||||
|
||||
#ifdef __TMS320C28XX_FPU64__
|
||||
rt_uint32_t r0l;
|
||||
rt_uint32_t r1l;
|
||||
rt_uint32_t r2l;
|
||||
rt_uint32_t r3l;
|
||||
rt_uint32_t r4l;
|
||||
rt_uint32_t r5l;
|
||||
rt_uint32_t r6l;
|
||||
rt_uint32_t r7l;
|
||||
#endif
|
||||
|
||||
#ifdef __TMS320C28XX_VCRC__
|
||||
rt_uint32_t vcrc;
|
||||
rt_uint32_t vstatus;
|
||||
rt_uint32_t vcrcpoly;
|
||||
rt_uint32_t vcrcsize;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
rt_uint8_t *rt_hw_stack_init(void *tentry,
|
||||
@@ -81,20 +102,17 @@ rt_uint8_t *rt_hw_stack_init(void *tentry,
|
||||
|
||||
stack_frame = (struct stack_frame *)stk;
|
||||
|
||||
/* init all register */
|
||||
/* zero all registers */
|
||||
for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++)
|
||||
{
|
||||
((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef;
|
||||
((rt_uint32_t *)stack_frame)[i] = 0;
|
||||
}
|
||||
|
||||
stack_frame->exception_stack_frame.t_st0 = 0x11110000 | rt_hw_get_st0();
|
||||
stack_frame->exception_stack_frame.acc = 0x33332222;
|
||||
stack_frame->exception_stack_frame.ar1_ar0 = 0x00001111 & (unsigned long)parameter; /* ar0 : argument */
|
||||
stack_frame->exception_stack_frame.p = 0x55554444; /* p */
|
||||
stack_frame->exception_stack_frame.dp_st1 = (0x00000000) | rt_hw_get_st1() & 0xFFFFFFFE; /* dp_st1 */
|
||||
stack_frame->exception_stack_frame.dbgstat_ier = 0; /* dbgstat_ier */
|
||||
stack_frame->exception_stack_frame.return_address = (unsigned long)tentry; /* return_address */
|
||||
stack_frame->rpc = (unsigned long)texit;
|
||||
/* configure special registers*/
|
||||
stack_frame->exception_stack_frame.dp_st1 = 0x00000A08;
|
||||
stack_frame->xar4 = (rt_uint32_t)parameter;
|
||||
stack_frame->exception_stack_frame.return_address = (rt_uint32_t)tentry;
|
||||
stack_frame->rpc = (rt_uint32_t)texit;
|
||||
|
||||
#ifdef __TMS320C28XX_FPU32__
|
||||
stack_frame->stf = 0x00000200;
|
||||
@@ -145,3 +163,32 @@ RT_WEAK void rt_hw_cpu_shutdown(void)
|
||||
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
|
||||
void rt_interrupt_enter(void)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
__asm(" EINT");
|
||||
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_int32_t)rt_interrupt_nest));
|
||||
}
|
||||
|
||||
void rt_interrupt_leave(void)
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq is going to leave, irq current nest:%d\n",
|
||||
(rt_int32_t)rt_interrupt_nest));
|
||||
|
||||
rt_hw_interrupt_disable();
|
||||
RT_OBJECT_HOOK_CALL(rt_interrupt_leave_hook,());
|
||||
rt_interrupt_nest --;
|
||||
if(rt_thread_switch_interrupt_flag && !rt_interrupt_nest)
|
||||
{
|
||||
__asm(" OR IFR, #0x8000"); /* trigger rtos int */
|
||||
}
|
||||
/* rt_hw_interrupt_enable auto done by hardware on IRET */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user