互斥量不能在中断例程中使用的原因

背景

今天在看资料,发现在互斥锁这一块儿,有用法要求,说是 互斥锁不能在中断服务程序中使用。
但是为什么不能用呢?却没见文章中有写,于是顺着这条线向找。

解释

从RT-thread论坛上看到的解释如下:
如果在中断例程中能使用互斥量,万一其他更高优先级的中断来了,需要互斥量,但获取不了,导致中断处理阻塞,而中断是不能阻塞的。

https://club.rt-thread.org/ask/question/5dc901cf99025727.html

疑点

获取mutex时,有一个time_out参数,可以设置为0,那么即不产生BLOCK,是不是就可以在中断中使用了呢?

于是我翻了一个源代码找到了这一段

rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time)
{
    register rt_base_t temp;
    struct rt_thread *thread;

    /* this function must not be used in interrupt even if time = 0 */
    RT_DEBUG_IN_THREAD_CONTEXT;

    /* parameter check */
    RT_ASSERT(mutex != RT_NULL);
    RT_ASSERT(rt_object_get_type(&mutex->parent.parent) == RT_Object_Class_Mutex);

    /* get current thread */
    thread = rt_thread_self();
	....
}

好家伙,源代码中的注释部分,直接说明了 this function must not be used in interrupt even if time = 0,再向下看,找到了thread = rt_thread_self();这说明这个锁仅为线程之间进行设计,若使用了,将会产生不可预知的错误。

我翻了一下ucOS-III源代码,发现ucOS-III源码中直接拦截了。

void  OSMutexPend (OS_MUTEX  *p_mutex,
                   OS_TICK    timeout,
                   OS_OPT     opt,
                   CPU_TS    *p_ts,
                   OS_ERR    *p_err)
{
    OS_TCB  *p_tcb;
    CPU_SR_ALLOC();

#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
    if (OSIntNestingCtr > 0u) {                                 /* Not allowed to call from an ISR                      */
        OS_TRACE_MUTEX_PEND_FAILED(p_mutex);
        OS_TRACE_MUTEX_PEND_EXIT(OS_ERR_PEND_ISR);
       *p_err = OS_ERR_PEND_ISR;
        return;
    }
#endif
	....
}

void  OSMutexPost (OS_MUTEX  *p_mutex,
                   OS_OPT     opt,
                   OS_ERR    *p_err)
{
    OS_PEND_LIST  *p_pend_list;
    OS_TCB        *p_tcb;
    CPU_TS         ts;
    OS_PRIO        prio_new;
    CPU_SR_ALLOC();

#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
    if (OSIntNestingCtr > 0u) {                                 /* Not allowed to call from an ISR                      */
        OS_TRACE_MUTEX_POST_FAILED(p_mutex);
        OS_TRACE_MUTEX_POST_EXIT(OS_ERR_POST_ISR);
       *p_err = OS_ERR_POST_ISR;
        return;
    }
#endif
	....
}

结论

互斥锁量是专门为任务与任务之间共享资源而设计,不适用中断的场合。

posted @ 2023-03-30 14:56  海林的菜园子  阅读(1244)  评论(0编辑  收藏  举报