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:状态机的当前状态 // 初始状态为STATE1int 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走一步elsecurrent_state = STATE1;break;case STATE2:if (num == 2)current_state = STATE3; // 用户输入对了一步,STATE走一步elsecurrent_state = STATE1;break;case STATE3:if (num == 3)current_state = STATE4; // 用户输入对了一步,STATE走一步elsecurrent_state = STATE1;break;case STATE4:if (num == 4)current_state = STATE5; // 用户输入对了一步,STATE走一步elsecurrent_state = STATE1;break;case STATE5:if (num == 5)current_state = STATE6; // 用户输入对了一步,STATE走一步elsecurrent_state = STATE1;break;case STATE6:if (num == 6)current_state = STATE7; // 用户输入对了一步,STATE走一步elsecurrent_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; //事件IDState 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);}