在 150ns 容差范围内控制 GPIO 引脚
Control a GPIO pin within 150ns of tolerance
我的问题是打开和关闭我的 GPIO 引脚花费的时间太长,尽管使用了良好的计时功能,包括来自 linux/delay.h
的 ndelay
和我自己的 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 的时钟和设备的上升和下降时间也会导致延迟。
我的问题是打开和关闭我的 GPIO 引脚花费的时间太长,尽管使用了良好的计时功能,包括来自 linux/delay.h
的 ndelay
和我自己的 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 的时钟和设备的上升和下降时间也会导致延迟。