1.FSM 是什么?
一种用来进行对象行为建模的工具,用于描述对象在生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。
2.FSM 组成:状态、事件、动作
3.FSM类型:
3.1Moore: 输出:当前状态有关
输入事件无关
3.2Mealy: 输出:当前状态有关
输入事件有关
4.FSM应用:TCP协议状态机
5.示例-穷举法
6.示例-查表法
7.示例-无线通信协议状态机
8.示例-IPSec 加密状态机
语法
1.enmu
1.1限定作用域: 关键字:class struct
//1.定义
enum class color
{
RED,
GREEN,
BLUE
};
1.2不限定作用域
enum color
{
RED,
GREEN,
BLUE
};
解决重名的问题。
//1.定义两种枚举
enum class color_inner
{
RED,
GREEN,
BLUE
};
enum color_out
{
RED,
GREEN,
BLUE
};
//2.声明并赋值
color_inner colorinner = RED; //错误
color_inner colorinner = color_inner::RED; //正确
color_out colorout = RED; //正确
color_out colorout = color_out::RED; //正确
2.STRUCT
2.1结构体
struct 结构体名 变量名
struct 结构体名 变量名 = { 成员1值 , 成员2值…}
定义结构体时创建变量
struct student
{
string name;
int age;
int score;
}stu3;
int main(){
//结构体变量创建方式1: struct 结构体名 变量名
struct student stu1;
stu1.name = "七喜";
stu1.age = 20;
stu1.score = 95;
//结构体变量创建方式2: struct 结构体名 变量名 = { 成员1值 , 成员2值…}
struct student stu2 = {"可乐",19,100};
//结构体变量创建方式3:
stu3.name = "雪碧";
stu3.age = 20;
stu3.score = 90;
return 0;
}
2.2结构体数组
struct 结构体名 数组名[元素个数] = { { } , { } ,…, { } }
struct student
{
string name;
int age;
int score;
};
int main(){
//结构体数组
struct student stus[3] =
{
{"康师傅",20,95},
{"百事",19,100},
{"农夫山泉",20,90}
;
}
2.3
//C:1.struct- 无结构名字
// 变量在结尾声明 直接用
struct
{
string name;
int age;
int score;
} s1;
//2.struct+结构名字
// 变量新声明
struct STUDENT
{
member-list
};
STUDENT st1,st2[10],*st3;
//3. struct 前+ typedef创建新类型声明 结构名字在最后
// 变量新声明
typedef struct
{
string name;
int age;
int score;
} STUDENT;
5.示例-穷举法示例
//状态定义
typedef enum{
STATE1=0,
STATE2,
STATE3,
STATE4,
STATE5,
STATE6,
STATE7,
}STATE;
void CFsmDemoDlg::OnBnClickedexhaustion()
{
//current_state:状态机的当前状态
// 初始状态为STATE1
int num = 0;
STATE current_state = STATE1;
printf("请输入密码,密码正确开锁,\n");
while (1)
{
scanf("%d", &num);
printf("num=%d \n", num);
switch (current_state)
{
case STATE1:
if (num == 1)
current_state = STATE2; // 用户输入对了一步,STATE走一步
else
current_state = STATE1;
break;
case STATE2:
if (num == 2)
current_state = STATE3; // 用户输入对了一步,STATE走一步
else
current_state = STATE1;
break;
case STATE3:
if (num == 3)
current_state = STATE4; // 用户输入对了一步,STATE走一步
else
current_state = STATE1;
break;
case STATE4:
if (num == 4)
current_state = STATE5; // 用户输入对了一步,STATE走一步
else
current_state = STATE1;
break;
case STATE5:
if (num == 5)
current_state = STATE6; // 用户输入对了一步,STATE走一步
else
current_state = STATE1;
break;
case STATE6:
if (num == 6)
current_state = STATE7; // 用户输入对了一步,STATE走一步
else
current_state = STATE1;
break;
default:
current_state = STATE1;
}
if (current_state == STATE7)
{
printf("锁开了 \n");
break;
}
}
}
6.示例-查表法示例
6.1状态、事件、动作声明
//1.状态
typedef enum {
STATE_1=0,
STATE_2,
STATE_3,
STATE_4,
STATE_5,
STATE_6,
STATE_7
}FSM_STATES;
//2.事件
typedef enum {
EVENT_1 = 0,
EVENT_2,
EVENT_3,
EVENT_4,
EVENT_5,
EVENT_6
}FSM_EVENTS;
//3.动作
void action_func(int state)
{
printf("current state %d\n",state);
}
#define STATE_NUM 7
#define EVENT_NUM 6
struct MY_FSM
{
void(*action)(int);
int next_state;
};
//查的就是这张表
MY_FSM my_fsm[STATE_NUM][EVENT_NUM]=
{
{//STATE_1
{action_func, STATE_2},//event_1
},
{//STATE_2
{action_func, STATE_1},//event_1
{action_func, STATE_3},//event_2
},
{//STATE_3
{action_func, STATE_1},//event_1
{action_func, STATE_1},//event_2
{action_func, STATE_4},//event_3
},
{//STATE_4
{action_func, STATE_1},//event_1
{action_func, STATE_1},//event_2
{action_func, STATE_1},//event_3
{action_func, STATE_5},//event_4
},
{//STATE_5
{action_func, STATE_1},//event_1
{action_func, STATE_1},//event_2
{action_func, STATE_1},//event_3
{action_func, STATE_1},//event_4
{action_func, STATE_6},//event_5
},
{//STATE_6
{action_func, STATE_1},//event_1
{action_func, STATE_1},//event_2
{action_func, STATE_1},//event_3
{action_func, STATE_1},//event_4
{action_func, STATE_1},//event_5
{action_func, STATE_7},//event_6
},
};
6.2 运行
int main()
{
int state = STATE_1; //1.初始状态
int event;
while (1) //2.循环处理
{
scanf("%d", &event);
printf("event =%d \n", event);
event--;
if (state == STATE_4)
{
printf("锁开了,\n");
}
(*(my_fsm[state][event].action))(state); //3.修改此处的数据
state = my_fsm[state][event].next_state;
}
}
7.示例-无线通信协议状态机
很复杂的一张图,我也没看懂。
7.1数据
//1.状态转换数据库
typedef struct _state_trans_data
{
State cur_state; //当前状态
Event event; //事件ID
State next_state; //下一个状态
action act_func; //收到事件后的动作
}state_trans_data_t;
//2.
tyedef struct _state_machine
{
State real_state; //实际状态
int trans_num; //状态转换数
state_trans_data_t * st_data; //指向状态转换数据库
}state_machine_t;
//3.
static state_trans_data_t st_db[] =
{
{S1,E3,S2,f12},
{S1,E4,S2,NULL},
{S2,E1,S3,f23},
{S2,E4,S2,f22},
{S3,E2,S1,f31},
{S3,E3,S2,f32},
{S3,E5,S3,f33}
};
//4.测试:事件驱动
static Event input_event[15] =
{
E1,E2,E3,E4,E5,
E1,E2,E3,E4,E5,
E1,E2,E3,E4,E5
};
7.2 运行
void main(state_machine_t *pSM,Event evt)
{
state_trans_data_t* st_db = NULL;
st_db = find_st_data(psm, evt);
if (!st_db)
{
printf("current state =%d ignore count: %d\n",psm->real_state,evt);
return;
}
pSM->real_state = st_db->next_state;
action act_func = st_db->act_func;
if (!act_func)
{
printf("next state %d no action \n", pSM->real_state);
}
act_func(evt);
state_machine_t sm;
sm.eal_state = S1;
sm.trans_num = ARRAY_SIZE(st_db);
sm.st_data = st_db;
return;
}
8.示例-IPSec 加密状态机
8.1数据
struct XMIT_STATE {
enum ipsec_xmit_value(*action)(struct ipsec_xmit_state* ixs);
int next_state;
};
XMIT_STATE xmit_state_table[] = {
[IPSEC_XSM_INIT1] = {ipsec_xmit_init1, IPSEC_XSM_INIT2 },
[IPSEC_XSM_INIT2] = {ipsec_xmit_init2, IPSEC_ENCAP_INIT },
[IPSEC_XSM_ENCAP_INIT] = {ipsec_encap_init, IPSEC_ENCAP_SELECT },
[IPSEC_XSM_ENCAP_SELECT] = {ipsec_encap_select, IPSEC_XSM_DONE },
[IPSEC_XSM_ESP] = {ipsec_xmit_esp, IPSEC_ESP_AH },
[IPSEC_XSM_ESP_AH] = {ipsec_xmit_esp_ah, IPSEC_XSM_CONT },
[IPSEC_XSM_AH] = {ipsec_xmit_ah, IPSEC_XSM_CONT },
[IPSEC_XSM_IPIP] = {ipsec_xmit_ipip, IPSEC_XSM_CONT },
[IPSEC_XSM_IPCOMP] = {ipsec_xmit_ipcomp, IPSEC_XSM_CONT },
[IPSEC_XSM_CONT] = {ipsec_xmit_cont, IPSEC_XSM_DONE },
[IPSEC_XSM_DONE] = {NULL, IPSEC_XSM_DONE }
};
8.2运行
void ipxec_xsm(struct ipsec_xmit_state* lxs)
{
enum ipsec_xmit_value stat = IPSEC_XMIT_DNCAPFAIL;
unsigned more_allowed;
if (lxs == NULL)
return;
more_allowed = 1000;
while (lxs->state != IPSEC_XSM_DONE && --more_allowed)
{
lxs->next_state = xmit_state_table[lxs->state].next_state; //数据
stat = xmit_state_table(lxs->state).action(ixs);
if (stat == IPSEC_XMIT_OK)
{
lxs->state = lxs->next_state;
}
else if (state ==IPSEC_XMIT_DENDING)
{
return;
}
else
{
lxs->state = IPSEC_XSC_DONE;
}
}
lxs->xsm_complete(lxs, stat);
}