搜索
bottom↓
回复: 6

尝试写个简单任务调度内核voidtask

[复制链接]

出0入0汤圆

发表于 2009-6-5 00:12:32 | 显示全部楼层 |阅读模式
尝试写个简单任务调度内核。
自己写的玩玩,不保证正确,还没在目标板试过。

1.任务只有延时,切换功能。
2.任务切换未保护所有寄存器。
3.没有空闲任务,空闲时切换到主函数。
4.IAR必须设置STACK_DOUL为1,GCC必须设置STACK_DOUL为0。


#include "config.h"

TTask TaskA,TaskB,TaskC;
TTimer TimerA ,TimerB ,TimerC ;

void TaskAProc(void)
{
        while(1)
        {
            PORTD^=_BV(7);   
            TMR_Delay(&TimerA,3);
        }
}

void TaskBProc(void)
{
        while(1)
        {
          PORTD^=_BV(6);  
             TMR_Delay(&TimerB,4);
        }
}

void TaskCProc(void)
{
        while(1)
        {
           PORTD^=_BV(5);         
              TMR_Delay(&TimerC,5);
        }
}

int main()
{

     DDRD=_BV(7)|_BV(6)|_BV(5);
     PORTD=_BV(7)|_BV(6)|_BV(5);
         
     TCNT2 = 0;
     TCCR2A=_BV(WGM21);
     TCCR2B = T2_CLK_DIV_128;
     OCR2A=OCR2A_INIT;
     TIFR2|=_BV(OCF2A);
     TIMSK2=_BV(OCIE2A);

#if STACK_DOUL==1                 //AVRIAR 双堆栈
     TSK_Init(&TaskA,TaskAProc,0,64,32);
     TSK_Init(&TaskB,TaskBProc,1,64,32);
     TSK_Init(&TaskC,TaskCProc,2,64,32);
#else                            //AVRGCC 单堆栈
    TSK_Init(&TaskA,TaskAProc,0,64+32);
    TSK_Init(&TaskB,TaskBProc,1,64+32);
    TSK_Init(&TaskC,TaskCProc,2,64+32);
#endif
           
    sei();
           
    TSK_Start();
           
    while(1)
    {   
            
    }
}

SIGNAL(TIMER2_COMPA_vect)
{     
      VT_TicksHander();
}

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

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

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2009-6-6 15:04:46 | 显示全部楼层
更新一下:
点击此处下载 ourdev_451643.rar(文件大小:129K) (原文件名:VoidTask.7z.rar)







顺便把以前写的TEvent,TEventTiny一并放上来。
点击此处下载 ourdev_451147.rar(文件大小:878K) (原文件名:TEvent20090606.7z.rar)
点击此处下载 ourdev_451148.rar(文件大小:1.12M) (原文件名:TEventTiny20090606.7z.rar)

出0入0汤圆

 楼主| 发表于 2009-6-9 17:39:28 | 显示全部楼层
更新一下:20090609
点击此处下载 ourdev_452201.rar(文件大小:135K) (原文件名:VoidTask.7z.rar)


#include "config.h"

TTask TaskA,TaskB,TaskC;

void TaskAProc(void)  
{
    sei();
    while(1)
   {
       PORTD^=_BV(7);   
       TSK_Delay(VT_TICKS_PER_SEC/2);   
   }
}

void TaskBProc(void)  
{
    sei();
    while(1)
   {  
       PORTD^=_BV(6);     
       TSK_Delay(VT_TICKS_PER_SEC/3);
   }
}

void TaskCProc(void)  
{
    sei();
    while(1)
    {
      PORTD^=_BV(5);        
      TSK_Delay(VT_TICKS_PER_SEC/4);   
    }
}

int main()
{
     DDRD=_BV(7)|_BV(6)|_BV(5);
     PORTD=_BV(7)|_BV(6)|_BV(5);
         
     TCNT2 = 0;
     TCCR2=_BV(WGM21) | T2_CLK_DIV_128;
     OCR2=OCR2_INIT;
     TIFR|=_BV(OCF2);
     TIMSK=_BV(OCIE2);

#if STACK_DOUL==1                 //AVRIAR 双堆栈
     TSK_Init(&TaskA,TaskAProc,0,64,32);
     TSK_Init(&TaskB,TaskBProc,1,64,32);
     TSK_Init(&TaskC,TaskCProc,2,64,32);
#else                            //AVRGCC 单堆栈
    TSK_Init(&TaskA,TaskAProc,0,64+32);
    TSK_Init(&TaskB,TaskBProc,1,64+32);
    TSK_Init(&TaskC,TaskCProc,2,64+32);
#endif
           
    sei();
           
    TSK_Start();
           
    while(1)
    {   
        while(VT_MainScheduler());
         SleepIdle();
        
    }
}

