/**********************************************************************/
/*                                                                    */
/* File name: uip_kernel_isr_engine.c                                 */
/*                                                                    */
/* Since:     2013-08-27                                              */
/*                                                                    */
/* Version:   uip Kernel v1.09                                        */
/*            Copyright (C) 2006..2018 Wang Baojin.                   */
/*                                                                    */
/* Author:    Designed by Wang Baojin(王保进)                         */
/*                                                                    */
/*                                                                    */
/* Purpose:   Definition of interrupt handler                         */ 
/*            architecture functions in C.                            */
/*            中断处理服务框架的C语言部分                             */
/*                                                                    */
/* Distribution: This file is part of uip kernel.                     */
/*            uip Kernel is free software, you can redistribute it    */
/*            and/or modify it under the terms of the GNU General     */
/*            Public License as published by the Free Software        */
/*            Foundation either version 2, or (at your option)        */
/*            any later version.                                      */
/*                                                                    */
/*            uip Kernel is distributed in the hope that it will be   */
/*            useful, but WITHOUT ANY WARRANTY without even the       */
/*            implied warranty of MERCHANTABILITY or FITNESS FOR A    */
/*            PuipICULAR PURPOSE.  See the GNU General Public         */
/*            License for more details.                               */
/*                                                                    */
/*            You should have received a copy of the GNU General      */
/*            Public License along with gpsim see the file            */
/*            COPYING.txt. If not, write to the Free Software         */
/*            Foundation, 59 Temple Place - Suite 330,                */
/*            Boston, MA 02111-1307, USA.                             */
/*                                                                    */
/*          > A special exception to the GPL can be applied should    */
/*            you wish to distribute a combined work that includes    */
/*            uip Kernel, without being obliged to provide the        */
/*            source code for any proprietary components.             */
/*                                                                    */
/* History:                                                           */
/*   2013/08/27  [WBJ] Create this file.                              */
/*                                                                    */
/**********************************************************************/

#include "uip_kernel_api.h"

/**********************************************************************/ 
/*                                                                    */ 
/*  Function name                                       Version       */ 
/*                                                                    */ 
/*    uipInterruptServiceEngine                          1.09         */ 
/*                                                                    */ 
/*  Author                                                            */ 
/*                                                                    */ 
/*    Wang Baojin                                                     */ 
/*                                                                    */ 
/*  Description                                                       */ 
/*                                                                    */ 
/*    Trigger interrupt for context switch in Cortex-M                */ 
/*                                                                    */ 
/*    触发实现现场切换处理逻辑的中断                                  */
/*                                                                    */ 
/*                                                                    */ 
/*  Parameter(In)                                                     */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Parameter(Out)                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Return Status                                                     */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Call functions                                                    */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Called by                                                         */ 
/*                                                                    */ 
/*    None                                                            */ 
/*                                                                    */ 
/*  Release                                                           */ 
/*                                                                    */ 
/*  author name         release date              Description         */ 
/*                                                                    */ 
/*  Wang Baojin          2013.08.27           Initial Version 1.09    */ 
/*                                                                    */ 
/**********************************************************************/
VOID uipInterruptServiceEngine(VOID)
{    
    uip_INTERRUPT_STATE_SAVED;
    
    /* 关闭中断 */
    uip_KERNEL_DISABLE_INTS;

    /* 如果当前还没有进入UIP Kernel 调度内核，则直接返回 */
    if (uipSystemMode != uip_KERNEL_RUNNING) 
    {
        /* 恢复全局中断控制的原有值 */
        /* Restore original sys-int-ctrl value */
        uip_KERNEL_RESTORE_INTS;
        
        return;    
    }
    
    /* 首先判断中断嵌套的层级是否越界 */
    /* Check interrupt nested level */
    if (uipNestedInterrupts > uip_INT_NESTED_MAX) 
    {
        /* 恢复全局中断控制的原有值 */
        /* Restore original sys-int-ctrl value */
        uip_KERNEL_RESTORE_INTS;
        
        return;
    }
    /* 中断嵌套层级加1 */
    /* Add 1 to interrupt nest state global variable */
    uipNestedInterrupts++;
    
    /* 恢复全局中断控制的原有值 */
    /* Restore original sys-int-ctrl value */
    uip_KERNEL_RESTORE_INTS;
    
    /* 利用回调函数执行中断处理程序 */
    /* Callback for interrupt handling */
    uipInterruptHandlingCallback();
    
    /** 执行UIP Kernel定义的中断退出操作 **/
    /* 关闭中断 */
    uip_KERNEL_DISABLE_INTS;
    
    /* 判断中断嵌套标示字的有效性 */
    if (uipNestedInterrupts <= uip_NULL) 
    {
        /* 恢复全局中断控制的原有值 */
        /* Restore original sys-int-ctrl value */
        uip_KERNEL_RESTORE_INTS;
         
        return;
    }
    
    uipNestedInterrupts--;
    
    /* 若还有嵌套的中断 */
    if (uipNestedInterrupts > 0) 
    {
        /* 恢复全局中断控制的原有值 */
        /* Restore original sys-int-ctrl value */
        uip_KERNEL_RESTORE_INTS;
      
        return;
    }    

    /* 若当前为低功耗模式，则直接返回到被中断的点 */   
    /* Check to see if there was in low power mode */
    if (uipLowPowerMode != 0) 
    {
        /* 恢复全局中断控制的原有值 */
        /* Restore original sys-int-ctrl value */
        uip_KERNEL_RESTORE_INTS;
       
        return;
    }
    
    /* 如果当前还没有进入UIP Kernel 调度内核，则直接返回 */
    if (uipSystemMode != uip_KERNEL_RUNNING) 
    {
        /* 恢复全局中断控制的原有值 */
        /* Restore original sys-int-ctrl value */
        uip_KERNEL_RESTORE_INTS;
     
        return;    
    }

    /* 若当前被禁止发生切换 */
    if (uipSchedulerLock != 0) 
    {
        /* 恢复全局中断控制的原有值 */
        /* Restore original sys-int-ctrl value */
        uip_KERNEL_RESTORE_INTS;
      
        return;
    }
    
    /* 获得下一个将要运行的任务（更高优先级任务） */
    uipGetNextTask();
    
    /* 若被中断的即为当前最高优先级任务，则直接返回 */
    if (uipNextRunningTaskTCBPtr == uipCurrentTaskTCBPtr) 
    {        
        /* 若被中断的不为调度循环 */
        if (uipCurrentTaskTCBPtr != 0) 
        {             
            /* 重置保存将运行任务信息的全局变量 */
            /* Reset next running task's info */            
            uipNextRunningTaskTCBPtr = uip_NULL;
            
            uipNextRunningTaskPriority = uipMinPriority;            
        } 
        
        /* 恢复全局中断控制的原有值 */
        /* Restore original sys-int-ctrl value */
        uip_KERNEL_RESTORE_INTS;

        return;            
    } 
	
    if (((uipCurrentTaskTCBPtr -> uipTaskState) & uip_TASK_STATE_MASK) == RUNNING_STATE )
    {
        uipCurrentTaskTCBPtr -> uipTaskState &= uip_TASK_EXTENDED;
        uipCurrentTaskTCBPtr -> uipTaskState |= READY_STATE;      
    } 
        
    /* 进入调度内核 */  
    uipScheduler();
    
    /* 恢复全局中断控制的原有值 */
    /* Restore original sys-int-ctrl value */
    uip_KERNEL_RESTORE_INTS;   
}

/***************************************************************************************/
/*                     End of File : uip_kernel_isr_engine.c                           */
/***************************************************************************************/
