概念
通信有两种方式,一种是最简单的同步通信方式,也就是说发送数据后,系统一直在等待数据的到来,这样通信非常好理解,但是由于CPU一直等待数据,导致效率很低,当然对于常规单片机来说,是没有问题的;但是在有界面体系的单片机上,是肯定不行的,因为循环等待数据肯定会导致界面无法响应;
另外一种通信方式就是异步的,一般带有界面的系统都会启用异步方案,所谓异步方案,就是指发送数据后程序继续执行,当收到合适的数据后,自动启动预先设置好的处理代码来完成数据处理;这种方式效率高,但是对于C语言来说实现不好实现(JS、lua、python等比较容易实现);而对于嵌入式系统来说,一般通用的做法是利用线程把异步代码改成同步的代码,但是需要考虑线程的并发性,对于只熟悉单片机C代码用户的开发者都不是优选;
为了更好的利用C语言完成异步加载,我们通过研究,提出了“状态机队列”这个体系,通过状态机队列将异步的通信变成了好理解的伪同步代码
que_do(通道号,步骤号,超时时间){
//在此书写通信发送代码
}then{
//在此书写接收数据处理代码
//要区分通信结果正常和异常并分别处理
}else{
//在此书写超时处理代码
}
具体思路如下:
- 1、将通信拆分成n个步骤,每个步骤精确到一个发送语句,和可能接受到数据的格式;
- 2、在app.que_step()方法中书写所有步骤的处理代码
- 3、需要启动通信的时候,执行:
if (que_create(1)) {que_go(1,10);}
这将启动1号串口通道(对应PCB接口串口2)的第10步通信
- 4、通过app.onwifi()事件获取执行结果
需要注意的事项
- 因为通信不知道何时来,因此处理代码必须卸载appbase这个全局控件类中,每个页面都有这个控件,因此不管到哪个页面,数据传来时都可以正常处理
- que执行实际上也是启动了一个独立的执行体系,因此在onwifi事件中不能再次启动另外一个que队列,任何一个que队列在执行过程中,都不能启动另外一个新的que队列;如果非要启动,我们一般采取设置变量,然后使用页面上控件的定时器检测设置的变量,如果符合要求,就在定时器中启动que队列;
具体
请参见队列各种功能调用的说明