搜索
bottom↓
回复: 31

voidtask

[复制链接]

出0入0汤圆

发表于 2009-10-27 16:48:51 | 显示全部楼层 |阅读模式
任务上下文切换部分重写,上下文切换保护所有寄存器,中断切换与非中断切换分开处理,
加入空闲任务控制块,空闲任务运行实际是运行主函数。

编译器IAR EWAVR 5.30 , AVR_Studio+WinAVR 2009

简单例子:


#include "config.h"

TTask TaskA,TaskB,TaskC;

void TaskAProc(void)  
{
    sei();                     //任务开始开中断
    while(1)
   {
       PORTB^=_BV(0);   
       TSK_Delay(VT_TICKS_PER_SEC/2);   
   }
}

void TaskBProc(void)  
{
    sei();                     //任务开始开中断
    while(1)
   {  
       PORTB^=_BV(1);     
       TSK_Delay(VT_TICKS_PER_SEC/3);
   }
}

void TaskCProc(void)  
{
    sei();                    //任务开始开中断
    while(1)
    {
      PORTB^=_BV(2);        
      TSK_Delay(VT_TICKS_PER_SEC/4);   
    }
}

int main()
{
     cli();                        //任务开始调度前,要关中断
     
     DDRB  |=_BV(0)|_BV(1)|_BV(2);
     PORTB |=_BV(0)|_BV(1)|_BV(2);
         
     VT_TicksInit();

#ifdef __AVR_IAR__               
     TSK_Init(&TaskA,TaskAProc,0,64,32);
     TSK_Init(&TaskB,TaskBProc,1,64,32);
     TSK_Init(&TaskC,TaskCProc,2,64,32);
#else                                    
     TSK_Init(&TaskA,TaskAProc,0,64+32);
     TSK_Init(&TaskB,TaskBProc,1,64+32);
     TSK_Init(&TaskC,TaskCProc,2,64+32);
#endif
                    
    TSK_Start();
   
    sei();                 //主程序开中断
    while(1)
    {   
   
         SleepIdle();
        
    }
}

//系统节拍中断
ISR_ATTR_NAKED(TIMER2_COMP_vect)  //裸中断
{     
      VT_IntEnter();
      VT_TicksHandler();
      VT_IntExit();  
}

20091027:
点击此处下载 ourdev_496842.rar(文件大小:311K) (原文件名:vt.rar)

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

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2009-10-27 16:50:20 | 显示全部楼层
跟新一下:20091028
点击此处下载 ourdev_496947.rar(文件大小:315K) (原文件名:vt.rar)

出0入0汤圆

 楼主| 发表于 2009-10-29 17:07:42 | 显示全部楼层
再更新一下:20091029
cpu换atmega48,一个用户任务+一个空闲任务(实为主函数)

#include "config.h"

TTask TaskA;

#define LED IO_BIT_ALIAS(&PORTB,2)    //IO口位域

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

int main()
{
     cli();                        //任务开始调度前,要关中断
     
      DDRB   |=  _BV(2);     //LED,输出
      
      LED=1;   
      _delay_ms(1000);
      LED=0;
         
     VT_TicksInit();         //节拍初始化

#ifdef __AVR_IAR__               
     TSK_Init(&TaskA,(void (*)(void))TaskAProc,0,64,32);  //任务初始化,优先级0,双堆栈64+32
#else                                    
     TSK_Init(&TaskA,(void (*)(void))TaskAProc,0,64+32);  //任务初始化,优先级0,单堆栈64+32
#endif
                    
    TSK_Start();           //任务开始调度
   
    sei();                 //主程序开中断
   
    while(1)               //任务空闲,运行主函数while(1)循环
    {   
   
         SleepIdle();      //空闲休眠
        
    }
}



(原文件名:Image0043.JPG)


(原文件名:Image0044.JPG)

貌似WinAVR2009优化还不错,代码比IAR还小

点击此处下载 ourdev_497343.rar(文件大小:386K) (原文件名:VoidTask.rar)

出0入0汤圆

 楼主| 发表于 2009-10-30 11:10:22 | 显示全部楼层
20091030:
堆栈分配直接用数组;
加入任务自己挂起,自己删除
AVRGCC修正ATTR_CTASK宏

cpu,atmega32,IAR EWAVR 5.30 ,AVR_STudio 4.18 + WinAVR 20090313

#include "config.h"

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

#define TaskAStackSize 100   //任务A堆栈大小
#define TaskBStackSize 100   //任务B堆栈大小
#define TaskCStackSize 100   //任务C堆栈大小

uint8 TaskAStack[TaskAStackSize];  //任务A堆栈空间
uint8 TaskBStack[TaskBStackSize];  //任务B堆栈空间
uint8 TaskCStack[TaskCStackSize];  //任务C堆栈空间

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

ATTR_CTASK void TaskAProc(void)   //任务A处理
{
    volatile float f1=1.0;        //测试浮点运算
  
    sei();                        //任务开始开中断(每个任务都有自己单独的总中断标志位,任务开始执行时,总中断标志位是关闭的)
    while(1)
   {
       f1+=0.1;                        //测试浮点运算
     
       LED_A=1;                        //LED_A写1  
       TSK_Delay(VT_TICKS_PER_SEC/2);  //延时1/2S
      
       LED_A=0;                        //LED_A写0
       TSK_Delay(VT_TICKS_PER_SEC-VT_TICKS_PER_SEC/2);  //延时1/2S
   }
}

ATTR_CTASK void TaskBProc(void)  
{
    volatile float f2=1.0;     //测试浮点运算
  
    sei();                     //任务开始开中断
    while(1)
   {  
       f2+=0.1;                        //测试浮点运算
           
       LED_B=1;                        //LED_B写1  
       TSK_Delay(VT_TICKS_PER_SEC/3);  //延时1/3S
      
       LED_B=0;                        //LED_B写0
       TSK_Delay(VT_TICKS_PER_SEC-VT_TICKS_PER_SEC/3);  //延时2/3S
   }
}

