打印
[技术问答]

单片机简单的时间片轮询

[复制链接]
84|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
modesty3jonah|  楼主 | 2024-9-27 15:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
时间片轮询调度
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翻转一次
{

使用特权

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

本版积分规则

22

主题

1383

帖子

2

粉丝