读源码写作,尊重原创;
本博文根据蓝牙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
}
}
//