FreeRTOS临界保护

下面的是个人笔记,所有的话都适用于我本人理解,可能存在不对的地方。

进入临界保护(支持嵌套):taskENTER_CRITICAL();

退出临界保护(支持嵌套):taskEXIT_CRITICAL();

中断里进入临界保护(支持嵌套):  taskENTER_CRITICAL_FROM_ISR();

中断里退出临界保护(支持嵌套):   taskEXIT_CRITICAL_FROM_ISR( x );

进入临界保护的定义代码:

从中可以看出,uxCriticalNesting++,正因为该变量的处理,才支持了嵌套。

退出临界保护的定义代码大同小异。


void vPortEnterCritical( void )

{

    portDISABLE_INTERRUPTS();

    uxCriticalNesting++;

    /* This is not the interrupt safe version of the enter critical function so

    assert() if it is being called from an interrupt context.  Only API

    functions that end in "FromISR" can be used in an interrupt.  Only assert if

    the critical nesting count is 1 to protect against recursive calls if the

    assert function also uses a critical section. */

    if( uxCriticalNesting == 1 )

    {

        configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );

    }

}


继续深入,可以看到,实际上是操作了 basepri寄存器来实现开关中断的机理,而要关闭的中断是哪些优先级的中断,则是由 configMAX_SYSCALL_INTERRUPT_PRIORITY所决定。

configMAX_SYSCALL_INTERRUPT_PRIORITY = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << 4,所有小于该优先级的中断都会被关断。


static portFORCE_INLINE void vPortRaiseBASEPRI( void )

{

uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;

    __asm

    {

        /* Set BASEPRI to the max syscall priority to effect a critical

        section. */

        msr basepri, ulNewBASEPRI

        dsb

        isb

    }

}


在裸机中,开关中断是下面两个语句:

使能全局中断: __set_PRIMASK(0);

禁止全局中断: __set_PRIMASK(1);

要注意,因为 FreeRTOS 存在不受其控制的更高优先级中断,用户需要根据实际情况进行特别处理,可以不采用 FreeRTOS 的开关中断函数,而是直接使用__set_PRIMASK 实现全局中断的开关。

还要注意一点:使用临界保护时,在调度器没开始工作时,使用无效。有效的使用是在调度器开始工作后的任务里选择使用的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值