SIGNAL(TIMER2_COMP_vect)
{     
      VT_TicksHander();
}

出0入0汤圆

 楼主| 发表于 2009-6-10 11:25:20 | 显示全部楼层
更新一下:20090610
移植到IAR8051

IAR8051堆栈处理很麻烦,汇编也不会,硬着头皮移植过来的,不保证正确。
任务切换只保护了寄存器:R6,R7,V0-Vn,VB,PSW,EA,DPH,DPL,SP

mcu是CC1110,必须设置为Near,Large,XDATA stack reentrant,1 DPTR。



#include "config.h"

TTask TaskA,TaskB,TaskC;

void TaskAProc(void)  
{
  volatile float f1=1.0;     //测试浮点运算
    EA=1;
    while(1)
   {
       P0_7=!P0_7;
       f1+=0.1;
       TSK_Delay(VT_TICKS_PER_SEC/2);
   }
}

void TaskBProc(void)  
{
  volatile float f2=1.0;     //测试浮点运算
    EA=1;
    while(1)
   {
       P0_6=!P0_6;
       f2+=0.1;
       TSK_Delay(VT_TICKS_PER_SEC/3);   
   }
}

void TaskCProc(void)  
{
  volatile float f3=1.0;     //测试浮点运算
    EA=1;
    while(1)
   {
       f3+=0.1;
       TSK_Delay(VT_TICKS_PER_SEC/4);   
   }
}


int main()
{
    CLK_RC_TO_XOSC();
   
    P0DIR|=_BV(6)|_BV(7);

    TSK_Init(&TaskA,TaskAProc,0,100);
    TSK_Init(&TaskB,TaskBProc,1,100);
    TSK_Init(&TaskC,TaskCProc,2,100);
   
    TMR_TicksInit();
   
    EA=1;  
    TSK_Start();
     
   
    while(1)
    {   
       while(VT_MainScheduler());        
    }
}

ISR(T4_VECTOR)
{
    EA=0;
   
    T4OVFIF = 0;
    T4IF = 0;
     
    VT_TicksHander();
   
    EA=1;
}



点击此处下载 ourdev_452359.rar(文件大小:219K) (原文件名:VoidTask.7z.rar)

出0入0汤圆

发表于 2009-6-10 12:54:47 | 显示全部楼层
帮顶

出0入0汤圆

 楼主| 发表于 2009-6-12 13:08:36 | 显示全部楼层
更新一下:20090612

简化移植。
移植只需要重写两个函数CTX_Init和CTX_Swap(另外还有临界段)。



IAREWAVR:

#include "VT.h"

#if STACK_DOUL!=1
#error   "STACK_DOUL must be 1 in avriar"
#endif

//上下文初始化,IAR是双堆栈,GCC是单堆栈
void CTX_Init(TContext **ppContext,TTaskProc *TaskCode,void *Stack1,void *Stack2)
{
  ctx_sp_t *ctx_sp;
  ctx_y_t  *ctx_y;

  ctx_y=(ctx_y_t *)((char *)Stack1) - 1;
  ctx_sp=(ctx_sp_t *)Stack2 - 1;

  ctx_sp->_pcl = (uint16)TaskCode%256;
  ctx_sp->_pch = (uint16)TaskCode/256;
     
  ctx_y->_spl  = (uint16)ctx_sp%256;
  ctx_y->_sph  = (uint16)ctx_sp/256;
  
  //ctx_y->_sreg = 0x00;
  
  ctx_y->_r27 = 0x27;
  ctx_y->_r26 = 0x26;  
  ctx_y->_r25 = 0x25;
  ctx_y->_r24 = 0x24;  
  
  ctx_y->_r15 = 0x15;
  ctx_y->_r14 = 0x14;  
  ctx_y->_r13 = 0x13;
  ctx_y->_r12 = 0x12;  
  ctx_y->_r11 = 0x11;
  ctx_y->_r10 = 0x10;  
  ctx_y->_r9  = 0x9;
  ctx_y->_r8  = 0x8;  
  ctx_y->_r7  = 0x7;
  ctx_y->_r6  = 0x6;  
  ctx_y->_r5  = 0x5;
  ctx_y->_r4  = 0x4;  
  
  CRITICAL()
  {
    *ppContext=ctx_y;
  }
}

//寄存器分为 "草稿寄存器“和 "存储寄存器" --------个人叫法
//外部函数可以任意使用草稿寄存器而不必恢复,而使用存储寄存器必须先保护

