tos_knl_irq_enter和tos_knl_irq_leave
__API__ void tos_knl_irq_enter(void) { if (!tos_knl_is_running()) { return; } if (unlikely(k_irq_nest_cnt >= K_NESTING_LIMIT_IRQ)) { return; } ++k_irq_nest_cnt; } __API__ void tos_knl_irq_leave(void) { TOS_CPU_CPSR_ALLOC(); if (!tos_knl_is_running()) { return; } TOS_CPU_INT_DISABLE(); if (!knl_is_inirq()) { TOS_CPU_INT_ENABLE(); return; } --k_irq_nest_cnt; if (knl_is_inirq()) { TOS_CPU_INT_ENABLE(); return; } if (knl_is_sched_locked()) { TOS_CPU_INT_ENABLE(); return; } k_next_task = readyqueue_highest_ready_task_get(); if (knl_is_self(k_next_task)) { TOS_CPU_INT_ENABLE(); return; } cpu_irq_context_switch(); TOS_CPU_INT_ENABLE(); }
SysTick_Handler(void)
{ if (tos_knl_is_running()) { tos_knl_irq_enter(); tos_tick_handler(); tos_knl_irq_leave(); } } /* LPUART2_IRQn interrupt handler */ void LPUART2_IRQHandler(void) { uint8_t data; tos_knl_irq_enter(); /* If new data arrived. */ if ((kLPUART_RxDataRegFullFlag)&LPUART_GetStatusFlags(LPUART2)) { data = LPUART_ReadByte(LPUART2); tos_at_uart_input_byte(data); } tos_knl_irq_leave(); } /* LPUART4_IRQn interrupt handler */ void LPUART4_IRQHandler(void) { uint8_t data; tos_knl_irq_enter(); /* If new data arrived. */ if ((kLPUART_RxDataRegFullFlag)&LPUART_GetStatusFlags(LPUART4)) { data = LPUART_ReadByte(LPUART4); tos_at_uart_input_byte(data); } tos_knl_irq_leave(); }
TencentOS-tiny/arch/arm/arm-v7a/cortex-a7/gcc/exceptions.S
/* Fuchsia's code is nice here, so I learn from it(fine, almost copy). thanks */ #include "exceptions.h" .global arm_undefined .global arm_syscall .global arm_prefetch_abort .global arm_data_abort .global arm_reserved .global arm_irq .global arm_fiq .extern tos_knl_irq_enter .extern tos_knl_irq_leave .extern interrupt_irq .syntax unified .text .type arm_undefined, %function arm_undefined: save /* r0 now holds pointer to iframe */ bl arm_undefined_handler restore .type arm_syscall, %function arm_syscall: b . .type arm_prefetch_abort, %function arm_prefetch_abort: saveall_offset #4 /* r0 now holds pointer to iframe */ bl arm_prefetch_abort_handler restoreall .type arm_data_abort, %function arm_data_abort: saveall_offset #8 /* r0 now holds pointer to iframe */ bl arm_data_abort_handler restoreall .type arm_reserved, %function arm_reserved: b . .type arm_irq, %function arm_irq: saveall_offset #4 /* r0 now holds pointer to iframe */ bl tos_knl_irq_enter /* call into higher level code */ bl interrupt_irq bl tos_knl_irq_leave restoreall .type arm_fiq, %function arm_fiq: b . .end
saveall_offset restoreall
/* macros to align and unalign the stack on 8 byte boundary for ABI compliance */ .macro stack_align, tempreg /* make sure the stack is aligned */ mov \tempreg, sp tst sp, #4 subeq sp, #4 push { \tempreg } /* tempreg holds the original stack */ .endm .macro stack_restore, tempreg /* restore the potentially unaligned stack */ pop { \tempreg } mov sp, \tempreg .endm /* save and disable the vfp unit */ .macro vfp_save, temp1 /* save old fpexc */ vmrs \temp1, fpexc push { \temp1 } /* hard disable the vfp unit */ bic \temp1, #(1<<30) vmsr fpexc, \temp1 .endm /* restore the vfp enable/disable state */ .macro vfp_restore, temp1 /* restore fpexc */ pop { \temp1 } vmsr fpexc, \temp1 .endm /* Save callee trashed registers. * At exit r0 contains a pointer to the register frame. */ .macro save /* save spsr and r14 onto the svc stack */ srsdb #0x13! /* switch to svc mode, interrupts disabled */ cpsid i, #0x13 /* save callee trashed regs and lr */ push { r0-r3, r12, lr } #if 0 #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) /* save and disable the vfp unit */ vfp_save r0 #endif #endif /* make sure the stack is 8 byte aligned */ stack_align r0 /* r0 now holds the pointer to the original iframe (before alignment) */ .endm .macro save_offset, offset sub lr, \offset save .endm .macro restore /* undo the stack alignment we did before */ stack_restore r0 #if 0 #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) /* restore the old state of the vfp unit */ vfp_restore r0 #endif #endif pop { r0-r3, r12, lr } /* return to whence we came from */ rfeia sp! .endm /* Save all registers. * At exit r0 contains a pointer to the register frame. */ .macro saveall /* save spsr and r14 onto the svc stack */ srsdb #0x13! /* switch to svc mode, interrupts disabled */ cpsid i,#0x13 /* save all regs */ push { r0-r12, lr } #if 0 #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) /* save and disable the vfp unit */ vfp_save r0 #endif #endif /* make sure the stack is 8 byte aligned */ stack_align r0 /* r0 now holds the pointer to the original iframe (before alignment) */ .endm .macro saveall_offset, offset sub lr, \offset saveall .endm .macro restoreall /* undo the stack alignment we did before */ stack_restore r0 #if 0 #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) /* restore the old state of the vfp unit */ vfp_restore r0 #endif #endif pop { r0-r12, r14 } /* return to whence we came from */ rfeia sp! .endm
interrupt_irq
TencentOS-tiny/arch/arm/arm-v7a/common/tos_interrupt.c
__STATIC__ int_handle_t int_handle_table[INTERRUPT_MAX]; __KNL__ void interrupt_irq(int_frame_t *int_frame) { uint32_t vector; int_handle_t *handle; vector = gic_interrupt_id_get(0u); if (vector > INTERRUPT_MAX || vector == (uint32_t)-1) { return; } handle = &int_handle_table[vector]; if (handle->handler) { handle->handler(handle->arg); } gic_interrupt_end(0u, vector); }