마더보드의 GPIO 핀이 작동하도록 하려고 하는데 핀의 번호/설명과 드라이버가 로드되었는지 알 수 없습니다.
내가 찾은이것어디로 가야 할지 안내해줘에코설명을 핀으로 지정하고 출력을 다음으로 리디렉션합니다./sys/class/gpio/export
/sys/class/gpio # echo 0 > export
그래서 나는 그랬다. 이것/시스템/클래스/GPIO/내 시스템에 다음 내용이 포함된 폴더가 있습니다.
[user@host ~]$ ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 Nov 30 18:12 export
--w------- 1 root root 4096 Nov 30 18:12 unexport
[user@host ~]$
(그런데 이 폴더가 보이면 드라이버가 로드되었다는 뜻인가요?)
그런 다음 마더보드 데이터시트에서 여러 핀 이름을 시도했지만 항상 다음과 같은 결과가 나타납니다.
[root@host gpio]# echo 31 > export
echo: write error: Invalid argument
[root@host gpio]#
나는 사용하고있다아키텍처Linux내 커널 버전은 4.19.2-arch1-1-ARCH입니다.
제가 사용하는 메인보드는슈퍼마이크로 X10SBA.https://www.supermicro.com/products/motherboard/celeron/x10/x10sba.cfm
마더보드의 GPIO에 대해 찾을 수 있는 유일한 정보는 2-25페이지에 있습니다.X10SBA 마더보드 데이터시트:
1 +3.3V
2 SOC_P3V3_GPIO_S5_31
3 SOC_P3V3_GPIO_S5_32
4 SOC_P3V3_GPIO_S5_33
5 SOC_P3V3_GPIO_S5_34
6 SOC_P3V3_GPIO_S5_35
7 SOC_P3V3_GPIO_S5_36
8 3_GPIO_S5 _37
9 SOC_P3V3_GPIO_S5_38
10 접지
제가 이해한 바에 따르면 이는 보드에 8개의 GPIO가 있음을 의미합니다.
그래서 다양한 조합을 시도했습니다./sys/class/gpio/export좋다
echo SOC_P3V3_GPIO_S5_31 > export
echo 111 > export
echo 531 > export
echo S531 > export
echo S5_31 > export
...
등. 아무것도 작동하지 않습니다.
여기서 근본적으로 잘못된 일을 하고 있는 걸까요? 이러한 GPIO 이름은 어디에 정의되어 있습니까? 어디출구정보를 어디서 얻을 수 있나요? 먼저 이러한 정의를 직접 내려야 합니까? 어쩌면 커널을 다시 컴파일해야 할까요?
GPIO 헤더에 어떤 칩이 사용되었는지 계속해서 알아내려고 노력했습니다.
회로 기판의 GPIO 핀 헤더(JP1) 옆에 칩이 있습니다.NXP GTL2010(데이터 시트) 및 D1에서 D8까지의 핀이 여기에 연결됩니다. 칩은 출력이 3.3V 또는 5V가 되도록 약간의 전압 변환을 수행하는 것 같습니다. 따라서 신호는 S1-S8 핀에서 나와야 합니다. 불행히도 트레이스가 보드의 비아로 연결되기 때문에 GTL2010의 소스 핀이 어디에 연결되어 있는지 찾을 수 없습니다.
하지만 핀이 CPU에 직접 연결되어 있다고 가정합니다. 나는 이것에 대해 100% 확신하지 못합니다. 하지만 그건 내 가정이다.
마더보드의 CPU는 Intel Celeron J1900입니다. 하지만 안타깝게도 데이터시트나 GPIO 유무에 대한 정보를 찾을 수 없습니다.
Linux의 보드에 GPIO를 나열할 수 있습니까? 특정 GPIO 드라이버가 내 시스템에서 이미 사용 중인지 어떻게 확인합니까?
편집하다
약간의 조사 끝에CPU 데이터시트GPIO 설정을 변경하려면 GPIO_BASE_ADDRESS 레지스터(데이터시트 페이지 1219)를 설정해야 한다는 것을 알았습니다. 이 레지스터에는 GPIO 로직이 있는 I/O 공간의 기본 주소가 필요합니다. 이제 여기에 어떤 주소를 입력해야 할지 모르겠습니다. I/O 공간에 256개의 여유 바이트가 있을 수 있습니까?
그 외에도 GPIO_BASE_ADDRESS 레지스터에 액세스하는 방법을 이해하지 못합니다. 데이터시트에는 이 레지스터가 PCI 구성 공간에 있다고 명시되어 있습니다. 버스 0, 장치 31(16진수 1f), 기능 0. (데이터시트 56페이지)
이제 lspci는 장치 31에 대해 다음과 같은 출력을 제공합니다.
[user@host ~]$ sudo lspci -vvvvvv
...
00:1f.0 ISA bridge: Intel Corporation Atom Processor Z36xxx/Z37xxx Series Power Control Unit (rev 0e)
Subsystem: Super Micro Computer Inc Atom Processor Z36xxx/Z37xxx Series Power Control Unit
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Capabilities: [e0] Vendor Specific Information: Len=0c <?>
Kernel driver in use: lpc_ich
Kernel modules: lpc_ich
00:1f.3 SMBus: Intel Corporation Atom Processor E3800 Series SMBus Controller (rev 0e)
Subsystem: Super Micro Computer Inc Atom Processor E3800 Series SMBus Controller
Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin B routed to IRQ 18
Region 0: Memory at 90a04000 (32-bit, non-prefetchable) [size=32]
Region 4: I/O ports at e000 [size=32]
Capabilities: [50] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: i801_smbus
Kernel modules: i2c_i801
레지스터에 기본 주소를 쓰기 위해 이 영역에 어떻게 접근해야 하는지 모르겠고, IO 공간에서 레지스터를 어디에 넣어야 할지 모르겠습니다. C에서 어떻게 이를 달성할 수 있나요? 이를 달성하기 위해 기존 Linux 기능을 활용할 수 있습니까?
편집하다
구성 공간의 16진 덤프는 다음을 출력합니다.
[user@host ~]$ sudo lspci -xxx -s 00:1f.0
[sudo] password for user:
00:1f.0 ISA bridge: Intel Corporation Atom Processor Z36xxx/Z37xxx Series Power Control Unit (rev 0e)
00: 86 80 1c 0f 07 00 10 02 0e 00 01 06 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 d9 15 16 08
30: 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00
40: 03 04 00 00 02 30 d0 fe 03 05 00 00 02 c0 d0 fe
50: 02 80 d0 fe 02 10 d0 fe 02 00 f0 fe 02 50 d0 fe
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 cf ff 00 00 00 00 00 00
e0: 09 00 0c 10 00 00 00 00 00 00 00 00 00 00 00 00
f0: 01 c0 d1 fe 00 00 00 00 1a 0f 0e 01 03 03 00 00
[user@host ~]$
내 해석에 따르면 ACPI_BASE_ADDRESS 레지스터(매뉴얼 1217페이지)에는 "03 04 00 00"이 포함되어 있습니다.
GPIO_BASE_ADDRESS 레지스터(매뉴얼 1219페이지)에는 "03 05 00 00"이 포함되어 있습니다.
dmesg에서 acpi를 찾으면 여러 항목이 반환됩니다(여기에 게시하기에는 너무 많습니다).
/proc/ioports는 다음을 출력합니다:
[user@host ~]$ sudo cat /proc/ioports
[sudo] password for user:
0000-006f : PCI Bus 0000:00
0000-001f : dma1
0020-0021 : pic1
0040-0043 : timer0
0050-0053 : timer1
0060-0060 : keyboard
0064-0064 : keyboard
0070-0077 : PCI Bus 0000:00
0070-0077 : rtc0
0078-0cf7 : PCI Bus 0000:00
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
02e0-02e7 : serial
02f8-02ff : serial
03e0-03e7 : serial
03f8-03ff : serial
0400-047f : pnp 00:01
0400-0403 : ACPI PM1a_EVT_BLK
0404-0405 : ACPI PM1a_CNT_BLK
0408-040b : ACPI PM_TMR
0420-042f : ACPI GPE0_BLK
0430-0433 : iTCO_wdt.0.auto
0430-0433 : iTCO_wdt
0450-0450 : ACPI PM2_CNT_BLK
0460-047f : iTCO_wdt.0.auto
0460-047f : iTCO_wdt
0500-05fe : pnp 00:01
0600-061f : pnp 00:01
0680-069f : pnp 00:01
0a30-0a3f : pnp 00:07
0cf8-0cff : PCI conf1
0d00-ffff : PCI Bus 0000:00
1000-1fff : PCI Bus 0000:01
b000-cfff : PCI Bus 0000:03
b000-cfff : PCI Bus 0000:04
b000-bfff : PCI Bus 0000:07
b000-b01f : 0000:07:00.0
b000-b01f : ahci
b020-b023 : 0000:07:00.0
b020-b023 : ahci
b030-b037 : 0000:07:00.0
b030-b037 : ahci
b040-b043 : 0000:07:00.0
b040-b043 : ahci
b050-b057 : 0000:07:00.0
b050-b057 : ahci
c000-cfff : PCI Bus 0000:05
c000-c01f : 0000:05:00.0
d000-dfff : PCI Bus 0000:02
d000-d01f : 0000:02:00.0
e000-e01f : 0000:00:1f.3
e000-e01f : i801_smbus
e020-e027 : 0000:00:02.0
답변1
일반적으로 GPIO 핀은 하드웨어에 따라 매우 다릅니다. 시스템 이름, 시스템 드라이버, 시스템 레지스터가 없습니다.
당신이 할 수 있는 유일한 일은 당신이 가지고 있는 정보를 읽고, 구글링하고, 추측하는 것입니다.
마더보드 설명서에 나와 있듯이 GPIO 헤더가 있으며 GPIO 핀이 실제로 물리적으로 라우팅되어 있다고 가정할 수 있습니다. (이는 주어진 것이 아닙니다. GPIO 핀은 BIOS에서 다른 목적으로 사용될 수도 있고 그냥 남겨질 수도 있습니다. 열려 있는 ). "SOC"는 "시스템 온 칩"을 의미하고 "3V3"은 3.3V(TTL 레벨)를 의미합니다.
첫째,경고하다: 이 헤더를 SoC에 직접 연결하면 잘못된 작동으로 인해 SoC가 손상되기 쉽습니다. 정전기 방전, 잘못된 전압 레벨, 혼란스러운 입력 및 출력 등으로 인해 SoC와 메인 CPU가 손상될 수 있습니다.언제나사용하시려면 먼저 버퍼칩을 연결해 주세요. 옆에 있는 버퍼 칩도 실제로는 이 헤더를 보호할 뿐 다른 어떤 것도 보호하지 않습니다.
이제 데이터 테이블이 필요합니다. 구글 검색이 나오네요이것,좋아 보이네요.
이는 SoC에 S0용 GPIO 핀 101개, S5용 GPIO 핀 43개가 있음을 알려줍니다. 그 중 10개만이 마더보드 헤더에 표시되었지만 운 좋게도 우리는 그것이 어떤 것인지 알고 있습니다. 다른 것들은 마더보드의 다른 것들에 연결될 수 있으므로 그대로 두는 것이 중요합니다.
56페이지에서는 GPIO(PCU)가 I/O 구조의 PCI 장치에 의해 디코딩된 256바이트 길이의 이동식 I/O 범위임을 알려줍니다. 어떻게 설명해야 할지 모르겠습니다 GBA: PCI[B:0,D:31,F:0] + 48h
. 어쨌든 이것이 의미하는 바는 다음 단계는 lspci
어떤 PCI 장치가 의미하는지 파악하고 유망해 보이는 256바이트 영역을 찾는 데 필요한 만큼의 세부 정보를 사용하는 것입니다.
1262페이지부터 PCU(플랫폼 장치 컨트롤러), 특히 GPIO 레지스터에 대해 자세히 소개합니다.
따라서 다음 단계는 이 모든 내용을 읽고 이해한 후 올바른 PCI 카드와 영역을 사용하는 커널 드라이버를 작성하는 것입니다. 이 드라이버는 I/O 핀이 아래에 나타나도록 합니다 /sys/class/gpio
. 기사를 쓰면 안 된다.또한어렵고, 기존 GPIO 드라이버를 검색하고 이 하드웨어에 맞게 수정하는 것만으로도 충분합니다. C로 프로그래밍하는 방법을 알아야 하고, 커널 모듈 작성 방법을 스스로 가르칠 수 있어야 합니다.
해당 특정 하드웨어에 대한 드라이버가 이미 존재하지만 적어도 커널에 없을 수도 있습니다(또는 이미 일부 핀이 표시되어 있음).
편집하다
OK, B, D, F는 PCI 장치의 버스, 장치 및 기능과 일치하는 것으로 보이며 SMBus 컨트롤러에는 2개의 32바이트 영역이 있으므로 적어도 하나는 설명서에 설명된 영역과 일치합니다.
그러나 지역은 없고 00:1f.0
공급업체별 블록만 있습니다. 데이터 시트에는 +40
ACPI 전원 관리, +48h
GPIO 및 +f0h
RCBA가 언급되어 있으며 "BAR(기본 주소 레지스터) 또는 이와 유사한 것을 사용하여 설정됩니다"라고 나와 있으므로 BAR/지역이 아니라 PCI 구성의 바이트일 수도 있습니다.
lspci -xxx -s 00:1f.0
따라서 전체 구성 공간을 hexdump로 표시하는 이와 같은 작업(루트로)을 시도하십시오 . 또한 dmesg
부팅 후 어딘가에 ACPI 전원 관리가 나타나는지 확인하십시오 cat /proc/ioports
(즉, 연결된 I/O 포트 범위가 있는지). 와 비교할 수 있습니다 +40h
. 정보로 질문을 편집하십시오.
GPIO 범위가 BAR/지역에 없으면 활성화하기가 매우 어려워집니다. 이 시점에서 커널 드라이버 작성을 시작해야 합니다.
편집하다
Coreboot 프로젝트에는 다음과 같은 Intel의 GPIO 항목에 액세스하는 코드도 있습니다.GPIO.c그리고GPIO.h베이트레일 아키텍처. Celeron J1900이 어떤 아키텍처에 속하는지는 확실하지 않지만, 일치하지 않더라도 GPIO 영역이 제대로 작동하는지 여부에 대한 힌트를 줄 수 있습니다.
편집하다
음, BAR은 실제로 비어 있습니다. +40h와 +48h가 스트립처럼 작동한다고 가정하면 둘 다 I/O 공간입니다(최하위 비트는 1).
+40h (ACPI) = 0400h
+48h (GPIO) = 0500h
/proc/ioports
이는 다음과 비교하면 의미가 있습니다. ACPI는 0400-047f이고 0500-05fe는 동일한 장치에 예약되어 있습니다 pnp 00:01
.
이는 I/O 범위이며 매핑되었습니다. /dev/port
올바른 오프셋에서 읽고 써서 액세스하거나 C 프로그램에서 사용할 수 있습니다 ioperm
. Linux 커널 개발자가 이러한 기능 중 하나 또는 둘 다를 비활성화하겠다고 위협한 것을 어렴풋이 기억하지만 여전히 작동하는지 모르겠습니다. 이 경우 커널 드라이버가 필요합니다.
그럼에도 불구하고 I/O 공간을 사용할 때는 매우 주의해야 합니다. 잘못된 주소를 읽는 경우에도 하드웨어 작동이 발생할 수 있으며, 임의의 주소에서 수행하면 어떤 일이 발생할 수 있습니다. 그래서 아니야 hexdump -C /dev/port
. 또한 액세스 크기도 중요합니다.
데이터시트에서 GPIO I/O 공간이 어떻게 작동하는지에 대한 구체적인 내용을 찾을 수 없으므로 더 나은 데이터시트를 위해 Google을 검색해야 하거나 Coreboot 파일이 충분히 유사하게 작동할 수 있습니다.
답변2
비슷한 하드웨어를 구입했는데 비슷한 문제가 발생했습니다. 처음에는 다른 분들이 알려주신 경로를 탐색해 보려고 하다가 다음과 같이 해결했습니다.
내 시스템: CPU 버전: Intel(R) Celeron(R) CPU J1900 @ 1.99GHz
어느 시점에서 나는 이것이 IT8786 칩에 구현되어 있다고 생각했습니다.
커널 구성을 확인하면 IT87x 시리즈 드라이버에 대한 지원을 찾을 수 있습니다(물론 GPIO 드라이버 아래). 내 경우에는 모듈로만 활성화됩니다.
그런 다음 모듈을 로드했습니다.
sudo insmod /lib/modules/5.8.0-55-generic/kernel/drivers/gpio/gpio-it87.ko
dmesg는 다음 항목을 반환합니다.
gpio_it87: Found Chip IT8786 rev 2. 64 GPIO lines starting at 0a00h
/dev를 확인하면 gpiochip0이 나타나고 거기에서 원하는 경우 이미 언급한(비록 은퇴했지만) sysfs 방법을 사용할 수 있습니다.
물리적 핀을 하드웨어와 연결하는 방법을 모르는 경우 다음을 시도해 보십시오.
apt-get install gpiod
제 경우에는 gpioinfo를 실행하면 다음이 반환됩니다.
gpiochip0 - 64 lines:
line 0: "it87_gp10" unused input active-high
line 1: "it87_gp11" unused input active-high
line 2: "it87_gp12" "sysfs" input active-high [used]
line 3: "it87_gp13" unused input active-high
line 4: "it87_gp14" unused input active-high
line 5: "it87_gp15" unused input active-high
line 6: "it87_gp16" unused input active-high
line 7: "it87_gp17" unused input active-high
line 8: "it87_gp20" unused input active-high
line 9: "it87_gp21" unused input active-high
line 10: "it87_gp22" unused input active-high
line 11: "it87_gp23" unused input active-high
line 12: "it87_gp24" "sysfs" input active-high [used]
line 13: "it87_gp25" unused input active-high
line 14: "it87_gp26" unused input active-high
line 15: "it87_gp27" unused input active-high
line 16: "it87_gp30" unused input active-high
line 17: "it87_gp31" unused input active-high
line 18: "it87_gp32" unused input active-high
line 19: "it87_gp33" unused input active-high
line 20: "it87_gp34" unused input active-high
line 21: "it87_gp35" unused input active-high
line 22: "it87_gp36" "sysfs" output active-high [used]
line 23: "it87_gp37" unused input active-high
line 24: "it87_gp40" unused input active-high
line 25: "it87_gp41" unused input active-high
line 26: "it87_gp42" unused input active-high
line 27: "it87_gp43" unused input active-high
line 28: "it87_gp44" unused input active-high
line 29: "it87_gp45" unused input active-high
line 30: "it87_gp46" unused input active-high
line 31: "it87_gp47" unused input active-high
line 32: "it87_gp50" unused input active-high
line 33: "it87_gp51" unused input active-high
line 34: "it87_gp52" unused input active-high
line 35: "it87_gp53" unused input active-high
line 36: "it87_gp54" unused input active-high
line 37: "it87_gp55" unused input active-high
line 38: "it87_gp56" unused input active-high
line 39: "it87_gp57" unused input active-high
line 40: "it87_gp60" unused input active-high
line 41: "it87_gp61" unused input active-high
line 42: "it87_gp62" unused input active-high
line 43: "it87_gp63" unused input active-high
line 44: "it87_gp64" unused input active-high
line 45: "it87_gp65" unused input active-high
line 46: "it87_gp66" unused input active-high
line 47: "it87_gp67" unused input active-high
line 48: "it87_gp70" unused input active-high
line 49: "it87_gp71" unused input active-high
line 50: "it87_gp72" unused input active-high
line 51: "it87_gp73" "sysfs" input active-high [used]
line 52: "it87_gp74" "sysfs" output active-high [used]
line 53: "it87_gp75" "sysfs" input active-high [used]
line 54: "it87_gp76" "sysfs" input active-high [used]
line 55: "it87_gp77" unused input active-high
line 56: "it87_gp80" unused input active-high
line 57: "it87_gp81" unused output active-high
line 58: "it87_gp82" unused input active-high
line 59: "it87_gp83" unused input active-high
line 60: "it87_gp84" unused input active-high
line 61: "it87_gp85" unused input active-high
line 62: "it87_gp86" unused input active-high
line 63: "it87_gp87" unused input active-high
gpiod 유틸리티를 사용하여 다양한 핀을 처리할 수 있습니다. 제조업체에서 사용할 수 있는 GPI/O를 지시하는 경우 "라인"을 "it87_gpXX" 부분, 즉 제조업체에서 제공할 수 있는 XX 핀과 연결할 수 있습니다.
빠른 검사는 구식 방식으로 수행할 수 있습니다.
/sys/class/gpio로 이동하여 발견된 gpio칩을 확인하세요. gpiochip 내부의 베이스는 시작 위치이고, gpioinfo에서 반환된 선 포인트는 오프셋입니다.
제 경우에는 448을 베이스로 사용했습니다. 57번째 줄인 GP81에 도달하려면 다음을 수행합니다.
echo 505 > /sys/class/gpio/export
이게 도움이 되길 바란다! 덕분에 드라이버를 작성할 필요가 없어졌습니다(제조업체에서 드라이버를 보냈지만 작동하지 않았습니다).