ATTR_CTASK void TaskCProc(void)  
{
    volatile float f3=1.0;     //测试浮点运算
  
    sei();                             //任务开始开中断
    while(1)
    {
       f3+=0.1;                        //测试浮点运算
     
       LED_C=1;                        //LED_C写1  
       TSK_Delay(VT_TICKS_PER_SEC/4);  //延时1/4S
      
       LED_C=0;                        //LED_C写0
       TSK_Delay(VT_TICKS_PER_SEC-VT_TICKS_PER_SEC/4);  //延时3/4S
    }
}

int main()
{
     cli();                   //任务开始调度前,要关中断
     
     DDRB  |=_BV(0)|_BV(1)|_BV(2);    //LED_A,LED_B,LED_C输出
     PORTB |=_BV(0)|_BV(1)|_BV(2);    //LED_A,LED_B,LED_C写1
     _delay_ms(1000);
     PORTB &=~(_BV(0)|_BV(1)|_BV(2)); //LED_A,LED_B,LED_C写0
         
     VT_TicksInit();                   //系统节拍初始化

#ifdef __AVR_IAR__  
     //AVR IAR使用双堆栈
     TSK_Init(&TaskA,(void (*)(void))TaskAProc,0,&TaskAStack[TaskAStackSize-33],&TaskAStack[TaskAStackSize-1]); //任务A初始化,优先级0
     TSK_Init(&TaskB,(void (*)(void))TaskBProc,1,&TaskBStack[TaskBStackSize-33],&TaskBStack[TaskBStackSize-1]); //任务B初始化,优先级1
     TSK_Init(&TaskC,(void (*)(void))TaskCProc,2,&TaskCStack[TaskCStackSize-33],&TaskCStack[TaskCStackSize-1]); //任务C初始化,优先级2
#else
     //AVR GCC使用单堆栈
     TSK_Init(&TaskA,(void (*)(void))TaskAProc,0,&TaskAStack[TaskAStackSize-1]); //任务A初始化,优先级0
     TSK_Init(&TaskB,(void (*)(void))TaskBProc,1,&TaskBStack[TaskBStackSize-1]); //任务B初始化,优先级1
     TSK_Init(&TaskC,(void (*)(void))TaskCProc,2,&TaskCStack[TaskCStackSize-1]); //任务C初始化,优先级2
#endif
                    
    TSK_Start();           //任务开始调度(开始调度由空闲任务主函数切换到用户任务)
   
    sei();                 //空闲任务主函数开中断
   
    volatile float f0=1.0;     //测试浮点运算
      
    while(1)              //任务空闲时,运行这里
    {   
              
      f0=f0+0.01;         //测试浮点运算
      
     SleepIdle();
        
    }
}

ISR_ATTR_NAKED(TIMER2_COMP_vect)
{     
      VT_IntEnter();        
      VT_TicksHandler();
      VT_IntExit();  
}



(原文件名:Image0190.JPG)


(原文件名:Image0191.JPG)


点击此处下载 ourdev_497931.rar(文件大小:328K) (原文件名:voidtask.rar)

出0入0汤圆

发表于 2009-10-31 09:24:15 | 显示全部楼层
20091031:
任务切换宏更新

IAR:

#define SAVE_REGS()                         \
  do{                                       \
  asm  ("ST      -Y,   R0    ");            \
  asm  ("ST      -Y,   R1    ");            \
  asm  ("ST      -Y,   R2    ");            \
  asm  ("ST      -Y,   R3    ");            \
  asm  ("ST      -Y,   R4    ");            \
  asm  ("ST      -Y,   R5    ");            \
  asm  ("ST      -Y,   R6    ");            \
  asm  ("ST      -Y,   R7    ");            \
  asm  ("ST      -Y,   R8    ");            \
  asm  ("ST      -Y,   R9    ");            \
  asm  ("ST      -Y,   R10   ");            \
  asm  ("ST      -Y,   R11   ");            \
  asm  ("ST      -Y,   R12   ");            \
  asm  ("ST      -Y,   R13   ");            \
  asm  ("ST      -Y,   R14   ");            \
  asm  ("ST      -Y,   R15   ");            \
  asm  ("ST      -Y,   R16   ");            \
  asm  ("ST      -Y,   R17   ");            \
  asm  ("ST      -Y,   R18   ");            \
  asm  ("ST      -Y,   R19   ");            \
  asm  ("ST      -Y,   R20   ");            \
  asm  ("ST      -Y,   R21   ");            \
  asm  ("ST      -Y,   R22   ");            \
  asm  ("ST      -Y,   R23   ");            \
  asm  ("ST      -Y,   R24   ");            \
  asm  ("ST      -Y,   R25   ");            \
  asm  ("ST      -Y,   R26   ");            \
  asm  ("ST      -Y,   R27   ");            \
  asm  ("ST      -Y,   R30   ");            \
  asm  ("ST      -Y,   R31   ");            \
  asm  ("IN      R24,  0x3D  ");            \
  asm  ("ST      -Y,   R24   ");            \
  asm  ("IN      R24,  0x3E  ");            \
  asm  ("ST      -Y,   R24   ");            \
  asm  ("IN      R24,  0x3F  ");            \
  asm  ("ST      -Y,   R24   ");            \
  }while(0)

#define RESTORE_REGS()                      \
  do{                                       \
  asm  ("LD      R24,  Y+    ");            \
  asm  ("OUT     0X3F, R24   ");            \
  asm  ("LD      R24,  Y+    ");            \
  asm  ("OUT     0X3E, R24   ");            \
  asm  ("LD      R24,  Y+    ");            \
  asm  ("OUT     0X3D, R24   ");            \
  asm  ("LD      R31,  Y+    ");            \
  asm  ("LD      R30,  Y+    ");            \
  asm  ("LD      R27,  Y+    ");            \
  asm  ("LD      R26,  Y+    ");            \
  asm  ("LD      R25,  Y+    ");            \
  asm  ("LD      R24,  Y+    ");            \
  asm  ("LD      R23,  Y+    ");            \
  asm  ("LD      R22,  Y+    ");            \
  asm  ("LD      R21,  Y+    ");            \
  asm  ("LD      R20,  Y+    ");            \
  asm  ("LD      R19,  Y+    ");            \
  asm  ("LD      R18,  Y+    ");            \
  asm  ("LD      R17,  Y+    ");            \
  asm  ("LD      R16,  Y+    ");            \
  asm  ("LD      R15,  Y+    ");            \
  asm  ("LD      R14,  Y+    ");            \
  asm  ("LD      R13,  Y+    ");            \
  asm  ("LD      R12,  Y+    ");            \
  asm  ("LD      R11,  Y+    ");            \
  asm  ("LD      R10,  Y+    ");            \
  asm  ("LD      R9,   Y+    ");            \
  asm  ("LD      R8,   Y+    ");            \
  asm  ("LD      R7,   Y+    ");            \
  asm  ("LD      R6,   Y+    ");            \
  asm  ("LD      R5,   Y+    ");            \
  asm  ("LD      R4,   Y+    ");            \
  asm  ("LD      R3,   Y+    ");            \
  asm  ("LD      R2,   Y+    ");            \
  asm  ("LD      R1,   Y+    ");            \
  asm  ("LD      R0,   Y+    ");            \
  asm  ("RET " );                           \
  }while(0)

