利用 ProtoThreads实现Arduino多线程处理(2)
转载请注明:@小五义http://www.cnblogs.com/xiaowuyiQQ群:64770604
感谢小V分享给大家的博文。
我在做产品设计的课题的时候,小五义推荐我使用Protothread这个库来进行编写,研究了之后应用于自己的设计上效果还不错,应小五义的请写了这个Protothread的介绍,谈不上懂,就浅浅谈一谈我的理解,帮助大家应用,如果有错误的,欢迎指教。
Protothread(以下简称PT),是牛逼哄哄的来自瑞典皇家啥啥啥的Adam Dunkels大师编写的用于协程的一个库,你说协程是啥,简单的理解就是类似多任务处理器。当你开始做有关硬件C语言的编程之后,你会发现你的核心芯片不是无敌的,资源是有限的,这个时候合理安排资源就极为重要了,对于8位16位的单片机来说,用真正的多任务处理几乎是无法承受的,这种时候就需要PT的出马了。
举个例子,你有两个触发端,分别是你老妈和你老婆,当你老婆生气的时候,你要跪键盘10秒,你老妈叫你的时候,你就要去给她捶背15秒,问题是你的脑子只有8位或者16位,一个时间点只能做一件事情。现在你老婆生气了,你就跪在键盘上,用最基础的delay函数数数:1秒,2秒,3秒……这时候你老妈叫你给她捶背,可是你听不见,因为你在数数,如果你老妈耐心好还好,等你跪完再叫你给她捶背,如果她老人家耐心差,叫一遍就不叫了,那可就完蛋了,直接跟你老婆开干,当然你唯一收获的就是不用跪了,准备完蛋吧。
PT的有一个能力就是你跪下之后,不用你数数,它帮你数数,然后你膝盖就保持跪的状态,然后双手给你老妈捶背,10秒到后,它跟你讲:“诶,气管炎,10秒到了。”这个时候你想不想起来看你自己了,反正老婆给的任务完成了。
当然这只是一个很狭窄的例子,不要狭隘的理解为PT只是给你计数,timer只是PT的一个方便的应用,这是使PT提醒的原因不是计时多久,而是一个条件,条件是数完十秒,所以说PT很灵活,你可以给把触发端给PT,比如你为了向老婆展示你的诚心,就一直跪着键盘,这时候不是叫PT数数,告诉PT,如果老妈叫你,就提醒你去敲背,这样都是可以的。
原理大致如此,然后上几个常用的宏定义吧:
PT_INIT(pt) 初始化任务变量,只在初始化函数中执行一次就行
PT_BEGIN(pt) 启动任务处理,放在函数开始处
PT_END(pt) 结束任务,放在函数的最后
PT_WAIT_UNTIL(pt, condition) 等待某个条件(条件可以为时钟或其它变量,IO等)成立,否则直接退出本函数,下一次进入本函数就直接跳到这个地方判断
想要真正的理解PT,自然是需要看懂源代码的,我不会那么无聊给你一个一个罗列,我就给你看几个精髓的,
#define PT_BEGIN(pt) switch((pt)->lc) {case 0;
#define PT_WAIT_UNTIL(pt,condition) (pt)->lc = __LINE__; case __LINE__: if(!(condition)) return
啊哈哈哈哈,是不是没看懂!!!我一开始也是这样的!!!如果你看懂了你现在真的可以离开了,我没啥可以告诉你的了。。。
如果你一头雾水,心生怯意,那我来给你打一级强心针吧!
#define PT_END(pt) }
怎么样!是不是不敢相信!就一个“}”,所以那些大神跟你讲你PT_BEGIN之后,一定要一个PT_END,知道为啥了吧!因为你看看PT_BEGIN,里面一开始有个“{”。
其实你懂了PT_WAIT_UNTIL之后,你对PT就算是基本的了解,我们一句一句来,首先pt是啥,pt就是一个struct变量,里面有什么呢?里面就一个lc,lc就是用来记住当前的位置,然后 下次进入函数的时候就直接从当前位置开始的,那又怎么做到从当前位置开始呢!这个时候就是展现Adam牛逼哄哄的时候了,_LINE_闪亮登场,_LINE_的作用就是能取到当前_LINE_所在位置的行数,现在你知道了当前的位置,你怎么到这个位置呢,就用的switch case语句,用static pt记录_LINE_的行数,然后通过switch((pt)->lc)跳到case _LINE_,怎么样,理解了之后是不是感叹Adam机智!
最后就简单的我下面列一个示例吧,是按照arduino的编译器格式写的,就按照上面说的老妈老婆的例子,我个人不敢给老妈老婆分高下,一个管我一生,一个管我下半身,所以就老婆叫跪就跪10秒,不然不跪,老妈叫敲背就敲背15秒,否则浪费。
#include<pt.h>//声明protothread
#include<PT_timer.h>//声明pt.timer
#define ANGEROFWIFE 1//老婆的愤怒
#define MOTHERCALL 2//老母的呼唤
#define KNEE 3//遭殃的膝盖
#define HAND 4//幸福的双手
static struct pt pt1,pt2;
PT_timer servotimer1;
PT_timer servotimer2;//定义两个计时器
void setup()
{
pinMode(ANGEROFWIFE,INPUT);
pinMode(MOTHERCALL,INPUT);
pinMode(KNEE,OUTPUT);
pinMode(HAND,OUTPUT);//定义端口输入输出
PT_INIT(&pt1);
PT_INIT(&pt2);//两个线程初始化,其实就是pt->lc归零
}
static int mission1(struct pt *pt)
{
PT_BEGIN(pt);//线程开始
while()
{
digitalWrite(KNEE,LOW);//老婆不生气我不跪
PT_WAIT_UNTIL(pt,digitalRead(ANGEROFWIFE));//等老婆生气
digitalWrite(KNEE,HIGH);//我擦真生气了,赶紧跪
servotimer1.setTimer();//设定跪10秒,这里单位1为一微妙
PT_WAIT_UNTIL(pt,(servotimer1.Expired()));//当时间溢出,这里是10秒就结束
}
PT_END(pt);//线程结束
}
Static int mission2(struct pt *pt)
{
PT_BEGIN(pt);
While()
{
digitalWrite(HAND,LOW);
PT_WAIT_UNTIL(pt,digitalRead(MOTHERCALL));
digitalWrite(HAND,HIGH);
servotiemr2.setTimer();
PT_WAIT_UNTIL(pt,(servotimer2.Expired()));
}
PT_END(pt);
} void loop()
{
mission1(&pt1);
mission2(&pt2);//循环执行,特步,永不停息
}
上述只是关于PT一个很简单的例子,有一点需要提醒的是,尽量不要在线程里声明变量,如果要用也要用static变量,不然很容易出错也不易察觉,更多的关于protothread详细的源代码和理解可以参照REFERENCE,TV领进门,修行在个人。多多应用,勇于尝试,你就能熟练应用这一神器。
利用 ProtoThreads实现Arduino多线程处理(2)的更多相关文章
- 利用 ProtoThreads实现Arduino多线程处理(1)
转载请注明:@小五义http://www.cnblogs.com/xiaowuyiQQ群:64770604 这几天和群里小V同学讨论一个项目时,偶然发现了 ProtoThreads,简称PT,用其来实 ...
- 利用EEPROM实现arduino的断电存储
转载请注明:@小五义http://www.cnblogs.com/xiaowuyiQQ群:64770604 一.EEPROM简介 EEPROM (Electrically Erasable Progr ...
- 利用web workers实现多线程处理
利用web workers在后台线程中实现对数据库的增删改查操作,并在后台线程中生成页面上某个列表的完整的HTML代码,然后再前台脚本中直接将这段HTML代码输出到页面上! 利用web workers ...
- 用Python利用pyFirmata控制Arduino实现Blink
2018-03-2809:20:44 arduino中有相应的库 1.安装pyFirmata包 pip install pyFirmata 在python2.7或python3.X下都可以执行. py ...
- Netty实战七之EventLoop和线程模型
简单地说,线程模型指定了操作系统.编程语言.框架或者应用程序的上下文中的线程管理的关键方面.Netty的线程模型强大但又易用,并且和Netty的一贯宗旨一样,旨在简化你的应用程序代码,同时最大限度地提 ...
- Day 29 process&thread_1
进程和线程 1 进程(process): 1.定义: 最小的执行单元.进程就是一个程序在一个数据集上的一次动态执行过程. 进程一般由程序.数据集.进程控制块三部分组成: 我们编写的程序用来描述进程要完 ...
- 利用Arduino快速制作Teensy BadUSB
0×00 介绍 本文想以较简单的方式,叙述Arduino版BadUSB的制作过程.我知道在这之前已经有很多前辈都写过相关的文章,但小白可能还有点迷糊,所以这篇文章是快速带大家入门了解,我也是菜B大神不 ...
- Arduino线程库ProtoThreads
参考: Arduino线程库ProtoThreads 一个“蝇量级” C 语言协程库
- 利用Arduino快速制作Teensy BadUSB, 攻击计算机
BadUsb介绍 BadUSB是计算机安全领域的热门话题之一,该漏洞由Karsten Nohl和Jakob Lell共同发现,并在2014年的BlackHat安全大会上公布. 虽然已隔一两年,但还是有 ...
随机推荐
- Node.js+Koa开发微信公众号个人笔记(一)准备工作
本人也是在学习过程中,所以文章只作为学习笔记,如果能帮到你,那就更好啦~当然也难免会有错误,请不吝指出~ 一.准备工作 1.本人学习教程:慕课网Scott老师的<Node.js七天搞定微信公众号 ...
- 2017-07-20 在Maven Central发布中文API的Java库
知乎原链 相关问题: 哪些Java库有中文命名的API? 且记下随想. 之前没有发布过, 看了SO上的推荐:Publish a library to maven repositories 决定在son ...
- OSPF协议总结
总结: 1.ospf协议报文不会泛洪扩散,而是逐级路由器处理后,再从所有ospf启用端口发送出去,也就是说,只能从邻居接收到ospf报文,报文的源ip是邻居的ip地址,目的ip是组播ip. 2.开启o ...
- Tsung CentOS 操作系统下搭建tsung性能测试环境_Part 1
CentOS 操作系统下搭建tsung性能测试环境_Part 1 by:授客 QQ:1033553122 步骤1.下载软件安装包 CentOS-6.0-x86_64-bin-DVD1.iso jdk- ...
- Kotlin入门(17)等式判断的情况
话说等式可是编程语言最基本的表达式之一,不管哪种高级语言,无一例外都采用双等号“==”判断两个变量是否相等:就算是复杂的对象,在Java中也可通过equals函数判断两个实例是否相等.按理说这些能够满 ...
- 【Java入门提高篇】Day34 Java容器类详解(十五)WeakHashMap详解
源码详解系列均基于JDK8进行解析 说明 在Java容器详解系列文章的最后,介绍一个相对特殊的成员:WeakHashMap,从名字可以看出它是一个 Map.它的使用上跟HashMap并没有什么区别,所 ...
- Vue延迟点击
从点击屏幕上的元素到触发元素的 click 事件,移动浏览器会有大约 300 毫秒的等待时间 fastclick清除点击延迟,让程序更灵敏 1.导出fastclick import Vue from ...
- 弱符号__attribute__((weak))
弱符号是什么? 弱符号: 若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak symbol(弱符号),则这些全局符号不会引发重定义错误.链接器会忽略弱符号,去使用普通的全局符号 ...
- Python学习—Pycharm连接mysql服务器
安装pymysql pip3 install pymysql 安装Mysql客户端驱动(基于Pycharm工具) 点击download,下载mysql驱动 等待驱动安装成功后,点击OK即可 创建数据库 ...
- Zabbix3.x 监控磁盘IO与自定义模板
引言 Zabbix自带的模板,帮助我们完成了一些比较常用的监控.但如果想要监控磁盘的IO,zabbix并没有给我们提供这么一个模板,所以我们需要自己来创建一个模板来完成磁盘IO的监控. 操作步骤 1. ...