Rubberazer / JETGPIO

C library to manage the GPIO header of the Nvidia Jetson boards
https://rubberazer.github.io/JETGPIO
MIT License
72 stars 13 forks source link
gpio gpio-pins i2c jetson jetson-gpio jetson-nano jetson-orin jetson-orin-agx jetson-orin-nano jetson-tx1 lcd1602 mpu6050 nano nx orin pwm spi zig

JETGPIO library

C library to manage the GPIO header of the Nvidia JETSON boards

IMPORTANT NOTICE: This version of the library installs and works along a kernel module: Jetclocks. This provides extra functionality and allows to play with clocks in a simpler way. If you don't want that and prefer the old, standalone JETGPIO, you will find it as a release here: standalone JETGPIO

FUNCTIONALITY:

INSTALLATION:

NOTICE: make install will automatically install the library and the kernel module but, if you have heavily tuned your: /boot/extlinux/extlinux.conf and device tree blob e.g. remove the default blob and so forth, the automatic module installation might fail, in those cases manual module installation is recommended, see instructions in: Jetclocks

Clone/download the content into any folder in your JETSON, cd to that folder and type:

sudo make   
sudo make install                                             

If you have an Orin, you should reboot at this point to get all the functionality, also make install will print information on screen, keep an eye on that in case something is out of place. To uninstall the library:

sudo make uninstall

HOW TO:

You will find code examples to learn how to use the library in both: EXAMPLES_C & EXAMPLES_C++ folders, the first one contains all the C examples, the second one contains the same examples ready to compile in C++. To compile the examples you will find instructions in the comment section at the top of each of the example files. I have also added a folder with examples in the Zig programming language to test interoperability.

DOCUMENTATION:

Some doxygen documentation here. As a rule of thumb, the library functions names and usage mimic the ones of the pigpio library (which I recommend if you work with Raspberry Pis). Learnt a lot from that one

THE NEED FOR SPEED:

I created a couple of little programs to measure reaction time e.g. how fast an output pin turns from 0 to 1 (3.3v), or how fast a change to an input pin is detected by the library, a diagram of the physical setup is shown below, basically I set up pin 38 as an output and pin 40 as an input and connect both through a resistor to observe the interaction:

jetson_speed

Compiling and running jetgpio_round_trip.c I am measuring the time from before executing the function that writes a logic 1 (3.3v) to pin 38 until the point when this is detected (by voltage level not edge interrupt) at pin 40. Here the intention is to measure the worst case scenario of a combination of 2 different actions:

The results that I am getting for the round trip (total time to execute both actions) by running this program are:

Nano Classic Orin Nano
Minimum 1.3 us 3.1 us **
Maximum 1.8 us 4.2 us **

Compiling and running jetgpio_speed_edge.c I am trying to measure the time using a similar setup as described above, the difference here is that I am using the library function: gpioSetISRFunc() which basically goes through the linux gpio driver in order to catch rising and falling edges, the reason to use the linux driver for this has to do with the fact that catching interrupts from user space (this is a library after all) is basically 'problematic' for a number of reasons, in short, if driver performance and/or device tree stuff got in my way I would basically replace the current driver by my own, but that is beyond the scope of this library.

Nano Classic Orin Nano
Minimum 250 us 200 us
Maximum 700 us 1000 us

Note that this doesn't measure individual actions but the total time to execute both (round trip). It is clear that the timestamp produced by the linux driver is the one to blame for the slow reaction on detecting a change on the input pin, still interesting as there is no meaningful cpu waste as the hardware is producing the interrupt for us (no polling)

Compiling and running jetgpio_output.c I am writing high/low to pin 38 on a continuous loop, what I am getting on the oscilloscope are the following results:

Nano Classic Orin Nano
Average 0.6 us 2 us **

**Yes, the new Orin has a slower response/higher latency than the old Jetson Nano, this is due to the fact that writing to some registers is being monitored by an external CPU called BPMP (Boot and Power Management Processor). This CPU is an addition to what is called CPU Complex (the 6 Arm A78A cores that are described on the Orin Nano/NX specs) and is completely independent from the main system, running its own firmware and with an independent device tree. Some of the tasks performed by this CPU are clock and power supply management for peripherals inside the SOM e.g. PWM, GPIO... but it also plays a "firewall" role, in other words before writing to some registers in the standard CPU Complex the writing instructions have to pass through this "firewall" making the whole thing slower. This extra, out of the system security manager can be very useful on some applications but it has obviously a downside. Again sorting this out goes beyond the scope of any user space application (library) and it would imply flashing the Orin after modifying stuff, which is something along with other things like modifying the device tree (and reflashing probably) that I wanted to avoid when I created this library.

freenove_i2c_1602_lcd

JETSON NANO AND ORIN FAMILY PINOUT:

The library uses the typical 40 pin header numbering, taking the dev kit as reference so for instance pin 3 is I2C_2_SDA on Nano, I2C1_SDA on Orin Nano and I2C5_DAT on Orin AGX, pin 1 is 3.3 VDC power and so on. You can check the official NVIDIA pinmux configuration for reference or if not available you can use the ones below:

https://jetsonhacks.com/nvidia-jetson-nano-j41-header-pinout/

https://jetsonhacks.com/nvidia-jetson-orin-nano-gpio-header-pinout/

https://jetsonhacks.com/nvidia-jetson-agx-orin-gpio-header-pinout/

The library has been tested on a Jetson Nano: tegra210 (TX1), on a Jetson Orin Nano and also on an Orin AGX.