本文基于协议栈1.3.2阐述,请尊重原创
总论:
OSAL提供一种可以带回调函数功能的定时器,它的实现主要在Osal_ctimer.c与Osal_cbtimer.h两个文件中。回调定时器的是在OSAL的软件定时器基础上注册一个回调函数,当定时器时间到的时候,会执行事先注册的回调函数。相比与事件定时器的比较是:回调定时器用一个任务来处理所有回调定时器的相关事件,每个任务可以处理15个回调定时器的事件,事件标志events 的bit0 ~ bit14 是回调定时器的事件标志位,bit15是 SYS_EVENT_MSG 系统消息事件,不能用于回调定时器;当然你可以定义连续两个任务处理回调定时器的相关事件,那么可以处理多大30的回调定时器事件。
如图是一个任务用于处理回调定时器事件的实例。bit0 ~bit14是回调定时器对应的事件id,每一位是一个回调定时器的事件
技术细节解析
1、定义回调定时器的结构体
回调定时器的结构非常简单,只需要两个元素:一个是指向回调函数的函数指针;另一个则是要传递给回调函数的参数。如下:
// Callback Timer structure
typedef struct
{
pfnCbTimer_t pfnCbTimer; // callback function to be called when timer expires
uint8 *pData; // data to be passed in to callback function
} cbTimer_t;
pfnCbTimer_t是定义的函数指针类型,带有一个参数,在定时器定时时间到了的时候会执行这个指针指向的函数:
typedef void (*pfnCbTimer_t)( uint8 *pData );
//几个常量宏的定义
//每个任务可有的最多的回调定时器
#define NUM_CBTIMERS_PER_TASK 15
//总的回调定时器个数
#define NUM_CBTIMERS ( OSAL_CBTIMER_NUM_TASKS * NUM_CBTIMERS_PER_TASK )
//其中OSAL_CBTIMER_NUM_TASKS是在预编译选项里面设定的,默认设为OSAL_CBTIMER_NUM_TASKS=1
// Find out event id using timer id
//根据定时器ID寻找事件ID,每个处理回调函数的任务可以处理15个回调事件。每个任务的15个回调定时器对应事件id的 bit0 ~ bit14 位,bit15对应SYS_EVENT_MSG系统消息事件,不能用于回调定时器用途,刚好这里取余把15给去掉了,所以遍历的时候不会遍历到定时器id为15的。
#define EVENT_ID( timerId ) ( 0x0001 << ( ( timerId ) % NUM_CBTIMERS_PER_TASK ) )
// Find out task id using timer id
//根据定时器ID查找任务ID,注意下面用的是整除,上面宏用的是取余数。
#define TASK_ID( timerId ) ( ( ( timerI