首页 资讯 应用 高压 设计 行业 低压 电路图 关于

嵌入式

旗下栏目: PLC 嵌入式 单片机 光电技术

OSAL之回调定时器分析

嵌入式 | 发布时间:2017-10-04 | 人气: | #评论# |本文关键字:OSAL,定时器
摘要:OSAL 的提供一种可以带回调函数功能的定时器,它的实现主要在 Osal_ctimer.c 与 Osal_cbtimer.h 两个文件中。回调定时器的是在 OSAL 的定时器基础上注册一个回调函数,当定时器时间到的时候

OSAL的提供一种可以带回调函数功能的定时器,它的实现主要在Osal_ctimer.cOsal_cbtimer.h两个文件中。回调定时器的是在OSAL的定时器基础上注册一个回调函数,当定时器时间到的时候,会执行事先注册的回调函数。

1、定义回调定时器的结构体

回调定时器的结构非常简单,只需要两个元素:一个是指向回调函数的函数指针;另一个则是要传递给回调函数的参数。如下:

typedef struct{  pfnCbTimer_t pfnCbTimer;   uint8 *pData;            } cbTimer_t;

其中pfnCbTimer_t类型是自定义的函数指针类型,它带一个参数,如下:

typedef void (*pfnCbTimer_t)( uint8 *pData );

2、几个常量的定义

(1)每个任务最多可以拥有的回调定时器的个数:

#define NUM_CBTIMERS_PER_TASK    15

(2)回调定时器的总数:

#define NUM_CBTIMERS (OSAL_CBTIMER_NUM_TASKS*NUM_CBTIMERS_PER_TASK )

回调定时器的总数与跟系统定义的专门处理回调定时器事件的任务个数有关,也就是上面的OSAL_CBTIMER_NUM_TASKS,这个变量在IAR编译器的预编译宏定义区中定义:OSAL_CBTIMER_NUM_TASKS = 1;在官方的BLE工程中默认都定义成1。所以此时回调定时器的总数量为1*15=15个回调定时器。

3、几个宏定义

(1)根据定时器ID(timer id)查找事件ID(event id)

#define EVENT_ID(timerId) (0x0001<<((timerId)%NUM_CBTIMERS_PER_TASK ))

可以看出一个任务的15个回调定时器都对应着事件idbit0~bit14(至于剩下的bit15则用作系统事件SYS_EVENT_MSG)

OSAL之回调定时器的分析

 (2)根据定时器id(timer id)查找任务id(task id)

#define TASK_ID( timerId )  ( ( ( timerId ) / NUM_CBTIMERS_PER_TASK ) + baseTaskID )

上面理解上有困难的可能是对baseTaskID的理解的。baseTaskID是系统连续分配给处理回调定时器多个任务的第一个任务的task id,举个例子说,系统连续分配两个任务用来处理回调定时器事件,他们的task id分别为8,9,则baseTaskID的值就是8

(3)根据任务id查找不同任务对应回调定时器的起始编号(BANK_TASK_ID)

#define BANK_TASK_ID( taskId ) ((baseTaskID-(taskId))*NUM_CBTIMERS )

以我个人的理解,这个宏定义也许是BLE Stack 1.3版本的一个bug。前面说过baseTaskID是系统连续分配给处理回调定时器多个任务的第一个任务的task id,而taskId则是对应的回调定时器的taks idtaskId应该会大于basetaskID,所以应该讲上面的宏定义改成:

#define BANK_TASK_ID( taskId ) (((taskId)-baseTaskID)*NUM_CBTIMERS )

其中的BANK_TASK_ID可以理解成不同任务对应回调定时器的起始编号。举例来说,系统分配taskid分别为89的回调定时器处理任务,而每个任务又对应着15个回调定时器,给这些定时器从0~29编号,所以BANK_TASK_ID(8)表示taskid8的任务对应着的回调定时器的起始编号为(8-8)*15=0BANK_TASK_ID(9)则表示task id9的任务对应的回调定时器的起始编号为(9-8)*15=15

4、几个变量定义

