GPIO – increase read/write rate

I’m trying to send data between a Raspberry Pi and a Jetson TX2 board utilizing GPIO-pins of both. I’m successfully sending an image from the Raspberry to the Jetson and it displays without issue, however the Jetson reads the data far too slowly and I need to find away to mitigate that.

On the Raspberry Pi (model 2B) I’m using the WiringPI library, http://wiringpi.com/, and on the Jetson TX2 I use a library from JetsonHacks, https://github.com/jetsonhacks/jetsonTX1GPIO. This library was written for the TX1 but I expanded the jetsonGPIO.h file with a jetsonTX2GPIONumber enum. To send the data I use 8 pins on each device – written by the Rasberry and read by the Jetson – so that I send all bits of a byte in parallell. I also have a one pin written by the Raspberry to say when the 8 data pins are ready to be read, and one pin written by the Jetson to say when the data pins have been read and can be updated. Everything is implemented with c++. With this setup I use no timer control whatsoever, and it’s significantly faster than previous solutions that used one.

One would think (at least I did) that the Raspberry is the bottleneck in this scenario, however I investigated the response times of each device with an oscilloscope and it’s actually the Jetson that pulls down the performance dramatically. After the Rasberry control pin switches state (indicating that data can be read to the Jetson), it takes 163 µs for the Jetson to read it and switch state on its control pin (telling the Raspberry it can write a new byte). It then takes the Raspberry 1.3 µs to write a new byte to the data pins and switch state on its control pin.

Needless to say, the issue lays with the Jetson. My guess is that the library I use is not written to be as fast, but I know little about the area and I haven’t found any other GPIO implementations I can use with the Jetson. Any help or pointers would be much appreciated!

I’ve been trying to refer to the documentation to try and implement something myself, but I can’t find anything of use to me (it doesn’t help that I haven’t done anything like it before). Any pointers at all would be greatly helpful!

You’re not going to get high throughput by direct bit banging. You need to use built-in hardware channels.

The fastest built-in channel on the Raspberry Pi is the USB 2 port, so your best bet is to send the data over USB. (The Jetson can expose Gadget mode as a USB device on the USB 2 port with some kernel configuration, I’m told.)

The second-fastest built-in channel on the Raspberry Pi is the Ethernet port, so if you can’t get USB working, then Ethernet might work okay. (Note: The RPi Ethernet port actually is a USB device!)

The third-fastest built-in channel on the Raspberry Pi is the SPI channel. Thus, you can use the SPI bus to talk between the Jetson and the Pi, at up to about 30 MHz, depending on how far you want to send the data and how good the cabling and electrical environment is.
(The Pi allegedly goes up to 125 MHz on the SPI bus, but I haven’t seen that working reliably other than when using PCBs attached directly to the RPi header.)

Hi JohanPi,

This is a interesting subject, as snarky said, you are not likely to get high throughput of data using GPIOs so if you are looking for quick data interchange it might be better use a standard data channel instead (I2C, SPIO, or USB 2.0). In both the Rasperry pi and the TX1, you are using a userspace interface to write to GPIOs (/sys/class/gpio/) so it should be slow by default, what seems really interesting is that the TX2 seems the be bottleneck in this case; my rough guess is that there are some electrical limitations on the GPIO being used (might be related to pull up registers, pinmuxing configuration and schematics of the TX2). However, for some applications having fast GPIO respose is critical so being able to tune that performance is of interest, a couple of post that had similar questions:

1-https://devtalk.nvidia.com/default/topic/995395/?comment=5096642
2-https://devtalk.nvidia.com/default/topic/977514/?comment=5024051

Post number 2 has increasing the priority of the task marked as answer, perhaps you can have higher respose incresing the priority.

Thank you for your help!

Yeah, that does seem to be the case. I guess I got led on by the fact that I got enough speed on the RPi-side beforehand. I also tried my best utilizing the UARTs on both devices (the J17 one on the Jetson TX2). I managed to reliably send images at a 115200 baud rate, but not any faster. Tried with both hardware and software flow control as well without any improvement (though I can’t say for certain that the flow control actually worked).

Both USB and ethernet is troublesome in my case so I’m now trying the SPI route. Right now I’m working through the issues enabling it on the Jetson TX2 with all the different (and conflicting) sources on how to do it.

Thanks for the input!

I already do have the priorities as high as possible (on both devices), as well as compiled the code with the -O3 flag.

When digging around in the documentation to try and enable the SPI I stumbled upon the following note:

This prompted me to retry my UART efforts. Making this change alone didn’t help at all though.

However by some sheer luck I figured out that the RPi didn’t apply the higher baud rates I tried. (If I set the RPi to a baud rate of 230400 I could still read it with a baud rate setting of 115200 at the Jetson). By increasing the uart clock rate at the RPi I was able to significantly increase the baud rate. Now I’m enjoying rates up to 4000000 – above and beyond what I need. This link was very helpful in finding out the RPi baud rate limit as well as to overcome it: http://www.thedevilonholiday.co.uk/raspberry-pi-increase-uart-speed/