VoidTask更新

发布: 2009-11-01 17:46 | 作者: voidx | 来源: StmFans思蜕盟 OPELC 自由电子联盟

[i=s] 本帖最后由 voidx 于 2009-11-1 18:04 编辑

20091031
移植平台avr+gcc,avr+iar,stm32+iar

CODE:

#include "config.h"

TTask TaskA;   //任务A控制块
TTask TaskB;   //任务B控制块
TTask TaskC;   //任务C控制块
TTask TaskD;   //任务D控制块

#define TaskAStackSize 400   //任务A堆栈大小
#define TaskBStackSize 400   //任务B堆栈大小
#define TaskCStackSize 400   //任务C堆栈大小
#define TaskDStackSize 400   //任务D堆栈大小


uint32 TaskAStack[TaskAStackSize/4];  //任务A堆栈空间
uint32 TaskBStack[TaskBStackSize/4];  //任务B堆栈空间
uint32 TaskCStack[TaskCStackSize/4];  //任务C堆栈空间
uint32 TaskDStack[TaskDStackSize/4];  //任务D堆栈空间


ATTR_CTASK void TaskAProc(void)  
{
  volatile double f0=1.0;     //测试浮点运算

  __enable_interrupt();     //任务开始开中断
  while(1)
   {   
       f0+=0.001;            //测试浮点运算
     
       LED_0^=1;
       TSK_Delay(VT_TICKS_PER_SEC/2);  
   }
}

ATTR_CTASK void TaskBProc(void)  
{
   volatile double f1=1.0;     //测试浮点运算
  
    __enable_interrupt();     //任务开始开中断
    while(1)
   {   
       f1+=0.001;            //测试浮点运算
      
       LED_1=~LED_1;
       TSK_Delay(VT_TICKS_PER_SEC/3);   
   }
}

ATTR_CTASK void TaskCProc(void)  
{
   volatile double f2=1.0;     //测试浮点运算
  
    __enable_interrupt();    //任务开始开中断
    while(1)
    {
      f2+=0.001;           //测试浮点运算
      
      LED_2=!LED_2;
      TSK_Delay(VT_TICKS_PER_SEC/4);      
    }
}

ATTR_CTASK void TaskDProc(void)  
{
  volatile double f3=1.0;     //测试浮点运算
    __enable_interrupt();    //任务开始开中断
    while(1)
    {
     f3+=0.001;     //测试浮点运算
      
      LED_3=!LED_3;
      TSK_Delay(VT_TICKS_PER_SEC/4);      
    }
}


int main()
{
     __disable_interrupt();  //任务切换前关闭中断
   
#ifdef VECT_TAB_RAM
     NVIC_SetVectorTable(NVIC_VectTab_RAM , 0x0);
#else
     NVIC_SetVectorTable(NVIC_VectTab_FLASH , 0x0);
#endif
   
     SystemInit();
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  
   
     LED_Init();
   
     SysTick_Config(SystemFrequency /VT_TICKS_PER_SEC);
     
     TSK_Init(&TaskA,(TTaskProc *)TaskAProc,0,&TaskAStack[TaskAStackSize/4]-1);//任务TaksA,优先级0
     TSK_Init(&TaskB,(TTaskProc *)TaskBProc,1,&TaskBStack[TaskBStackSize/4]-1);//任务TaksB,优先级1
     TSK_Init(&TaskC,(TTaskProc *)TaskCProc,2,&TaskCStack[TaskCStackSize/4]-1);//任务TaksC,优先级2
     TSK_Init(&TaskD,(TTaskProc *)TaskDProc,3,&TaskDStack[TaskDStackSize/4]-1);//任务TaksD,优先级3
      
     TSK_Start();
   
     __enable_interrupt();   //主程序开中断
   
   while(1)      //任务空闲时,运行主函数while(1)循环
    {
   
    }
}

voidtask.rar
(2009-11-01 17:50:37, Size: 1.06 MB, Downloads: 5)

catwill (2009-11-01 19:19:40)
下载了,学习一下,谢谢!!
binglin (2009-11-01 22:30:10)
我也下载学习,谢谢!
voidx (2009-11-01 22:47:30)
[i=s] 本帖最后由 voidx 于 2009-11-1 23:22 编辑

只是自己尝试写写RTOS,没有经过严谨测试。
上面代码硬件平台是三合一实验板。

只说一下:voidtask与一般RTOS不同的地方是,任务空闲的时候,不是去运行空闲任务,而是运行主函数(或者说主函数,就是voidtask里面的空闲任务)。
这样做可以不必为空闲任务单独分配堆栈,在AVR上这种小RAM MCU还是可以节省一点RAM。
binglin (2009-11-01 23:12:45)
简单实用呢。
voidx (2009-11-04 18:17:40)
[i=s] 本帖最后由 voidx 于 2009-11-4 18:18 编辑

20091104
修改avriar,avrgcc上下文切换,
增加移植MSP430F1611。

CODE:

#include "config.h"

TTask TaskA;                            //任务A控制块
#define TaskAStackSize 100              //任务A堆栈大小
uint16 TaskAStack[TaskAStackSize/2];    //任务A堆栈空间

TTask TaskB;                            //任务B控制块
#define TaskBStackSize 100              //任务B堆栈大小
uint16 TaskBStack[TaskBStackSize/2];    //任务B堆栈空间


#define LED_A   IO_BIT_ALIAS(&P6OUT,0)    //LED_A,IO口位域别名
#define LED_B   IO_BIT_ALIAS(&P6OUT,1)    //LED_B,IO口位域别名


ATTR_NAKED void TaskAProc(void)       //任务处理
{
    __enable_interrupt();             //任务开始开中断
    while(1)
   {
       LED_A=0;               
       TSK_Delay(VT_TICKS_PER_SEC/2);   //延时1/2S
      
       LED_A=1;
       TSK_Delay(VT_TICKS_PER_SEC-VT_TICKS_PER_SEC/2);  //延时1/2S
   }
}

ATTR_NAKED void TaskBProc(void)       //任务处理
{
     __enable_interrupt();             //任务开始开中断
    while(1)
   {
       LED_B=0;                  
       TSK_Delay(VT_TICKS_PER_SEC/4);   //延时1/4S
           
       LED_B=1;  
       TSK_Delay(VT_TICKS_PER_SEC-VT_TICKS_PER_SEC/4);  //延时3/4S
   }
}

int main()
{
     WDTCTL = WDTPW + WDTHOLD;
  
     BCSCTL1 &= ~XT2OFF;                     
     do
     {
        IFG1 &= ~OFIFG;                       
        _delay_us(20);
     }
     while ((IFG1 & OFIFG));                  

     BCSCTL2 |= SELM_2 | SELS | DIVS_3;        
      
     P6DIR |=     _BV(0)|_BV(1);
     P6OUT |=     _BV(0)|_BV(1);

     VT_TicksInit();         //节拍初始化
                                 
     TSK_Init(&TaskA,(void (*)(void))TaskAProc,0,&TaskAStack[TaskAStackSize/2]-1);  //任务A初始化,优先级0
     TSK_Init(&TaskB,(void (*)(void))TaskBProc,1,&TaskBStack[TaskBStackSize/2]-1);  //任务B初始化,优先级1
      
     TSK_Start();           //任务开始调度
          
     __enable_interrupt();  //住函数开中断
   
    while(1)                 //任务空闲,运行主函数while(1)循环
    {   
   
        __low_power_mode_3();   //休眠
        
    }
}

voidtask.rar
(2009-11-04 18:17:40, Size: 574 KB, Downloads: 0)

()