#define INT_SAVE_REGS()                     \
  do{                                       \
  asm  ("CLI ");                            \
  asm  ("ST      -Y,   R0    ");            \
  asm  ("ST      -Y,   R1    ");            \
  asm  ("ST      -Y,   R2    ");            \
  asm  ("ST      -Y,   R3    ");            \
  asm  ("ST      -Y,   R4    ");            \
  asm  ("ST      -Y,   R5    ");            \
  asm  ("ST      -Y,   R6    ");            \
  asm  ("ST      -Y,   R7    ");            \
  asm  ("ST      -Y,   R8    ");            \
  asm  ("ST      -Y,   R9    ");            \
  asm  ("ST      -Y,   R10   ");            \
  asm  ("ST      -Y,   R11   ");            \
  asm  ("ST      -Y,   R12   ");            \
  asm  ("ST      -Y,   R13   ");            \
  asm  ("ST      -Y,   R14   ");            \
  asm  ("ST      -Y,   R15   ");            \
  asm  ("ST      -Y,   R16   ");            \
  asm  ("ST      -Y,   R17   ");            \
  asm  ("ST      -Y,   R18   ");            \
  asm  ("ST      -Y,   R19   ");            \
  asm  ("ST      -Y,   R20   ");            \
  asm  ("ST      -Y,   R21   ");            \
  asm  ("ST      -Y,   R22   ");            \
  asm  ("ST      -Y,   R23   ");            \
  asm  ("ST      -Y,   R24   ");            \
  asm  ("ST      -Y,   R25   ");            \
  asm  ("ST      -Y,   R26   ");            \
  asm  ("ST      -Y,   R27   ");            \
  asm  ("ST      -Y,   R30   ");            \
  asm  ("ST      -Y,   R31   ");            \
  asm  ("IN      R24,  0x3D  ");            \
  asm  ("ST      -Y,   R24   ");            \
  asm  ("IN      R24,  0x3E  ");            \
  asm  ("ST      -Y,   R24   ");            \
  asm  ("IN      R24,  0x3F  ");            \
  asm  ("ST      -Y,   R24   ");            \
  }while(0)

#define INT_RESTORE_REGS()                  \
  do{                                       \
  asm  ("LD      R24,  Y+    ");            \
  asm  ("OUT     0X3F, R24   ");            \
  asm  ("LD      R24,  Y+    ");            \
  asm  ("OUT     0X3E, R24   ");            \
  asm  ("LD      R24,  Y+    ");            \
  asm  ("OUT     0X3D, R24   ");            \
  asm  ("LD      R31,  Y+    ");            \
  asm  ("LD      R30,  Y+    ");            \
  asm  ("LD      R27,  Y+    ");            \
  asm  ("LD      R26,  Y+    ");            \
  asm  ("LD      R25,  Y+    ");            \
  asm  ("LD      R24,  Y+    ");            \
  asm  ("LD      R23,  Y+    ");            \
  asm  ("LD      R22,  Y+    ");            \
  asm  ("LD      R21,  Y+    ");            \
  asm  ("LD      R20,  Y+    ");            \
  asm  ("LD      R19,  Y+    ");            \
  asm  ("LD      R18,  Y+    ");            \
  asm  ("LD      R17,  Y+    ");            \
  asm  ("LD      R16,  Y+    ");            \
  asm  ("LD      R15,  Y+    ");            \
  asm  ("LD      R14,  Y+    ");            \
  asm  ("LD      R13,  Y+    ");            \
  asm  ("LD      R12,  Y+    ");            \
  asm  ("LD      R11,  Y+    ");            \
  asm  ("LD      R10,  Y+    ");            \
  asm  ("LD      R9,   Y+    ");            \
  asm  ("LD      R8,   Y+    ");            \
  asm  ("LD      R7,   Y+    ");            \
  asm  ("LD      R6,   Y+    ");            \
  asm  ("LD      R5,   Y+    ");            \
  asm  ("LD      R4,   Y+    ");            \
  asm  ("LD      R3,   Y+    ");            \
  asm  ("LD      R2,   Y+    ");            \
  asm  ("LD      R1,   Y+    ");            \
  asm  ("LD      R0,   Y+    ");            \
  asm  ("RETI " );                          \
  }while(0)   

#define SAVE_OLD_PCONTEXT()                 \
  do{                                       \
  __require(&VTCurrentTask);                \
  __require(&VTToTask);                     \
  asm(" LDS     R30, VTCurrentTask");       \
  asm(" LDS     R31, (VTCurrentTask + 1)"); \
  asm(" STD     Z+5, R28 ");                \
  asm(" STD     Z+6, R29 ");                \
  }while(0)

#define LOAD_NEW_PCONTEXT()                 \
  do{                                       \
  __require(&VTCurrentTask);                \
  __require(&VTToTask);                     \
  asm(" LDS     R30, VTToTask");            \
  asm(" LDS     R31, (VTToTask + 1)");      \
  asm(" STS     VTCurrentTask,R30 ");       \
  asm(" STS    (VTCurrentTask+1),R31 ");    \
  asm(" LDD     R28,Z+5 ");                 \
  asm(" LDD     R29,Z+6 ");                 \
  }while(0);

