搜索
bottom↓
回复: 91

推荐protothread多任务,很适合lgt

  [复制链接]

出0入0汤圆

发表于 2012-5-25 22:27:04 | 显示全部楼层
本帖最后由 ljt80158015 于 2012-5-26 09:03 编辑

感觉挺麻烦的!

《时间触发嵌入式设计》  这个我觉得更好!

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2012-5-26 09:55:56 | 显示全部楼层
wear778899 发表于 2012-5-26 09:41
收藏  有时间研究一下  看上去比 《时间触发嵌入式设计》  消耗RAM低很多   不知道实用性怎么样 ...

《时间触发嵌入式设计》  也没什么内存消耗吧!~

出0入0汤圆

发表于 2012-5-27 10:41:43 | 显示全部楼层
http://www.mesnet.com.cn/htm/article_view.asp?id=2581
无法访问,代码在哪下载呢?

出0入0汤圆

发表于 2012-5-27 10:58:36 | 显示全部楼层
protothread学习 .
     ◆ protothread是专为资源有限的系统设计的一种耗费资源特别少并且不使用堆栈的线程模型,相比于嵌入式操作系统,其有如下优点:

      1. 以纯C语言实现,无硬件依靠性; 因此不存在移植的困难。

      2. 极少的资源需求,每个Protothread仅需要2个额外的字节;

      3. 支持阻塞操纵且没有栈的切换。

      ◆它的缺陷在于:

      1. 函数中不具备可重入型,不能使用局部变量;

      2. 按顺序判断各任务条件是否满足,因此无优先级抢占;

      3. 任务中的各条件也是按顺序判断的,因此要求任务中的条件必须是依次出现的。

      ◆ protothread的阻塞机制: 在每个条件判断前,先将当前地址保存到某个变量中,再判断条件是否成立,若条件成立,则往下

          运行;若条件不成立,则返回。

      ◆ protothread基本源码及注释:

         
[c-sharp] view plaincopyprint?
01.#ifndef PC_H  
02.#define PC_H   
03.  
04.typedef unsigned int INT16U;  
05.  
06.struct pt  
07.{  
08.  INT16U lc;   
09.};  
10.
11.
12.#define PT_THREAD_WAITING   0  
13.#define PT_THREAD_EXITED    1   
14.  
15.  
16.//初始化任务变量,只在初始化函数中执行一次就行  
17.#define PT_INIT(pt)     (pt)->lc = 0   
18.  
19.//启动任务处理,放在函数开始处  
20.#define PT_BEGIN(pt)    switch((pt)->lc) { case 0:   
21.  
22.// 等待某个条件成立,若条件不成立则直接退出本函数,下一次进入本函数就直接跳到这个地方判断     
23.// __LINE__ 编译器内置宏,代表当前行号,比如:若当前行号为8,则 s = __LINE__; case __LINE__: 展开为 s = 8; case 8:  
24.#define PT_WAIT_UNTIL(pt,condition)   (pt)->lc = __LINE__;   case __LINE__: /   
25.                                      if(!(condition))  return               
26.  
27.// 结束任务,放在函数的最后  
28.#define PT_END(pt)      }   
29.  
30.  
31.  
32.  
33.  
34.// 等待某个条件不成立        
35.#define PT_WAIT_WHILE(pt,cond)    PT_WAIT_UNTIL((pt),!(cond))   
36.  
37.// 等待某个子任务执行完成  
38.#define PT_WAIT_THREAD(pt,thread)   PT_WAIT_UNTIL((pt),(thread))     
39.  
40.// 新建一个子任务,并等待其执行完退出  
41.#define PT_SPAWN(pt,thread) /   
42.  PT_INIT((pt));            /  
43.  PT_WAIT_THREAD((pt),(thread))  
44.   
45.// 重新启动某任务执行  
46.#define PT_RESTART(pt)  PT_INIT(pt); return   
47.  
48.// 任务后面的部分不执行,直接退出  
49.#define PT_EXIT(pt)     (pt)->lc = PT_THREAD_EXITED;return   
50.
51.
52.
53.#endif  
#ifndef PC_H
#define PC_H

typedef unsigned int INT16U;

struct pt
{
  INT16U lc;  
};


#define PT_THREAD_WAITING   0
#define PT_THREAD_EXITED    1


//初始化任务变量,只在初始化函数中执行一次就行
#define PT_INIT(pt)     (pt)->lc = 0

//启动任务处理,放在函数开始处
#define PT_BEGIN(pt)    switch((pt)->lc) { case 0:

// 等待某个条件成立,若条件不成立则直接退出本函数,下一次进入本函数就直接跳到这个地方判断  
// __LINE__ 编译器内置宏,代表当前行号,比如:若当前行号为8,则 s = __LINE__; case __LINE__: 展开为 s = 8; case 8:
#define PT_WAIT_UNTIL(pt,condition)   (pt)->lc = __LINE__;   case __LINE__: /
                                      if(!(condition))  return            

// 结束任务,放在函数的最后
#define PT_END(pt)      }





// 等待某个条件不成立      
#define PT_WAIT_WHILE(pt,cond)    PT_WAIT_UNTIL((pt),!(cond))

// 等待某个子任务执行完成
#define PT_WAIT_THREAD(pt,thread)   PT_WAIT_UNTIL((pt),(thread))  

// 新建一个子任务,并等待其执行完退出
#define PT_SPAWN(pt,thread) /
  PT_INIT((pt));            /
  PT_WAIT_THREAD((pt),(thread))
  
// 重新启动某任务执行
#define PT_RESTART(pt)  PT_INIT(pt); return

