tick一般是作为任务延迟调度的内部机制,其接口主要是系统内部使用。但是对于使用OS的应用软件有时也需要定时触发相关功能的接口,包括单次定时器和周期定时器。从用户层面来讲,不需要关注底层cpu的定时机制以及tick的调度,用户希望的定时器接口是可以创建和使能一个软件接口定时器,时间到了之后,用户的hook函数能被执行。而对于操作系统的定时器本身来讲,其也需要屏蔽底层定时模块的差异。因此,在软件层次上,对于定时器硬件相关的操作由tick模块完成,定时器(timer)模块基于tick作为最基本的时间调度单元,即最小时间周期,来推动自己时间轴的运行。 AliOS Things提供基本的软件定时器功能,包括定时器的创建、删除、启动,以及单次和周期定时器。
API 列表
aos_timer_new() | 创建软件定时器 |
aos_timer_new_ext() | 创建软件定时器 |
aos_timer_start() | 启动软件定时器 |
aos_timer_stop() | 停止软件定时器 |
aos_timer_change() | 修改软件定时器的定时参数 |
aos_timer_free() | 删除软件定时器 |
使用
添加该组件
软件定时器是AliOS Things 默认添加的组件,开发者无需再手动添加。
包含头文件
#include <aos/kernel.h>
使用示例
创建自动运行的周期执行定时器
aos_timer_t g_timer;
int ret = -1;
...
static void timer_handler(void *arg1, void* arg2)
{
printf("timer handler\r\n");
...
}
/*创建定时周期为200ms的周期执行的定时器,并自动运行*/
ret = aos_timer_new(&g_timer, timer_handler, NULL, 200, 1);
if (ret != 0) {
printf("timer create failed\r\n");
...
}
....
/*停止定时器*/
aos_timer_stop(&g_timer);
....
/*启动定时器*/
aos_timer_start(&g_timer);
....
/*停止定时器*/
aos_timer_stop(&g_timer);
/*释放定时器*/
aos_timer_free(&g_timer);
....
创建不自动运行的周期执行定时器,并在使用中改变定时周期。
aos_timer_t g_timer;
int ret = -1;
...
static void timer_handler(void *arg1, void* arg2)
{
printf("timer handler\r\n");
...
}
/*创建定时周期为200ms的周期执行的定时器,不自动运行*/
ret = aos_timer_new_ext(&g_timer, timer_handler, NULL, 200, 0, 0);
if (ret != 0) {
printf("timer create failed\r\n");
...
}
....
/*需要手动启动定时器*/
aos_timer_start(&g_timer);
....
/*停止定时器*/
aos_timer_stop(&g_timer);
....
/*改变定时周期为1000ms, 注意:需要在定时器未启动状态是才能修改*/
aos_timer_change(&g_timer, 1000);
/*启动定时器*/
aos_timer_start(&g_timer);
....
/*停止定时器*/
aos_timer_stop(&g_timer);
/*释放定时器*/
aos_timer_free(&g_timer);
....
API详情
定时器的应用层API说明请参考include/aos/kernel.h
aos_timer_new()
创建一个软件定时器,创建后自动运行。
函数原型
int aos_timer_new(aos_timer_t *timer,void (*fn)(void *, void *),void *arg, int ms, int repeat);
输入参数
timer |
软件定时器句柄 | |
fn |
定时到期处理函数 | |
arg |
定时到期处理函数的参数 | |
ms |
定时器超时时间(单位ms),即间隔多少时间执行fn | 1000 |
repeat |
周期定时或单次定时(1:周期,0:单次) | 1 |
返回参数
0表示成功,其他值表示失败。具体的返回值见本文档返回参数定义小节。
调用示例
static void timer_handler(void *arg1, void* arg2)
{
/* 定时到期处理函数内不应调用能引起阻塞的函数 */
……
}
int ret = -1;
ret = aos_timer_new(&g_timer, timer_handler, NULL, 200, 1);
aos_timer_new_ext()
创建一个软件定时器,可通过入参决定创建后是否自动运行。
函数原型
int aos_timer_new_ext(aos_timer_t *timer, void (*fn)(void *, void *),void *arg, int ms, int repeat, unsigned char auto_run);
输入参数
timer |
软件定时器句柄 | |
fn |
定时到期处理函数 | |
arg |
定时到期处理函数的参数 | |
ms |
定时器超时时间(单位ms),即间隔多少时间执行fn | 1000 |
repeat |
周期定时或单次定时(1:周期,0:单次) | 1 |
auto_run |
1表示自动运行,0表示不自动运行,需要手动调用aos_timer_start才能启动 | 0 |
返回参数
0表示成功,其他值表示失败。具体的返回值见本文档返回参数定义小节。
调用示例
static void timer_handler(void *arg1, void* arg2)
{
/* 定时到期处理函数内不应调用能引起阻塞的函数 */
……
}
int ret = -1;
ret = aos_timer_new_ext(&g_timer, timer_handler, NULL, 200, 1, 0);
aos_timer_stop()
停止软件定时器。
函数原型
int aos_timer_stop(aos_timer_t *timer);
输入参数
timer |
软件定时器句柄 |
返回参数
0表示成功,其他值表示失败。具体的返回值见本文档返回参数定义小节。
调用示例
int ret = -1;
ret = aos_timer_new(&g_timer, timer_handler, NULL, 200, 1);
……
/*停止定时器*/
aos_timer_stop(&g_timer);
aos_timer_free()
删除软件定时器。删除定时器前需调用aos_timer_stop停止定时器。
函数原型
void aos_timer_free(aos_timer_t *timer);
输入参数
timer |
软件定时器句柄 |
返回参数
无
调用示例
int ret = -1;
ret = aos_timer_new(&g_timer, timer_handler, NULL, 200, 1);
……
/*停止定时器*/
aos_timer_stop(&g_timer);
aos_timer_free(&g_timer);
aos_timer_start()
启动软件定时器。
函数原型
int aos_timer_start(aos_timer_t *timer);
输入参数
timer |
软件定时器句柄 |
返回参数
0表示成功,其他值表示失败。具体的返回值见本文档返回参数定义小节。
调用示例
int ret = -1;
ret = aos_timer_new_ext(&g_timer, timer_handler, NULL, 200, 1, 0);
aos_timer_start(&g_timer);
aos_timer_change()
修改软件定时器的定时参数。调用该函数前需先调用aos_timer_stop停止定时器。
函数原型
int aos_timer_change(aos_timer_t *timer, int ms);
输入参数
timer |
软件定时器句柄 | |
ms |
新的定时器超时时间(单位ms),即间隔多少时间执行定时器到期处理函数 | 1000 |
返回参数
0表示成功,其他值表示失败。具体的返回值见本文档返回参数定义小节。
调用示例
int ret = -1;
ret = aos_timer_new(&g_timer, timer_handler, NULL, 200, 1);
……
/*停止定时器*/
aos_timer_stop(&g_timer);
aos_timer_change(&g_timer, 1000);
aos_timer_start(&g_timer);
其他
返回参数定义
返回值定义在core/rhino/include/k_err.h文件中。该文件为内部文件,出错时可根据返回值查阅该文件确认出错原因。
typedef enum
{
RHINO_SUCCESS = 0u,
RHINO_SYS_FATAL_ERR,
RHINO_SYS_SP_ERR,
RHINO_RUNNING,
RHINO_STOPPED,
RHINO_INV_PARAM,
RHINO_NULL_PTR,
RHINO_INV_ALIGN,
RHINO_KOBJ_TYPE_ERR,
RHINO_KOBJ_DEL_ERR,
RHINO_KOBJ_DOCKER_EXIST,
RHINO_KOBJ_BLK,
RHINO_KOBJ_SET_FULL,
RHINO_NOTIFY_FUNC_EXIST,
RHINO_MM_POOL_SIZE_ERR = 100u,
RHINO_MM_ALLOC_SIZE_ERR,
RHINO_MM_FREE_ADDR_ERR,
RHINO_MM_CORRUPT_ERR,
RHINO_DYN_MEM_PROC_ERR,
RHINO_NO_MEM,
RHINO_RINGBUF_FULL,
RHINO_RINGBUF_EMPTY,
RHINO_SCHED_DISABLE = 200u,
RHINO_SCHED_ALREADY_ENABLED,
RHINO_SCHED_LOCK_COUNT_OVF,
RHINO_INV_SCHED_WAY,
RHINO_TASK_INV_STACK_SIZE = 300u,
RHINO_TASK_NOT_SUSPENDED,
RHINO_TASK_DEL_NOT_ALLOWED,
RHINO_TASK_SUSPEND_NOT_ALLOWED,
RHINO_TASK_CANCELED,
RHINO_SUSPENDED_COUNT_OVF,
RHINO_BEYOND_MAX_PRI,
RHINO_PRI_CHG_NOT_ALLOWED,
RHINO_INV_TASK_STATE,
RHINO_IDLE_TASK_EXIST,
RHINO_NO_PEND_WAIT = 400u,
RHINO_BLK_ABORT,
RHINO_BLK_TIMEOUT,
RHINO_BLK_DEL,
RHINO_BLK_INV_STATE,
RHINO_BLK_POOL_SIZE_ERR,
RHINO_TIMER_STATE_INV = 500u,
RHINO_NO_THIS_EVENT_OPT = 600u,
RHINO_BUF_QUEUE_INV_SIZE = 700u,
RHINO_BUF_QUEUE_SIZE_ZERO,
RHINO_BUF_QUEUE_FULL,
RHINO_BUF_QUEUE_MSG_SIZE_OVERFLOW,
RHINO_QUEUE_FULL,
RHINO_QUEUE_NOT_FULL,
RHINO_SEM_OVF = 800u,
RHINO_SEM_TASK_WAITING,
RHINO_MUTEX_NOT_RELEASED_BY_OWNER = 900u,
RHINO_MUTEX_OWNER_NESTED,
RHINO_MUTEX_NESTED_OVF,
RHINO_NOT_CALLED_BY_INTRPT = 1000u,
RHINO_TRY_AGAIN,
RHINO_WORKQUEUE_EXIST = 1100u,
RHINO_WORKQUEUE_NOT_EXIST,
RHINO_WORKQUEUE_WORK_EXIST,
RHINO_WORKQUEUE_BUSY,
RHINO_WORKQUEUE_WORK_RUNNING,
RHINO_TASK_STACK_OVF = 1200u,
RHINO_INTRPT_STACK_OVF,
RHINO_STATE_ALIGN = INT_MAX /* keep enum 4 bytes at 32bit machine */
} kstat_t;
在文档使用中是否遇到以下问题
更多建议
匿名提交