我做了一个这样的函数
trace_printk("111111");
udelay(4000);
trace_printk("222222");
日志显示它是 4.01 毫秒,没问题
但是当我这样打电话时
trace_printk("111111");
ndelay(10000);
ndelay(10000);
ndelay(10000);
ndelay(10000);
....
....//totally 400 ndelay calls
trace_printk("222222");
日志将显示 4.7 毫秒。这是 Not Acceptable 。 为什么ndelay的误差这么大?
深入内核代码我发现了这两个函数的实现
void __udelay(unsigned long usecs)
{
__const_udelay(usecs * 0x10C7UL); /* 2**32 / 1000000 (rounded up) */
}
void __ndelay(unsigned long nsecs)
{
__const_udelay(nsecs * 0x5UL); /* 2**32 / 1000000000 (rounded up) */
}
我以为udelay会是ndelay的1000倍,但事实并非如此,为什么?
最佳答案
正如您已经注意到的,纳秒延迟实现与毫秒延迟相比是相当粗略的近似,因为使用了 0x5
常数因子。 0x10c7/0x5
大约为 859。使用 0x4
将更接近 1000(大约 1073)。
但是,使用 0x4 会导致ndelay
小于请求的纳秒数。一般来说,延迟函数的目标是提供至少只要用户请求的延迟(参见此处:http://practicepeople.blogspot.jp/2013/08/kernel-programming-busy-waiting-delay.html)。
关于timer - 为什么linux内核中的udelay和ndelay不准确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30396869/