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

📄 fsm.c

📁 介绍ROCK OS操作系统.一般用于汽车电子,类似OCVX.里面是个DEMO文档,内附说明.
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
    Copyright (c) 2006 by RockOS.
    All rights reserved.

    This software is supported by the Rock Software Workroom only.

    Any bugs please contact the author with e-mail or QQ:
     E-mail : baobaoba520@yahoo.com.cn
         QQ : 59681888
*******************************************************************************
File name   : fsm.c
Description : FSM management module for RockOS.
            : 
            : 
Auther      : sunxinqiu
History     :
  2006-3-15   first release.
******************************************************************************/

#include "os.h"

/******************************************************************************
Global var  : FSMCB g_fsmCB[];
Description : The FSM control block, it may be free or used by some task, or by
            : NULL_TASK if it is the task fsm.
******************************************************************************/
FSMCB g_fsmCB[MAX_FSM_NUM];

/******************************************************************************
Function    : STATUS fsm_init(void)
Params      : N/A
            : 
            : 
            : 
Return      : NO_ERROR always.
Description : This function should only be called when the system is starting
            : up.
******************************************************************************/
STATUS fsm_init()
{
    HANDLE handle;

    if (g_OSRunning != OS_PHASE_INIT)
    {
        OS_error("fsm_init(): this function can't be called after system in scheduling!!!\n");
        return OS_FAIL;
    }

    for (handle = 0; handle < MAX_FSM_NUM; handle++)
    {
        memset (&g_fsmCB[handle], 0, sizeof(FSMCB));

        g_fsmCB[handle].state = OS_FSM_FREE;
        g_fsmCB[handle].owner = NULL_TASK;
    }

    return OS_SUCCESS;
}

/******************************************************************************
Function    : HFSM fsmCreate()
Params      : pfsmMap - the FSM MAP table.
            : counter - the FSM MAP table element's counter.
            : owner   - the owner task.
            : name    - the fsm's name provided by the owner task.
Return      : the FSM handle.
Description : To use a FSM, the task should create a FSM first, then register
            : the fsm map and some additional actions.
******************************************************************************/
HFSM fsmCreate(FSM_MAP * pfsmMap, U16 counter, HTASK owner, const char * name)
{
    HANDLE handle;
    HFSM hfsm;

    hfsm = NULL_HANDLE;

    /* find a free fsm entry. */
    OS_ENTER_CRITICAL();
    for (handle = 0; handle < MAX_FSM_NUM; handle++)
    {
        if (g_fsmCB[handle].state == OS_FSM_FREE)
        {
            hfsm = handle;
            g_fsmCB[hfsm].state = OS_FSM_BUSY;
            break;
        }
    }
    OS_LEAVE_CRITICAL();

    /* config the fsm. */
    if (hfsm != NULL_HANDLE)
    {
        g_fsmCB[hfsm].nIdxCount   = counter;
        g_fsmCB[hfsm].pIndexMap = fsmCreateIdxMap (hfsm, pfsmMap, counter);
        g_fsmCB[hfsm].owner = owner;
        strncpy (&g_fsmCB[hfsm].name[0], name, strlen(name));
    }

    return hfsm;
}

/******************************************************************************
Function    : STATUS fsmReg()
Params      : hFsm        - the FSM handle
            : getOldState - FSM scheduler calls this function to get instance's 
            :               old state.
            : dumpFsm     - the scheduler calls this function to dump the fsm's
            :               running track.
Return      : OS_SUCCESS or OS_FAIL.
Description : This function should be called next the fsmCreate before the 
            : fsm can be used.
******************************************************************************/
STATUS fsmReg(HFSM hFsm, GET_OLD_STATE getOldState, FSM_DUMP dumpFsm)
{
    /* params check. */
    if (hFsm >= MAX_FSM_NUM)
    {
        OS_error("fsmReg(): the fsm instance [%d] is invalid!!!\n", hFsm);
        return OS_FAIL;
    }

    if (g_fsmCB[hFsm].state == OS_FSM_FREE)
    {
        OS_error("fsmReg(): the fsm instance [%d] is free!!!\n", hFsm);
        return OS_FAIL;
    }

    /* config the fsm. */
    if (getOldState != NULL)
    {
        g_fsmCB[hFsm].getOldState = getOldState;
    }

    if (dumpFsm != NULL)
    {
        g_fsmCB[hFsm].dumpFsm = dumpFsm;
    }
    else
    {
        g_fsmCB[hFsm].dumpFsm = fsmDumpDefault;
    }

    return OS_SUCCESS;
}

