我有一个需要微秒延迟的驱动程序.为了创建这个延迟,我的驱动程序正在使用内核的udelay函数.具体来说,有一个调用udelay(90):
iowrite32(data, addr + DATA_OFFSET);
iowrite32(trig, addr + CONTROL_OFFSET);
udelay(30);
trig |= 1;
iowrite32(trig, addr + CONTROL_OFFSET);
udelay(90); // This is the problematic call
Run Code Online (Sandbox Code Playgroud)
我们的设备存在可靠性问题.经过大量的调试,我们在90us过去之前将问题追溯到驱动程序恢复.(参见下面的"证据".)
我在Intel Pentium Dual Core(E5700)上运行内核版本2.6.38-11-generic SMP(Kubuntu 11.04,x86_64).
据我所知,文档声明udelay将延迟执行至少指定的延迟,并且是不可中断的.这个版本的内核是否有错误,或者我是否误解了udelay的使用?
为了说服自己这个问题是由于udelay过早返回引起的,我们向其中一个I/O端口提供了一个100kHz的时钟,并按如下方式实现了我们自己的延迟:
// Wait until n number of falling edges
// are observed
void clk100_delay(void *addr, u32 n) {
int i;
for (i = 0; i < n; i++) {
u32 prev_clk = ioread32(addr);
while (1) {
u32 clk = ioread32(addr);
if (prev_clk && !clk) { …Run Code Online (Sandbox Code Playgroud)