#define SET_INT_CONTEXT_FLAG()              \
  do{                                       \
  asm(" LDI     R24, 1"   );                \
  asm(" STD     Z+7, R24" );                \
  }while(0)

#define CLR_INT_CONTEXT_FLAG()              \
  do{                                       \
  asm(" LDI     R24, 0"   );                \
  asm(" STD     Z+7, R24" );                \
  }while(0)

#define SWAP_CTX_ENTER()                    \
  do{                                       \
  SAVE_REGS();                              \
  SAVE_OLD_PCONTEXT();                      \
  CLR_INT_CONTEXT_FLAG();                   \
  }while(0)

#define SWAP_CTX_EXIT()                     \
  do{                                       \
  LOAD_NEW_PCONTEXT();                      \
  if(VTCurrentTask->IntSwapFlag==0)         \
  {                                         \
      RESTORE_REGS();                       \
  }                                         \
  else                                      \
  {                                         \
      INT_RESTORE_REGS();                   \
  }                                         \
}while(0)


#define INT_SWAP_CTX_ENTER()                \
  do{                                       \
  INT_SAVE_REGS();                          \
  SAVE_OLD_PCONTEXT();                      \
  SET_INT_CONTEXT_FLAG();                   \
  }while(0)


#define INT_SWAP_CTX_EXIT()    SWAP_CTX_EXIT()

#define DELETE_SWAP_CTX_EXIT() SWAP_CTX_EXIT()


#define VT_IntEnter()              \
  do{                              \
  __require((void *)&VTIntNest);   \
  INT_SWAP_CTX_ENTER();            \
  VTIntNest++;                     \
}while(0)
   

#define VT_IntExit()               \
  do{                              \
  __require((void *)&VTIntNest);   \
  cli();                           \
  if(--VTIntNest==0)               \
   {                               \
       TSK_IntSwap();              \
   }                               \
     INT_RESTORE_REGS();           \
  }while(0);




GCC:
#define SAVE_REGS()                              \
  do{                                            \
  asm volatile  ("PUSH   R0    ");               \
  asm volatile  ("PUSH   R1    ");               \
  asm volatile  ("PUSH   R2    ");               \
  asm volatile  ("PUSH   R3    ");               \
  asm volatile  ("PUSH   R4    ");               \
  asm volatile  ("PUSH   R5    ");               \
  asm volatile  ("PUSH   R6    ");               \
  asm volatile  ("PUSH   R7    ");               \
  asm volatile  ("PUSH   R8    ");               \
  asm volatile  ("PUSH   R9    ");               \
  asm volatile  ("PUSH   R10   ");               \
  asm volatile  ("PUSH   R11   ");               \
  asm volatile  ("PUSH   R12   ");               \
  asm volatile  ("PUSH   R13   ");               \
  asm volatile  ("PUSH   R14   ");               \
  asm volatile  ("PUSH   R15   ");               \
  asm volatile  ("PUSH   R16   ");               \
  asm volatile  ("PUSH   R17   ");               \
  asm volatile  ("PUSH   R18   ");               \
  asm volatile  ("PUSH   R19   ");               \
  asm volatile  ("PUSH   R20   ");               \
  asm volatile  ("PUSH   R21   ");               \
  asm volatile  ("PUSH   R22   ");               \
  asm volatile  ("PUSH   R23   ");               \
  asm volatile  ("PUSH   R24   ");               \
  asm volatile  ("PUSH   R25   ");               \
  asm volatile  ("PUSH   R26   ");               \
  asm volatile  ("PUSH   R27   ");               \
  asm volatile  ("PUSH   R28   ");               \
  asm volatile  ("PUSH   R29   ");               \
  asm volatile  ("PUSH   R30   ");               \
  asm volatile  ("PUSH   R31   ");               \
  asm volatile  ("IN     R24,  0x3F  ");         \
  asm volatile  ("PUSH   R24   ");               \
  }while(0)


#define RESTORE_REGS()                            \
do{                                               \
  asm volatile ("POP      R24  ");                \
  asm volatile ("OUT      0X3F, R24   ");         \
  asm volatile ("POP      R31     ");             \
  asm volatile ("POP      R30     ");             \
  asm volatile ("POP      R29     ");             \
  asm volatile ("POP      R28     ");             \
  asm volatile ("POP      R27     ");             \
  asm volatile ("POP      R26     ");             \
  asm volatile ("POP      R25     ");             \
  asm volatile ("POP      R24     ");             \
  asm volatile ("POP      R23     ");             \
  asm volatile ("POP      R22     ");             \
  asm volatile ("POP      R21     ");             \
  asm volatile ("POP      R20     ");             \
  asm volatile ("POP      R19     ");             \
  asm volatile ("POP      R18     ");             \
  asm volatile ("POP      R17     ");             \
  asm volatile ("POP      R16     ");             \
  asm volatile ("POP      R15     ");             \
  asm volatile ("POP      R14     ");             \
  asm volatile ("POP      R13     ");             \
  asm volatile ("POP      R12     ");             \
  asm volatile ("POP      R11     ");             \
  asm volatile ("POP      R10     ");             \
  asm volatile ("POP      R9      ");             \
  asm volatile ("POP      R8      ");             \
  asm volatile ("POP      R7      ");             \
  asm volatile ("POP      R6      ");             \
  asm volatile ("POP      R5      ");             \
  asm volatile ("POP      R4      ");             \
  asm volatile ("POP      R3      ");             \
  asm volatile ("POP      R2      ");             \
  asm volatile ("POP      R1      ");             \
  asm volatile ("POP      R0      ");             \
  asm volatile ("RET " );                         \
  }while(0)


