在 150ns 容差范围内控制 GPIO 引脚

Control a GPIO pin within 150ns of tolerance

我的问题是打开和关闭我的 GPIO 引脚花费的时间太长,尽管使用了良好的计时功能,包括来自 linux/delay.hndelay 和我自己的 accurate_ndelay 其中(如下所示)使用 linux/ktime.h 中的 ktime_get_ns()

我的内核版本是 4.19.38,带有 Armbian,运行 在 OrangePi Zero 上。

static inline void accurate_ndelay(uint16_t ns){
  uint64_t s = ktime_get_ns();
  uint64_t e = s + ns;
  while(ktime_get_ns() < e);
}
static inline void unsafe_bit2812(struct WS2812* ws2812, uint8_t b){
  if(b){
    gpio_set_value(ws2812->pin, 1);
    accurate_ndelay(ws2812->t0h);
    gpio_set_value(ws2812->pin, 0);
    accurate_ndelay(ws2812->t0l);
  } else {
    gpio_set_value(ws2812->pin, 1);
    accurate_ndelay(ws2812->t1h);
    gpio_set_value(ws2812->pin, 0);
    accurate_ndelay(ws2812->t1l);
  }
}

当我测量真实世界的延迟时(如我的示波器所示,不是坏软件)。延迟不是预期的 350ns,而是 920ns。对于 WS2812 来说 770ns 太多了!

那是一些非常紧迫的时间。 OrangePi 零 运行 在 1.2 GHz,所以 150 ns 是 180 个时钟周期。那不会给你时间做太多事情。

首先要做的是使用 ktime_get_ns() 来测量 gpio_set_value() 调用需要多长时间。或者去掉延迟,用示波器测量。您可能已经知道答案了,如果您延迟 350ns 并测量 920ns,则大约需要 600ns。

您正在调用 gpio_set_value(),它会引入安全、便携的 Linux gpio 库。最大可能的性能是为 GPIO 编写您自己的驱动程序,该驱动程序直接进入硬件寄存器并设置两个状态,延迟,作为一个动作。

即使使用自定义驱动程序,驱动 gpio 的时钟和设备的上升和下降时间也会导致延迟。