Tasks任务系统介绍

  littleVGL 自带了一个任务管理系统,此任务系统除了给 littleVGL 内部使用外,还开放出来给我们用户使用,这给我们的应用程序设计带来了极大的便利,它支持6个任务优先级,高优先级的任务可以抢占低优先级的任务,注意,此任务管理系统是非实时的,因为任务的时效性是取决于 lv_task_handler()函数的调用,而 lv_task_handler()函数一般放在 main 函数主循环中进行调用,所以你也要确保 main 函数主循环中不能有其他过大的延时存在,满足上述要求之后,对于一般的应用来说,此任务系统的时效性误差可以忽略不计.对于我们用户而言,littleVGL 的任务管理系统主要是由 3 个数据类型和 13 个 API 接口组成的,下面我们来详细介绍。

1.主要数据类型

1.1 任务回调函数数据类型
申明去定义一种函数指针数据类型,此数据类型就是用来约束任务回调函数的申明,保证我们写的任务回调函数只能有一个 struct _lv_task_t *形参和返回值必须是 void 的。

typedef void (*lv_task_cb_t)(struct _lv_task_t *);

1.2 任务优先级数据类型

enum {
LV_TASK_PRIO_OFF = 0,
LV_TASK_PRIO_LOWEST,
LV_TASK_PRIO_LOW,
LV_TASK_PRIO_MID,
LV_TASK_PRIO_HIGH,
LV_TASK_PRIO_HIGHEST,
_LV_TASK_PRIO_NUM,
};
typedef uint8_t lv_task_prio_t;

  任务优先级数据类型的本质就是一个 enum 枚举体,这很简单,总共具有LV_TASK_PRIO_OFF 到 LV_TASK_PRIO_HIGHEST 之间的 6 个优先级,这里需要注意,_LV_TASK_PRIO_NUM(值为 6)对于我们来说没有实际意义,它是归 littleVGL 任务管理内部使用的,用来记录总共有 6 个优先级,然后还可以用作优先级形参的合法性判断。

1.3 任务管理句柄数据类型

typedef struct _lv_task_t
{
uint32_t period; //任务的回调周期
uint32_t last_run; //最近一次的运行时间点
lv_task_cb_t task_cb; //任务回调函数
void * user_data; //用户自定义数据
uint8_t prio : 3; //任务的优先级,占 3 位
uint8_t once : 1; //记录此任务是否只运行一次
} lv_task_t;

2.API接口

2.1 核心初始化

void lv_task_core_init(void);

  想要使用 littleVGL 的任务管理系统,就必须得调用lv_task_core_init 进行初始化一下,但是好处在于不需要我们自己去手动调用了,littleVGL 内部已经帮我们完成了初始化调用,如下图所示:
在这里插入图片描述  在 lv_init 函数中可以看到 lv_task_core_init 函数的调用,而我们又在 main 函数中调用了lv_init 函数,所以我们完全可以不用去理会 lv_task_core_init 这个 API 接口。

2.2 事务处理器

LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void);

  LV_ATTRIBUTE_TASK_HANDLER 是在 lv_conf.h 配置文件中定义的一个宏,默认情况下是为空的,不用理会,lv_task_handler 这个 API 接口是非常重要的,littleVGL 内部的所有事务都是通过这个接口来处理的,所以我称它为事务处理器,它需要不断的被周期性调用,我们通常把它放到 main 函数的主循环中去。

2.3 创建最基本的任务

lv_task_t * lv_task_create_basic(void);

  这个函数是用来创建最基本的任务对象,创建完成之后,还需要通过其他的 API 接口来设置其属性,这个 API 接口归 littleVGL 内部使用。

2.4 创建任务

lv_task_t * lv_task_create(lv_task_cb_t task_xcb, uint32_t period, lv_task_prio_t prio, void *user_data);

  我们创建任务一般都是通过这个API接口来进行的,可以一步到位,其实 lv_task_create 的实现原理是先通过调用 lv_task_create_basic 来创建最基本的任务,然后再通过其他的 API 接口来对其进行属性设置。

2.5 删除任务

void lv_task_del(lv_task_t * task);

2.6 设置任务回调函数

void lv_task_set_cb(lv_task_t * task, lv_task_cb_t task_cb);

2.7 设置任务优先级

void lv_task_set_prio(lv_task_t * task, lv_task_prio_t prio);

2.8 设置任务回调周期

void lv_task_set_period(lv_task_t * task, uint32_t period);

2.9 使任务立即准备就绪

void lv_task_ready(lv_task_t * task);

  通过调用此 API 接口,我们可以使刚创建出来的任务立即处于就绪状态,然后在下一个lv_task_handler 调用时,使任务回调函数立即得到运行,而不用去等它的第一个运行周期,注意了这里说的是第一个周期不用等了,但是后面的周期还是要等的。

2.10 使任务回调函数只运行一次

void lv_task_once(lv_task_t * task);

  通过调用此 API 接口,我们可以让任务的回调函数只运行一次,而非周期性调用,在一次调用完成之后,littleVGL 内部会通过 lv_task_del 接口来自动删除此任务的。

2.11 复位任务

void lv_task_reset(lv_task_t * task);

2.12 是否使能任务管理系统

void lv_task_enable(bool en);

  按理来说,任务管理系统是必须得使能的,否则 littleVGL 的内部事务将会失效,比如界面就不会刷新了,控件的点击事件也会失效,所以千万不要使用这个 API 接口,除非你有特殊的需求。

2.13 获取任务的空闲百分比

uint8_t lv_task_get_idle(void);

  注意这个空闲百分比仅仅只能代表 littleVGL 任务管理系统的一个空闲情况,并不能代表我们整个应用的空闲情况。

Logo

快速构建 Web 应用程序

更多推荐