目录
- Linux GPIO子系统
- TX2 Linux GPIO计算
- Xavier Linux GPIO计算
- 参考
- 用C快捷计算TX2 Linux GPIO
- 用C快捷计算Xavier Linux GPIO
- Debug
- 微信公众号
Linux GPIO子系统
Linux命令行常用echo, cat等操作GPIO:
$ ls /sys/class/gpio
export gpiochip232 gpiochip240 gpiochip256 gpiochip320 unexport
$ echo 277 > /sys/class/gpio/export
$ ls /sys/class/gpio
export gpio277 gpiochip232 gpiochip240 gpiochip256 gpiochip320 unexport
$ echo out > /sys/class/gpio/gpio277/direction
$ echo 1 > /sys/class/gpio/gpio277/value
$ cat /sys/class/gpio/gpio277/value
1
当然这些命令断电失效, 可以写成脚本设置开机运行, 有兴趣搜索Ubuntu16,或者Ubuntu18设置开机脚本.
TX2 Linux GPIO计算
关于上面277的由来 GPIO4_CAM_STROBE -> GPIO3_PV.05 -> V=>2, 2*8+256+5=277
.
原理图中用的是GPIO4_CAM_STROBE
这个引脚:
查 Jetson TX2 Series Pinmux 这个xls表格:
表格中 GPIO4_CAM_STROBE -> GPIO3_PV.05
.
linux/include/dt-bindings/gpio/tegra186-gpio.h github, linux的代码对TX2端口进行了编号(TX2->tegra186-gpio.h, Xavier->tegra194-gpio.h):
#define TEGRA186_MAIN_GPIO_PORT_A 0
#define TEGRA186_MAIN_GPIO_PORT_B 1
#define TEGRA186_MAIN_GPIO_PORT_C 2
#define TEGRA186_MAIN_GPIO_PORT_D 3
#define TEGRA186_MAIN_GPIO_PORT_E 4
#define TEGRA186_MAIN_GPIO_PORT_F 5
#define TEGRA186_MAIN_GPIO_PORT_G 6
#define TEGRA186_MAIN_GPIO_PORT_H 7
#define TEGRA186_MAIN_GPIO_PORT_I 8
#define TEGRA186_MAIN_GPIO_PORT_J 9
#define TEGRA186_MAIN_GPIO_PORT_K 10
#define TEGRA186_MAIN_GPIO_PORT_L 11
#define TEGRA186_MAIN_GPIO_PORT_M 12
#define TEGRA186_MAIN_GPIO_PORT_N 13
#define TEGRA186_MAIN_GPIO_PORT_O 14
#define TEGRA186_MAIN_GPIO_PORT_P 15
#define TEGRA186_MAIN_GPIO_PORT_Q 16
#define TEGRA186_MAIN_GPIO_PORT_R 17
#define TEGRA186_MAIN_GPIO_PORT_T 18
#define TEGRA186_MAIN_GPIO_PORT_X 19
#define TEGRA186_MAIN_GPIO_PORT_Y 20
#define TEGRA186_MAIN_GPIO_PORT_BB 21
#define TEGRA186_MAIN_GPIO_PORT_CC 22
#define TEGRA186_MAIN_GPIO(port, offset) \
((TEGRA186_MAIN_GPIO_PORT_##port * 8) + offset)
#define TEGRA186_AON_GPIO_PORT_S 0
#define TEGRA186_AON_GPIO_PORT_U 1
#define TEGRA186_AON_GPIO_PORT_V 2
#define TEGRA186_AON_GPIO_PORT_W 3
#define TEGRA186_AON_GPIO_PORT_Z 4
#define TEGRA186_AON_GPIO_PORT_AA 5
#define TEGRA186_AON_GPIO_PORT_EE 6
#define TEGRA186_AON_GPIO_PORT_FF 7
#define TEGRA186_AON_GPIO(port, offset) \
((TEGRA186_AON_GPIO_PORT_##port * 8) + offset)
其中的:
- TEGRA186_MAIN_GPIO, 也就是
tegra-gpio, at base index 320
, 来源 TX2 GPIO Changes - TEGRA186_AON_GPIO, 也就是
tegra-gpio-aon, at base index 256
- offset = base + pin
TEGRA186_AON_GPIO_PORT_V
对应2, 属于tegra-gpio-aon组, 基值是256, 那么 GPIO3_PV.05 对应的就是TEGRA186_MAIN_GPIO(V, (256+5)) => ((TEGRA186_MAIN_GPIO_PORT_V* 8) + offset) = 2*8+256+5 = 277
.
Xavier Linux GPIO计算
tegra194-gpio.h, 这里把Xavier的 linux/include/dt-bindings/gpio/tegra194-gpio.h github也贴过来方便查阅:
#ifndef _DT_BINDINGS_GPIO_TEGRA194_GPIO_H
#define _DT_BINDINGS_GPIO_TEGRA194_GPIO_H
#include <dt-bindings/gpio/gpio.h>
#define TEGRA194_MAIN_GPIO_PORT_A 0
#define TEGRA194_MAIN_GPIO_PORT_B 1
#define TEGRA194_MAIN_GPIO_PORT_C 2
#define TEGRA194_MAIN_GPIO_PORT_D 3
#define TEGRA194_MAIN_GPIO_PORT_E 4
#define TEGRA194_MAIN_GPIO_PORT_F 5
#define TEGRA194_MAIN_GPIO_PORT_G 6
#define TEGRA194_MAIN_GPIO_PORT_H 7
#define TEGRA194_MAIN_GPIO_PORT_I 8
#define TEGRA194_MAIN_GPIO_PORT_J 9
#define TEGRA194_MAIN_GPIO_PORT_K 10
#define TEGRA194_MAIN_GPIO_PORT_L 11
#define TEGRA194_MAIN_GPIO_PORT_M 12
#define TEGRA194_MAIN_GPIO_PORT_N 13
#define TEGRA194_MAIN_GPIO_PORT_O 14
#define TEGRA194_MAIN_GPIO_PORT_P 15
#define TEGRA194_MAIN_GPIO_PORT_Q 16
#define TEGRA194_MAIN_GPIO_PORT_R 17
#define TEGRA194_MAIN_GPIO_PORT_S 18
#define TEGRA194_MAIN_GPIO_PORT_T 19
#define TEGRA194_MAIN_GPIO_PORT_U 20
#define TEGRA194_MAIN_GPIO_PORT_V 21
#define TEGRA194_MAIN_GPIO_PORT_W 22
#define TEGRA194_MAIN_GPIO_PORT_X 23
#define TEGRA194_MAIN_GPIO_PORT_Y 24
#define TEGRA194_MAIN_GPIO_PORT_Z 25
#define TEGRA194_MAIN_GPIO_PORT_FF 26
#define TEGRA194_MAIN_GPIO_PORT_GG 27
#define TEGRA194_MAIN_GPIO(port, offset) \
((TEGRA194_MAIN_GPIO_PORT_##port * 8) + offset)
#define TEGRA194_AON_GPIO_PORT_AA 0
#define TEGRA194_AON_GPIO_PORT_BB 1
#define TEGRA194_AON_GPIO_PORT_CC 2
#define TEGRA194_AON_GPIO_PORT_DD 3
#define TEGRA194_AON_GPIO_PORT_EE 4
#define TEGRA194_AON_GPIO(port, offset) \
((TEGRA194_AON_GPIO_PORT_##port * 8) + offset)
#endif
基地值也变了:
- tegra-gpio, at base index 288
- tegra-gpio-aon, at base index 248
如 原理图中的信号 SPI1_SCK:
- 查 [Jetson AGX Xavier Pinmux] 表格, 对应
GPIO3_PZ.03
- 上面头文件
tegra194-gpio.h
定义了#define TEGRA194_MAIN_GPIO_PORT_Z 25
TEGRA194_MAIN_GPIO
, 也就是tegra-gpio
, 基值为288- Linux GPIO计算结果: 25*8 + 288 + 3 = 491
参考
Tegra Wiki 里面写了模型号 TX2->T186
, Xavier->T194
:
Xavier GPIO Changes 里面指出了tegra-gpio
基值288, tegra-gpio-aon
基值248.
TX2 GPIO Changes 里面指出了tegra-gpio
基值320, tegra-gpio-aon
基值256.
Jetson TX2 Series Pinmux excel表格可以查TX2信号名与引脚标号的对应关系.
Jetson AGX Xavier Pinmux excel表格可以查Xavier信号名与引脚标号的对应关系.
Jeson Pinmux
NVIDIA Jetson TX2 J21 Header Pinout JetsonHacks
NVIDIA Jetson AGX Xavier GPIO Header Pinout JetsonHacks
用C快捷计算TX2 Linux GPIO
顺手撸了个TX2的tx2_pinout.c
:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
char port_array[33][3] = {"P0","P1",
"S","U","V","W","Z","AA","EE","FF", \
"A","B","C","D","E","F","G","H", \
"I","J","K","L","M","N","O","P", \
"Q","R","T","X","Y","BB","CC"};
char *strupr(char *str){
char *orign=str;
for (; *str!='\0'; str++)
*str = toupper(*str);
return orign;
}
int main(int argc, char **argv)
{
if(argc >= 3) {
for(int i = 0; i < 33; i++) {
if( (strcmp(port_array[i], strupr(argv[1])) == 0) && (atoi(argv[2]) < 8)) {
printf("%s.%s Linux GPIO: %d\n", argv[1], argv[2], i * 8 + atoi(argv[2]) + 240);
return 0;
}
}
}
printf("Segmentation fault, input like \"./tx2_pinout AA 02\"\n");
return 0;
}
gcc -o tx2_pinout tx2_pinout.c
, 然后测试一下:
$ ./tx2_pinout A 04
A.04 Linux GPIO: 324
$ ./tx2_pinout P1 6
P1.6 Linux GPIO: 254
$ ./tx2_pinout N 04
N.04 Linux GPIO: 428
$ ./tx2_pinout EE 01
EE.01 Linux GPIO: 305
其中, ./tx2_pinout P1 6
指P16. 这里的P0, P1是为了迎合 TX2用I2C通过TCA9539扩展的GPIO对应的P16, P17的计算, 这个基值是240:
可参考Jetson TX2 GPIO mapping
用C快捷计算Xavier Linux GPIO
再顺手撸个Xavier的xavier_pinout.c
:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
char port_array[33][3] = {"AA","BB", "CC", "DD", "EE", \
"A","B","C","D","E","F","G", \
"H","I","J","K","L","M","N", \
"O","P","Q","R","S","T", \
"U","V","W","X","Y","Z", \
"FF","GG"};
char *strupr(char *str){
char *orign=str;
for (; *str!='\0'; str++)
*str = toupper(*str);
return orign;
}
int main(int argc, char **argv)
{
if(argc >= 3) {
for(int i = 0; i < 33; i++) {
if( (strcmp(port_array[i], strupr(argv[1])) == 0) && (atoi(argv[2]) < 8)) {
printf("%s.%s Linux GPIO: %d\n", argv[1], argv[2], i * 8 + atoi(argv[2]) + 248);
return 0;
}
}
}
printf("Segmentation fault, input like \"./tx2_pinout AA 02\"\n");
return 0;
}
gcc -o xavier_pinout xavier_pinout.c
, 然后测试一下:
$ ./xavier_pinout Q 06
Q.06 Linux GPIO: 422
$ ./xavier_pinout R 02
R.02 Linux GPIO: 426
$ ./xavier_pinout B 00
B.00 Linux GPIO: 296
$ ./xavier_pinout BB 00
BB.00 Linux GPIO: 256
$ ./xavier_pinout CC 07
CC.07 Linux GPIO: 271
$ ./xavier_pinout I 01
I.01 Linux GPIO: 353
可以和 Jetson AGX Xavier GPIO Expansion Header Mapping 对照结果.
Debug
有时出现错误:
$ ls /sys/class/gpio
export gpio245 gpiochip232 gpiochip240 gpiochip256 gpiochip320 unexport
$ echo 247 > /sys/class/gpio/export
-bash: echo: write error: Device or resource busy
用sudo, unexport也不行, 可以sudo cat /sys/kernel/debug/gpio
查看:
$ sudo cat /sys/kernel/debug/gpio
gpiochip3: GPIOs 232-239, parent: platform/max77620-gpio, max77620-gpio, can sleep:
gpio-232 ( |external-connection:) in hi
gpio-237 ( |spmic_gpio_input ) in hi
gpio-238 ( |spmic_gpio_input ) in hi
gpiochip2: GPIOs 240-255, parent: i2c/0-0074, tca9539, can sleep:
gpio-240 ( |vdd-usb2-5v ) out lo
gpio-241 ( |en-vdd-ts-1v8 ) out hi
gpio-242 ( |en-vdd-ts-hv-3v3 ) out hi
gpio-243 ( |en-vdd-disp-3v3 ) out lo
gpio-244 ( |vdd-fan ) out hi
gpio-245 ( |sysfs ) out hi
gpio-247 ( |en-mdm-pwr-3v7 ) out lo
...
可以看到, 247已经用作输出0被占用了, 这种需要修改刷写设备树了.
微信公众号
欢迎扫描二维码关注本人微信公众号, 及时获取或者发送给我最新消息:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)