//AVRIAR   
//草稿寄存器  R0-R3,R16-R23,R30-R31   
//存储寄存器  R4-15,R24-R27
//特殊寄存器  R28-R29

//AVRGCC   
//草稿寄存器  R18-R27,R30-R31   
//存储寄存器  R2-R17,R28-R29
//特殊寄存器  R0-R1

//上下文切换只保护存储寄存器寄存器,sp
#define SAVE_CONTEXT()             \
  do{                              \
  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,   R24   ");   \
  asm  ("ST      -Y,   R25   ");   \
  asm  ("ST      -Y,   R26   ");   \
  asm  ("ST      -Y,   R27   ");   \
  asm  ("in      R24,  0x3D  ");   \
  asm  ("ST      -Y,   R24   ");   \
  asm  ("IN      R24,  0x3E  ");   \
  asm  ("ST      -Y,   R24   ");   \
}while(0)

#define RESTORE_CONTEXT()          \
  do{                              \
  asm  ("LD      R24,  Y+    ");   \
  asm  ("OUT     0X3E, R24   ");   \
  asm  ("LD      R24,  Y+    ");   \
  asm  ("OUT     0X3D, R24   ");   \
  asm  ("LD      R27,  Y+    ");   \
  asm  ("LD      R26,  Y+    ");   \
  asm  ("LD      R25,  Y+    ");   \
  asm  ("LD      R24,  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+    ");   \
}while(0)

//                       R16:R17          R18:R19         
void CTX_Swap(TContext **ppContext1,TContext **ppContext2)
{
    SAVE_CONTEXT();
   
    asm ("movw    r30,r16");       //Z=ppContext1
    asm ("st      z+, r28");       //*ppContext1=Y
    asm ("st      z,  r29");
   
    asm ("movw    r30,r18");       //Z=ppContext2
    asm ("ld      r28, z+");       //Y=*ppContext2
    asm ("ld      r29, z");
     
    RESTORE_CONTEXT();
   
   asm ("ret");
}


点击此处下载 ourdev_452919.rar(文件大小:200K) (原文件名:VoidTask.7z.rar)

出0入0汤圆

 楼主| 发表于 2009-6-14 23:50:23 | 显示全部楼层
更新一下:20090614

移植到STM32,只能使用主堆栈,上下文切换只保护R4-11,LR。


#include "VT.h"
#include "hal_cpu.h"

void CTX_Init(TContext **ppContext,TTaskProc *TaskProc,void *Stack1)
{
  ctx_sp_t *ctx_sp;
  
  ctx_sp=(ctx_sp_t *)Stack1 - 1;    //调整上下文指针,预留空间保存上下文
  
  ctx_sp->_lr = ((uint32)TaskProc); //填充任务地址  

  ctx_sp->_r4 = 0x04;          //填充R4-R11
  ctx_sp->_r5 = 0X05;
  ctx_sp->_r6 = 0x06;
  ctx_sp->_r7 = 0x07;
  ctx_sp->_r8 = 0x08;
  ctx_sp->_r9 = 0x09;  
  ctx_sp->_r10 = 0x10;
  ctx_sp->_r11 = 0x11;
  
  CRITICAL()
  {
    *ppContext=(void *)ctx_sp;   //保存新的上下文指针
  }
}

//寄存器分为 "草稿寄存器“和 "存储寄存器" --------个人叫法
//外部函数可以任意使用草稿寄存器而不必恢复,而使用存储寄存器必须先保护

//Cortex-M3  
//草稿寄存器  R0-R3,R12
//存储寄存器  R4-11,
//特殊寄存器  SP,LR,PC

//上下文切换只保护存储寄存器寄存器,lr
#define SAVE_CONTEXT()             \
  do{                              \
    asm ("push {r4-r11,lr}");      \
}while(0)

#define RESTORE_CONTEXT()          \
  do{                              \
    asm ("pop {r4-r11,lr}");       \
}while(0)



//注意:CM3任务只能使用主堆栈!!!!!!

//void CTX_Swap(TContext **ppContext1,TContext **ppContext2)
//SAVE_CONTEXT
//*ppContext1=SP
//SP=*ppContext2
//RESTOR_CONTEXT
//return

//                     r0                       r1
void CTX_Swap(TContext **ppContext1,TContext **ppContext2)
{
  SAVE_CONTEXT();
  
  asm ("mov    r4,sp");         //*ppContext1=SP
  asm ("str    r4,[r0, #+0]");
  
  asm ("ldr    r4,[r1, #+0]");  //SP=*ppContext2
  asm ("mov    sp,r4");
  
  RESTORE_CONTEXT();
  
  asm ("bx    lr");
}


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

本版积分规则

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

GMT+8, 2024-5-20 11:22

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

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