九鼎创展论坛
标题:
关于延时函数udelay的疑惑(已解决)
[打印本页]
作者:
laotang365
时间:
2014-10-3 00:33
标题:
关于延时函数udelay的疑惑(已解决)
本帖最后由 laotang365 于 2014-10-10 10:38 编辑
s5pv210-tick-delay.c文件中
udelay中,首先 hz = get_system_hz,我用串口打印出来hz等于100,而
那么udelay(us)等价于
__delay(us * loops_per_jiffy / (1000000 / hz));而,
loops_per_jiffy 等于29440。百度说
loops_per_jiffy为
每0.5个TICK时间范围内CPU可以执行空指令的条数,那么get_system_hz返回值是什么?100Mhz?
还是我自己解答吧:
get_system_hz返回每hz的tick数
void s5pv210_tick_initial(void)
{
...
...
/* initial system tick */
tick_hz = 100;//每秒 100个tick
jiffies = 0;//时刻,从初始化开始计时,每10ms +1
}
u32_t get_system_hz(void)
{
return tick_hz;
}
u64_t clock_gettime(void)
{
if(get_system_hz() > 0)
return (u64_t)jiffies * 1000000 / get_system_hz();//返回cpu已运行时间(us)
return 0;
}
void udelay(u32_t us)
{
u32_t hz = get_system_hz();//每秒100个tick
if(hz)
__delay(us * loops_per_jiffy / (1000000 / hz)); //(每tick的loop数 * 100个tick为每秒loop数,
else //再除以1000000即得1us应__delay的loops数)
__delay(us); //或者这样理解:1000000/每秒tick数 = 每tick的时长(us)=10000us)
}
static void calibrate_delay(void)//校准loops_per_jiffy
{
u32_t ticks, loopbit;
s32_t lps_precision = 8;
u32_t hz = get_system_hz();//每秒tick数,即100个tick
if(hz > 0)
{
loops_per_jiffy = (1<<12);//4096
while((loops_per_jiffy <<= 1) != 0)//8192
{
/* wait for "start of" clock tick */
ticks = jiffies;
while (ticks == jiffies);
/* go ... */
ticks = jiffies;
__delay(loops_per_jiffy);
ticks = jiffies - ticks;//8192个loop之后,经过的tick数
if(ticks) //1tick后立即跳出,得到1tick运行的loops(粗略值) 大于实际值
break;
}
loops_per_jiffy >>= 1;//loops_per_jiffy / 2,1个tick里至少经过的loop数
loopbit = loops_per_jiffy;
while(lps_precision-- && (loopbit >>= 1))//8-- && (loopbit / 2)即8-- && (loops_per_jiffy / 2) ,校准8次
{
loops_per_jiffy |= loopbit;//loops_per_jiffy | = (loops_per_jiffy / 2),即每次循环loops_per_jiffy加上 loopbit 的一半(的一半的一半。。。)
ticks = jiffies;
while(ticks == jiffies);
ticks = jiffies;
__delay(loops_per_jiffy);//延时1个tick
/* longer than 1 tick */
if(jiffies != ticks)/
loops_per_jiffy &= ~loopbit;//loop超过1tick,则loops_per_jiffy低位清零(减小)
}
}
else
{
loops_per_jiffy = 0;
}
}
复制代码
void __attribute__ ((noinline)) __delay(volatile u32_t loop)
{
for(; loop > 0; loop--);
}
void udelay(u32_t us)
{
u32_t hz = get_system_hz();
serial_printf(0,"get_system_hz = %u",hz);
if(hz)
__delay(us * loops_per_jiffy / (1000000 / hz));
else
__delay(us);
}
复制代码
作者:
jjj
时间:
2014-11-25 19:43
计算bogomips可是有一段很有意思的故事,linux创始人实现的,可以网上搜搜
欢迎光临 九鼎创展论坛 (http://bbs.9tripod.com/)
Powered by Discuz! X3.2