/******************************************************************************
Function    : STATUS fsmRegNameTable()
Params      : hFsm     - the fsm
            : type     - type of name table
            : size     - the name table entries number
            : pNameTbl - the name table
            : 
Return      : OS_SUCCESS or OS_FAIL
Description : This function is not mandatory, it is only used to improve the
            : readability of the fsm dump information.
******************************************************************************/
STATUS fsmRegNameTable(HFSM hFsm, U32 type, U32 size, const FSM_NAME_TBL * pNameTbl)
{
    U32 nsize;
    char name[MAX_NAME_LEN+1];

    U32 i, j;
    FSM_NAME_TBL item;

    if (hFsm >= MAX_FSM_NUM)
    {
        OS_error("fsmRegNameTable(): the fsm instance [%d] is invalid!!!\n", hFsm);
        return OS_FAIL;
    }

    if (g_fsmCB[hFsm].state == OS_FSM_FREE)
    {
        OS_error("fsmRegNameTable(): the fsm instance [%d] is free!!!\n", hFsm);
        return OS_FAIL;
    }

    switch(type)
    {
    case FSM_STATE_NAME:
        /* copy the name table. */
        g_fsmCB[hFsm].stateTblSize = size;
        nsize = size * sizeof(FSM_NAME_TBL);
        sprintf(&name[0], "fsm %d state name", hFsm);
        g_fsmCB[hFsm].pStateTbl = (FSM_NAME_TBL *)memAlloc(nsize, taskIdSelf(), &name[0]);
        memcpy (g_fsmCB[hFsm].pStateTbl, pNameTbl, nsize);

        /* sort increase. */
        for (i = size; i > 0; i--)
        {
            for (j = 0; j < i-1; j++)
            {
                if (g_fsmCB[hFsm].pStateTbl[j].value > g_fsmCB[hFsm].pStateTbl[j+1].value)
                {
                    /* swap element. */
                    memcpy (&item, &g_fsmCB[hFsm].pStateTbl[j], sizeof(FSM_NAME_TBL));
                    memcpy (&g_fsmCB[hFsm].pStateTbl[j], &g_fsmCB[hFsm].pStateTbl[j+1], sizeof(FSM_NAME_TBL));
                    memcpy (&g_fsmCB[hFsm].pStateTbl[j+1], &item, sizeof(FSM_NAME_TBL));
                }
            }
        }
        break;

    case FSM_EVENT_NAME:
        g_fsmCB[hFsm].eventTblSize = size;
        nsize = size * sizeof(FSM_NAME_TBL);
        sprintf(&name[0], "fsm %d evt name", hFsm);
        g_fsmCB[hFsm].pEventTbl = (FSM_NAME_TBL *)memAlloc(nsize, taskIdSelf(), &name[0]);
        memcpy (g_fsmCB[hFsm].pEventTbl, pNameTbl, nsize);

        /* sort increase. */
        for (i = size; i > 0; i--)
        {
            for (j = 0; j < i-1; j++)
            {
                if (g_fsmCB[hFsm].pStateTbl[j].value > g_fsmCB[hFsm].pStateTbl[j+1].value)
                {
                    /* swap element. */
                    memcpy (&item, &g_fsmCB[hFsm].pStateTbl[j], sizeof(FSM_NAME_TBL));
                    memcpy (&g_fsmCB[hFsm].pStateTbl[j], &g_fsmCB[hFsm].pStateTbl[j+1], sizeof(FSM_NAME_TBL));
                    memcpy (&g_fsmCB[hFsm].pStateTbl[j+1], &item, sizeof(FSM_NAME_TBL));
                }
            }
        }
        break;

    case FSM_ACTION_NAME:
        g_fsmCB[hFsm].actionTblSize = size;
        nsize = size * sizeof(FSM_NAME_TBL);
        sprintf(&name[0], "fsm %d act name", hFsm);
        g_fsmCB[hFsm].pActionTbl = (FSM_NAME_TBL *)memAlloc(nsize, taskIdSelf(), &name[0]);
        memcpy (g_fsmCB[hFsm].pActionTbl, pNameTbl, nsize);

        /* sort increase. */
        for (i = size; i > 0; i--)
        {
            for (j = 0; j < i-1; j++)
            {
                if (g_fsmCB[hFsm].pStateTbl[j].value > g_fsmCB[hFsm].pStateTbl[j+1].value)
                {
                    /* swap element. */
                    memcpy (&item, &g_fsmCB[hFsm].pStateTbl[j], sizeof(FSM_NAME_TBL));
                    memcpy (&g_fsmCB[hFsm].pStateTbl[j], &g_fsmCB[hFsm].pStateTbl[j+1], sizeof(FSM_NAME_TBL));
                    memcpy (&g_fsmCB[hFsm].pStateTbl[j+1], &item, sizeof(FSM_NAME_TBL));
                }
            }
        }
        break;

    default:
        OS_error("fsmRegNameTable(): unknown name type [%d].\n", type);
        break;
    }
    return OS_SUCCESS;
}

