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

嵌入式

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

OSAL之定时器分析

嵌入式 | 发布时间:2017-10-04 | 人气: | #评论# |本文关键字:OSAL,定时器
摘要:OSAL的定时器的相关代码实现在OSAL_Timers.c与OSAL_Timers..h两个文件中。OSAL用最简的代码实现以一个功能完善、方便管理、的定时器。 1、在OSAL_Timers.c中定义一个定时器类型的共用体结构:

OSAL的定时器的相关代码实现在OSAL_Timers.c与OSAL_Timers..h两个文件中。OSAL用最简的代码实现以一个功能完善、方便管理、的定时器。

1、在OSAL_Timers.c中定义一个定时器类型的共用体结构:

typedef union {
 uint32 time32;
 uint16 time16[2];
 uint8 time8[4];
} osalTime_t;

这个定时器类型的奥妙之处在于它采用共用体结构,构造出了132位的定时器、216位的定时器、48位的定时器。

OSAL之定时器分析

2、根据面向对象的方法,构造一个带各种属性的定时器链表结构,如下:

typedef struct{  void   *next;  osalTime_t timeout;  uint16 event_flag;  uint8  task_id;  uint32 reloadTimeout;} osalTimerRec_t;

OSAL的定时器主要为任务提供服务,所以定时器的结构需要包括任务的身份(task_id)以及它承载的信息(event_flag),以便告诉OSAL让哪个任务做什么事情;除此之外定时器还需要记录的定时时间(timeout)以及超时后需要重载的定时值(reloadTimeout)。

OSAL之定时器分析

 3、新建定时器链表头指针,这个头指针会指向定时器管理链表的链表头,方便定时器管理。

osalTimerRec_t *timerHead;

4、定义一个变量,用来记录系统上电的运行时间:

static uint32 osal_systemClock;


osalTimerInit()初始化定时器

osal_systemClock = 0;


osalAddTimer()添加一个定时器到定时器列表中

参数:

task_id-任务的id

event_flag-事件标志

timeout-超时时间

1、查看是定时器是否存在,如果存在,则更新定时时间

newTimer = osalFindTimer( task_id, event_flag );if ( newTimer ){  newTimer->timeout.time32 = timeout;  return ( newTimer );}

2、新建新的定时器,并填充定时器信息

newTimer = osal_mem_alloc( sizeof( osalTimerRec_t ) );newTimer->task_id = task_id;newTimer->event_flag = event_flag;newTimer->timeout.time32 = timeout;newTimer->next = (void *)NULL;newTimer->reloadTimeout = 0;

3、如果定时器类表不存在,则作为定时器列表头

timerHead = newTimer;

4、如果定时器列表存在,查找列表尾部,并添加定时器

srchTimer = timerHead;while ( srchTimer->next )  srchTimer = srchTimer->next;srchTimer->next = newTimer;


osalFindTimer()在定时器列表中查找制定的定时器

参数;

task_id-任务id

event_flag-事件标志

1、获取定时器列表头

srchTimer = timerHead;

2、查找指定的定时器在定时器列表中的位置

while ( srchTimer ){  if ( srchTimer->event_flag == event_flag &&     srchTimer->task_id == task_id )  {    break;  }  srchTimer = srchTimer->next;}


osalDeleteTimer() 删除定时器

参数:

rmTimer-要溢出的定时器

要删除指定的定时器值,只要将它的event_flag元素清零就可以,至于将它从定时器列表移除恶过程在其他函数中操作。

rmTimer->event_flag = 0;


osal_start_timerEx()启动指定单次定时的定时器

参数:

taskID-任务id

event_flag-时间标志

timeout_value-超时时间

直接调用osalAddTimer()函数完定时器列表中添加一个定时器:

newTimer = osalAddTimer( taskID, event_id, timeout_value );


osal_start_reload_timer()启动一个周期定时的定时器

参数:

taskID-任务id

event_id-事件标志

timeout_value-超时时间

1、添加一个定时器到定时器列表中

newTimer = osalAddTimer( taskID, event_id, timeout_value );

2、加载定时器的重装值

newTimer->reloadTimeout = timeout_value;


osal_stop_timerEx()停止指定单次定时的定时器

参数:

task_id-任务id

event_id-时间标志

1、查找task_idevent_id对应的定时器

foundTimer = osalFindTimer( task_id, event_id );

2、删除查找到的定时器

osalDeleteTimer( foundTimer );


osal_get_timeoutEx()获取指定单次定时的定时器的定时值

参数:

task_id-任务id

event_id-事件标志

1、查找指定的定时器

tmr = osalFindTimer( task_id, event_id );

2、获取该定时器的定时器值

rtrn = tmr->timeout.time32;


osal_timer_num_active()获取当前正在使用的定时器个数

1、获取定时器列表头

srchTimer = timerHead;

2、计算定时器列表中定时器的个数

while ( srchTimer != NULL ){  num_timers++;  srchTimer = srchTimer->next;}


osalTimerUpdate()更新定时器时间

参数:

updateTime-要更新的时间

1、更新系统时间

osal_systemClock += updateTime;

2、更新每个定时器的定时时间

srchTimer->timeout.time8[0] -= timeUnion.time8[0];

srchTimer->timeout.time32 -= timeUnion.time32;

srchTimer->timeout.time32 = 0;

3、定时器定时是否超时或需要删除定时器

(1)定时器没有超时,则检查下一个定时器

prevTimer = srchTimer;srchTimer = srchTimer->next;

OSAL之定时器分析

OSAL之定时器分析

 (2)定时时间到,且有定时重载值有时间标志,则设置一个超时时间,转载重载值

f ( (srchTimer->timeout.time16[0] == 0) && (srchTimer->timeout.time16[1] == 0) &&   (srchTimer->reloadTimeout) && (srchTimer->event_flag) ){    osal_set_event( srchTimer->task_id, srchTimer->event_flag );    srchTimer->timeout.time32 = srchTimer->reloadTimeout;}

(3)超时时间到,无重载值,则删除定时器

情况1prevTimer == NULL

timerHead = srchTimer->next;freeTimer = srchTimer;srchTimer = srchTimer->next;

OSAL之定时器分析

OSAL之定时器分析

 情况2prevTimer != NULL

prevTimer->next = srchTimer->next;freeTimer = srchTimer;srchTimer = srchTimer->next;

OSAL之定时器分析

OSAL之定时器分析

 (4)设置超时定时器对应任务的事件

if ( freeTimer ){    if ( (freeTimer->timeout.time16[0] == 0) && (freeTimer->timeout.time16[1] == 0) )    {        osal_set_event( freeTimer->task_id, freeTimer->event_flag );    }    osal_mem_free( freeTimer );}

osal_next_timeout()在定时器列表中查找最短的超时时间

1、获取定时器列表

srchTimer = timerHead;

2、查找最短的超时时间

while ( srchTimer != NULL ){  if (srchTimer->timeout.time32 < nextTimeout)  {     nextTimeout = srchTimer->timeout.time32;     }  srchTimer = srchTimer->next;}

osal_GetSystemClock()获取系统时钟

直接返回变量osal_systemClock

return ( osal_systemClock );


责任编辑:电气自动化网

热门文章

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

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

电脑版 | 移动版

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