Jetson.GPIO, and the Raspberry Pi API running on a Tegra board
A Python library that enables the use of Jetson's GPIOs
At a glance
- What is it?
- Jetson.GPIO gives NVIDIA Jetson boards a Python GPIO library with the same API as RPi.GPIO, so a Raspberry Pi program can move to a Jetson with little more than a changed import. The interesting parts are the four pin numbering modes, the udev rules you must install by hand, and the pinmux lookup tool.
- Who is it for?
- Adopt Jetson.GPIO if you are moving an application from a Raspberry Pi to a Jetson, or writing new GPIO code for a Jetson and want the same import path and API you already know, since the library deliberately mirrors RPi.GPIO down to the module alias. Do not adopt it if you need I2C, SPI or PWM beyond what the samples demonstrate, because the documentation here covers the GPIO API and the pin numbering.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 90 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The same API, on a different board
Jetson TX1, TX2, AGX Xavier and Nano development boards contain a 40 pin GPIO header, similar to the 40 pin header in the Raspberry Pi. These GPIOs can be controlled for digital input and output using the Python library provided in the Jetson GPIO Library package.
The reason the project exists in this form is the compatibility. The library has the same API as the RPi.GPIO library for the Raspberry Pi, in order to provide an easy way to move applications running on the Raspberry Pi to the Jetson board.
That is a specific and useful goal, and it is worth being precise about what it does and does not give you. It gives you the API surface: the same import name, the same function names, the same pin numbering modes where the hardware allows. It does not give you the same hardware, and the four numbering modes section makes that concrete, because two of the four modes on a Jetson refer to a different set of numbers than the Raspberry Pi ones.
The documentation describes itself as a walk through what is contained in the Jetson GPIO library package, how to configure the system and run the provided sample applications, and the library API. That is a complete manual for a library with a small surface, and it is the kind of document that tells you the project is stable and settled rather than evolving.
The primary language is Python, the licence is MIT, the last push was on 2026-07-24, and the repository is not archived.
Three modules and five samples, and which of them you may import
The package components section is short and has one instruction that saves people a mistake.
The lib/python/ subdirectory contains the Python modules that implement all the library functionality. The gpio.py module is the main component that will be imported into an application and provides the needed APIs. The gpio_event.py and gpio_pin_data.py modules are used by the gpio.py module and must not be imported directly into an application.
That last clause is the kind of detail that belongs in a README and rarely does. The two support modules are internal, and importing them directly ties your code to an implementation detail that carries no compatibility promise.
The samples/ subdirectory contains sample applications to help in getting familiar with the library API and getting started on an application. The simple_input.py and simple_output.py applications show how to perform read and write to a GPIO pin respectively, while button_led.py, button_event.py and button_interrupt.py show how a button press may be used to blink an LED using busy-waiting, blocking wait and interrupt callbacks respectively.
Those three button samples differ only in how they wait, and that is the point of having all three. A busy-wait loop burns CPU while it waits. A blocking wait does not, but the thread is stuck. An interrupt callback does not block and does not spin, and it is the one you want in anything that has to stay responsive.
The repository also carries more than the five documented samples, with simple_pwm.py, test_all_apis.py, test_all_pins.py, test_all_pins_input.py, jetson_gpio_super_test_script.py, jetson_model.py, an issue40.py and an issue40-trigger.py, a test for the pinmux lookup tool, a docker directory and the run_sample.sh script.
Installation, and the two ways to get the udev rule in place
Installation is either pip or a manual setup, and the pip path is the easiest one.
sudo pip install Jetson.GPIOThe manual route lets you clone the repository or download it as an archive and decompress it, and you may place the library files anywhere you like. You can then use the library directly from that directory by manually setting PYTHONPATH, or install it with setup.py.
sudo python3 setup.py installThe important thing about the manual route is that it changes where the udev rules file lives, and the documentation handles both cases separately. If you have downloaded the source, the rules are at lib/python/Jetson/GPIO/99-gpio.rules and you copy them into the rules.d directory. If you installed from a package, for example with pip into a virtual environment, the path is venv/lib/pythonNN/site-packages/Jetson/GPIO/99-gpio.rules, and the NN stands for the interpreter version.
That difference is a real gotcha, because a virtual environment changes the layout of the installed package and the copy command in the documentation is different. A user who installed with pip into a venv and then copied from the source tree path would end up with no rules file where udev expects it, and the symptom would be permission errors when opening a pin.
After copying the rules, the new rule takes place either after a reboot or after reloading the udev rules.
Why the gpio group and a udev rule exist at all
The permissions section is the part of the setup that a Raspberry Pi user does not expect to have to do, and the reason is that the Jetson and the Raspberry Pi expose their pins differently.
The instructions are to create a new gpio user group and then add your user to the newly created group.
sudo groupadd -f -r gpio
sudo usermod -a -G gpio your_user_nameThen install the custom udev rules by copying the 99-gpio.rules file into the rules.d directory, and either reboot or reload the udev rules.
sudo udevadm control --reload-rules && sudo udevadm triggerThe 99 prefix is the conventional way to order a udev rule so that it runs after the distribution's own rules, and the -f flag on groupadd makes the command idempotent so that re-running it does not fail when the group already exists. The usermod adds your user to the group, which takes effect on the next login, or on the reboot that the rules also need.
The reason the permissions step exists at all is the device model. Without the group and the udev rule, your process cannot open the pin, so the library appears broken in a way that is really a permissions problem.
For a user who arrives from the Raspberry Pi, this is the step that makes the difference between a working script and an unhelpful permission error, and it is why the documentation puts it before the samples.
Four numbering modes, two of which the Raspberry Pi does not have
The Jetson GPIO library provides four ways of numbering the I/O pins, and the distinction matters for any code ported from a Raspberry Pi.
The first two correspond to the modes provided by the RPi.GPIO library, BOARD and BCM, which refer to the pin number of the 40 pin GPIO header and the Broadcom SoC GPIO numbers respectively. The remaining two modes, CVM and TEGRA_SOC, use strings instead of numbers, and they correspond to signal names on the CVM/CVB connector and the Tegra SoC respectively.
The mode is mandatory and is set with a single call.
GPIO.setmode(GPIO.BOARD)
# or
GPIO.setmode(GPIO.BCM)
# or
GPIO.setmode(GPIO.CVM)
# or
GPIO.setmode(GPIO.TEGRA_SOC)The trap for a ported application is BCM. On a Raspberry Pi, BCM numbers are Broadcom SoC numbers, and on a Jetson the BCM numbers are Broadcom numbers for a chip that is not there. The library provides the mode because the code needs a number, and a number that means something is the difference between a program that runs on both boards and one that quietly drives the wrong pin.
The string modes are the ones a Raspberry Pi has no equivalent for, and they exist because a Tegra board has signal names that are stable across board revisions in a way that a header position is not. The CVM and CVB connector is a physical interface with named signals, and naming a pin survives board revisions better than counting a header.
For a project that has to run on more than one kind of board, that is the mode worth using, at the cost of a change to the application.
The pinmux lookup tool, and the sample scripts that drive the pins
One extra tool sits alongside the library, and it addresses a problem specific to Tegra.
The jetson-gpio-pinmux-lookup command line tool helps you find the pinmux register address for GPIO pins, which is useful for debugging or setting up pinmux configurations. It takes a BOARD mode GPIO pin number, 1 to 40, and returns the corresponding pinmux register address in hexadecimal.
jetson-gpio-pinmux-lookup 7
# Output on Orin Device: GPIO Pin 7: Mux Register Address = 0x2430070The reason this tool is needed is that on a Tegra board a header pin is not a fixed function. The pin multiplexing hardware decides whether a given physical pin is a GPIO, a UART, an I2C or something else, and that decision lives in a register. Getting the pinmux right is a prerequisite for the GPIO library to control the pin at all, and when it is wrong the symptom is a pin that never changes state.
The sample applications then exercise the library. simple_input.py reads the value at pin 12 of the 40 pin header using BCM numbering and prints it. simple_out.py outputs alternating high and low values at BCM pin 18, or board pin 12, every two seconds.
The three button samples share a wiring recipe: a button between pin 18 and GND, a pull-up resistor from pin 18 to 3V3, and an LED with a current limiting resistor on pin 12. button_led.py reads the button state and keeps the LED on for a second per press. button_event.py does the same with a blocking wait to reduce CPU usage. button_interrupt.py adds a second LED on pin 13, blinking the first continuously and the second five times only on a press.
They can be run directly with python3, or through the run_sample.sh script, which also has a help flag.
Version 2.1.13, a Python 2 classifier, and a Debian directory
The packaging metadata is in setup.py rather than in a modern configuration file, and it carries a couple of details that describe the project's age.
The package name is Jetson.GPIO and the version is 2.1.13. The author is NVIDIA, with the contact address [email protected], and the classifiers list POSIX Linux, the MIT licence, developers as the intended audience, and both Python 2.7 and Python 3 as supported programming language versions.
That Python 2.7 classifier is a leftover from a period when the library supported both, and it is worth noticing because the documentation in the README is written in Python 3 terms, using python3 for the manual install and for running the samples. The code has clearly moved on, while the classifier list has not.
The repository layout matches the structure of a project that ships to several places. There is a lib directory with the Python package, a samples directory, a debian directory for distribution packaging, a dev directory, a setup.py, a MANIFEST.in, a LICENSE.txt and a README, plus a.gitlab-ci.yml and a.github directory.
The licence file is the MIT text with an NVIDIA copyright for 2020 to 2022, and the project publishes no GitHub releases, so the version in setup.py and the version on the package index are the markers.
The last push was on 2026-07-24 and the repository is not archived. For a library whose API is a mirror of another one and whose purpose is to keep working across board generations, that is the expected maintenance profile.
Editorial conclusion
Adopt Jetson.GPIO if you are moving an application from a Raspberry Pi to a Jetson, or writing new GPIO code for a Jetson and want the same import path and API you already know, since the library deliberately mirrors RPi.GPIO down to the module alias. Do not adopt it if you need I2C, SPI or PWM beyond what the samples demonstrate, because the documentation here covers the GPIO API and the pin numbering. Before you write code, install the 99-gpio.rules udev file and reload the udev rules, because the library needs group membership and a device rule to open the pins, and check which of the four numbering modes your application uses, since BOARD and BCM mean different things on a Jetson than they do on a Raspberry Pi.
Frequently asked questions
What is Jetson.GPIO and which boards does it support?
It is a Python library for the 40 pin GPIO header on the Jetson TX1, TX2, AGX Xavier and Nano development boards, providing digital input and output with the same API as the RPi.GPIO library so applications can be moved from a Raspberry Pi.
How do I install Jetson.GPIO and the udev rules?
The easiest route is `sudo pip install Jetson.GPIO`. You also need to create a gpio group, add your user to it, copy the 99-gpio.rules file into the udev rules.d directory and either reboot or run `sudo udevadm control --reload-rules && sudo udevadm trigger`.
Which pin numbering modes does Jetson.GPIO support?
Four: BOARD and BCM, which match the RPi.GPIO modes, plus CVM and TEGRA_SOC, which use signal names on the CVM/CVB connector and the Tegra SoC. The mode is mandatory and is set with a call such as GPIO.setmode(GPIO.BOARD).
What does the jetson-gpio-pinmux-lookup tool do?
It finds the pinmux register address for a GPIO pin, given a BOARD mode pin number from 1 to 40, and prints it in hexadecimal. It is useful for debugging or setting up pinmux configurations on Tegra boards.
Which modules may I import directly?
Only gpio.py, the main component that provides the APIs. The gpio_event.py and gpio_pin_data.py modules are used by gpio.py and must not be imported directly into an application.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nvidia-jetson-gpio)