📄 fsm.c
字号:
}
memset (&g_fsmCB[hFsm], 0, sizeof(FSMCB));
g_fsmCB[hFsm].state = OS_FSM_FREE;
g_fsmCB[hFsm].owner = NULL_TASK;
return OS_SUCCESS;
}
/******************************************************************************
Function : FSM_IDX_MAP * fsmCreateIdxMap ()
Params : hFsm - the fsm.
: pfsmMap - the fsm map provide by application.
: counter - the fsm map's entry/element numbers.
:
Return : the sorted fsm index map.
Description : This function is used build a sorted table to accelerate finding
: finding oldstate-event procedure.
******************************************************************************/
FSM_IDX_MAP * fsmCreateIdxMap (HFSM hFsm, FSM_MAP * pfsmMap, U16 counter)
{
U16 i, j;
U32 size;
FSM_IDX_MAP * pIdxMap;
FSM_IDX_MAP tmpElement;
/* param checking. */
if (hFsm >= MAX_FSM_NUM)
{
OS_error("fsmCreateIdxMap(): the fsm instance [%d] is invalid!!!\n", hFsm);
return NULL;
}
if (pfsmMap == NULL)
{
OS_error ("fsmCreateIdxMap(): no fsm map!!!\n");
return NULL;
}
if (counter == 0)
{
OS_error ("fsmCreateIdxMap(): fsm map entery counter is zero!!!\n");
return NULL;
}
if (g_fsmCB[hFsm].state == OS_FSM_FREE)
{
OS_error("fsmCreateIdxMap(): the fsm instance [%d] is free!!!\n", hFsm);
return NULL;
}
size = counter * sizeof(FSM_IDX_MAP);
pIdxMap = (FSM_IDX_MAP *)memAlloc(size, g_fsmCB[hFsm].owner, g_fsmCB[hFsm].name);
if (pIdxMap == NULL)
{
OS_error("fsmCreateIdxMap(): fail to alloc memory for fsm index table, hfsm = [%d:%s]!!!\n",
hFsm, g_fsmCB[hFsm].name);
return NULL; /* memory not enough. */
}
g_fsmCB[hFsm].pIndexMap = pIdxMap;
memset(pIdxMap, 0, size);
/* create the index map by app fsm map. */
for (i = 0; i < counter; i++)
{
pIdxMap[i].index = ((U32)pfsmMap[i].oldState<<16) + pfsmMap[i].event;
pIdxMap[i].action = pfsmMap[i].action;
}
/* sort the index map. */
for (i = counter; i > 0; i--)
{
for (j = 0; j < i-1; j++)
{
if (pIdxMap[j].index > pIdxMap[j+1].index)
{
/* swap element. */
tmpElement.index = pIdxMap[j+1].index;
tmpElement.action = pIdxMap[j+1].action;
pIdxMap[j+1].index = pIdxMap[j].index;
pIdxMap[j+1].action = pIdxMap[j].action;
pIdxMap[j].index = tmpElement.index;
pIdxMap[j].action = tmpElement.action;
}
}
}
return pIdxMap;
}
/******************************************************************************
Function : FSM_ACTION fsmGetAction(HFSM hFsm, U16 oldState, U16 event)
Params : hFsm - the fsm
: oldState - the old state
: event - the event arrived for this FSM.
:
Return : the action relative to this FSM's state-event, or NULL if not
: found or error.
Description :
:
******************************************************************************/
FSM_ACTION fsmGetAction(HFSM hFsm, U16 oldState, U16 event)
{
U32 index;
U16 next;
U16 head, tail;
FSM_ACTION action;
/* params checking. */
if (hFsm >= MAX_FSM_NUM)
{
OS_error("fsmGetAction(): the fsm instance [%d] is invalid!!!\n", hFsm);
return NULL;
}
if (g_fsmCB[hFsm].state == OS_FSM_FREE)
{
OS_error("fsmGetAction(): the fsm instance [%d] is free!!!\n", hFsm);
return NULL;
}
index = ((U32)oldState<<16) + event;
if ((index < g_fsmCB[hFsm].pIndexMap[0].index)
||(index > g_fsmCB[hFsm].pIndexMap[g_fsmCB[hFsm].nIdxCount-1].index))
{
OS_error("fsmGetAction(): unknown fsm entry, fsm [%d:%s], oldstate [%d], event [%d]!!!\n",
hFsm, g_fsmCB[hFsm].name, oldState, event);
return NULL;
}
/* the next statements are a devide search algrithm. */
head = 0;
tail = g_fsmCB[hFsm].nIdxCount-1;
action = NULL;
while (head <= tail)
{
next = (head + tail)/2;
if (index == g_fsmCB[hFsm].pIndexMap[next].index)
{
action = g_fsmCB[hFsm].pIndexMap[next].action;
break;
}
else if (index < g_fsmCB[hFsm].pIndexMap[next].index)
{
tail = next - 1;
}
else if (index > g_fsmCB[hFsm].pIndexMap[next].index)
{
head = next + 1;
}
}
return action;
}
/******************************************************************************
Function : const char * fsmGetName(HFSM hFsm, U32 type, U32 value)
Params : hFsm - the fsm
: type - the name type, state, event or action.
: value - the state, event or action value
:
Return : the name, or "unknown" string.
Description : This function accesses the fsm's CB to find the name string, if
: the name is not registered, return unknown.
******************************************************************************/
const char * fsmGetName(HFSM hFsm, U32 type, U32 value)
{
U32 head, tail, next;
FSM_NAME_TBL * pNameTbl;
const char * pname;
static const char sys_unknown[] = "Unknown";
/* params check. */
if (hFsm >= MAX_FSM_NUM)
{
OS_error("fsmGetName(): the fsm instance [%d] is invalid!!!\n", hFsm);
return &sys_unknown[0];
}
if (g_fsmCB[hFsm].state == OS_FSM_FREE)
{
OS_error("fsmGetName(): the fsm instance [%d] is free!!!\n", hFsm);
return &sys_unknown[0];
}
head = 0;
switch (type)
{
case FSM_STATE_NAME:
tail = g_fsmCB[hFsm].stateTblSize - 1;
pNameTbl = g_fsmCB[hFsm].pStateTbl;
break;
case FSM_EVENT_NAME:
tail = g_fsmCB[hFsm].eventTblSize - 1;
pNameTbl = g_fsmCB[hFsm].pEventTbl;
break;
case FSM_ACTION_NAME:
tail = g_fsmCB[hFsm].actionTblSize - 1;
pNameTbl = g_fsmCB[hFsm].pActionTbl;
break;
default:
tail = 0;
pNameTbl = NULL;
break;
}
pname = &sys_unknown[0];
while (head <= tail)
{
next = (head + tail)/2;
if (value == pNameTbl[next].value)
{
pname = &pNameTbl[next].name[0];
break;
}
else if (value < pNameTbl[next].value)
{
tail = next - 1;
}
else if (value > pNameTbl[next].value)
{
head = next + 1;
}
}
return pname;
}
/******************************************************************************
Function : void fsmDumpDefault ()
Params : hFsm - the fsm.
: hInst - the instance in the fsm.
: oldState - the old state of the instance.
: event - the event for this instance.
Return : none.
Description : This function is the default dump action for any fsm. The app
: might use another dump function instead.
******************************************************************************/
void fsmDumpDefault (HFSM hFsm, HANDLE hInst, U16 oldState, U16 event, void *action)
{
if ((hFsm < MAX_FSM_NUM)&&(g_fsmCB[hFsm].state == OS_FSM_BUSY))
{
OS_printf("[FSM %d(%s), Inst %d]: [%d:%s] + [%d:%s] = Action[0x%08x:%s];\n",
hFsm, &g_fsmCB[hFsm].name[0], hInst,
oldState, fsmGetName(hFsm, FSM_STATE_NAME, (U32)oldState),
event, fsmGetName(hFsm, FSM_EVENT_NAME, (U32)event),
action, fsmGetName(hFsm, FSM_ACTION_NAME, (U32)action));
}
}
/******************************************************************************
Function : void fsmShowAll()
Params : hfsm - the fsm, or all fsm.
:
:
:
Return : N/A
Description : show fsm as a list table.
:
******************************************************************************/
void fsmShowAll()
{
HFSM hfsm;
if (hfsm == NULL_FSM)
{
OS_printf ("\nHFSM TotalEntries Owner Name\n");
OS_printf ("===== ============= ======== ==========================\n");
for (hfsm = 0; hfsm < MAX_FSM_NUM; hfsm++)
{
if (g_fsmCB[hfsm].state != OS_FSM_FREE)
{
OS_printf("%-5d %-8d %-8d %s\n",
hfsm,
g_fsmCB[hfsm].nIdxCount,
g_fsmCB[hfsm].owner,
g_fsmCB[hfsm].name);
}
}
OS_printf ("==========================================================\n\n");
}
}
/******************************************************************************
Function : void fsmShowSingle(HFSM hfsm)
Params : hfsm - the fsm.
:
:
:
Return : N/A
Description : display a fsm's detail information.
:
******************************************************************************/
void fsmShowSingle(HFSM hfsm)
{
U32 i;
if (g_fsmCB[hfsm].state != OS_FSM_FREE)
{
OS_printf ("FSM handle : [%d]\n", hfsm);
OS_printf ("FSM name : [%s]\n", g_fsmCB[hfsm].name);
OS_printf ("FSM owner : [%d]\n", g_fsmCB[hfsm].owner);
OS_printf ("FSM entry count : total [%d]\n", g_fsmCB[hfsm].nIdxCount);
OS_printf ("OldState Event Action\n");
OS_printf ("======== ======== ==========\n");
for (i = 0; i < g_fsmCB[hfsm].nIdxCount; i++)
{
OS_printf ("%-8d %-8d 0x%08x\n",
(g_fsmCB[hfsm].pIndexMap[i].index&0xFFFF0000)>>16,
g_fsmCB[hfsm].pIndexMap[i].index&0x0000FFFF,
g_fsmCB[hfsm].pIndexMap[i].action);
}
}
else
{
OS_printf ("Fsm [%d] is free...\n", hfsm);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -