Arduino问答实验室

protothread, a powerfull library protothread 一个厉害的 arduino 多线程链接库0条评论

作者:学长   发布于:2013年9月11日 15:32:17 周三    分类: Arduino    5974 人浏览

protothread, a powerfull library protothread 

一个厉害的 arduino 多线程链接库


(学长1: 堆栈的原文是 stack ,又称为栈。意指私有变数)
(学长2: 阻塞的原文是 block 或 blocking 。字面上是中断程序,到此处执行。但有时指的是一个程序的片段。)
Some weeks ago, while browsing around the net i found Adam Dunkels website.
Back in 2005 he wrote protothread as an easy way to implement blocking conditions.
几周以前,我在网络上发现了Adam Dunkels的网站。
2005年时他写了protothread ,以简单的方式实现 阻塞条件

"Protothreads are a extremely lightweight, stackless threads that provides a blocking context on top of an event-driven system, without the overhead of per-thread stacks. The purpose of protothreads is to implement sequential flow of control without using complex state machines or full multi-threading. Protothreads provides conditional blocking inside a C function." [http://www.sics.se/~adam/pt/about.html]
Protothread 是一个很轻量的、无栈式多线程,提供事件驱动系统之上的阻塞式 context , 
不需要管理每个线程的 stack 。
protothread 的方式,是实现一个串行化的流程来控制,而不需要复杂的 状态机制 或 完整的多线程。
Protothreads 提供一个在 C 函数内部的条件式组塞。

Basically protothread is the implementation of stack less coroutines. Of course no real coroutines because the basic µc has only one core and no scheduler. What it does, is that it gives you the possibility to manage your code in a very easy way using 'thread a like functionality'. It consists of a few include files defining macro's that are used to implement threads as switch/case constructs.
The trick was originally invented by Tom Duff and dubbed Duff's device.
基本上 protothread 是无堆栈式协同工作的实现。当然不是真正的协同,
因为基本上 µc (一种实时操作系统) 只有一个核心而且没有排程功能。
它所做的,只是让你可以用一种简单的方式,使用'类多线程'管理程序代码。
由几个定义 macro 的程序文件所组成,macro 里面是使用 switch/case 实现的多线程结构。

When you have a complex program consisting of many functions, maybe some options for user input and periodic calculations or sensor input to check for, you need to organize your code in a way that all functions are called 'often enough'. If not you risk to loose data or, in the case of user input, your user interface will lag. Often you'll have to check if a timer has run out and in case it has not, wait with further action until it has.
当你有一个由很多函数组成的复杂程序,也许包括用户输入的选项和周期式的运算,或是检查感知器讯号输入,
你需要用一种方式管理你的程序代码,让所有的函数尽可能的执行多次。
如果不是的话,你就有可能遗失数据或是用户的输入,或是使用界面延迟。
一般来说,你必须在定时器到达时间时检查,如果未到时间就进行别的工作来等待时间到达。

This is where protothreads come in very handy. They let you use the functions
void PT_WAIT_UNTIL(struct pt *pt, condition);
Block and wait until condition is true.
void PT_WAIT_WHILE(struct pt *pt, condition);
Block and wait while condition is true.


以下是 protothreads 提供的能够简单使用的函数
void PT_WAIT_UNTIL(struct pt *pt, condition);
阻塞并且等待, 直到条件式 condition 成立 (True)
void PT_WAIT_WHILE(struct pt *pt, condition);
当条件式成立(True) 时,阻塞并等待。

among some others. Look here for a condensed version of the protothreads API. But there are some constraints you need to consider:
还有一些其他的。查询这个网站,就有 protothreads API 的介绍版本。
但是有些限制,必须思考一下:

protothreads do not save the stack context across a blocking call, local variables are not preserved when the protothread blocks. This means that local variables should be used with utmost care - if in doubt, do not use local variables inside a protothread!
protothread 没有堆栈(私有的变量)来给阻塞呼叫使用, 所以在 prothread 程序片段内 局部变量(local variables) 是无法保存的。
这表示 局部变量(local variables) 应该“很小心“的使用。
在不确定的情况下,尽量避免在 protothread 内使用 局部变量(local variables)  。

So how do you use it?
Here's a protothread function skeleton:
所以,怎么使用呢?
以下是一个 prothread 功能的骨架



#include <pt.h>

static int protothread1(struct pt *pt) { 
    PT_BEGIN(pt); 
    while(1) {           
        PT_WAIT_UNTIL(pt, function_returns_true() ); 
        do_something(); 
    } 
    PT_END(pt);
}


Here, the magic is happening: every time this function is called, the boolean condition of PT_WAIT_UNTIL() is evaluated again. So if this condition is a function that can return either true or false, the function_returns_true() is called and if the return value is not true, the protothread1() function stops here, until the next call. This means do_something() doesnt run this time.
Notice that protothread functions have to be declared static int.
神奇的事发生了:每次这个函数被呼叫之后, PT_WAIT_UNTIL() 里的 boolean 条件式,就被执行一次。
所以说,如果这个条件式是一个函数,就可以在执行完后返回 true  或 false 。
上面例子里的 function_returns_true() 被执行之后,如果返回值不是 true , 
protothread1() 函数就会在这里停止,一直到下一次被呼叫。
这表示 do_something() 这个函数,这次不会被执行。
注意 protothread 函数必须被定义成 Static int

And this is the way you have to initialize the protothreads and call them in your main loop
而且, 你必须按照下面举例的方式来初始化 protothreads , 以及在主回圈里面呼叫。


// every protothread needs an own struct pt variable
// 每個 protothread 都需要有自已的 pt 結構變數
static struct pt pt1, pt2;
int main(void) {     
 /* Initialize the protothread state variables with PT_INIT(). */     
 /*使用 PT_INIT() 來初始化 protothread 狀態變數 */
 PT_INIT(&pt1);     
 PT_INIT(&pt2);     
      
 /* Then we schedule the two protothreads by repeatedly calling their 
  * protothread functions and passing a pointer to the protothread     
  * state variables as arguments.     
  * 然後我們 排入這兩個 protothread  ,在重復執行 prtothread 函數的地方
  * 然後用 參數 傳遞 protothread 狀態的指針*/
  while(1) {        
   protothread1(&pt1);        
   protothread2(&pt2);     
  }
}


"Many of us use the switch/case construct to explicitly implement concurrent state machines in our code. The [protothread] macros merely provide a level of abstraction above that so that the code appears more linear and the overall logic more visible."
我们许多人在程序里面使用 switch/case 结构来实现状态机制.
[protothread] 宏 单纯的 提供 一个在抽象层之上的实现,
所以程序代码显然更直接,程序逻辑更容易阅读

So if this sounds interesting to you, why not download the protothread library and give it a shot?
如果以上这些引起你的兴趣, 为什么不下载 protothread 链接库,而且试它一试?

UPDATE: i also wrote an example as a tutorial, see here

更新:我也写了一个指导范例,在这里


因为域名到期的原因,开始整理、重贴一些有价值的旧文章。

原文:http://harteware.blogspot.tw/2010/11/protothread-powerfull-library.html

本文原作者的另一篇指导范例翻译

Me.png

Arduino问答实验室- 本站版权
1、本主题由文章作者发表,文章作者与Arduino问答实验室享有文章相关版权
2、转载或引用本文时请同时征得文章作者和Arduino问答实验室的同意
3、本站部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
4、如本帖侵犯到任何版权问题,请立即告知本站即时予与以处理
5、原文链接:www.985z.com/?post=28
二维码
继续查看有关 arduino multithread pt protothread embedded 的文章

我来说说

*

*