#define INT_SAVE_REGS()                           \
  do{                                              \
  asm volatile  ("CLI ");                          \
  asm volatile  ("PUSH   R0    ");                 \
  asm volatile  ("PUSH   R1    ");                 \
  asm volatile  ("PUSH   R2    ");                 \
  asm volatile  ("PUSH   R3    ");                 \
  asm volatile  ("PUSH   R4    ");                 \
  asm volatile  ("PUSH   R5    ");                 \
  asm volatile  ("PUSH   R6    ");                 \
  asm volatile  ("PUSH   R7    ");                 \
  asm volatile  ("PUSH   R8    ");                 \
  asm volatile  ("PUSH   R9    ");                 \
  asm volatile  ("PUSH   R10   ");                 \
  asm volatile  ("PUSH   R11   ");                 \
  asm volatile  ("PUSH   R12   ");                 \
  asm volatile  ("PUSH   R13   ");                 \
  asm volatile  ("PUSH   R14   ");                 \
  asm volatile  ("PUSH   R15   ");                 \
  asm volatile  ("PUSH   R16   ");                 \
  asm volatile  ("PUSH   R17   ");                 \
  asm volatile  ("PUSH   R18   ");                 \
  asm volatile  ("PUSH   R19   ");                 \
  asm volatile  ("PUSH   R20   ");                 \
  asm volatile  ("PUSH   R21   ");                 \
  asm volatile  ("PUSH   R22   ");                 \
  asm volatile  ("PUSH   R23   ");                 \
  asm volatile  ("PUSH   R24   ");                 \
  asm volatile  ("PUSH   R25   ");                 \
  asm volatile  ("PUSH   R26   ");                 \
  asm volatile  ("PUSH   R27   ");                 \
  asm volatile  ("PUSH   R28   ");                 \
  asm volatile  ("PUSH   R29   ");                 \
  asm volatile  ("PUSH   R30   ");                 \
  asm volatile  ("PUSH   R31   ");                 \
  asm volatile  ("IN     R24,  0x3F  ");           \
  asm volatile  ("PUSH   R24   ");                 \
  }while(0)


#define INT_RESTORE_REGS()                         \
do{                                                \
  asm volatile  ("POP      R24     ");             \
  asm volatile  ("OUT      0X3F, R24   ");         \
  asm volatile  ("POP      R31     ");             \
  asm volatile  ("POP      R30     ");             \
  asm volatile  ("POP      R29     ");             \
  asm volatile  ("POP      R28     ");             \
  asm volatile  ("POP      R27     ");             \
  asm volatile  ("POP      R26     ");             \
  asm volatile  ("POP      R25     ");             \
  asm volatile  ("POP      R24     ");             \
  asm volatile  ("POP      R23     ");             \
  asm volatile  ("POP      R22     ");             \
  asm volatile  ("POP      R21     ");             \
  asm volatile  ("POP      R20     ");             \
  asm volatile  ("POP      R19     ");             \
  asm volatile  ("POP      R18     ");             \
  asm volatile  ("POP      R17     ");             \
  asm volatile  ("POP      R16     ");             \
  asm volatile  ("POP      R15     ");             \
  asm volatile  ("POP      R14     ");             \
  asm volatile  ("POP      R13     ");             \
  asm volatile  ("POP      R12     ");             \
  asm volatile  ("POP      R11     ");             \
  asm volatile  ("POP      R10     ");             \
  asm volatile  ("POP      R9      ");             \
  asm volatile  ("POP      R8      ");             \
  asm volatile  ("POP      R7      ");             \
  asm volatile  ("POP      R6      ");             \
  asm volatile  ("POP      R5      ");             \
  asm volatile  ("POP      R4      ");             \
  asm volatile  ("POP      R3      ");             \
  asm volatile  ("POP      R2      ");             \
  asm volatile  ("POP      R1      ");             \
  asm volatile  ("POP      R0      ");             \
  asm volatile  ("RETI " );                        \
}while(0)


#define SAVE_OLD_PCONTEXT()                        \
  do{                                              \
  asm volatile  ("IN     R28,0x3D");               \
  asm volatile  ("IN     R29,0x3E");               \
  asm volatile  (" LDS     R30, VTCurrentTask");       \
  asm volatile  (" LDS     R31, (VTCurrentTask + 1)"); \
  asm volatile  (" STD     Z+5, R28 ");             \
  asm volatile  (" STD     Z+6, R29 ");             \
  }while(0)

#define LOAD_NEW_PCONTEXT()                       \
do{                                               \
  asm volatile (" LDS     R30, VTToTask");        \
  asm volatile (" LDS     R31, (VTToTask + 1)");  \
  asm volatile (" STS     VTCurrentTask,R30 ");   \
  asm volatile (" STS    (VTCurrentTask+1),R31 ");\
  asm volatile (" LDD     R28,Z+5 ");             \
  asm volatile (" LDD     R29,Z+6 ");             \
  asm volatile (" OUT     0x3E,R29 ");            \
  asm volatile (" OUT     0x3D,R28 ");            \
  }while(0)


#define SET_INT_CONTEXT_FLAG()              \
  do{                                       \
  asm(" LDI     R24, 1"   );                \
  asm(" STD     Z+7, R24" );                \
  }while(0)

#define CLR_INT_CONTEXT_FLAG()              \
  do{                                       \
  asm(" LDI     R24, 0"   );                \
  asm(" STD     Z+7, R24" );                \
  }while(0)


#define SWAP_CTX_ENTER()                    \
  do{                                       \
  SAVE_REGS();                              \
  SAVE_OLD_PCONTEXT();                      \
  CLR_INT_CONTEXT_FLAG();                   \
  }while(0)

#define SWAP_CTX_EXIT()                     \
  do{                                       \
  LOAD_NEW_PCONTEXT();                      \
  if(VTCurrentTask->IntSwapFlag==0)         \
  {                                         \
      RESTORE_REGS();                       \
  }                                         \
  else                                      \
  {                                         \
      INT_RESTORE_REGS();                   \
  }                                         \
}while(0)


#define INT_SWAP_CTX_ENTER()                \
  do{                                       \
  INT_SAVE_REGS();                          \
  SAVE_OLD_PCONTEXT();                      \
  SET_INT_CONTEXT_FLAG();                   \
  }while(0)


#define INT_SWAP_CTX_EXIT()    SWAP_CTX_EXIT()

#define DELETE_SWAP_CTX_EXIT() SWAP_CTX_EXIT()

#define VT_IntEnter()              \
  do{                              \
  INT_SWAP_CTX_ENTER();            \
  VTIntNest++;                     \
}while(0)
   

