实现简单的多任务轮询(C语言)

您所在的位置:网站首页 操作系统进程调度c语言代码怎么写 实现简单的多任务轮询(C语言)

实现简单的多任务轮询(C语言)

#实现简单的多任务轮询(C语言)| 来源: 网络整理| 查看: 265

实现简单的多任务轮询(C语言) 前言总体思路实现过程调用示例完整代码

前言

好久没有做MCU的项目了,最近因为工作需要接手一个STM32的项目,因为项目要求比较简单,也就没有用到操作系统,而是用了简单的状态机+任务轮询的方式。闲暇之余写下这篇简短的博客,记录一下自己的所知所想,也希望对那些刚进入MCU的新手们,能有些许的帮助。

总体思路

利用状态机的方式,在一个循环中不停的去判断每一个任务的执行标识,当判断标识为真时,则执行响应的任务,任务执行结束后及时的清除任务标识。

实现过程

先定义一个任务的结构体,结构体中包含任务的执行函数和是否需要执行的标识。

typedef struct __TASK{ int (*func)(void *); //任务执行的函数,执行时会传入下面的参数 void *arg; //任务执行时带入的参数 int flag; } task_t;

在定义一个任务组用于管理这些需要被轮询的任务:

typedef struct __TASK_GRP{ task_t *task_list; //需要执行任务集合 int list_size; //list的大小 }taskGrp_t;

下面定义两个宏用于定义和初始化一个任务列表和任务组。注意下面的方法在有些编译器中不支持,目前我知道的就是在keil下的C89就不支持这种方式。

#define TASK_LIST_INIT(name,size) task_t name[size]={0}; #define TASK_GPR_INIT(name,list,size) \ struct __TASK_GRP name={ \ .task_list = list, \ .list_size = size, \ };

有些人看到这个肯定有点懵!其实上面的方式就是利用在定义变量时对变量进行初始化,然后再用宏把这个过程包装起来就行,在使用的时候只需要调用宏并传入响应的参数就行。例如:TASK_GPR_INIT(task_group,task_list,TASK_SIZE); 等价于 struct __TASK_GRP task_group={ .task_list = task_list, .list_size = TASK_SIZE, }; 然后定义几个函数用于对任务组和任务进行操作:

初始化一个任务组,目的和上面提高的两个初始化相同。两种方式调用哪个都可以。

void task_grop_init(taskGrp_t *grp,task_t *list,int size) { grp->task_list = list; grp->list_size = size; memset(list,0,sizeof(task_t)*size); }

将要执行的操作函数添加到任务组中相应的任务中。flag标识用于是否默认激活任务。

void task_add_to_list(taskGrp_t *grp,int index,int (*func)(void *),void *arg,int flag) { grp->task_list[index].func = func; grp->task_list[index].arg = arg; grp->task_list[index].flag = flag; }

激活索引为index的任务,让其能参与轮询。

void activate_task(taskGrp_t *grp,int index) { grp->task_list[index].flag = 1; }

开始任务轮询操作,里面是一个大循环,会一直查找任务状态并执行相应任务。当判断到任务的返回值为1时则认为任务一次执行完成,将关闭任务,只有等待下一次重新激活后,才重新执行相应任务。

void start_polling(struct __TASK_GRP *grp) { int i=0; if(grp->task_list != NULL){ while(1){ for(i=0;ilist_size;i++){ if((grp->task_list[i].flag)&&(grp->task_list[i].func != NULL)){ grp->task_list[i].flag = grp->task_list[i].func(grp->task_list[i].arg) ? 0 : 1; }else{ grp->task_list[i].flag = 0; } } } } } 调用示例 enum{ TASK_1, TASK_2, TASK_3, TASK_SIZE }TASK_INDEX; TASK_LIST_INIT(task_list,TASK_SIZE); TASK_GPR_INIT(task_group,task_list,TASK_SIZE); int task1_func(void *arg) { int retval=0; static int step=0; switch(step){ case 0: printf("%s step %d\n",__func__,step); step=1; break; case 1: printf("%s step %d\n",__func__,step); step=2; break; case 2: printf("%s step %d\n",__func__,step); step=0; retval=1; break; } return retval; } int task2_func(void *arg) { int retval=0; static int step=0; switch(step){ case 0: printf("%s step %d\n",__func__,step); step=1; break; case 1: printf("%s step %d\n",__func__,step); step=2; break; case 2: printf("%s step %d\n",__func__,step); step=0; retval=1; break; } return retval; } int task3_func(void *arg) { int retval=0; static int step=0; switch(step){ case 0: printf("%s step %d\n",__func__,step); step=1; break; case 1: printf("%s step %d\n",__func__,step); step=2; break; case 2: printf("%s step %d\n",__func__,step); step=0; retval=1; break; } return retval; } int main(void) { task_add_to_list(&task_group,TASK_1,task1_func,NULL,1); task_add_to_list(&task_group,TASK_2,task2_func,NULL,1); task_add_to_list(&task_group,TASK_3,task3_func,NULL,1); start_polling(&task_group); } 完整代码

task.h

#ifndef __TASK_H__ #define __TASK_H__ #define TASK_LIST_INIT(name,size) task_t name[size]={0}; #define TASK_GPR_INIT(name,list,size) \ struct __TASK_GRP name={ \ .task_list = list, \ .list_size = size, \ }; typedef struct __TASK{ int (*func)(void *); void *arg; //任务执行时带入的参数 int flag; } task_t; typedef struct __TASK_GRP{ task_t *task_list; //需要执行任务表 int list_size; //list的大小 }taskGrp_t; extern void task_grop_init(taskGrp_t *grp,task_t *list,int size); extern void task_add_to_list(taskGrp_t *grp,int index,int (*func)(void *),void *arg,int flag); extern void activate_task(taskGrp_t *grp,int index); extern void start_polling(struct __TASK_GRP *grp); #endif /* __TASK_H__ */

task.c

#include #include "task.h" void task_grop_init(taskGrp_t *grp,task_t *list,int size) { grp->task_list = list; grp->list_size = size; memset(list,0,sizeof(task_t)*size); } void task_add_to_list(taskGrp_t *grp,int index,int (*func)(void *),void *arg,int flag) { grp->task_list[index].func = func; grp->task_list[index].arg = arg; grp->task_list[index].flag = flag; } void activate_task(taskGrp_t *grp,int index) { grp->task_list[index].flag = 1; } void start_polling(struct __TASK_GRP *grp) { int i=0; if(grp->task_list != NULL){ while(1){ for(i=0;ilist_size;i++){ if((grp->task_list[i].flag)&&(grp->task_list[i].func != NULL)){ grp->task_list[i].flag = grp->task_list[i].func(grp->task_list[i].arg) ? 0 : 1; }else{ grp->task_list[i].flag = 0; } } } } }

main.c

#include #include "task.h" enum{ TASK_1, TASK_2, TASK_3, TASK_SIZE }TASK_INDEX; TASK_LIST_INIT(task_list,TASK_SIZE); TASK_GPR_INIT(task_group,task_list,TASK_SIZE); int task1_func(void *arg) { int retval=0; static int step=0; switch(step){ case 0: printf("%s step %d\n",__func__,step); step=1; break; case 1: printf("%s step %d\n",__func__,step); step=2; break; case 2: printf("%s step %d\n",__func__,step); step=0; retval=1; break; } return retval; } int task2_func(void *arg) { int retval=0; static int step=0; switch(step){ case 0: printf("%s step %d\n",__func__,step); step=1; break; case 1: printf("%s step %d\n",__func__,step); step=2; break; case 2: printf("%s step %d\n",__func__,step); step=0; retval=1; break; } return retval; } int task3_func(void *arg) { int retval=0; static int step=0; switch(step){ case 0: printf("%s step %d\n",__func__,step); step=1; break; case 1: printf("%s step %d\n",__func__,step); step=2; break; case 2: printf("%s step %d\n",__func__,step); step=0; retval=1; break; } return retval; } int main(void) { task_add_to_list(&task_group,TASK_1,task1_func,NULL,1); task_add_to_list(&task_group,TASK_2,task2_func,NULL,1); task_add_to_list(&task_group,TASK_3,task3_func,NULL,1); start_polling(&task_group); }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3