【问题标题】:How to implement delay time (microsec order) on system call in C如何在 C 中的系统调用上实现延迟时间(微秒顺序)
【发布时间】:2014-11-19 00:51:43
【问题描述】:

如何在 C 中实现系统调用的延迟时间? 我正在使用 stm32f429 和 hc-sr04 传感器。我需要给出一个 10 微秒的触发脉冲。我试过了:

gpio_set_value(TRIG, 1 );
for(k=0;k<16;k++)
asm("nop");
gpio_set_value(TRIG, 0 );

但我认为 asm("nop") 对于延迟是不准确的。 就准确性而言,在系统调用中实现微秒级延迟的最佳方法是什么? 另一个小问题:关于asm("nop"),知道我设备的ARM处理器频率为180MHz,如何计算单个asm("nop")对应的延迟时间? 谢谢!

【问题讨论】:

  • 你真的在上面运行 linux 吗?要使用 NOP 进行准确的延迟,您将不得不禁用中断和其他任务切换,即便如此,仍受总线仲裁器的支配。考虑使用众多硬件计时器之一。
  • 您可以在驱动程序中进行。调用 spin_lock_irq(&lock);乌德莱(10); spin_unlock_irq(&lock).
  • 嗨,克里斯!是的,我已经禁用了中断。但是出于好奇,我如何计算 asm("nop") 在时间方面对应多少?嗨,约翰!在 spin_lock 和 spin_unlock 之间,我必须只将延迟或整个代码放入系统调用中吗?谢谢你的回答
  • 只有延迟(udelay),记住它是一个延迟循环......你说的系统调用是什么意思?
  • 嗨,约翰。我将系统调用视为内核的接口。它们为操作系统本身提供的服务提供接口。不过谢谢你的回答。

标签: c linux-kernel delay embedded-linux system-calls


【解决方案1】:

对于短延迟,使用内核函数:

udelay(unsigned long usecs) - microsec delay
mdelay(unsigned long msecs) - millisec delay

这些是以独立于架构的方式实现的定时循环,比以下方法要好得多:

for (i = 0; i < 1000000; i++)
        ;

这取决于 CPU 速度。

注意:设置一个非常大的值(15000 毫秒),那么内核可能会给出软锁定。当信号必须进行软锁定时,这是一个硬编码值。此外,在等待期间使用udelay() or mdelay() 是不可中断的,因此您可能需要考虑使用内核计时器。

【讨论】:

  • 嗨,问!那么,您认为就我而言,由于我在内核级别工作,因此就准确性而言,使用 udelay 是更好的选择?感谢您的回答
  • @Anth 如前所述,您可能想使用udelay() 或内核计时器(如果您想使用可中断等待)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-07
相关资源
最近更新 更多