#define VT_IntExit()               \
  do{                              \
  cli();                           \
  if(--VTIntNest==0)               \
   {                               \
       TSK_IntSwap();              \
   }                               \
     INT_RESTORE_REGS();           \
  }while(0);

点击此处下载 ourdev_497947.rar(文件大小:322K) (原文件名:voidtask.rar)

出0入0汤圆

发表于 2009-10-31 14:33:01 | 显示全部楼层
20091031:
voidtask移植stm32


#include "config.h"

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

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


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


void TaskAProc(void)  
{
  __enable_interrupt();     //任务开始开中断
  while(1)
   {   
       LED_0^=1;
       TSK_Delay(VT_TICKS_PER_SEC/2);  
   }
}

void TaskBProc(void)  
{
    __enable_interrupt();     //任务开始开中断
    while(1)
   {   
       LED_1=~LED_1;
       TSK_Delay(VT_TICKS_PER_SEC/3);   
   }
}

void TaskCProc(void)  
{
    __enable_interrupt();    //任务开始开中断
    while(1)
    {
      LED_2=!LED_2;
      TSK_Delay(VT_TICKS_PER_SEC/4);      
    }
}

void TaskDProc(void)  
{
    __enable_interrupt();    //任务开始开中断
    while(1)
    {
      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,TaskAProc,0,&TaskAStack[TaskAStackSize/4]-1);//任务TaksA,优先级0
     TSK_Init(&TaskB,TaskBProc,1,&TaskBStack[TaskBStackSize/4]-1);//任务TaksB,优先级1
     TSK_Init(&TaskC,TaskCProc,2,&TaskCStack[TaskCStackSize/4]-1);//任务TaksC,优先级2
     TSK_Init(&TaskD,TaskDProc,3,&TaskDStack[TaskDStackSize/4]-1);//任务TaksD,优先级3
      
     TSK_Start();
   
     __enable_interrupt();   //主程序开中断
    while(1)
    {
   
    }
}

点击此处下载 ourdev_498057.rar(文件大小:1.35M) (原文件名:voidtask.rar)

出0入0汤圆

发表于 2009-11-3 22:26:15 | 显示全部楼层
20091103:
修改avrgcc,avriar上下文切换,
移植到msp430f1611

#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/4);   //延时1/4S
      
       LED_A=1;
       TSK_Delay(VT_TICKS_PER_SEC-VT_TICKS_PER_SEC/4);  //延时3/4S
   }
}

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();   //休眠
        
    }
}

#define SAVE_REGS()                        \
  do{                                      \
    asm("push      r2");                   \
    asm("push      r4");                   \
    asm("push      r5");                   \
    asm("push      r6");                   \
    asm("push      r7");                   \
    asm("push      r8");                   \
    asm("push      r9");                   \
    asm("push      r10");                  \
    asm("push      r11");                  \
    asm("push      r12");                  \
    asm("push      r13");                  \
    asm("push      r14");                  \
    asm("push      r15");                  \
   }while(0)

#define RESTORE_REGS()                     \
  do{                                      \
    asm("pop      r15");                   \
    asm("pop      r14");                   \
    asm("pop      r13");                   \
    asm("pop      r12");                   \
    asm("pop      r11");                   \
    asm("pop      r10");                   \
    asm("pop      r9");                    \
    asm("pop      r8");                    \
    asm("pop      r7");                    \
    asm("pop      r6");                    \
    asm("pop      r5");                    \
    asm("pop      r4");                    \
    asm("pop      r2");                    \
    asm("ret");                            \
   }while(0);

#define INT_SAVE_REGS()                    \
  do{                                      \
    asm("push      r4");                   \
    asm("push      r5");                   \
    asm("push      r6");                   \
    asm("push      r7");                   \
    asm("push      r8");                   \
    asm("push      r9");                   \
    asm("push      r10");                  \
    asm("push      r11");                  \
    asm("push      r12");                  \
    asm("push      r13");                  \
    asm("push      r14");                  \
    asm("push      r15");                  \
   }while(0)

#define INT_RESTORE_REGS()                 \
  do{                                      \
    asm("pop      r15");                   \
    asm("pop      r14");                   \
    asm("pop      r13");                   \
    asm("pop      r12");                   \
    asm("pop      r11");                   \
    asm("pop      r10");                   \
    asm("pop      r9");                    \
    asm("pop      r8");                    \
    asm("pop      r7");                    \
    asm("pop      r6");                    \
    asm("pop      r5");                    \
    asm("pop      r4");                    \
    asm("BIC.W    #0xf0, 0(SP)");          \
    asm("reti");                           \
   }while(0);  

#define SAVE_OLD_PCONTEXT()                 \
  do{                                       \
  __require(&VTCurrentTask);                \
  __require(&VTToTask);                     \
  asm(" MOV.W   &VTCurrentTask, R15 ");     \
  asm(" MOV.W   SP, 0x6(R15) ");            \
  }while(0)

#define LOAD_NEW_PCONTEXT()                 \
  do{                                       \
  __require(&VTCurrentTask);                \
  __require(&VTToTask);                     \
  asm(" MOV.W   &VTToTask, R15 ");          \
  asm(" MOV.W   R15, &VTCurrentTask ");     \
  asm(" MOV.W   0x06(R15), SP ");           \
  }while(0);

#define SWAP_CTX_ENTER()                    \
  do{                                       \
  SAVE_REGS();                              \
  SAVE_OLD_PCONTEXT();                      \
  }while(0)

#define SWAP_CTX_EXIT()                     \
  do{                                       \
  LOAD_NEW_PCONTEXT();                      \
  RESTORE_REGS();                           \
}while(0)


#define INT_SWAP_CTX_ENTER()                \
  do{                                       \
  INT_SAVE_REGS();                          \
  SAVE_OLD_PCONTEXT();                      \
  }while(0)


#define INT_SWAP_CTX_EXIT()                 \
  do{                                       \
  LOAD_NEW_PCONTEXT();                      \
  INT_RESTORE_REGS();                       \
}while(0)

#define VT_IntEnter()                       \
  do{                                       \
  __require((void *)&VTIntNest);            \
  INT_SWAP_CTX_ENTER();                     \
  VTIntNest++;                              \
}while(0)
   

