티스토리 뷰

Study/Linux

[Linux] GPIO interface

생각많은 소심남 2015. 10. 12. 11:56

 *이 글은 linux documentation에 있는 내용을 번역하고 개인 의견을 첨부한 것이다.


GPIO란 무엇인가?

 General Purpose Input / Output (GPIO)는 디지털 신호를 소프트웨어로 처리할 수 있는 개념을 말한다. 이런 기능을 제공하는 다양한 컨트롤러 칩들이 있고, embedded 시스템이나 특수한 하드웨어를 제어하는데 있어서 많이 사용된다. 보통 각각의 GPIO 라고 하는 것은 컨트롤러 칩의 특정 핀과 연결된 형태를 말하기도 하고, 혹은 Ball Grid Array라고 하는 규격에서의 Ball을 나타내기도 한다. 보드의 설계도를 보게 되면 어떤 GPIO가 어떤 외부 하드웨어와 연결되어 있는지를 보여주고 있기 때문에 GPIO를 통해서 하드웨어를 제어하고자 하는 사람은 반드시 설계도와 코드를 동시에 볼 수 있어야 한다. 

 일반적인 System-on-Chip 형태의 프로세서는 거의 상당 부분의 신호를 GPIO를 통해서 전달한다. 몇몇 상황에서 대해서는 특정 기능이 할당되어 있지 않는 출력핀은 GPIO로 동작하기도 하고, 대부분 여러 개의 묶음 형태로 제공한다. FPGA와 같이 내부 회로를 프로그래밍을 통해서 설계하는 하드웨어(예를 들어서 power manager와 같은 다양한 기능을 제공하는 칩이나 오디오 코덱)같은 경우는 SoC 자체에서 나오는 핀 수 자체가 적기 때문에 GPIO로 동작하는 핀 수 자체가 적다. 물론 이런 불편을 해소하기 위해서 I2C나 SPI(Serial Peripheral Interface) bus를 사용한 GPIO Expander 같이 확장 기능을 제공하는 칩들도 존재한다. 대부분의 PC 메인보드에 있는 southbridge에도 이런 GPIO 기능을 하는 핀 여러개가 제공된다.


 GPIO가 하는 기능은 시스템에 따라서 다를 수 있는데, 일반적으로 제공하는 기능은 다음과 같다.

 - 입/출력 기능 (high = 1, low = 0)

 - IRQ 신호 감지 : 이를 통해서 power management 상에서 suspend 상태에 있는 system을 wakeup 시키는데 사용하기도 함.

 - Spinlock이 걸렸을 때도 접근이 가능

위의 기능을 통해서 MMC/SD 카드가 삽입/제거가 되었는지, 혹은 쓰기 보호 기능이 활성화되어 있는지의 여부, 또는 LED를 제어하거나 Transceiver 설정, hardware의 watchdog 기능을 활성화시키거나 switch sensing 같은 용도로 활용할 수 있다.


GPIO의 특성

- Active High와 Active Low : 보통 GPIO 출력이 1이 나왔을 때를 Active, 0이 나왔을 때를 inactive라고 한다. 그런데 경우에 따라서는 GPIO 출력을 어떻게 활용하냐에 따라서 이 active의 의미가 다르게 바뀔 수 있다.(예를 들어서 pull down circuit과 같이 출력 신호가 0일때 모듈이 동작한다던가,,,)  이런 정의는 GPIO를 통해서 출력이 나오는 칩이나 이 출력을 활용해서 뭔가를 쓰는 모듈 사이에선 사전에 정의되어야 하며, 이런 경우로 인해서 active-high(1일때 active인 상황)이나 active-low(0일때 active) 와 같은 형태로도 정의될 수 있다. 결국 드라이버 입장에서는 GPIO를 통해서 나오는 출력 값이 얼마인지를 알 게 아니라 어떨때 active인지만 알면 그에 맞는 동작을 구현할 수 있게 된다.

 - Open Drain과 Open Source : 이걸 이해하려면 MOSFET의 동작원리에 대해서 알아야 하는데 Drain과 Source가 어떤 상태에 있느냐에 따라서 원하는 결과만 뽑을 수 있다. 보통 MOSFET을 제어할 때는 Gate에 입력을 줘서 하는데, Drain이 open되어 있을 때 mosfet 제어를 해주면 0과 어떤 알 수 없는 값(Z)을 출력으로 뽑을 수 있다. 반대의 경우인 Source가 open되어 있는 상태에서도 mosfet 제어를 해줄 경우, 1과 어떤 알수 없는 값(Z)를 뽑을 수 있다. 전자와 같은 경우를 open drain, 후자의 경우를 open-source 라고 한다. 물론 이런 신호를 제어할 때는 외부적으로 pullup resistor나 pulldown resistor 같은게 필요하다. 아무튼 GPIO 상에서 이런 기능을 활용하는 대표적인 예가 active-low IRQ signal을 받는 경우다. 말하자면 GPIO가 0이 될때 IRQ가 활성화될 때 open-drain 방식의 GPIO handling이 필요하다. 또는 입출력이 동시에 가능한 bidirectional bus signal을 다룰 때도 open-drain 방식의 형태를 사용한다. 

 몇몇 GPIO 컨트롤러들은 따로 설정을 안하더라도 직접적으로 open-drain이나 open-source 형태의 출력을 받아들일 수 있지만, 그렇지 않은 경우라면 driver단에서 해당 신호를 제어할 수 있게끔 작성되어야 한다. 이때는 kernel API를 사용하는데 이에 대한 정의는 /drivers/gpio/gpiolib.c 에서 제공한다.

LOW: gpiod_direction_output(gpio, 0) - 해당 gpio로 신호가 들어온 경우 pull up으로 대응하게 해줌.

HIGH: gpiod_direction_input(gpio) - 해당 gpio의 output 기능을 비활성화시키고 pull up으로 동작하게 함

 이런 형태의 emulation은 GPIO framework에 의해서 드라이버와 사용 모듈 사이에 투명하게 처리되어야 한다.


출처 : Linux Documentation (https://www.kernel.org/doc/Documentation/gpio/gpio.txt)

댓글