Ejemplo n.º 1
0
/*************************************************************************************************
 *  功能:停止用户定时器函数                                                                     *
 *  参数:(1) pTimer   定时器地址                                                                *
 *        (2) pError   详细调用结果                                                              *
 *  返回: (1) eSuccess 操作成功                                                                  *
 *        (2) eFailure 操作失败                                                                  *
 *        (3) pError   详细调用结果                                                              *
 *  说明:                                                                                       *
 *************************************************************************************************/
TState xTimerStop(TTimer* pTimer, TError* pError)
{
    TState state = eFailure;
    TError error = TIMER_ERR_UNREADY;
    TReg32 imask;

    CpuEnterCritical(&imask);

    /* 检查定时器就绪属性 */
    if (pTimer->Property & TIMER_PROP_READY)
    {
        if (pTimer->Type == eUserTimer)
        {
            uTimerStop(pTimer);
            error = TIMER_ERR_NONE;
            state = eSuccess;
        }
        else
        {
            error = TIMER_ERR_FAULT;
        }
    }
    CpuLeaveCritical(imask);

    *pError = error;
    return state;
}
Ejemplo n.º 2
0
/*************************************************************************************************
 *  功能:将线程从指定的状态转换到就绪态,使得线程能够参与内核调度                               *
 *  参数:(1) pThread   线程结构地址                                                             *
 *        (2) status    线程当前状态,用于检查                                                   *
 *        (3) pError    保存操作结果                                                             *
 *  返回:(1) eFailure                                                                           *
 *        (2) eSuccess                                                                           *
 *  说明:函数名的前缀'u'(communal)表示本函数是全局函数                                          *
 *************************************************************************************************/
static TState SetThreadReady(TThread* pThread, TThreadStatus status, TBool* pHiRP, TError* pError)
{
    TState state = eFailure;
    TError error = THREAD_ERR_STATUS;

    /* 线程状态校验,只有状态符合的线程才能被操作 */
    if (pThread->Status == status)
    {
        /*
         * 操作线程,完成线程队列和状态转换,注意只有中断处理时,
         * 当前线程才会处在内核线程辅助队列里(因为还没来得及线程切换)
         * 当前线程返回就绪队列时,一定要回到相应的队列头
         * 当线程进出就绪队列时,不需要处理线程的时钟节拍数
         */
        uThreadLeaveQueue(&ThreadAuxiliaryQueue, pThread);
        if (pThread == uKernelVariable.CurrentThread)
        {
            uThreadEnterQueue(&ThreadReadyQueue, pThread, eQuePosHead);
            pThread->Status = eThreadRunning;
        }
        else
        {
            uThreadEnterQueue(&ThreadReadyQueue, pThread, eQuePosTail);
            pThread->Status = eThreadReady;
        }
        state = eSuccess;
        error = THREAD_ERR_NONE;

        /* 因为是在线程环境下,所以此时pThread一定不是当前线程 */
        if (pThread->Priority < uKernelVariable.CurrentThread->Priority)
        {
            *pHiRP = eTrue;
        }

#if (TCLC_TIMER_ENABLE)
        /* 如果是取消定时操作则需要停止线程定时器 */
        if ((state == eSuccess) && (status == eThreadDelayed))
        {
            uTimerStop(&(pThread->Timer));
        }
#endif
    }

    *pError = error;
    return state;
}
Ejemplo n.º 3
0
/* 中断或者线程都有可能调用本函数 */
TState uThreadSetReady(TThread* pThread, TThreadStatus status, TError* pError)
{
    TState state = eFailure;
    TError error = THREAD_ERR_STATUS;
    TBool HiRP = eFalse;

    /* 线程状态校验,只有状态符合的线程才能被操作 */
    if (pThread->Status == status)
    {
        /* 操作线程,完成线程队列和状态转换,注意只有中断处理时,
        当前线程才会处在内核线程辅助队列里(因为还没来得及线程切换) */
        uThreadLeaveQueue(&ThreadAuxiliaryQueue, pThread);
        uThreadEnterQueue(&ThreadReadyQueue, pThread, eQuePosTail);

        /* 当线程离开就绪队列时,已经放弃它的本轮执行,哪怕时间片并未耗尽。
        当线程再次进入就绪队列时,需要恢复线程的时钟节拍数,重新计算其分享处理器时间的能力 */
        pThread->Ticks = pThread->BaseTicks;
        pThread->Status = eThreadReady;
        state = eSuccess;
        error = THREAD_ERR_NONE;

        /* 如果是在线程环境下,那么此时pThread一定不是当前线程;
        如果是在中断环境下,那么
        第一,当前线程不一定在就绪队列里,不能作为任务调度的比较标准
        第二,中断在最后一级返回时统一做线程调度检查,这里得到的HiPR无意义 */
        if (pThread->Priority < uKernelVariable.CurrentThread->Priority)
        {
            HiRP = eTrue;
        }

        /* 尝试发起线程抢占 */
        uThreadPreempt(HiRP);

#if (TCLC_TIMER_ENABLE)
        /* 如果是取消定时操作则需要停止线程定时器 */
        if ((state == eSuccess) && (status == eThreadDelayed))
        {
            uTimerStop(&(pThread->Timer));
        }
#endif
    }

    *pError = error;
    return state;
}
Ejemplo n.º 4
0
/*************************************************************************************************
 *  功能:唤醒IPC阻塞队列中指定的线程                                                            *
 *  参数:(1) pThread 线程地址                                                                   *
 *        (2) state   线程资源访问返回结果                                                       *
 *        (3) error   详细调用结果                                                               *
 *        (4) pHiRP   是否因唤醒更高优先级而导致需要进行线程调度的标记                           *
 *  返回:无                                                                                     *
 *  说明:                                                                                       *
 *************************************************************************************************/
