查看: 16146|回复: 18

关于contiki 操作系统

[复制链接]
cddxhy 发表于 2010-9-12 08:24:15 | 显示全部楼层 |阅读模式
本帖最后由 cddxhy 于 2010-9-12 08:35 编辑

昨天从Outman处得到这个东东,看了看,呵呵,还挺好玩的。

先声明一下,坛子里高手很多,有错就"吱"一声.

先不说其他的,先上一段代码:
  1. 1 void* mymemcpy( void* dest, const void* src, size_t count )
  2. 2 {
  3. 3     char* d = (char*)dest;
  4. 4     const char* s = (const char*)src;
  5. 5     int n = count>>3;
  6. 6     switch( count & 7 )
  7. 7     {
  8. 8            case 0:  
  9. 9         do {  
  10. 10             *d++ = *s++;
  11. 11             case 7:      *d++ = *s++;
  12. 12             case 6:        *d++ = *s++;
  13. 13             case 5:        *d++ = *s++;
  14. 14             case 4:        *d++ = *s++;
  15. 15             case 3:        *d++ = *s++;
  16. 16             case 2:        *d++ = *s++;
  17. 17             case 1:        *d++ = *s++;
  18. 18         } while (--n > 0);
  19. 19     }
  20. 20     return dest;
  21. 21 }
复制代码
这是网上的一段代码,“据说”比纯的:
  1. void memcpy1(char *to , char *from , int count){
  2.     do{
  3.         *to++ = *from ++ ;
  4.     }while ( --count != 0 ) ;
  5. }
复制代码
这个要快。

据说而已,听听就行。

跑题了,和Outman一样。

贴上面那段代码的意思不外两个:

1. C 中,switch中间可以嵌套while!
2. switch case 语句从本质上来说,就是goto!!!!
 楼主| cddxhy 发表于 2010-9-12 08:24:38 | 显示全部楼层
本帖最后由 cddxhy 于 2010-9-12 08:52 编辑

晕倒,论坛非法操作,打的字呀,这么多!(也就两行),掉了

拿到Contiki也就两天,随便看了看,胡说几句,有人拿砖来我就潜水

这个东东实际上是一个抢占式的多任务系统,没有时间片在里面。
好处多多的:大家都有抢厕所的经历吧,你抢到了,在里面是不是很爽呢?
坏处呢也是很多:抢厕所,你没抢到,很急,可偏偏里面的人老不出来,郁闷哪!
 楼主| cddxhy 发表于 2010-9-12 08:25:07 | 显示全部楼层
本帖最后由 cddxhy 于 2010-9-12 09:17 编辑

说了这么多屁话,还是放代码吧:
  1. PROCESS(test_process1, "Test process");
  2. PROCESS_THREAD(test_process1, ev, data)
  3. {
  4.   static struct etimer etimer;

  5.   PROCESS_BEGIN();
  6.        
  7.   rs232_print (RS232_PORT_1, "test_process 1 starting\n");

  8.   while(1) {
  9.     etimer_set(&etimer, CLOCK_SECOND);
  10. PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
  11.     rs232_print (RS232_PORT_1, "Tick\n");
  12.     etimer_set(&etimer, CLOCK_SECOND);
  13. PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
  14.     rs232_print (RS232_PORT_1, "Tack\n");
  15.   }

  16. }
复制代码
这段代码是contiki里的一段自启动时钟任务。很简单的。

大家主要看到下面这几个东东:
  1. PROCESS_BEGIN();
  2. PROCESS_WAIT_UNTIL();
  3. PROCESS_END();
复制代码
因为这个系统不是时间片轮询的,所以在代码里会多出些帮助调度任务的东东。

现在将这几条指令展开,就得到如下结果:
  1. PROCESS(test_process1, "Test process");
  2. PROCESS_THREAD(test_process1, ev, data)
  3. {
  4. static struct etimer etimer;

  5. char PT_YIELD_FLAG = 1;
  6. switch(process_pt->lc)
  7. {
  8. case 0:
  9.        
  10.   rs232_print (RS232_PORT_1, "test_process 1 starting\n");

  11.   while(1) {
  12.             etimer_set(&etimer, CLOCK_SECOND);
  13.         process_pt->lc=__LINE__;
  14.         case __LINE__:
  15.                  if(!(etimer_expired(&etimer)))
  16.                          {                               
  17.                         return PT_WAITING;
  18.                         }
  19.                     rs232_print (RS232_PORT_1, "Tick\n");
  20.                     etimer_set(&etimer, CLOCK_SECOND);
  21.                 process_pt->lc=__LINE__;
  22.         case __LINE__:
  23.                 if(!(etimer_expired(&etimer)))
  24.                          {                               
  25.                         return PT_WAITING;
  26.                         }   
  27.             rs232_print (RS232_PORT_1, "Tack\n");
  28.   }
  29. }
  30. PT_YIELD_FLAG = 0;
  31. pt->lc=0; return PT_ENDED;
  32. }