// 任务后面的部分不执行,直接退出
#define PT_EXIT(pt)     (pt)->lc = PT_THREAD_EXITED;return



#endif

     

       ◆ 实例及展开源码:

         应用实例:

         
[c-sharp] view plaincopyprint?
01.static struct pt pt1,pt2;  
02.  
03.static int protothread1_flag,protothread2_flag;  
04.// ========================================   
05.// 线程1   
06.// ========================================   
07.static void protothread1(struct pt *pt)  
08.{  
09.  PT_BEGIN(pt); // 开始时调用   
10.  while(1)  
11.  {  
12.    // 应用代码   
13.    protothread1_flag = 1;  
14.    PT_WAIT_UNTIL(pt,protothread2_flag != 0); // 等待protothread2_flag 标志置位   
15.    protothread2_flag = 0;  
16.  
17.  }   
18.  PT_END(pt);  // 结束时调用   
19.}  
20.// ========================================   
21.// 线程2   
22.// ========================================   
23.static void protothread2(struct pt *pt)  
24.{  
25.  PT_BEGIN(pt);  
26.  while(1)  
27.  {  
28.    // 应用代码   
29.    protothread2_flag = 1;  
30.    PT_WAIT_UNTIL(pt,protothread1_flag != 0); // 等待protothread1_flag 标志置位   
31.  
32.    protothread1_flag = 0;  
33.  }  
34.  PT_END(pt);  
35.}  
36.// ========================================   
37.// 主函数   
38.// ========================================   
39.void main(void)  
40.{  
41.  PT_INIT(&pt1);  // 初始化   
42.  PT_INIT(&pt2);  
43.   
44.  while(1)  
45.  {  
46.    protothread1(&pt1);  
47.    protothread2(&pt2);  
48.  }  
49.}  
static struct pt pt1,pt2;

static int protothread1_flag,protothread2_flag;
// ========================================
// 线程1
// ========================================
static void protothread1(struct pt *pt)
{
  PT_BEGIN(pt); // 开始时调用
  while(1)
  {
    // 应用代码
    protothread1_flag = 1;
    PT_WAIT_UNTIL(pt,protothread2_flag != 0); // 等待protothread2_flag 标志置位
    protothread2_flag = 0;

  }  
  PT_END(pt);  // 结束时调用
}
// ========================================
// 线程2
// ========================================
static void protothread2(struct pt *pt)
{
  PT_BEGIN(pt);
  while(1)
  {
    // 应用代码
    protothread2_flag = 1;
    PT_WAIT_UNTIL(pt,protothread1_flag != 0); // 等待protothread1_flag 标志置位

    protothread1_flag = 0;
  }
  PT_END(pt);
}
// ========================================
// 主函数
// ========================================
void main(void)
{
  PT_INIT(&pt1);  // 初始化
  PT_INIT(&pt2);
  
  while(1)
  {
    protothread1(&pt1);
    protothread2(&pt2);
  }
}

        线程1,2的展开式:

         
[c-sharp] view plaincopyprint?
01.// ========================================   
02.// 线程1   
03.// ========================================   
04.static void protothread1(struct pt *pt)  
05.{  
06.  // PT_BEGIN(pt);展开   
07.  switch(pt->lc)  
08.  {  
09.    case 0:  
10.    ;     
11.      
12.    while(1)  
13.    {  
14.      protothread1_flag = 1;  
15.        
16.      // PT_WAIT_UNTIL(pt,protothread2_flag != 0);展开   
17.      // 条件判断部分,条件不成立,则调度   
18.      pt->lc = 26;   // 假定当前为26行   
19.      case 26:  
20.      if(protothread2_flag == 0)  
21.        return;      // 若protothread2_flag未发生,返回   
22.  
23.      protothread2_flag = 0;  
24.    }  
25.   
26.  // PT_END(pt); 对应switch   
27.  }  
28.}  
29.  
30.// ========================================   
31.// 线程2   
32.// ========================================   
33.static void protothread2(struct pt *pt)  
34.{  
35.  switch(pt->lc)  
36.  {  
37.    case 0:  
38.    ;            
39.    while(1)  
40.    {  
41.      protothread2_flag = 1;  
42.      pt->lc = 44;  
43.      case 44:  
44.      if(protothread1_flag == 0)  
45.        return;  
46.        
47.      myFunc2();  
48.      protothread1_flag = 0;  
49.    }  
50.  }  
51.  
52.}  



看这篇文章就清晰多了!~

出0入0汤圆

发表于 2012-5-27 11:08:16 | 显示全部楼层
◆它的缺陷在于:

      1. 函数中不具备可重入型,不能使用局部变量;



不是很明白,既然不抢占,为何不能使用局部变量?

出0入0汤圆

发表于 2012-5-27 11:47:40 | 显示全部楼层
smset 发表于 2012-5-27 11:40
在状态机函数内部,可以临时使用局部变量,但是一旦退出函数后,这些变量值就丢失了。 ...



protothread1()
protothread2()
中不能使用局部变量。

具体的应用:
myFunc1()
myFunc2()
这些函数中应该能使用局部变量的吧?

出0入0汤圆

发表于 2012-5-30 13:23:01 | 显示全部楼层
本帖最后由 ljt80158015 于 2012-5-30 15:47 编辑

它的缺陷在于:

      1. 函数中不具备可重入型,不能使用局部变量;


大体明白了

protothread1()
protothread2()
中不能使用局部变量。

具体的应用:
myFunc1()
myFunc2()
能使用局部变量。



很不错的操作系统!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-28 01:58

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表