⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sem.c

📁 介绍ROCK OS操作系统.一般用于汽车电子,类似OCVX.里面是个DEMO文档,内附说明.
💻 C
📖 第 1 页 / 共 2 页
字号:
            {
                q_del(g_semaCB[hSema].pendTaskQ, (HANDLE)selfTask);
                g_sysTcb[selfTask].bWaitTimeout = OS_FALSE;
                OS_LEAVE_CRITICAL();

                nret = OS_FAIL;
            }
            
            else
            {
                g_semaCB[hSema].ownerTask = selfTask;
                OS_LEAVE_CRITICAL();
                nret = OS_SUCCESS;
            }
        }
        break;

    case OS_SEMA_SYNC:
        OS_ENTER_CRITICAL();
        if (g_semaCB[hSema].semaphore != 0)
        {
            g_semaCB[hSema].semaphore --;

            OS_LEAVE_CRITICAL();

            taskSetTrigger(selfTask, T_TRIG_TAKE_SEMA_DONE, (void *)hSema);
            nret = OS_SUCCESS;
        }
        else
        {
            /* add this task to pend task queue. */
            q_add(g_semaCB[hSema].pendTaskQ, (HANDLE)selfTask, selfPriority);

            /* synchronization semaphore doesn't support auto priority inverse,
             * because I can't know which task's priority should be inverse. */
            OS_LEAVE_CRITICAL();

            /* pend task here. */
            params[0] = (U32)hSema;
            params[1] = (U32)timeout;
            taskSetTrigger(selfTask, T_TRIG_TAKE_SEMA_PEND, (void *)&params[0]);
            OS_ENTER_CRITICAL();

            trigger = getCoreEvent(selfTask);
            if (trigger == T_TRIG_DELAY_TMO)
            {
                q_del(g_semaCB[hSema].pendTaskQ, (HANDLE)selfTask);
                OS_LEAVE_CRITICAL();

                nret = OS_FAIL;
            }
            else
            {
                /* the task has been added to the semaphore's owner queue already (in semGive).*/
                OS_LEAVE_CRITICAL();

                nret = OS_SUCCESS;
            }
        }
        break;

    default:
        OS_error("semTake(): semapore [%d] state is [%d]!!!\n", hSema, g_semaCB[hSema].state);
        nret = OS_FAIL;
        break;
    }
    return nret;
}

/******************************************************************************
Function    : STATUS semGive(HSEMA hSema)
Params      : hSema - the semaphore.
            : 
            : 
            : 
Return      : OS_FAIL or OS_SUCCESS
Description : give up the semaphore.
            : 
******************************************************************************/
STATUS semGive(HSEMA hSema)
{
    HTASK nextTask;

    U16   selfPriority;
    HTASK selfTask;

    STATUS nret;

    /* param check. */
    if (hSema >= MAX_SYS_SEMA)
    {
        OS_error("semGive(): semapore [%d] is invlaid!!!\n", hSema);
        return OS_FAIL;
    }

    if (g_semaCB[hSema].state == OS_SEMA_FREE)
    {
        OS_error("semGive(): semapore [%d] is free!!!\n", hSema);
        return OS_FAIL;
    }

    selfTask = taskIdSelf();
    selfPriority = taskPrioritySelf();

    switch(g_semaCB[hSema].state)
    {
    case OS_SEMA_MUTEX:
        /* task fsm event. */
        taskSetTrigger(selfTask, T_TRIG_SEMA_GIVE, (void *)&hSema);

        OS_ENTER_CRITICAL();

        /* clear the semaphore owner task. */
        g_semaCB[hSema].ownerTask = NULL_TASK;

        /* free the next pending task from the samaphore's pending task queue. */
        if (q_head(g_semaCB[hSema].pendTaskQ, (HANDLE *)&nextTask) == OS_FAIL)
        {
            g_semaCB[hSema].ownerTask = NULL_TASK;
            g_semaCB[hSema].semaphore = 1;
            OS_LEAVE_CRITICAL();

            nret = OS_SUCCESS;
        }
        else
        {
            q_enum(g_semaCB[hSema].pendTaskQ, (HANDLE *)&nextTask);

            /* restore the owner task's priority. */
            taskSetPriorityAuto(selfTask);

            if ((getTaskState(nextTask) == OS_TASK_PEND_ON_SEMA)
                 &&(getTaskPendObj(nextTask) == (HANDLE)hSema))
            {
                g_semaCB[hSema].ownerTask = nextTask;
                OS_LEAVE_CRITICAL();

                /* the nextTask can now continue. */
                taskSetTrigger(nextTask, T_TRIG_TAKE_SEMA_DONE, (void *)hSema);
            }

            nret = OS_SUCCESS;
        }
        break;

    case OS_SEMA_SYNC:

        /* task fsm event. */
        taskSetTrigger(selfTask, T_TRIG_SEMA_GIVE, (void *)&hSema);

        OS_ENTER_CRITICAL();

        /* free the next pending task from the samaphore's pending task queue. */
        if (q_head(g_semaCB[hSema].pendTaskQ, (HANDLE *)&nextTask) == OS_FAIL)
        {
            g_semaCB[hSema].semaphore++;
            OS_LEAVE_CRITICAL();

            nret = OS_SUCCESS;
        }
        else
        {
            q_enum(g_semaCB[hSema].pendTaskQ, (HANDLE *)&nextTask);
            if ((getTaskState(nextTask) == OS_TASK_PEND_ON_SEMA)
                &&(getTaskPendObj(nextTask) == (HANDLE)hSema))
            {
                OS_LEAVE_CRITICAL();

                /* the nextTask can now continue. */
                taskSetTrigger(nextTask, T_TRIG_TAKE_SEMA_DONE, (void *)hSema);
            }
        }
        break;

    default:
        OS_error("semGive(): semapore [%d] state is [%d]!!!\n", hSema, g_semaCB[hSema].state);
        nret = OS_FAIL;
        break;
    }
    return nret;
}

