• TencentOS tiny 中断嵌套


     

    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();
    }
    /* 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

    __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);
    }
  • 相关阅读:
    LINUX按键驱动程序
    s3c2440地址分配
    Linux内核代码
    C语言初始化
    tftp协议
    ARM工作模式
    Bootstrap3隐藏滑动侧边栏菜单代码特效
    javascript 中slice,substr,substring方法的对比
    vue 的简述
    鼠标移动出自己想要的效果
  • 原文地址:https://www.cnblogs.com/dream397/p/15931044.html
Copyright © 2020-2023  润新知