#define VT_IntExit()                        \
  do{                                       \
  __require((void *)&VTIntNest);            \
  __disable_interrupt();                    \
  if(--VTIntNest==0)                        \
   {                                        \
       TSK_IntSwap();                       \
   }                                        \
     INT_RESTORE_REGS();                    \
  }while(0);

点击此处下载 ourdev_499491.rar(文件大小:1.50M) (原文件名:voidtask.rar)

出0入0汤圆

发表于 2009-11-26 22:02:03 | 显示全部楼层
20091126
点击此处下载 ourdev_507897.rar(文件大小:1.48M) (原文件名:voidtask.rar)

出0入0汤圆

发表于 2009-11-26 22:23:00 | 显示全部楼层
多谢 有时间来研究研究

出0入0汤圆

发表于 2009-12-8 15:39:34 | 显示全部楼层
收下来看看,谢谢!

出0入0汤圆

发表于 2009-12-15 00:13:04 | 显示全部楼层
楼主这个东西看起来很晦涩啊!
#define CRITICAL()\
  for(critical_flag_t __flags=CriticalEnter(),__ToDo=1;__ToDo;__ToDo=0,CriticalExit(__flags))
类似这样的东西我还是第一次看到
这个TODO还可以这样用啊
我的C语言看来还是太孤陋寡闻了
我翻了C99标准也没找到这个宏定义的解释

出0入0汤圆

发表于 2009-12-15 01:26:27 | 显示全部楼层
搞了半天我弄明白了
第一次是定义了两个变量__flag __ToDo

测试__ToDo,执行了一次for里面的循环语句
然后把条件置为不满足,同时执行后半截的恢复
我靠
太麻烦了

出0入0汤圆

发表于 2009-12-15 11:36:22 | 显示全部楼层
CRITICAL()
{
…………
}

展开就是:
for(critical_flag_t __flags=CriticalEnter(),__ToDo=1;__ToDo;__ToDo=0,CriticalExit(__flags))
{
…………
}

TODO优化掉:
critical_flag_t __flags=CriticalEnter()
…………
CriticalExit(__flags));

继续优化就是:
uint8 flag=SREG;
      cli();
…………
      SREG=flag;


CRITICAL可以任意嵌套,如
CRITICAL()
{
    …………  //临界段
     CRITICAL()
       {
         …………//临界段
       }
    …………//临界段
}

还可以:
CRITICAL()
{
    …………//临界段
     NOCRITICAL()
       {
         …………//非临界段
       }
    …………//临界段
}


这种写法是参考WinAVR自带头文件
C:\WinAVR-20090313\avr\include\util\atomic.h
里面的
     ATOMIC_BLOCK(ATOMIC_FORCEON)
     {
       …………
     }
用法。

个人认为用起来很方便啊,编译效率也高。

uint8 CriticalReadByte(const volatile uint8 * pdata)
{
    uint8 result;
    CRITICAL()
    {
        result=pdata[0];
    }
    return result;
}

IAR编译汇编代码:
        RSEG CODE:CODE:NOROOT(1)
//   25 uint8 CriticalReadByte(const volatile uint8 * pdata)
CriticalReadByte:

        IN      R18, 0x3F
        CLI

        MOVW    R31:R30, R17:R16
        LD      R16, Z

        OUT     0x3F, R18

        RET


GCC编译汇编代码:

5ce:        fc 01               movw        r30, r24

5d0:        9f b7               in        r25, 0x3f        ; 63
5d2:        f8 94               cli

5d4:        80 81               ld        r24, Z

5d6:        9f bf               out        0x3f, r25        ; 63

5d8:        08 95               ret

出0入0汤圆

发表于 2009-12-15 15:18:44 | 显示全部楼层
为了这段东西我最后翻了谭浩强的书才找到答案,
for循环的第一个语句可以定义两个循环变量,
第二个是判断语句
第三个可以执行两个语句自加自减

出0入0汤圆

发表于 2009-12-15 19:09:54 | 显示全部楼层
有几个问题
main函数里调用sleep指令后
拿什么唤醒
T1比较中断能唤醒CPU吗

出0入0汤圆

发表于 2009-12-15 19:43:21 | 显示全部楼层
有几个问题
main函数里调用sleep指令后
拿什么唤醒
------------------------------
系统节拍中断。
程序里面应该是T1 CTC中断做系统节拍中断。

出0入0汤圆

发表于 2009-12-15 20:03:46 | 显示全部楼层
我看了datasheet,IDLE状态下 wakeup source可没有TC1 COMPARE中断
只有TC0

出0入0汤圆

