[LOOK] 【M0第三贴】基于LOOK的多任务详解【LOOK第一帖】

[复制链接]
 楼主| nixianmin 发表于 2011-9-26 22:41 | 显示全部楼层 |阅读模式
LED, TE, ST, TI, ANTI
虽然M0才没写几个模块,不过我觉得现在这样写和写单片机的程序差不多,就决定看能不能从LOOK入手边了解基于LOOK的程序,边熟悉M0的模块。先写个简单的LOOK程序,根据老师的文档和大家的例子搭建LOOK,刚开使遇到点问题,像LOOK版本搞错会编译错误,我现在用的是0522版的,0909的以前向导不能用。基本的框架搞定后就开始写程序了,基本框架:

在LOOK中任务是一个派生类,其中routine()就是代表1个任务
  1. class task_led_t : public task_t {
  2. public:
  3.         task_led_t() __OPT_ATTR__;        // 构造函数
  4.        
  5. protected:
  6.         void routine();                // 任务例程
  7. };



下面这段是声明一个task_led的任务对象,task类已经将task_led_t类加到调度器中

  1. #ifdef LOOK_SCHEDULING_PRIORITY
  2. instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led(0);
  3. #else
  4. instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led;
  5. #endif



下面这一段是我在instantiate中找的,是task类模板的结构
  1.         template<typename TASK, uintptr_t STACK_SIZE>
  2.         class task : public TASK {
  3. #ifndef __DOXYGEN__
  4.         public:
  5.                 static_assert(__is_base_of(task_t, TASK), "the type argument for <TASK> must be derived from task_t");
  6. #ifdef LOOK_SCHEDULING_PRIORITY
  7.                 template<typename ... R>
  8.                 task(uintptr_t priority, R ... r)
  9.                 : TASK(r ...)
  10.                 {
  11.                         init(stack[STACK_SIZE], priority);
  12.                         scheduler.add_task(*this);   //将任务加到调度器里
  13.                 }
  14. #else
  15.                 template<typename ... R>
  16.                 task(R ... r)
  17.                 : TASK(r ...)
  18.                 {
  19.                         init(stack[STACK_SIZE]);
  20.                         scheduler.add_task(*this);
  21.                 }
  22. #endif        // LOOK_SCHEDULING_PRIORITY

  23.         private:
  24.                 uint8_t align[8 - ((sizeof(TASK) + (STACK_SIZE + TASK::MIN_CONTEXT_SIZE) * sizeof(uintptr_t)) & 7)];
  25.                 uintptr_t stack[STACK_SIZE + TASK::MIN_CONTEXT_SIZE];
  26. #endif        // __DOXYGEN__
  27.         };



那么如何创建多任务呢,知道了任务是如何创建和加到调度器的,那多任务就是将多个任务加到调度器,而要任务不一样那就要写多个任务类了,下面是我的2个简单任务,都是亮LED的

led.h
  1. #include "look_config.h"
  2. #include <look.h>
  3. #include <instantiate>
  4. #include"M0Base.h"

  5. // 任务类 task_led_t 的定义
  6. class task_led_t : public task_t {
  7. public:
  8.         task_led_t() __OPT_ATTR__;        // 构造函数
  9.        
  10. protected:
  11.         void routine();                // 任务例程
  12. };

  13. // 任务类 task_led_t 的构造函数
  14. __OPT_INLINE__ task_led_t::task_led_t()
  15. {
  16.         // TODO: 在此初始化 task_led_t 的类成员
  17.   LedIoOpen();

  18. }

  19. class task_led2_t : public task_t {
  20. public:
  21.         task_led2_t() __OPT_ATTR__;        // 构造函数
  22.        
  23. protected:
  24.         void routine();                // 任务例程
  25. };

  26. // 任务类 task_led_t 的构造函数
  27. __OPT_INLINE__ task_led2_t::task_led2_t()
  28. {
  29.         // TODO: 在此初始化 task_led_t 的类成员
  30.   LedIoOpen();
  31. }

  32. extern instantiate::task<task_led2_t, LOOK_STACK_SIZE> task_led2;
  33. extern instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led;