/******************************************************************************
Function    : void getSemType(HSEMA hsema)
Params      : hsema - the semaphore
            : 
            : 
            : 
Return      : N/A
Description : get the semaphore's type, a mutex or a synchronization semaphore.
            : 
******************************************************************************/
U16 getSemType(HSEMA hsema)
{
    if (hsema >= MAX_SYS_SEMA)
    {
        OS_error("getSemType(): semaphore [%d] out of range!!!\n", hsema);
        return OS_SEMA_FREE;
    }

    return g_semaCB[hsema].state;
}

/******************************************************************************
Function    : void semCheck(void)
Params      : N/A
            : 
            : 
            : 
Return      : N/A
Description : check the semaphore periodly, if a semphore is ready for free,
            : then free it.
******************************************************************************/
void semCheck ()
{
    HSEMA hsema;

    for (hsema = 0; hsema < MAX_SYS_SEMA; hsema++)
    {
        if (g_semaCB[hsema].state == OS_SEMA_FREE)
        {
            continue;
        }
        else if (g_semaCB[hsema].tobefree == OS_TRUE)
        {
            switch(g_semaCB[hsema].state)
            {
            case OS_SEMA_MUTEX:
                if ((g_semaCB[hsema].ownerTask == NULL_TASK)
                     &&(q_count(g_semaCB[hsema].pendTaskQ)==0))
                {
                    OS_ENTER_CRITICAL();
                    q_destroy(g_semaCB[hsema].pendTaskQ);
                    memset (&g_semaCB[hsema], 0, sizeof(SEMACB));

                    g_semaCB[hsema].state = OS_SEMA_FREE;
                    OS_LEAVE_CRITICAL();
                }
                break;

            case OS_SEMA_SYNC:
                if (q_count(g_semaCB[hsema].pendTaskQ)==0)
                {
                    OS_ENTER_CRITICAL();
                    q_destroy(g_semaCB[hsema].pendTaskQ);
                    memset (&g_semaCB[hsema], 0, sizeof(SEMACB));

                    g_semaCB[hsema].state = OS_SEMA_FREE;
                    OS_LEAVE_CRITICAL();
                }
                break;

            default:
                OS_error("semCheck(): semaphore [%d] is in error state [%d], recycle now!!!\n",
                            hsema, g_semaCB[hsema].state);

                OS_ENTER_CRITICAL();
                q_destroy(g_semaCB[hsema].pendTaskQ);
                memset (&g_semaCB[hsema], 0, sizeof(SEMACB));

                g_semaCB[hsema].state = OS_SEMA_FREE;
                OS_LEAVE_CRITICAL();
                break;
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -