打印
[STM32]

基于PendSV 双任务时间片切换

[复制链接]
578|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一路向北lm|  楼主 | 2020-9-30 16:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
// 定义任务 
um_task task1;      //任务1
um_task task2;      //任务2
um_task task_idle;  //空闲任务

// 定义任务堆栈
um_stack  task1_stack[1024];
um_stack  task2_stack[1024];
um_stack  task_idle_stack[1024];



um_task *CurrentTask,*NextTask;
um_task *TaskTable[3];


void task1_thread(void *param);
void task2_thread(void *param);
void TaskInit(um_task *task,void(*entry)(void*),void *param,unsigned int *task_tack);
void Um_TaskSched();
void ProductPendSV();


使用特权

评论回复

相关帖子

沙发
一路向北lm|  楼主 | 2020-9-30 16:59 | 只看该作者
// 任务调度
void Um_TaskSched()
{
  if(CurrentTask == TaskTable[2])
        {
            if(TaskTable[0]->DelayTicks == 0)
                                NextTask = TaskTable[0];
                        else if(TaskTable[1]->DelayTicks == 0)
                                NextTask = TaskTable[1];
                        else  return;
        }
        else
        {
            if(CurrentTask == TaskTable[0])
                        {
                                if(TaskTable[1]->DelayTicks == 0)
                                        NextTask = TaskTable[1];
                                else if(CurrentTask->DelayTicks != 0)
                                        NextTask = TaskTable[2];
                          
                        }
                        else if(CurrentTask == TaskTable[1])
                        {
                          if(TaskTable[0]->DelayTicks == 0)
                                        NextTask = TaskTable[0];
                                else if(CurrentTask->DelayTicks != 0)
                                        NextTask = TaskTable[2];
                        }
        }
                 
        ProductPendSV();
}


使用特权

评论回复
板凳
一路向北lm|  楼主 | 2020-9-30 16:59 | 只看该作者
// 设置Systick 中断定时
void SetSysTickPeriod(unsigned int ms)
{
         SysTick->LOAD = ms * SystemCoreClock/1000 -1;
         NVIC_SetPriority(SysTick_IRQn,(1<<__NVIC_PRIO_BITS)-1);
         SysTick->VAL = 0;
         SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;
       

}


使用特权

评论回复
地板
一路向北lm|  楼主 | 2020-9-30 17:01 | 只看该作者
// Systick 中断函数
void SysTick_Handler()
{
   int i;
   for(i=0;i<2;i++)
   {
      if(TaskTable[i]->DelayTicks >0)
                        {
                           TaskTable[i]->DelayTicks--;
                        }
   }       
         Um_TaskSched();
}


使用特权

评论回复
5
一路向北lm|  楼主 | 2020-9-30 17:02 | 只看该作者
// 任务延时函数
void TaskDelay(unsigned int delay)
{
  CurrentTask->DelayTicks = delay;
        Um_TaskSched();
}


使用特权

评论回复
6
一路向北lm|  楼主 | 2020-9-30 17:03 | 只看该作者
// 任务1 任务2 空闲任务 初始化任务
unsigned char flag1,flag2;
void task1_thread(void *param)
{
         SetSysTickPeriod(10);
        while(1)
        {
           flag1 = 1;
           TaskDelay(10);
           flag1 = 0;
           TaskDelay(10);                 
        }       
}
void task2_thread(void *param)
{
        while(1)
        {
           flag2 = 1;
           TaskDelay(10);
           flag2 = 0;
           TaskDelay(10);
        }       
}
void idel_thread(void *param)
{
       
        while(1)
        {
          
        }       
}

void FirstTask()
{
        __set_PSP(0);
  ProductPendSV();
}


使用特权

评论回复
7
一路向北lm|  楼主 | 2020-9-30 17:03 | 只看该作者
主函数

int main()
{

         
   TaskInit(&task1,task1_thread,(void*)1234,&task1_stack[1024]);
         TaskInit(&task2,task2_thread,(void*)5678,&task2_stack[1024]);
         TaskInit(&task_idle,idel_thread,(void*)0023,&task_idle_stack[1024]);
       
         TaskTable[0] = &task1;
         TaskTable[1] = &task2;
         TaskTable[2] = &task_idle;
       
         NextTask = TaskTable[0];
         FirstTask();
               
}


使用特权

评论回复
8
一路向北lm|  楼主 | 2020-9-30 17:03 | 只看该作者
//任务初始化函数
void TaskInit(um_task *task,void(*entry)(void*),void *param,um_stack *task_tack)
{
   *(--task_tack) = (unsigned long)(1<<24);
         *(--task_tack) = (unsigned long)entry;   //pc寄存器
         *(--task_tack) = (unsigned long)0x14;
         *(--task_tack) = (unsigned long)0x12;
         *(--task_tack) = (unsigned long)0x3;
         *(--task_tack) = (unsigned long)0x2;
         *(--task_tack) = (unsigned long)0x1;
         *(--task_tack) = (unsigned long)param;
       
         *(--task_tack) = (unsigned long)0x11;
         *(--task_tack) = (unsigned long)0x10;
         *(--task_tack) = (unsigned long)0x9;
         *(--task_tack) = (unsigned long)0x8;
         *(--task_tack) = (unsigned long)0x7;
         *(--task_tack) = (unsigned long)0x6;
         *(--task_tack) = (unsigned long)0x5;
         *(--task_tack) = (unsigned long)0x4;
         task->stack_addr = task_tack;
         task->DelayTicks = 0;
}

使用特权

评论回复
9
一路向北lm|  楼主 | 2020-9-30 17:03 | 只看该作者
// 进入临界区保护
unsigned int TaskEnterCritical()
{
  unsigned int primask;
       
        primask = __get_PRIMASK();
        __disable_irq();
        return primask;
}

// 退出临界区保护
void TaskExitCritical(unsigned int status)
{
   __set_PRIMASK(status);
}

使用特权

评论回复
10
一路向北lm|  楼主 | 2020-9-30 17:04 | 只看该作者
// PendSV异常
void ProductPendSV()
{
   *(volatile unsigned long *)NVIC_SYSPRI2 = NVIC_PENDSV_PRI;
   *(volatile unsigned long *)NVIC_INT_CTRL = NVIC_PENDSV_SET;
}       

// PendSV中断处理函数
__asm__ void PendSV_Handler(void)
{
                   
         IMPORT CurrentTask
         IMPORT NextTask
         MRS R0, PSP                   //将PSP寄存器保存到R0中
         CBZ R0,PendSVHander_nosave    //判断PSP寄存器的值是否为0 从而判断是否是
                                       //FirstTask任务触发还是umTaskSwitch()触发
         STMDB R0!,{R4-R11}
         LDR R1, = CurrentTask
         LDR R1,[R1]
         STR R0,[R1]

PendSVHander_nosave
   LDR R0, = CurrentTask     //完成了nextTask向currentTask赋值操作
   LDR R1, = NextTask
   LDR R2,[R1]   
   STR R2,[R0]        
   LDR R0,[R2]              //从currentTask取出堆栈的地址
   LDMIA R0!,{R4-R11}       //批量加载R4-R11寄存器
   MSR PSP,R0        
   ORR LR,LR,#0x04
   BX  LR         
       
}

使用特权

评论回复
11
QuakeGod| | 2020-10-3 12:38 | 只看该作者
不错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

275

主题

3784

帖子

76

粉丝