static uint16 previousLLTimerTick = 0;
static uint16 remUsTicks = 0;
</pre><pre name="code" class="cpp">/*********************************************************************
* 函数名称 osalTimeUpdate
*
* 说 明 得到消逝时间(单位 ms)的整数和小数,小数以余数形式存在
* 这个函数是循环调用的,不是中断
* Uses the free running rollover count of the MAC backoff timer;
* this timer runs freely with a constant 625 usec interval. The
* count of 625-usec ticks is converted to msecs and used to update
* the OSAL clock and Timers by invoking osalClockUpdate() and
* osalTimerUpdate(). This function is intended to be invoked
* from the background, not interrupt level.
*
* 入口参数 无
* 出口参数 无
*
********************************************************
* 注释:timer ticks 这个东西不好翻译,这里暂时理解
* 为时钟周期(及时钟滴答一次),此处为625us一个周期。
*/
void osalTimeUpdate( void )
{
uint16 tmp; /* 临时变量 */
uint16 ticks625us; /* 相邻两次调用相差的 ticks,每个ticks为625微妙 */
uint16 elapsedMSec = 0; /* 临时变量 */
// Get the free-running count of 625us timer ticks
tmp = ll_McuPrecisionCount(); /* 获取当前的 ticks,此函数无法找到源码 */
if ( tmp != previousLLTimerTick ) /* 当前的 ticks 数不等于上一次获取的 ticks */
{
// Calculate the elapsed ticks of the free-running timer.
ticks625us = tmp - previousLLTimerTick; /* 计算两次调用时的时间差,及 ticks 差 */
// Store the LL Timer tick count for the next time through this function.
previousLLTimerTick = tmp; /* 把当前的 ticks 作为下一次调用的参考 ticks */
/* It is necessary to loop to convert the usecs to msecs in increments so as
* not to overflow the 16-bit variables.
* MAXCALCTICKS 定义为 13105
* 相邻两次逝去的时间数计算(单位 ms) elapsedMSec = ticks625us * 5 / 8;
* 这里做这个循环是为了不使 ticks625us * 5 溢出,MAXCALCTICKS * 5 = 65525 不会溢出
*/
while ( ticks625us > MAXCALCTICKS )
{
ticks625us -= MAXCALCTICKS;
elapsedMSec += MAXCALCTICKS * 5 / 8; /* ms的整数 */
remUsTicks += MAXCALCTICKS * 5 % 8; /* ms的小数,余数方式存在,remUsTicks为全局变量,
还存储着上一次调用此函数产生的余数 */
}
// update converted number with remaining ticks from loop and the
// accumulated remainder from loop
tmp = (ticks625us * 5) + remUsTicks; /* 余数加上去,计算循环剩下的 ticks数 */
// Convert the 625 us ticks into milliseconds and a remainder
elapsedMSec += tmp / 8; /* 计算两次调用最终的相差的ms整数 */
remUsTicks = tmp % 8; /* 计算两次调用最终的相差的ms余数 */
// Update OSAL Clock and Timers
if ( elapsedMSec )
{
osalClockUpdate( elapsedMSec ); /* 更新系统时钟 UTCTime以秒为单位记录 */
osalTimerUpdate( elapsedMSec ); /* 更新每个软件定时器,减去一定的时间 */
}
}
}
整个系统的时间都由 ll_McuPrecisionCount() 提供的,这是一个16位硬件定时器(其他博客上说的),源码没有公开;这部分代码在获得当前LL Timer的计数值后进行时间计算,主要包括计算elapsedMSec时间,该定时器1个tick就代表625us;
在最开始看这个函数是有一个疑问,就是ll_McuPrecisionCount(),这个函数的返回值,在 0 - 65535之间,那么问题就来了,假如前一次取的的 ticks数为 65535时,而当前取得的 ticks 为 100时,怎么计算 时间 ticks625us
ticks625us = tmp - previousLLTimerTick;
后来查资料,在TI的论坛
(http://www.deyisupport.com/question_answer/wireless_connectivity/bluetooth/f/103/t/72445.aspx)
中有人给出了答案,其实对两个正数之间的差其实求得是它们相隔的距离,及ticks625us= 201;如果有人要问要是两次调用超过了一个周期呢,既前一次取的的 ticks数为 65535,过了一个 0 - 65535 计数,又计数到了200,实际相差的时间是 65637,那怎么计算?我也不知道,也许系统有限制吧;