GPIO 프로그래밍 개요 - 2. 직접 제어 방식 (sysfs 인터페이스 활용)

2025. 2. 25. 19:49프로그래밍/시스템

2. 직접 제어 방식 (sysfs 인터페이스 활용)

리눅스에서는 /sys/class/gpio/ 디렉터리를 통해 파일 시스템 방식으로 GPIO를 직접 제어할 수 있다.
이는 GPIO를 제어할 때 별도의 라이브러리 없이 기본적인 파일 읽기/쓰기 명령어(echo, cat)를 활용하는 방식이다.
터미널에서 직접 실행하거나, C/C++ 프로그램 내에서 파일 조작을 통해 GPIO 핀을 제어할 수 있다.


📌 기본적인 sysfs GPIO 제어 과정

sysfs 인터페이스를 활용한 GPIO 제어는 다음 5단계로 진행된다.


1️⃣ GPIO 핀을 활성화

GPIO를 사용하기 위해서는 먼저 해당 핀을 시스템에 등록(export) 해야 한다.

🔧 터미널 명령어 (Bash)

echo 17 > /sys/class/gpio/export

🔹 GPIO 17번 핀을 활성화하여 사용할 수 있도록 설정.

실행 후, 아래 디렉터리가 생성됨

ls /sys/class/gpio/gpio17/
# 방향 설정 파일: /sys/class/gpio/gpio17/direction
# 값 설정 파일: /sys/class/gpio/gpio17/value

2️⃣ 핀 모드 설정 (입력/출력)

GPIO 핀을 입력(input) 또는 출력(output) 모드로 설정해야 한다.

🔧 출력 모드 설정 (LED 제어용)

echo out > /sys/class/gpio/gpio17/direction

🔹 GPIO 17번 핀을 출력 모드(out)로 설정.

🔧 입력 모드 설정 (버튼 입력용)

echo in > /sys/class/gpio/gpio17/direction

🔹 GPIO 17번 핀을 입력 모드(in)로 설정.

출력 모드 → LED ON/OFF 가능
입력 모드 → 버튼 상태 확인 가능


3️⃣ 출력 설정 (LED 켜기/끄기)

GPIO를 출력 모드로 설정한 후, HIGH(1) 또는 LOW(0) 값을 설정하여 LED를 제어할 수 있다.

🔧 LED 켜기

echo 1 > /sys/class/gpio/gpio17/value

🔹 GPIO 17번 핀을 HIGH(1) 상태로 설정하여 LED를 켬.

🔧 LED 끄기

echo 0 > /sys/class/gpio/gpio17/value

🔹 GPIO 17번 핀을 LOW(0) 상태로 설정하여 LED를 끔.

출력값을 변경하면 LED가 켜졌다가 꺼짐
릴레이, 모터 등 다양한 출력 장치를 제어 가능


4️⃣ 입력 읽기 (버튼 상태 확인)

GPIO를 입력 모드로 설정한 후, cat 명령어를 이용하여 핀의 상태를 읽을 수 있다.

🔧 버튼 상태 확인

cat /sys/class/gpio/gpio17/value

🔹 GPIO 17번 핀의 입력 값을 확인함.

  • 버튼이 눌리지 않으면 1 (HIGH)
  • 버튼이 눌리면 0 (LOW)

센서 입력 값도 같은 방식으로 읽을 수 있음


5️⃣ GPIO 핀 해제 (사용 종료 시)

GPIO 핀을 더 이상 사용하지 않을 경우, 시스템에서 해제해야 한다.

🔧 GPIO 해제

echo 17 > /sys/class/gpio/unexport

🔹 GPIO 17번 핀을 비활성화하여 더 이상 사용하지 않도록 설정.

이 명령을 실행하면 /sys/class/gpio/gpio17/ 디렉터리가 삭제됨


📌 sysfs 방식으로 C 프로그램에서 GPIO 제어하기

터미널 명령어뿐만 아니라, C 언어에서도 파일 조작(fopen, fprintf, fclose)을 이용하여 GPIO를 제어할 수 있다.

🔧 C 코드로 sysfs GPIO 제어 (LED 깜빡이기)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define GPIO_PIN "17"  // 사용할 GPIO 핀 번호 (문자열로 정의)

void writeGPIO(const char *file, const char *value) {
    FILE *fp = fopen(file, "w");
    if (fp == NULL) {
        perror("파일 열기 오류");
        exit(EXIT_FAILURE);
    }
    fprintf(fp, "%s", value);
    fclose(fp);
}

int main() {
    // 1. GPIO 활성화
    writeGPIO("/sys/class/gpio/export", GPIO_PIN);
    usleep(100000);  // 0.1초 대기

    // 2. GPIO 출력 모드 설정
    writeGPIO("/sys/class/gpio/gpio" GPIO_PIN "/direction", "out");

    // 3. LED 깜빡이기
    for (int i = 0; i < 10; i++) {
        writeGPIO("/sys/class/gpio/gpio" GPIO_PIN "/value", "1");  // LED ON
        usleep(500000);  // 0.5초 대기
        writeGPIO("/sys/class/gpio/gpio" GPIO_PIN "/value", "0");  // LED OFF
        usleep(500000);
    }

    // 4. GPIO 해제
    writeGPIO("/sys/class/gpio/unexport", GPIO_PIN);
    return 0;
}

파일 시스템을 조작하여 GPIO를 직접 제어하는 방식
터미널에서 실행한 명령어를 C 코드에서 자동으로 실행
기본적인 LED 점멸, 버튼 감지, 센서 데이터 수집 등에 활용 가능


📌 sysfs 방식의 장점과 단점

sysfs 방식의 장점

추가 라이브러리 없이 기본적으로 사용 가능 → 표준 리눅스 환경에서 바로 실행 가능
터미널 명령어로 간단하게 테스트 가능 → echo, cat을 이용한 빠른 디버깅
C/C++에서도 파일 입출력을 통해 쉽게 활용 가능

sysfs 방식의 단점

속도가 느림 → 파일을 읽고 쓰는 방식이므로 빠른 응답이 필요한 경우 비효율적
PWM(서보 모터), 인터럽트(버튼 이벤트 감지) 기능 미지원
최신 커널에서는 지원이 중단됨 (deprecated)


📌 결론

  • sysfs 인터페이스는 GPIO를 파일 시스템을 통해 직접 제어하는 방식이다.
  • 터미널 명령어(echo, cat)를 이용하여 쉽게 GPIO를 활성화, 설정, 출력, 입력 처리 가능하다.
  • C/C++에서도 파일 조작(fopen, fprintf)을 이용하여 GPIO를 제어할 수 있음.
  • 속도가 느리고 최신 커널에서는 deprecated 되었기 때문에, 고속 처리가 필요하면 라이브러리(wiringPi, pigpio)를 활용하는 것이 더 유리함. 🚀