void uIpcUnblockThread(TIpcContext* pContext, TState state, TError error, TBool* pHiRP)
{
    TThread* pThread;
    TQueuePos pos = eQuePosTail;
    TThreadStatus newStatus = eThreadReady;
	
    /* 
     * 将线程从IPC资源的阻塞队列中移出,加入到内核线程就绪队列,
     * 如果当前线程刚刚被阻塞到阻塞队列中,但还未发生线程切换,
     * 而在此时被ISR打断并且ISR又将当前线程唤醒,则当前线程也不必返回就绪队列头 
     */
    pThread = (TThread*)(pContext->Owner);

    /* 只有处于阻塞状态的线程才可以被解除阻塞 */
    if (pThread->Status != eThreadBlocked)
    {
        uDebugPanic("", __FILE__, __FUNCTION__, __LINE__);
    }

    /*
     * 操作线程,完成线程队列和状态转换,注意只有中断处理时,
     * 当前线程才会处在内核线程辅助队列里(因为还没来得及线程切换)
     * 当前线程返回就绪队列时,一定要回到相应的队列头
     * 当线程进出就绪队列时,不需要处理线程的时钟节拍数
     */
    uThreadLeaveQueue(uKernelVariable.ThreadAuxiliaryQueue, pThread);
    if (pThread == uKernelVariable.CurrentThread)
    {
        pos = eQuePosHead;
        newStatus = eThreadRunning;
    }
    uThreadEnterQueue(uKernelVariable.ThreadReadyQueue, pThread, pos);
    pThread->Status = newStatus;

    /* 将线程从阻塞队列移出 */
    LeaveBlockedQueue(pContext->Queue, pContext);

    /* 设置线程访问资源的结果和错误代码 */
    *(pContext->State) = state;
    *(pContext->Error) = error;

    /* 如果线程是以时限方式访问资源则取消该线程的时限定时器 */
#if ((TCLC_IPC_TIMER_ENABLE) && (TCLC_TIMER_ENABLE))
    if ((pContext->Option & IPC_OPT_TIMED) && (error != IPC_ERR_TIMEO))
    {
        KNL_ASSERT((pThread->Timer.Type == eIpcTimer), "");
        uTimerStop(&(pThread->Timer));
    }
#endif

    /* 设置线程调度请求标记,此标记只在线程环境下有效。
       在ISR里,当前线程可能在任何队列里,
       跟当前线程相比较优先级也是无意义的 */
    /*
    * 在线程环境下,如果当前线程的优先级已经不再是线程就绪队列的最高优先级,
    * 并且内核此时并没有关闭线程调度,那么就需要进行一次线程抢占
    */
    if (pThread->Priority < uKernelVariable.CurrentThread->Priority)
    {
        *pHiRP = eTrue;
    }
}