SylixOS中断抢占配置

SylixOS中断抢占

SylixOS是支持中断抢占的,通过IRQ的FLAG标志LW_IRQ_FLAG_PREEMPTIVE进行控制。SylixOS可以通过两种方式设置中断抢占,第一种是Arch层通过archIntHandle实现的,第二种是通过API_InterVectorSetFlag进行控制。这两种方式最终实现效果都是在Arch层实现的。

Arch层实现

在Arch层archIntHandle负责处理具体中断,archIntHandle代码实现如下。通过参数bPreemptive可以看出,它控制着当前中断是否能够被抢占,如果为true则可以被抢占,通过这种方式设置,如果可可抢占则所有中断都支持抢占。

/*********************************************************************************************************
** 函数名称: archIntHandle
** 功能描述: bspIntHandle 需要调用此函数处理中断 (关闭中断情况被调用)
** 输 入  : ulVector         中断向量
**           bPreemptive      中断是否可抢占
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
** 注  意  : 此函数退出时必须为中断关闭状态.
*********************************************************************************************************/
LW_WEAK VOID  archIntHandle (ULONG  ulVector, BOOL  bPreemptive)
{
    REGISTER irqreturn_t irqret;

    if (_Inter_Vector_Invalid(ulVector)) {
        return;                                                         /*  向量号不正确                */
    }

    if (LW_IVEC_GET_FLAG(ulVector) & LW_IRQ_FLAG_PREEMPTIVE) {
        bPreemptive = LW_TRUE;
    }

    if (bPreemptive) {
        VECTOR_OP_LOCK();
        __ARCH_INT_VECTOR_DISABLE(ulVector);                            /*  屏蔽 vector 中断            */
        VECTOR_OP_UNLOCK();
        KN_INT_ENABLE_FORCE();                                          /*  允许中断                    */
    }

    irqret = API_InterVectorIsr(ulVector);                              /*  调用中断服务程序            */
    
    KN_INT_DISABLE();                                                   /*  禁能中断                    */
    
    if (bPreemptive) {
        if (irqret != LW_IRQ_HANDLED_DISV) {
            VECTOR_OP_LOCK();
            __ARCH_INT_VECTOR_ENABLE(ulVector);                         /*  允许 vector 中断            */
            VECTOR_OP_UNLOCK();
        }
    
    } else if (irqret == LW_IRQ_HANDLED_DISV) {
        VECTOR_OP_LOCK();
        __ARCH_INT_VECTOR_DISABLE(ulVector);                            /*  屏蔽 vector 中断            */
        VECTOR_OP_UNLOCK();
    }
}

API接口实现

从archIntHandle代码实现中可以看到,它会通过LW_IVEC_GET_FLAG检查此中断使用使能标志LW_IRQ_FLAG_PREEMPTIVE,如果使能则 bPreemptive 置位,同样实现此中断抢占。

if (LW_IVEC_GET_FLAG(ulVector) & LW_IRQ_FLAG_PREEMPTIVE) {
bPreemptive = LW_TRUE;
}

而LW_IVEC_GET_FLAG宏函数是通过获取对应中断向量标志IDESC_ulFlag实现控制中断抢占的。通过代码可以看出,每个中断向量都可以单独控制中断标志,也就是都可以单独控制中断抢占。

#define LW_IVEC_GET_FLAG(vector)        \
        (_K_idescTable[vector].IDESC_ulFlag)

API_InterVectorSetFlag具体代码实现如下,可以看出根据中断向量号,分别设置中断标志。

/*********************************************************************************************************
** 函数名称: API_InterVectorSetFlag
** 功能描述: 设置指定中断向量的特性. 
** 输 入  : ulVector                      中断向量号
**           ulFlag                        特性
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
** 注  意  : LW_IRQ_FLAG_QUEUE 必须在安装任何一个驱动前设置, 且设置后不再能取消.
             最好放在 bspIntInit() 函数中完成设置.
                                           API 函数
*********************************************************************************************************/
LW_API
ULONG  API_InterVectorSetFlag (ULONG  ulVector, ULONG  ulFlag)
{
    INTREG              iregInterLevel;
    PLW_CLASS_INTDESC   pidesc;

    if (_Inter_Vector_Invalid(ulVector)) {
        _ErrorHandle(ERROR_KERNEL_VECTOR_NULL);
        return  (ERROR_KERNEL_VECTOR_NULL);
    }
    
    pidesc = LW_IVEC_GET_IDESC(ulVector);
    
    LW_SPIN_LOCK_QUICK(&pidesc->IDESC_slLock, &iregInterLevel);         /*  关闭中断同时锁住 spinlock   */
    
    if (LW_IVEC_GET_FLAG(ulVector) & LW_IRQ_FLAG_QUEUE) {               /*  已经是 QUEUE 类型中断向量   */
        LW_IVEC_SET_FLAG(ulVector, ulFlag | LW_IRQ_FLAG_QUEUE);
    
    } else {
        LW_IVEC_SET_FLAG(ulVector, ulFlag);
    }
    
    LW_SPIN_UNLOCK_QUICK(&pidesc->IDESC_slLock, iregInterLevel);        /*  打开中断, 同时打开 spinlock */
    
    return  (ERROR_NONE);
}

总结

API_InterVectorSetFlag可以指定某个中断可以被抢占,就是当这个中断发生时,其他中断可以抢占。而archIntHandle是在bsp适配时指定全部中断都可抢占,是通过ARCH中的archIntHandle参数实现的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值