(1)回调定时器处理任务的起始task id

uint16 baseTaskID = TASK_NO_TASK;

没有任务时,baseTaskID = 0xFF,在初始化回调定时器是它则会记录起始的task id

(2)回调定时器数组

cbTimer_t cbTimers[NUM_CBTIMERS];

这个数组的类型是cbTimer_t,每个回调定时器都管理着对应的回调函数与要传递的参数。

 

osal_CbTimerInit() 初始化回调定时器

参数:

taskId-系统分配的任务id

1、初始化回调定时器的初始化taskId

baseTaskID = taskId;

2、初始化回调定时器数组

osal_memset( cbTimers, 0, sizeof( cbTimers ) );


osal_CbTimerProcessEvent()处理回调定时器事件

参数:

taskId-任务的ID

events-回调函数事件

1、判断是否收到系统信息事件

if ( events & SYS_EVENT_MSG ){return ( events ^ SYS_EVENT_MSG );}

其中SYS_EVENT_MSG只栈eventsbit15, SYS_EVENT_MSG事件标志由osal_set_event()osal_clear_event()这两个函数设置或清除。

2、判断是否有回调定时器事件

(1)没有回调定时器事件,直接返回0

return 0;

(2)有回调则遍历所有回调定时器,查询是哪个定时器事件

for ( i = 0; i < NUM_CBTIMERS_PER_TASK; i++ ){if ( ( events >> i ) & 0x0001 ){......break;}}

(3)获取产生时间的回调定时器

cbTimer_t *pTimer = &cbTimers[BANK_TASK_ID( taskId )+i];

(4)开始执行该回调定时器注册的回调函数

pTimer->pfnCbTimer( pTimer->pData );

(5)执行万别后,清除回调函数及参数

pTimer->pfnCbTimer = NULL;pTimer->pData = NULL;

(6)清除对应位的事件标志

return ( events ^ event );

 

osal_CbTimerStart() 启动一个回调定时器

参数:

pfnCbTimer-要注册的回调函数指针

pData-要传递的参数

timeout-定时器的定时时间

pTimerId-回调定时器id

1、查找第一个可用的回调定时器

for ( i = 0; i < NUM_CBTIMERS; i++ ){if ( cbTimers[i].pfnCbTimer == NULL ){......return ( SUCCESS );}}

2、开始定时器,并注册回调函数

osal_start_timerEx( TASK_ID( i ), EVENT_ID( i ), timeout );cbTimers[i].pfnCbTimer = pfnCbTimer;cbTimers[i].pData = pData;

3、记录回调定时器的编号

*pTimerId = i;

 

osal_CbTimerUpdate() 更新回调定时器的定时值

参数:

timerId-回调定时器id

timeout-要更新的定时值

1、确保回调定时器有效

if ( timerId < NUM_CBTIMERS )

2、确保要更新的回调定时器已启动

if ( cbTimers[timerId].pfnCbTimer != NULL )

3、获取回调定时器当前定时值,如没超时,则更新超时时间

if ( osal_get_timeoutEx( TASK_ID( timerId ), EVENT_ID( timerId ) ) != 0 ){osal_start_timerEx( TASK_ID( timerId ), EVENT_ID( timerId ), timeout );}

 

osal_CbTimerStop() 停止回调定时器

参数:

timerId-回调定时器id

1、确保timerId有效

if ( timerId < NUM_CBTIMERS )

2、确保回调函数已启用

if ( cbTimers[timerId].pfnCbTimer != NULL )

3、停止回调定时器,并清除回调函数及参数

osal_stop_timerEx( TASK_ID( timerId ), EVENT_ID( timerId ) );cbTimers[timerId].pfnCbTimer = NULL;cbTimers[timerId].pData = NULL;


责任编辑:电气自动化网

热门文章

首页 | 资讯 | 应用 | 高压 | 设计 | 行业 | 低压 | 电路图 | 关于

Copyright 2017-2018 电气自动化网 版权所有 辽ICP备17010593号-1

电脑版 | 移动版

Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。