OSAL之时间管理,软件定时器链表管理

本文深入探讨了OSAL在蓝牙4.0中的时间管理和软件定时器管理,详细解析了OSAL_TimeUpdate及osalClockUpdate等关键函数,介绍了如何利用硬件定时器更新系统时间,并讲解了软件定时器链表的操作。内容涵盖时间API、UTC时间处理及定时器例程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

读源码写作,尊重原创;

本博文根据蓝牙4.0, 协议族版本是1.3.2
本博文分两大块。一部分是时间管理,另一部分是软件定时器管理。


OSAL的时钟实现在OSAL_CockBLE.c与OSAL_Clock.h两个文件中。OSAL支持完整的UTC(世界统一时间),以2000年1月1日00:00:00为时间起点,可以精确到年、月、日、时、分、秒的时间值。

背景知识

// number of seconds since 0 hrs, 0 minutes, 0 seconds, on the 1st of January 2000 UTC存储自2000年1月1日开始的**秒数**,uint32可存储大约135年的数据,就是到2135年左右。
typedef uint32 UTCTime;
UTCTime OSAL_timeSeconds = 0;//定义一个存储秒数的变量

// To be used with
typedef struct
{
  uint8 seconds;  // 0-59
  uint8 minutes;  // 0-59
  uint8 hour;     // 0-23
  uint8 day;      // 0-30
  uint8 month;    // 0-11
  uint16 year;    // 2000+
} UTCTimeStruct;//这是将UTCTime转化为UTCTimeStruct的结构

//几个宏定义,判断闰年
#define IsLeapYear(yr)  (!((yr) % 400) || (((yr) % 100) && !((yr) % 4)))
//每年多少天
#define YearLength(yr)  (IsLeapYear(yr) ? 366 : 365)
// (MAXCALCTICKS * 5) + (max remainder) must be <= (uint16 max),
// so: (13105 * 5) + 7 <= 65535这是防止微妙转化为毫秒是uint16溢出
#define MAXCALCTICKS  ((uint16)(13105))

#define BEGYEAR         2000     // UTC started at 00:00:00 January 1, 2000   UTC时间是自2000年1月1日开始

#define DAY             86400UL  // 24 hours * 60 minutes * 60 seconds一天的秒数


//全局变量
static uint16 previousLLTimerTick = 0;   //存储的是上次调用osalTimeUpdate获得的625us反转次数,也即上次调用的节拍数量
static uint16 remUsTicks = 0;   //存储的是每次更新us转ms *5/8的余数
static uint16 timeMSec = 0;     //存储的是ms转s   的余数

osalTimeUpdata

OSAL里面所有时间的根源都来自于硬件层一个定时器的更新,它是625us自动反转重新计时的定时器,只要计算前后两次获得它反转的次数想减那么就可以计算出之间花费了多少时间。
这个定时器由osalTimeUpdata调用。

void osalTimeUpdate( void )
{
  uint16 tmp;  //记录这次获得625us逝去的次数
  uint16 ticks625us;   //记录前后两次625us逝去的次数
  uint16 elapsedMSec = 0;  //记录前后两次625 us逝去的毫秒数

  // Get the free-running count of 625us timer ticks
 tmp = ll_McuPrecisionCount();   //计算当前过去了多少个625us次数

  if ( tmp != previousLLTimerTick )
  {
    // Calculate the elapsed ticks of the free-running timer.
    ticks625us = tmp - previousLLTimerTick;

    // Store the LL Timer tick count for the next time through this function.存储这次过去的625us的次数
    previousLLTimerTick = tmp;

    /* It is necessary to loop to convert the usecs to msecs in increments so as
     * not to overflow the 16-bit variables.
     */
    while ( ticks625us > MAXCALCTICKS ) //主要为了数据过大转换为ms是溢出了。MAXCALCTICKS >13105就会溢出从零开始,对时间来说是不行的
    {
      ticks625us -= MAXCALCTICKS;
      elapsedMSec += MAXCALCTICKS * 5 / 8;  //计算逝去的毫秒;整除,MAXCALCTICKS =13105个节拍转换为ms是8190ms
      remUsTicks += MAXCALCTICKS * 5 % 8;   //计算当前循环的余数,余数为5,时间0.625ms;5除8 =0.625
    }
    }

    // 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值