实现单片机简单的时间片轮询调度

时间片轮询调度

1.创建一个结构体链表

typedef struct taskMember
{
    pfuntion taskName;
    volatile uint32_t tick;
    uint32_t taskID;
    uint32_t taskStatus;
    struct taskMember *listNext;
}task_t;

2.声明一个链表头。

static task_t taskListHead;
task_t *currentTask = 0;

3.任务创建,每个任务都对应唯一id号码

uint32_t createTask(pfuntion taskName,uint32_t taskID)
{
    task_t *listHead = &taskListHead;
    task_t *temp = 0;
    uint32_t ret = 1;
       
    temp = (task_t *)malloc(sizeof(task_t));
    if(temp == 0)
    {
        free(temp);
        return 0;
    }
    
    temp->taskName = taskName;
    temp->taskStatus = 0;
    temp->taskID = taskID;
    temp->listNext = 0;
    while(listHead->listNext != 0)
    {
        listHead = listHead->listNext;
        if(listHead->taskID == taskID) 
        {
            ret = 0;
            free(temp);
            break; 
        }
    }
    if(ret == 1)
    {
        listHead->listNext = temp;
    }
    
    return ret;
}

4.任务调度,在中断定时器中调用,一般1ms一次

void taskScheduler(void)
{
    task_t *listHead = &taskListHead;
    
    while(listHead->listNext != 0)
    {
        listHead = listHead->listNext;
        if(listHead->tick > 0)
        {
            listHead->tick--;
        }   
    }
}

5.任务延时

void taskDelayMs(uint32_t tick)
{
    currentTask->tick = tick;
}

6.任务开始,在主循环调用

void taskRuning(void)
{
    task_t *listHead = taskListHead.listNext;
    
    while(1)
    {   
        if(listHead->tick == 0 && listHead->taskStatus == 0)
        {
            currentTask = listHead;
            listHead->taskName();
            if(listHead->tick < 1)
            {
                listHead->tick = 1;
            }
        }
        if(listHead->listNext != 0)
        {
            listHead = listHead->listNext;
        }
        else
        {
            listHead = taskListHead.listNext;
        }    
    }

}

7.任务挂起和恢复

void taskDelete(uint32_t taskID)
{
    task_t *listHead = &taskListHead;
    task_t *last = &taskListHead;
    
    while(listHead-> listNext != 0)
    {
        listHead = listHead->listNext; 
        if(listHead->taskID == taskID)
        {
            last->listNext = listHead->listNext;
            free(listHead);
            break;
        }
        else
        {
            last = listHead;
        }   
    } 
}


task_t * searchList(task_t * head,uint32_t taskID)
{
    task_t * temp = head;
    
    while(temp->listNext != 0)
    {
        temp = temp->listNext;
        if(temp->taskID == taskID)
        {
            break;
        }
    }
    return  currentTask;
}
//任务挂起
void taskPending(uint32_t taskID)
{
     task_t *temp = searchList(&taskListHead,taskID);
     if(temp != 0)
     {
         temp->taskStatus = 1;
     }   
}

//任务恢复
void taskResume(uint32_t taskID)
{
     task_t *temp = searchList( &taskListHead,taskID);
     if(temp != 0)
     {
         temp->taskStatus = 0;
         temp->tick = 0;
     }
}

这是一个简单的任务轮询调度,可以创建无数个,方便简单。

/****************************使用例子**********************/
void ledtask(void)//led间隔500ms翻转一次
{
	taskDelayMs(500);
	GPIO_LED = ~ GPIO_LED ;
}


int main(void)
{
	bsp_init();
	createTask(ledtask,1);
	taskRuning();
}

你可能感兴趣的:(单片机,stm32,51单片机,mcu)