/******************************************************************************
Function    : STATUS fsmSetTrig (HFSM hFsm, HANDLE hInst, U16 event, void * pData)
Params      : hFsm  - the fsm.
            : hInst - the instance in the fsm.
            : event - the event raised to the instance
            : pData - param for this event.
            : 
Return      : NO_ERROR or other error code.
Description : This function is the main trig function for a fsm.
            : 
******************************************************************************/
STATUS fsmSetTrig (HFSM hFsm, HANDLE hInst, U16 event, void * pData)
{
    U16 oldState;
    FSM_ACTION fsm_action;

    /* params check. */
    if (hFsm >= MAX_FSM_NUM)
    {
        OS_error("fsmSetTrig(): the fsm instance [%d] is invalid!!!\n", hFsm);
        return OS_FAIL;
    }

    if (g_fsmCB[hFsm].state == OS_FSM_FREE)
    {
        OS_error("fsmSetTrig(): the fsm instance [%d] is free!!!\n", hFsm);
        return OS_FAIL;
    }

    if (g_fsmCB[hFsm].getOldState == NULL)
    {
        OS_error("fsmSetTrig(): the fsm [%d:%s] has not been registered!!!\n", hFsm, g_fsmCB[hFsm].name);
        return OS_FAIL;
    }

    oldState = g_fsmCB[hFsm].getOldState(hInst);
    fsm_action = fsmGetAction(hFsm, oldState, event);


    /* dump the fsm running track. */
    taskLock();
    g_fsmCB[hFsm].dumpFsm(hFsm, hInst, oldState, event, (void *)fsm_action);
    taskUnlock();

    /* take action for this state-event combination. */
    if (fsm_action != NULL)
    {
        fsm_action(hInst, pData);
    }

    return OS_SUCCESS;
}

/******************************************************************************
Function    : STATUS fsmDestroy (HFSM hFsm)
Params      : hFsm - the fsm to be deleted.
            : 
            : 
            : 
Return      : OS_SUCCESS or OS_FAIL.
Description : If a fsm is no use, call this function to delete it.
            : 
******************************************************************************/
STATUS fsmDestroy (HFSM hFsm)
{
    /* params check. */
    if (hFsm >= MAX_FSM_NUM)
    {
        OS_error("fsmDestroy(): the fsm instance [%d] is invalid!!!\n", hFsm);
        return OS_FAIL;
    }

    if (g_fsmCB[hFsm].state == OS_FSM_FREE)
    {
        OS_error("fsmDestroy(): the fsm instance [%d] is free!!!\n", hFsm);
        return OS_SUCCESS;

⌨️ 快捷键说明

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