I tryed wiki GPIO using sysfs https://wiki.luckfox.com/Luckfox-Pico/Luckfox-Pico-GPIO and it is absolutely slow. For example, I need to maintain high signal for 700ns, but calling write/fwrite is about 20000ns. So I failed to implement the desired GPIO protocol.
Question 1. Is there a documented way to work with GPIO faster than using sysfs abstraction? For example via kernel drivers, registers, memory-mapped abstractions, WiringX library, so on?
Question 2. I looked at the RV1103 datasheet and it claims that processor has both 1) DMAC "Support data transfer types including memory-to-memory, memory-to-peripherals, peripherals-to-memory" and 2) Support 2 secure timers. So it there a way to ask processor to set value to GPIO pin in that way?
Thank you!
Luckfox fast GPIO
Hello,raider wrote: ↑2024-04-08 21:50 I tryed wiki GPIO using sysfs https://wiki.luckfox.com/Luckfox-Pico/Luckfox-Pico-GPIO and it is absolutely slow. For example, I need to maintain high signal for 700ns, but calling write/fwrite is about 20000ns. So I failed to implement the desired GPIO protocol.
Question 1. Is there a documented way to work with GPIO faster than using sysfs abstraction? For example via kernel drivers, registers, memory-mapped abstractions, WiringX library, so on?
Question 2. I looked at the RV1103 datasheet and it claims that processor has both 1) DMAC "Support data transfer types including memory-to-memory, memory-to-peripherals, peripherals-to-memory" and 2) Support 2 secure timers. So it there a way to ask processor to set value to GPIO pin in that way?
Thank you!
For efficient GPIO operations, I agree that writing a device driver is often a more reliable approach. It allows for the incorporation of mechanisms such as timers. Operating GPIOs at the application layer in Linux, especially using third-party libraries, might not be as efficient as implementing it at the driver level. The reason for using sysfs as an example is its simplicity and universality.
As for the use of DMA, it's typically employed for handling large amounts of data. In your scenario, if you're only dealing with a small amount of data, the performance difference between using the CPU for control and utilizing DMA would likely be minimal. However, when processing large volumes of data, factors such as data transfer reliability become crucial. At that point, employing communication protocols with DMA support, available in Linux kernel, would be advisable.
Dear @Crocodile, thank you very much for your detailed answer!
I wrote a kernel module and got to use Libgpio and also directly gpio_chip->set(...) function. My problem is that a call to such methods for setting GPIO pin takes about 500 nanoseconds. But by the way I have to write a protocol that have to switch pin state in about 700..2500 nanoseconds.
So for now I just mismatch timings, because calling a pin change function uses time which is same to timings of a protocol...
p.s. I checked that it is possible to call gpio_chip->set(...) function about 4 million times per second. I believe that GPIO of RV1106 may do more.. But for now I do not understand how to achieve that "more" :-/
Thank you in advance!
I wrote a kernel module and got to use Libgpio and also directly gpio_chip->set(...) function. My problem is that a call to such methods for setting GPIO pin takes about 500 nanoseconds. But by the way I have to write a protocol that have to switch pin state in about 700..2500 nanoseconds.
So for now I just mismatch timings, because calling a pin change function uses time which is same to timings of a protocol...
p.s. I checked that it is possible to call gpio_chip->set(...) function about 4 million times per second. I believe that GPIO of RV1106 may do more.. But for now I do not understand how to achieve that "more" :-/
Thank you in advance!
raider wrote: ↑2024-04-12 15:18 Dear @Crocodile, thank you very much for your detailed answer!
I wrote a kernel module and got to use Libgpio and also directly gpio_chip->set(...) function. My problem is that a call to such methods for setting GPIO pin takes about 500 nanoseconds. But by the way I have to write a protocol that have to switch pin state in about 700..2500 nanoseconds.
So for now I just mismatch timings, because calling a pin change function uses time which is same to timings of a protocol...
p.s. I checked that it is possible to call gpio_chip->set(...) function about 4 million times per second. I believe that GPIO of RV1106 may do more.. But for now I do not understand how to achieve that "more" :-/
Thank you in advance!
In the past, I attempted to use GPIO to simulate SPI on the RV1106. Although the speed of simulating SPI with GPIO was significantly reduced compared to using an SPI controller, it was still relatively easy to exceed the required 500ns. In my tests, GPIO-SPI could stably operate at a frequency of 10MHz. If you also need to implement some protocol using GPIO, referring to `kernel/drivers/spi-gpio.c` for implementation is a good choice. This approach is in the driver layer rather than the user layer, and it offers much higher runtime efficiency compared to directly manipulating `/sys/class/gpio`.
I hope this information is helpful for your exploration of high-speed level conversion with GPIO.
Thank you very much! I tested performance of GPIO from inside kernel (and thus not userspace).
Using in-kernel linux GPIO API gpiod_set_value (e.g. GPIO consumer interface). It gives about 4 million calls per second, e.g. 4 Mhz.
Same value if call chip driver "directly", e.g. gpio_chip->set(...) function.
Probably I'm doing something wrong, and thank you for pointing to spi-gpio.c! In any way, I wanted to achieve 24Mhz and seems will have no luck with that board / processor.
As you also pointed, a DMA may help. But I cannot find any documentation or examples on that for RV1106 or Pico.