Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support GPIO pins on Jetson Orin boards #26

Open
penguinland opened this issue Jan 4, 2023 · 9 comments
Open

Support GPIO pins on Jetson Orin boards #26

penguinland opened this issue Jan 4, 2023 · 9 comments

Comments

@penguinland
Copy link

penguinland commented Jan 4, 2023

What kind of new feature are you looking for?

  • Hardware: Jetson Orin AGX (and maybe other Jetson Orin boards, and maybe even other Jetson boards?)

Do you plan to:

  • Contribute an initial driver: Unsure: I'm likely to fork this repo and play around with things, but no guarantees I'll actually get anywhere or send a PR back when I'm finished
  • Write unit tests: No: the real proof that things work is in running on the proper hardware, and the github action runners for this repo don't have a Jetson Orin board connected.
  • Update https://github.com/periph/cmd to use the new functionality: Probably not: my first guess is that it probably doesn't need updating, and my second guess is that whoever contributes the initial driver should update this as well.

Description of the problem
For most sysfs systems, you can enable a GPIO pin by writing a number into /sys/class/gpio/export, at which point you get a new symlink named /sys/class/gpio/gpioN (where N is the number you wrote). This is so universally common that it's hard-coded into this repo, at https://github.com/periph/host/blob/main/sysfs/gpio.go#L493.

Unfortunately, the Jetson Orin (at least, the AGX model, not sure about the others) doesn't name their symlinks gpioN. For example, if you cd /sys/class/gpio; echo "336" > export, instead of getting a symlink named gpio336, you get one named PDD.00. However, the gpio.go file in this repo hardcodes that the symlink should always be at gpio336 (or another number), and then we get "file not found"/"pin not exported" errors later if we try to use any of the GPIO pins.

