IMTP 发表于 2013-9-24 13:40:54

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 系统的全部内容
均为个人意见,如有不对请更正。





tiger5 发表于 2013-9-24 14:31:04

老早有几个网友研究,后来觉得可能没那么强大,就停了。

IMTP 发表于 2013-9-24 14:39:28

而且平时使用开来的局部变量还要转用static 变量。不然跳出一下回来就不一样了。无形中增加了RAM的使用量。

kinsno 发表于 2013-9-29 21:09:53

IMTP 发表于 2013-9-24 14:39 static/image/common/back.gif
而且平时使用开来的局部变量还要转用static 变量。不然跳出一下回来就不一样了。无形中增加了RAM的使用量。 ...

哎?人家特指是任务函数是要使用static修饰,你的任务函数里有多少这种变量啊?没多少吧;它又不是让你底层函数也要static来修饰,那样就疯了;

dongfo 发表于 2014-4-24 11:55:00

切换任务其实就是保存当前一个switch项值然后return,下次直接跳到这里执行。由于这样的方式是不保存寄存器的,所以下次再来执行的时候与上次切换时的环境是不一样的。
所以说有得必有失,这种方式适合对RAM需求极为苛刻的情况,要不然不太容易做好。

gwnpeter 发表于 2014-4-24 21:09:35

用static很正常呀,如果自己用super loop结构,也会遇到很多下次进入时候的数据问题,这个时候就必须用到static变量了。
这个简化了superloop的书写,但是编译器那里估计会增加部分代码开销,还算好用吧..............

哼嘿哈嘿哈 发表于 2014-7-19 00:39:13

mark一下,有空研究研究

summarize 发表于 2014-7-19 06:57:35

分析的很好。
页: [1]
查看完整版本: Protothread 系统 分析