发表于 2009-12-15 20:22:24 | 显示全部楼层
还有个问题,你的任务里面好像中断没打开啊
void ctx_init(TContext **Context,TTaskProc *TaskProc,void *Stack1)
{
  ctx_sp_t *ctx_sp;

  ctx_sp=(ctx_sp_t *)Stack1 - 1;
  
  ctx_sp->_pcl  = (uint16)TaskProc%256;
  ctx_sp->_pch  = (uint16)TaskProc/256;

#if AVR_HAS_RAMPZ==1
  ctx_sp->_rampz=0;
#endif

  ctx_sp->_sreg = 0;
  
初始化堆栈的时候没看到开中断
sreg=0

然后调用了
task_start

//任务开始调度
//不能在中断中使用
void TSK_Start(void)                          //任务开始调度
{
   CRITICAL()
   {
      VTCurrentTask=&VTIdleTask;              //任务切换从空闲任务切到其他任务   
      VTTaskSwapEnable=1;                     //允许任务切换
      tsk_swap_ctx();                         //任务切换
   }
}
ATTR_NAKED void tsk_swap_ctx(void)
{
   SWAP_CTX_ENTER();
   tsk_next_ready();
   SWAP_CTX_EXIT();  
}

#define SWAP_CTX_ENTER()                    \
  do{                                       \
  SAVE_REGS();                              \
  SAVE_OLD_PCONTEXT();                      \
  }while(0)

#define SWAP_CTX_EXIT()                     \
  do{                                       \
  LOAD_NEW_PCONTEXT();                      \
  RESTORE_REGS();                           \
}while(0)
最后restore_regs的时候就意味着ret执行到任务中去了,这个时候中断时没有打开的
没中断只有到所有任务都阻塞后,跑到main里面,这时才打开中断,定时器中断服务得以响应
然后再次有高优先级任务就绪的时候,中断又关断了
这么严重的BUG...

  *Context=ctx_sp;

出0入0汤圆

发表于 2009-12-15 20:24:56 | 显示全部楼层
原来你是在每个任务里单独开的中断
那何必不放在堆栈初始化里呢

出0入0汤圆

发表于 2009-12-15 20:46:44 | 显示全部楼层
延时处理得比较奇怪
相对延时很有特色
每个人占一个坑
有人挤坑坑就变小点
确实很好,
比那个双延时链表好

出0入0汤圆

发表于 2009-12-15 21:23:14 | 显示全部楼层
非常感谢ralfak的指点。

m128还不太熟悉。程序使用M32搬过来的。

关于TTimer部分。
最初写程序的时候,TTimer是单独独立的,不在任务控制块里。
任务延时的时候,先定义一个TTimer,再调用延时函数。
后来觉得定义TTimer反而麻烦,干脆把TTimer放到任务控制块里面的(相当于每个任务都预先定义好了一个TTimer)。

显式在任务开中断,更能告诉编程者,每个任务都有自己的中断标志位。

出0入0汤圆

发表于 2009-12-15 21:53:45 | 显示全部楼层
释放信号量SEM_Post不带任务切换
EVENT只能存一个标志或者1个数据

这个定时器ETMR有何用
仔细看了一下
莫非是延时触发机制
这个还是前所未见

最后,

时钟节拍溢出的时候没有考虑
但是这个强制转换(ticks_size_t)(VTTimerTicks-VTLastTimerTicks)好像处理得也没问题,
但是在ETMR中溢出处理好像没有看到
比如
void etmr_adjust(TEventTimer *Timer)
{
  ticks_size_t ticsk_expired;
  
  ticsk_expired=V_TimerTicks - Timer->Start;

总之这些地方好像有些漏洞
void VT_TicksHandler(void)                    //时钟节拍处理
{
        static ticks_size_t VTLastTimerTicks=0;
         
         critical_flag_t critical_flag;
         
         critical_flag=CriticalEnter();
         
         VTTimerTicks++;                      //节拍加1  
            
         if(VTTaskTimerQueue.Object==NULL)    //如果定时器队列没有没有节点
         {
           CriticalExit(critical_flag);
           return ;
         }
         
         //如果定时器队列第一个节点延时到
         if( (ticks_size_t)(VTTimerTicks-VTLastTimerTicks) >= ((TTimer *)VTTaskTimerQueue.Object)->Rel )
         {
             ((TTimer *)VTTaskTimerQueue.Object)->Rel=0;  //清零节点延时
             VTLastTimerTicks=VTTimerTicks;               //记录当前节拍
            
             CriticalExit(critical_flag);
            
             TMR_Handler();                                //定时器处理,含任务切换3
            
             return ;                        
         }
         
         CriticalExit(critical_flag);
        return ;
}

出0入0汤圆

发表于 2009-12-15 21:58:01 | 显示全部楼层
写个文档吧
我觉得这个东西挺好的
链表处理得都很好,
尤其是那个分段延时,
比自减1要快,
又比双链表省事,
简单的做这样挺好

出0入0汤圆

发表于 2009-12-15 22:07:10 | 显示全部楼层
这个ETIMER,其实与这个系统关系不大。
ETIMER是我另外一个基于时间触发的轮训的小系统(叫VoidEvent),为了兼容VoidEvent,VoidTask也把VoidEvent包含在里面。

貌似以前发过一点点:这么久了,STM32还只会跑马灯,voidtask+voidevent (20090705)
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3437340&bbs_page_no=1&search_mode=1&search_text=voidevent&bbs_id=9999

ETIMER用法:

TEventTimer EventTimer;

while(1)
{
      if(ETMR_Expired(&EventTimer)==ETMR_EXPIRED)  // EventTimer到时
       {
            ………………//  处理
        }
        …………
}

出0入0汤圆

发表于 2009-12-15 22:14:39 | 显示全部楼层
最后还得说,楼主的C语言功底确实很深厚,
链表用得很好
简单说一下特色
每个任务需要定义一个任务块
需要定义堆栈空间
需要指定优先级
信号量没有限制数目
不存在空间分配问题
16位的时钟节拍
IDLE任务启动的时候含有sleep
优先级查询采用链表方式
取就绪表中的第一个
延时队列采用排队方式,任务处于延时队列当中,每个任务的延时采用相对延时,与上一个任务相对时差,时差为0的一起触发
信号量发送时不做任务切换
信号量获取有阻塞模式和非阻塞模式
不支持中断嵌套,至少mega128的移植早早的就把SREG ORR了
每个任务都需要单独设置开中断,包括IDLE任务
否则就运行于中断关闭模式,直到阻塞
信号量链表按优先级排序获取
事件链表按优先级排序获取
就绪任务按优先级排序运行
延时链表按延时大小排序
还有一个ETMR,应该属于定时触发程序
发出触发信号后延时若干时间,任务就绪
支持任务挂起任务就绪
支持任务调度加锁
支持延时取消
总共就这么多的功能

出0入0汤圆

发表于 2009-12-15 22:17:03 | 显示全部楼层
voidtask 这个ETMR好像意义不是很大

出0入0汤圆

发表于 2009-12-15 22:20:47 | 显示全部楼层
这样的东西应该自己写一个文档出来,写文档的时候你还可以仔细想想哪儿还有bug
把所有的内核函数描述一下
就算不卖钱,自己用着挺爽

出0入0汤圆

发表于 2009-12-21 20:36:14 | 显示全部楼层
20091221 加上TSK_SwapHook

点击此处下载 ourdev_517241.rar(文件大小:1.54M) (原文件名:voidtask.rar)

出0入0汤圆

发表于 2009-12-22 14:36:01 | 显示全部楼层
这个东西是用来计算任务运行时间的吧

出0入0汤圆

发表于 2011-1-13 18:02:17 | 显示全部楼层
mark

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-8-26 01:19

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

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