led.cpp
  1. #include "led.h"
  2. #include <NUC1xx.h>
  3. #include"NUC1xxM051Seriescfg.h"
  4. #include"M0Base.h"



  5. // 任务类 task_led_t 的例程
  6. void task_led_t::routine()
  7. {
  8.         // TODO: 在此编写 task_led_t 例程的内容
  9.   
  10.         while (true) {
  11.       for(uint8_t i=BIT0;i<BIT4;i<<=1 )
  12.       {
  13.         LedSet(i);
  14.         DrvSYS_Delay(100000);
  15.       }
  16.       scheduler.yield(); //当前的任务进入就绪态,调度下一个任务
  17.       
  18.                   // TODO: 在此编写 task_led_t 例程的内容
  19.         }
  20. }

  21. void task_led2_t::routine()
  22. {
  23.   while (true){   
  24.       for(uint8_t i=BIT3;i>0;i>>=1 )
  25.       {
  26.         LedSet(i);
  27.         DrvSYS_Delay(100000);
  28.       }
  29.       scheduler.yield(); //当前的任务进入就绪态,调度下一个任务
  30.                   // TODO: 在此编写 task_led_t 例程的内容
  31.   }
  32. }

  33. #ifdef LOOK_SCHEDULING_PRIORITY
  34. instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led(0);
  35. instantiate::task<task_led2_t, LOOK_STACK_SIZE> task_led2(1);
  36. #else
  37. instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led;
  38. instantiate::task<task_led2_t, LOOK_STACK_SIZE> task_led2;
  39. #endif



LOOK有6中调度算法,我这里简单的用了协作调度,时间片轮也试了下,其他调度就不怎么清楚了,
在协作调度中,任务结束后调用scheduler.yield(); 可进入下一个任务,
在时间片轮则是不调用scheduler.yield(); 当时间到就会进入下一个任务
  1. //*** <<< Use Configuration Wizard in Context Menu >>> ***
  2. // <o> 调度算法
  3. //                <0=> 协作(Co-operative)
  4. //                <1=> 时间片轮转(Round-Robin)
  5. //                <2=> 固定优先级(Fixed Priority)
  6. //                <3=> 最早截止期优先(Earliest Deadline First)
  7. //                <4=> 多级队列(Multi-Level Queue)
  8. //                <5=> 多级队列+时间片轮转(Multi-Level Queue & Round-Robin)
  9. #define LOOK_SCHEDULING_VAL                0



先写这么多,虽然弄出来了,不过很多东西只是了解点皮毛,看来还有好多要像大叔和John lee老师

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
hotpower 发表于 2011-9-26 22:54 | 显示全部楼层
继续努力~~
 楼主| nixianmin 发表于 2011-9-26 23:05 | 显示全部楼层
本帖最后由 nixianmin 于 2011-9-26 23:06 编辑

2# hotpower 谢谢大叔,今天像lee老师请教了半天,明天继续捣鼓其他几部分,不过以前没接触过,还是很有挑战的,也很新鲜,大家一起来LOOK下:lol
lixiaoxu2meng 发表于 2011-9-27 07:30 | 显示全部楼层
很好 顶楼主 以后还得向楼主学习:lol
Swallow_0322 发表于 2011-9-27 07:31 | 显示全部楼层
加油!↖(^ω^)↗
 楼主| nixianmin 发表于 2011-9-27 10:49 | 显示全部楼层
我都是学习大家的例子,不过有些例子都只有代码,应该带点解说就更好了,现在边复习c++,边学look还是有很多收获的
gdmgb520 发表于 2011-9-27 11:00 | 显示全部楼层
楼主CPP的基础比我好,对LOOK的了解比我多。

学习!
zzyaizll 发表于 2011-9-28 22:38 | 显示全部楼层
学习
hzj52188 发表于 2011-10-17 22:39 | 显示全部楼层
是学调试算法的一个不错的例程
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:电机控制,TI InstaSpin Foc交流群:335663930

40

主题

431

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部