Why udelay and ndelay is not accurate in linux kernel?

前端 未结 3 1244
萌比男神i
萌比男神i 2021-01-15 05:57

I make a function like this

trace_printk(\"111111\");
udelay(4000);
trace_printk(\"222222\");

and the log shows it\'s 4.01 ms , it\'OK

相关标签:
3条回答
  • 2021-01-15 06:20

    Every time you call it, a rounding error is added. Note the comment 2**32 / 1000000000. That value is really ~4.29, but it was rounded up to 5. That's a pretty hefty error.

    By contrast the udelay error is small: (~4294.97 versus 4295 [0x10c7]).

    0 讨论(0)
  • 2021-01-15 06:22

    As you've already noticed, the nanosecond delay implementation is quite a coarse approximation compared to the millisecond delay, because of the 0x5 constant factor used. 0x10c7 / 0x5 is approximately 859. Using 0x4 would be closer to 1000 (approximately 1073).

    However, using 0x4 would cause the ndelay to be less than the number of nanoseconds requested. In general, delay functions aim to provide a delay at least as long as requested by the user (see here: http://practicepeople.blogspot.jp/2013/08/kernel-programming-busy-waiting-delay.html).

    0 讨论(0)
  • 2021-01-15 06:31

    You can use ktime_get_ns() to get high precision time since boot. So you can use it not only as high precision delay but also as high precision timer. There is example:

    u64 t;
    t = ktime_get_ns(); // Get current nanoseconds since boot
    for (i = 0; i < 24; i++) // Send 24 1200ns-1300ns pulses via GPIO
    {
        gpio_set_value(pin, 1); // Drive GPIO or do something else
        t += 1200; // Now we have absolute time of the next step
        while (ktime_get_ns() < t); // Wait for it
        gpio_set_value(pin, 0); // Do something, again
        t += 1300; // Now we have time of the next step, again
        while (ktime_get_ns() < t);  // Wait for it, again
    }
    
    0 讨论(0)
提交回复
热议问题