Protothread 系统 分析
最近看了下Protothread ,就是一些宏定。至于程序的实时性基本上都要人工去算运行时间,和细分一个函数的执行步骤。好像没有宣传的那么强大。
1. IC-SWICHT.H 文件
这个是核心文件,里面只有5句代码,详细如下。
typedef unsigned short lc_t;
#define LC_INIT(s) s = 0;
#define LC_RESUME(s) switch(s) { case 0:
#define LC_SET(s) s = __LINE__; case __LINE__:
#define LC_END(s) }
其实这就是一个swithc 结构的宏定义。可以分解为如下。如下面的代码,展开宏后见下表。
void task(void)
{
LC_RESUME(s)
printf("hell 1\n");
LC_SET(s);
printf("hell 2\n");
LC_SET(s);
printf("hell 3\n");
LC_END(s);
}
展开宏后如下:
void task(void)
{
//LC_RESUME(s)
switch(s)
{
case 0:
printf( "hell 1\n" );
//LC_SET(s);
s = __LINE__;
case __LINE__ :
printf( "hell 2\n" );
//LC_SET(s);
s = __LINE__;
case __LINE__ :
printf( "hell 3\n" );
//LC_END(s);
}
}
而实时性就是在 s = __LINE__; 后面加如判断语句,判断时间或者状态,不符合就跳出,一个静态变量s记录了当前的行号,下次执行到此
函数时再从当前行号开始执行,就是swithc(s)。3句 printf( "hell 3\n" ); 就是将这个函数分解成为了3个过程执行。
pt.h 为调用文件。其中文件如下。
#include "lc.h"
struct pt {
lc_t lc;
};
#define PT_WAITING 0
#define PT_YIELDED 1
#define PT_EXITED2
#define PT_ENDED 3
/*调用LC_INIT(LC)函数,就是将sWITHC(a)的A 初始化为0。重新运行。*/
#define PT_INIT(pt)
/*函数声明,所有函数必需用这个声明*/
#define PT_THREAD(name_args)
/*函数开始运行*/
#define PT_BEGIN(pt)
/*函数结束*/
#define PT_END(pt)
/*一直等待 CONDITION 条件成立*/ //执行下面函数,指这句话之后的一句,多句要加括号
#define PT_WAIT_UNTIL(pt, condition)
/*和上面那个反过来,只要条件成立就继续等待,不成立执行下面函数*/
#define PT_WAIT_WHILE(pt, cond)PT_WAIT_UNTIL((pt), !(cond))
*//*让线性停止,等待别的线性执行完继续往下执行*/
#define PT_WAIT_THREAD(pt, thread)
*//*分离出一个子线程并等待子线程执行结束*/
#define PT_SPAWN(pt, child, thread)
/*初始化本线程,并退出,下次运行时就从头运行了*/
#define PT_RESTART(pt) \
/*可以在中间退出线程,下次从头运行*/
#define PT_EXIT(pt) \
*//*这个是线程调度宏,在线程执行结束是会返回非真值,判断是否继续调用*/
#define PT_SCHEDULE(f) ((f) < PT_EXITED)
*//*这个宏可以让线程退出,让其他线程执行,第二次再进入时继续执行,相当于
/* 线程暂停一次*/
#define PT_YIELD(pt) \
//*这个宏结合了PT-WAIT-UNTIL 和 PT-YIELD的功能,它先执行PT-YIELD的功能,不管条件有没有
/* 成立,就要先退出一次,让其他线程进入执行,然后执行PT-WHILE-UNTIL的功能,一直阻塞
等待条件成立*/
#define PT_YIELD_UNTIL(pt, cond)
以上为Protothread 系统的全部内容
均为个人意见,如有不对请更正。
老早有几个网友研究,后来觉得可能没那么强大,就停了。 而且平时使用开来的局部变量还要转用static 变量。不然跳出一下回来就不一样了。无形中增加了RAM的使用量。 IMTP 发表于 2013-9-24 14:39 static/image/common/back.gif
而且平时使用开来的局部变量还要转用static 变量。不然跳出一下回来就不一样了。无形中增加了RAM的使用量。 ...
哎?人家特指是任务函数是要使用static修饰,你的任务函数里有多少这种变量啊?没多少吧;它又不是让你底层函数也要static来修饰,那样就疯了; 切换任务其实就是保存当前一个switch项值然后return,下次直接跳到这里执行。由于这样的方式是不保存寄存器的,所以下次再来执行的时候与上次切换时的环境是不一样的。
所以说有得必有失,这种方式适合对RAM需求极为苛刻的情况,要不然不太容易做好。 用static很正常呀,如果自己用super loop结构,也会遇到很多下次进入时候的数据问题,这个时候就必须用到static变量了。
这个简化了superloop的书写,但是编译器那里估计会增加部分代码开销,还算好用吧.............. mark一下,有空研究研究 分析的很好。
页:
[1]