复制代码
那个__LINE__就不用解释了吧,就是编译时产生的行号,(都说不解释了!!)
有点多, 简化一下:
  1. PROCESS(test_process1, "Test process");
  2. PROCESS_THREAD(test_process1, ev, data)
  3. {
  4. char PT_YIELD_FLAG = 1;
  5. switch(process_pt->lc)
  6.   {
  7. case 0:
  8.         ...............
  9.           while(1) {
  10.             .................
  11.         process_pt->lc=__LINE__;
  12. case __LINE__:
  13.          if(!(condition))
  14.                 return PT_WAITING;
  15.         .............
  16.         process_pt->lc=__LINE__;
  17. case __LINE__:
  18.         if(!(condition))
  19.                 return PT_WAITING;
  20.         .........
  21.   }
  22. }
  23. PT_YIELD_FLAG = 0;
  24. pt->lc=0;
  25. return PT_ENDED;
  26. }
复制代码
明白了没有?
要不明白,那个while(1)大家就当他不存在吧。再看?
不要被while(1)搞晕了,这个函数是有返回的。
主函数里搞个任务表,放上这些任务的函数指针,挨个挨个地调用,一个任务返回了,再调下一个任务。
就像大家抢厕所排队

题外话,要是谁心情好,再对排队的抢厕所的家伙内急程度排个序,就是带优先级的抢占式多任务了。
outman 发表于 2010-9-12 08:31:05 | 显示全部楼层
一大早上来挖这么多坑,小心有人掉下去啊,楼主赶紧填上啊~~
 楼主| cddxhy 发表于 2010-9-12 08:41:31 | 显示全部楼层
坛主现身!

坛主的东东代码语法不加亮,比示一下!
outman 发表于 2010-9-12 09:46:23 | 显示全部楼层
终于把老师傅请出山了,想当年是我老师,这么多年了,还是甘拜下风。。。。
这段代码别说蹲厕所了,连今天早上做梦,那个s = __LINE__; case __LINE__:都在脑子里转,不废话了,搬个板凳,怀着崇敬的心情仔细研读一下大作。
outman 发表于 2010-9-12 10:22:11 | 显示全部楼层
HY大神的作品有毒啊~~~简直是欲罢不能~~

越看越觉得神奇,这个作者太有才了。从每个线程来看,似乎都是独占的,但实际上是在排队。

做一件事但没完成,中间断开,但保留行号,下次过来的时候从这一行继续往下走。宏观上来看这其实和时间片的轮询是一个效果啦?

只是时间片的轮询的方式保证了每个任务执行的实时性,但这种机制,着急了也没办法,前面的人不出来,后面脸憋红了也得憋着?

这种理解有没问题?还请指正。。。
 楼主| cddxhy 发表于 2010-9-12 10:41:55 | 显示全部楼层
理解上没什么问题,实际上这个东西对于写线程的人员还是有要求的。

不过对于单片机的系统,实时的是什么?中断!实时要求严的都用中断搞定了,剩下的都是其他处理了。
一个小任务,跑一圈下来也要不了多久,10-100uS级,而基本上一圈就会切一次任务,从这个角度看,比时间片轮询的ms级的切换要实时很多了。
时间片轮询对系统的堆栈要求比较大,花在轮询上的开销很大(有时占到50%)。

说到底,这玩意就是对写任务的人有点儿要求,千万不要写成delayms(100)!!!!
outman 发表于 2010-9-12 10:59:00 | 显示全部楼层
分析得透彻!受教了!

原来一直憋在s = __LINE__ 这里搞不明白,看了楼主大作醍醐灌顶啊!
hellojackie 发表于 2010-10-8 15:03:46 | 显示全部楼层
求源码,也想研究研究啊
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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