博客
关于我
基于状态机State Machine的程序设计技巧②状态转移图和简单通信协议
阅读量:336 次
发布时间:2019-03-04

本文共 1218 字,大约阅读时间需要 4 分钟。

        上一节定义了状态机的概念,状态机由两个重要的部分组成,一个是状态转移关系,另一个就是驱动源。状态转移关系可以由状态转移图定义,下面会说到。驱动源则是驱动状态机运行的动力源。我总结了两种最常用的状态机驱动源第一个是时间驱动,第二个是事件驱动。时间驱动源就是第一节中描述的,状态机使用100Hz的定时器中断作为状态机的驱动源,每发生一次定时器中断执行一次状态转移。事件驱动源就是使用事件来驱动状态机,说白了就是每次事件发生的时候执行一次状态转移而不是使用一个固定的时间中断来执行状态转移。下面就介绍一种以事件为驱动源的状态机实例。

        基于状态机进行程序设计的第一步是要设计状态机的状态设计,然后基于设计的状态画状态转移图,所谓状态转移图就是用于描述说明状态机中各个状态之间的转移条件以及操作。下面使用状态机设计一个之前常用的通信协议,之前大量使用标志位的技巧,虽然也能实现给定的通信协议,但是稳定性、可移植性和可维护性较差,这里使用状态机的方式重写这个通信协议。

        首先介绍一下这个通信协议,T作为帧起始字符,Q作为帧结束字符,\作为转义字符,这个是参考网络协议栈中的好像是PPP协议做的。下面是协议的状态转移图:

这个协议一共只有三个状态,默认处于状态0,且数据就绪标志位为假表示数据未就绪,当收到帧起始字符T的时候进入状态1,在状态1中收到非T、Q、\的字节则将该字节输入到输入缓冲区并自增接收计数。在状态1下如果收到帧结束字符时进入状态0并且置位数据就绪标志位为真表示数据就绪。在状态1下如果收到转义字符\,则进入到状态2。具体的状态转移方式在状态转移图上有详细说明。

        下面是使用C语言实现的协议程序:

u8 WifiBuff[20];u8 WifiBuffLen;bool IsDataReady = false;void InputData(u8 data){	static int state = 0;	static int count = 0;	if(state == 0)	{		if(IsDataReady == false)		{			if(data == 'T')			{				state = 1;				count = 0;			}		}	}	else if(state == 1)	{		if(data == '\\')		{			state = 2;		}		else if(data == 'Q')		{			state = 0;			IsDataReady = true;			WifiBuffLen = count;			printf("data ready:%d\r\n",count);		}		else		{			WifiBuff[count++] = data;		}	}	else if(state == 2)	{		state = 1;		WifiBuff[count++] = data;	}}

你可能感兴趣的文章
Nessus漏洞扫描教程之配置Nessus
查看>>
Nest.js 6.0.0 正式版发布,基于 TypeScript 的 Node.js 框架
查看>>
nestJS学习
查看>>
NetApp凭借领先的混合云数据与服务把握数字化转型机遇
查看>>
NetBeans IDE8.0需要JDK1.7及以上版本
查看>>
netcat的端口转发功能的实现
查看>>
netfilter应用场景
查看>>
netlink2.6.32内核实现源码
查看>>
Netpas:不一样的SD-WAN+ 保障网络通讯品质
查看>>
NetScaler的常用配置
查看>>
netsh advfirewall
查看>>
NETSH WINSOCK RESET这条命令的含义和作用?
查看>>
Netty WebSocket客户端
查看>>
netty 主要组件+黏包半包+rpc框架+源码透析
查看>>
Netty 异步任务调度与异步线程池
查看>>
Netty中集成Protobuf实现Java对象数据传递
查看>>
Netty事件注册机制深入解析
查看>>
Netty原理分析及实战(四)-客户端与服务端双向通信
查看>>
Netty和Tomcat的区别已经性能对比
查看>>
Netty客户端断线重连实现及问题思考
查看>>