To support the Jetson Orin AGX (and possibly other boards in the Jetson Orin family, though I haven't tried any of them yet), please make this configurable. The line that needs to change is https://github.com/periph/host/blob/main/sysfs/gpio.go#L493, though various other things probably need to change along with it (maybe the pin definitions need a new field? but that sounds like a lot of work, and hopefully there's an easier approach I haven't thought of).

I'd be happy to help brainstorm ideas of what to do, if that would help. I'm on the fence for whether I'm also willing to make the changes myself, but I'm not a flat-out "no" on that end.

@penguinland
Copy link
Author

If it helps, Nvidia themselves have published a very similar Python library at https://github.com/NVIDIA/jetson-gpio, and perhaps we could take inspiration from that to adapt support for Go as well. I haven't looked at enough details to see how Nvidia's version differs from Periph's version (aside from being written in a different language).

@maruel
Copy link
Member

maruel commented Jan 6, 2023

Thanks for the report. That's really interesting. Can you confirm which kernel version you are running and from which distro it is based from? You can check out via /etc/os-release. The python package you linked to seems to imply it's based on Debian. Maybe there's a way to gather the exported name?

@penguinland
Copy link
Author

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.5 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.5 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

@penguinland
Copy link
Author

penguinland commented Jan 6, 2023

I'd love to have a way to gather the exported names, but I've looked around in a handful of places within /sys/class/gpio, but haven't found anything useful yet. Then again, a month ago I'd never used sysfs, so don't really know what I'm doing yet and might be looking in the wrong places.

Instead, I've got this PDF, pages 38-39, which says what the symlinks will be named in the "SoC GPIO Port #" column of that table. but to be even more complete, I looked for every pin I could find on the machine:

viam@orindevkit2:~$ cd /sys/class/gpio/
viam@orindevkit2:/sys/class/gpio$ ls
export  gpiochip316  gpiochip348  unexport
viam@orindevkit2:/sys/class/gpio$ cat gpiochip316/base 
316
viam@orindevkit2:/sys/class/gpio$ cat gpiochip316/ngpio 
32
viam@orindevkit2:/sys/class/gpio$ cat gpiochip348/base
348
viam@orindevkit2:/sys/class/gpio$ cat gpiochip348/ngpio 
164

and then tried exporting them all to see what all their names are:

viam@orindevkit2:/sys/class/gpio$ for i in `seq 316 512`; do echo "$i: $(echo $i > export; ls|grep -v export|grep -v gpiochip3; echo $i > unexport)"; done
316: PAA.00
317: PAA.01
318: PAA.02
319: PAA.03
320: PAA.04
321: PAA.05
322: PAA.06
323: PAA.07
324: PBB.00
325: PBB.01
326: PBB.02
327: PBB.03
328: PCC.00
329: PCC.01
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
330: 
331: PCC.03
332: PCC.04
333: PCC.05
334: PCC.06
335: PCC.07
336: PDD.00
337: PDD.01
338: PDD.02
339: PEE.00
340: PEE.01
341: PEE.02
342: PEE.03
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
343: 
344: PEE.05
345: PEE.06
346: PEE.07
347: PGG.00
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
348: 
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
349: 
350: PA.02
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
351: 
352: PA.04
353: PA.05
354: PA.06
355: PA.07
356: PB.00
357: PC.00
358: PC.01
359: PC.02
360: PC.03
361: PC.04
362: PC.05
363: PC.06
364: PC.07
365: PD.00
366: PD.01
367: PD.02
368: PD.03
369: PE.00
370: PE.01
371: PE.02
372: PE.03
373: PE.04
374: PE.05
375: PE.06
376: PE.07
377: PF.00
378: PF.01
379: PF.02
380: PF.03
381: PF.04
382: PF.05
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
383: 
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
384: 
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
385: 
386: PG.03
387: PG.04
388: PG.05
389: PG.06
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
390: 
391: PH.00
392: PH.01
393: PH.02
394: PH.03
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
395: 
396: PH.05
397: PH.06
398: PH.07
399: PI.00
400: PI.01
401: PI.02
402: PI.03
403: PI.04
404: PI.05
405: PI.06
406: PJ.00
407: PJ.01
408: PJ.02
409: PJ.03
410: PJ.04
411: PJ.05
412: PK.00
413: PK.01
414: PK.02
415: PK.03
416: PK.04
417: PK.05
418: PK.06
419: PK.07
420: PL.00
421: PL.01
422: PL.02
423: PL.03
424: PM.00
425: PM.01
426: PM.02
427: PM.03
428: PM.04
429: PM.05
430: PM.06
431: PM.07
432: PN.00
433: PN.01
434: PN.02
435: PN.03
436: PN.04
437: PN.05
438: PN.06
439: PN.07
440: PP.00
441: PP.01
442: PP.02
443: PP.03
444: PP.04
445: PP.05
446: PP.06
447: PP.07
448: PQ.00
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
449: 
450: PQ.02
451: PQ.03
452: PQ.04
453: PQ.05
454: PQ.06
455: PQ.07
456: PR.00
457: PR.01
458: PR.02
459: PR.03
460: PR.04
461: PR.05
462: PX.00
463: PX.01
464: PX.02
465: PX.03
466: PX.04
467: PX.05
468: PX.06
469: PX.07
470: PY.00
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
471: 
472: PY.02
473: PY.03
474: PY.04
475: PY.05
476: PY.06
477: PY.07
478: PZ.00
479: PZ.01
480: PZ.02
481: PZ.03
482: PZ.04
483: PZ.05
484: PZ.06
485: PZ.07
486: PAC.00
487: PAC.01
488: PAC.02
489: PAC.03
490: PAC.04
491: PAC.05
492: PAC.06
-bash: echo: write error: Device or resource busy
-bash: echo: write error: Invalid argument
493: 
494: PAD.00
495: PAD.01
496: PAD.02
497: PAD.03
498: PAE.00
499: PAE.01
500: PAF.00
501: PAF.01
502: PAF.02
503: PAF.03
504: PAG.00
505: PAG.01
506: PAG.02
507: PAG.03
508: PAG.04
509: PAG.05
510: PAG.06
511: PAG.07
-bash: echo: write error: Invalid argument
-bash: echo: write error: Invalid argument
512: 

@penguinland
Copy link
Author

You also wanted the kernel version:

viam@orindevkit2:/sys/class/gpio$ uname -a
Linux orindevkit2 5.10.104-tegra #1 SMP PREEMPT Wed Aug 10 20:17:07 PDT 2022 aarch64 aarch64 aarch64 GNU/Linux

@maruel
Copy link
Member

maruel commented Jan 6, 2023

The best would be to search for the linux kernel driver source that generate these.

When exploring /sys, I recommend using ls -la as it will print out the symlink destination.

Searching for gpiochip348 tegra, I found https://developer.nvidia.com/docs/drive/drive-os/archives/6.0.3/linux/sdk/oxy_ex-1/common/topics/sys_components/CalculatingGPIOIndexinLinux32.html

and
https://developer.download.nvidia.com/assets/embedded/secure/jetson/agx_orin/Adaptation_and_Bringup_for_Jetson_AGX_Orin.pdf?LBKj9NpLo9EB8mwRVFJTb-f62Rr9jdlFSWGMmllVOd90fKgg8ETpxfU_U1aIEyNft8SDZQCHoJKPJJL1c1ocqeLsb1OWi1mO3IEgTg955uEhk-dFtMg0fplXEUOikIGX1-0Qt6d3jnwbBxU-g66_SvkKlTqTSvNH9XBFIg3fL6nLagF6FYq-piug_gRCRhFtGLyeRQ==

The gpio pin number calculation seems to be of a similar type than what allwinner does. You can check the calculation in periph's driver.

@penguinland
Copy link
Author

Your second link doesn't work for me, even if I'm logged into my Nvidia account. What does it describe?

Your first link seems like an excellent way to map a (bank, pin) pair to an index, but I think we're looking for the inverse mapping (from an index like 466 back to a bank/pin like PS.05). I'll think some more about whether there's an easy way to compute that inverse without just hardcoding a map of 200ish items.

@maruel
Copy link
Member

maruel commented Jan 8, 2023

This link should work: https://developer.nvidia.com/downloads/adaptation-and-bringup-jetson-agx-orinpdf

And yes, we want the reverse mapping.

@penguinland
Copy link
Author

I've made #27 to fix this. and it works, but I suspect there should have been a more elegant approach. I'm willing to some more cleanup/refactoring/reorganizing if it would help get this merged, but I'm also perfectly happy for it not to be merged at all, and I can just continue on my fork. 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants