C언어로 임베디드 리눅스에서 I2C 디바이스 제어하기

임베디드 리눅스 환경에서 I2C 디바이스를 제어하는 것은 센서, 액추에이터, 기타 하드웨어 장치와의 통신을 가능하게 하는 핵심 기술입니다. 본 기사에서는 C언어를 활용해 I2C 통신을 설정하고, 데이터를 읽고 쓰는 과정을 상세히 설명합니다. 이를 통해 개발자는 효율적으로 I2C 장치를 제어하고 통합할 수 있는 실질적인 방법을 배울 수 있습니다.

I2C 프로토콜의 개요


I2C(Inter-Integrated Circuit) 프로토콜은 단일 데이터 라인과 클럭 라인을 사용하여 다중 장치 간 통신을 가능하게 하는 직렬 통신 방식입니다.

동작 원리


I2C는 마스터-슬레이브 구조를 기반으로 하며, 마스터 장치가 클럭 신호를 생성하고 통신을 제어합니다. 슬레이브 장치는 고유의 주소를 통해 마스터와 통신하며, 데이터는 양방향으로 전송될 수 있습니다.

주요 구성 요소

  • SDA (Serial Data Line): 데이터 전송에 사용되는 라인
  • SCL (Serial Clock Line): 클럭 신호 전송에 사용되는 라인
  • 7비트 주소 체계: 각 슬레이브는 고유한 7비트 주소를 가지며, 이를 통해 특정 장치와 통신합니다.

I2C의 장점

  • 단순한 하드웨어 연결: 두 개의 라인만 사용
  • 다중 슬레이브 지원: 최대 127개의 장치 연결 가능
  • 소프트웨어 중심의 구현: 다양한 애플리케이션에 적응 가능

I2C는 다양한 임베디드 시스템에서 센서 및 외부 장치를 제어하기 위한 표준 프로토콜로 널리 사용됩니다.

임베디드 리눅스에서 I2C 인터페이스 설정

임베디드 리눅스 환경에서 I2C 인터페이스를 설정하려면 커널 모듈 구성과 시스템 파일 설정이 필요합니다.

1. I2C 커널 모듈 확인 및 로드


리눅스 커널에는 기본적으로 I2C를 지원하는 모듈이 포함되어 있습니다. 다음 명령어를 사용해 필요한 모듈을 확인하고 로드할 수 있습니다.

lsmod | grep i2c
modprobe i2c-dev
modprobe i2c-bcm2835 # (라즈베리파이 등 특정 플랫폼의 경우)

2. I2C 디바이스 파일 확인


I2C 디바이스는 /dev/i2c-X 형식으로 나타납니다(X는 버스 번호). 사용 가능한 I2C 버스를 확인하려면 다음 명령어를 사용합니다.

ls /dev/i2c-*

3. I2C 인터페이스 활성화


특정 보드에서는 I2C가 기본적으로 비활성화되어 있을 수 있습니다. 이를 활성화하려면 다음 작업을 수행해야 합니다.

  • Device Tree 파일 수정: 보드의 dtc 또는 설정 파일에서 I2C 인터페이스를 활성화
  • Configuration Tool 사용: 예를 들어, 라즈베리파이에서는 raspi-config를 사용하여 I2C를 활성화할 수 있습니다.
sudo raspi-config
# "Interface Options > I2C" 메뉴에서 활성화

4. I2C 버스 탐색


I2C 디바이스를 확인하려면 i2cdetect 유틸리티를 사용합니다.

sudo apt install i2c-tools  # i2c-tools 설치
sudo i2cdetect -y 1        # 버스 1 탐색

결과는 장치 주소가 매핑된 표 형태로 출력됩니다.

5. 문제 해결

  • I2C 디바이스 파일이 없는 경우: 커널 모듈이 로드되지 않았거나 인터페이스가 비활성화되었을 가능성이 있습니다.
  • 디바이스가 감지되지 않는 경우: 하드웨어 연결 및 장치 주소를 확인해야 합니다.

위 과정을 완료하면 I2C 인터페이스가 준비되며, C언어를 사용해 디바이스를 제어할 수 있습니다.

C언어를 사용한 I2C 디바이스 초기화

I2C 디바이스를 제어하려면 먼저 디바이스를 초기화하고 I2C 버스에 연결해야 합니다. C언어에서는 표준 파일 I/O 함수와 I2C 전용 시스템 호출을 활용합니다.

1. 필요 헤더 파일


I2C 통신을 위해 다음 헤더 파일이 필요합니다.

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>

2. I2C 디바이스 열기


open() 함수를 사용해 I2C 디바이스 파일을 엽니다.

int i2c_fd;
const char *device = "/dev/i2c-1"; // 사용 중인 I2C 버스
if ((i2c_fd = open(device, O_RDWR)) < 0) {
    perror("Failed to open the I2C device");
    exit(1);
}

3. 슬레이브 디바이스 주소 설정


ioctl() 함수로 통신할 슬레이브 디바이스 주소를 설정합니다.

int addr = 0x48; // 예: 슬레이브 디바이스 주소
if (ioctl(i2c_fd, I2C_SLAVE, addr) < 0) {
    perror("Failed to set the I2C slave address");
    close(i2c_fd);
    exit(1);
}

4. 초기화 성공 여부 확인


디바이스 파일이 성공적으로 열리고 슬레이브 주소가 설정되면 I2C 초기화가 완료된 것입니다.

5. 에러 처리

  • open() 실패: 디바이스 파일이 존재하지 않거나 접근 권한이 없는 경우 발생
  • ioctl() 실패: 슬레이브 디바이스가 연결되지 않았거나 주소가 잘못된 경우 발생

6. 초기화 코드 전체 예제

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>

int main() {
    int i2c_fd;
    const char *device = "/dev/i2c-1";
    int addr = 0x48; // 슬레이브 디바이스 주소

    // I2C 디바이스 열기
    if ((i2c_fd = open(device, O_RDWR)) < 0) {
        perror("Failed to open the I2C device");
        return 1;
    }

    // 슬레이브 디바이스 주소 설정
    if (ioctl(i2c_fd, I2C_SLAVE, addr) < 0) {
        perror("Failed to set the I2C slave address");
        close(i2c_fd);
        return 1;
    }

    printf("I2C device initialized successfully\n");
    close(i2c_fd);
    return 0;
}

위 코드는 I2C 디바이스 초기화를 위한 기본적인 과정을 보여줍니다. 이후 데이터를 읽고 쓰는 작업을 수행할 준비가 완료됩니다.

데이터 읽기 및 쓰기

C언어를 사용해 I2C 디바이스에서 데이터를 읽고 쓰는 방법을 알아보겠습니다. 데이터 전송은 슬레이브 디바이스와 통신하는 기본 작업으로, 적절한 함수 호출과 오류 처리가 필요합니다.

1. 데이터 쓰기


I2C 디바이스에 데이터를 쓰기 위해 write() 함수를 사용합니다.

unsigned char data_to_write[2] = {0x01, 0x80}; // 첫 번째는 명령, 두 번째는 데이터
if (write(i2c_fd, data_to_write, 2) != 2) {
    perror("Failed to write to the I2C device");
}
  • 매개변수
  • i2c_fd: 열려 있는 I2C 디바이스 파일의 파일 디스크립터
  • data_to_write: 전송할 데이터 배열
  • 2: 전송할 바이트 수

2. 데이터 읽기


I2C 디바이스에서 데이터를 읽기 위해 read() 함수를 사용합니다.

unsigned char data_to_read[2];
if (read(i2c_fd, data_to_read, 2) != 2) {
    perror("Failed to read from the I2C device");
} else {
    printf("Data read: 0x%02x 0x%02x\n", data_to_read[0], data_to_read[1]);
}
  • 매개변수
  • i2c_fd: 열려 있는 I2C 디바이스 파일의 파일 디스크립터
  • data_to_read: 읽어올 데이터를 저장할 배열
  • 2: 읽을 바이트 수

3. 읽기 전에 레지스터 주소 설정


대부분의 I2C 디바이스는 특정 레지스터에서 데이터를 읽습니다. 먼저 레지스터 주소를 설정한 뒤 데이터를 읽어야 합니다.

unsigned char reg = 0x10; // 읽고자 하는 레지스터 주소
if (write(i2c_fd, &reg, 1) != 1) {
    perror("Failed to write register address");
}

unsigned char value;
if (read(i2c_fd, &value, 1) != 1) {
    perror("Failed to read from the I2C device");
} else {
    printf("Read value: 0x%02x\n", value);
}

4. 에러 처리

  • 쓰기 실패: 슬레이브 디바이스가 연결되지 않았거나 슬레이브 주소가 잘못 설정된 경우 발생
  • 읽기 실패: 레지스터 주소를 잘못 설정하거나 디바이스 오류가 있는 경우 발생

5. 전체 코드 예제

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>

int main() {
    int i2c_fd;
    const char *device = "/dev/i2c-1";
    int addr = 0x48;

    // I2C 디바이스 열기
    if ((i2c_fd = open(device, O_RDWR)) < 0) {
        perror("Failed to open the I2C device");
        return 1;
    }

    // 슬레이브 주소 설정
    if (ioctl(i2c_fd, I2C_SLAVE, addr) < 0) {
        perror("Failed to set the I2C slave address");
        close(i2c_fd);
        return 1;
    }

    // 데이터 쓰기
    unsigned char data_to_write[2] = {0x01, 0x80};
    if (write(i2c_fd, data_to_write, 2) != 2) {
        perror("Failed to write to the I2C device");
        close(i2c_fd);
        return 1;
    }

    // 데이터 읽기
    unsigned char data_to_read[2];
    if (read(i2c_fd, data_to_read, 2) != 2) {
        perror("Failed to read from the I2C device");
        close(i2c_fd);
        return 1;
    }
    printf("Data read: 0x%02x 0x%02x\n", data_to_read[0], data_to_read[1]);

    close(i2c_fd);
    return 0;
}

위 코드는 I2C 디바이스에서 데이터를 읽고 쓰는 기본적인 방법을 보여줍니다. 이 과정을 통해 다양한 I2C 장치를 제어할 수 있습니다.

I2C 통신 오류 처리

I2C 통신 중 발생할 수 있는 오류를 처리하는 것은 안정적인 시스템 동작을 위해 중요합니다. 통신 오류는 하드웨어 문제, 잘못된 설정, 소프트웨어 버그 등 다양한 원인으로 발생할 수 있습니다. 아래에서는 일반적인 오류와 처리 방법을 다룹니다.

1. 일반적인 I2C 오류

1.1 슬레이브 주소 설정 오류


슬레이브 장치가 응답하지 않는 경우 발생합니다.

  • 원인: 잘못된 슬레이브 주소 지정, 디바이스 미연결
  • 처리 방법:
  1. 디바이스 주소 확인 (i2cdetect 사용)
  2. 올바른 주소로 ioctl() 호출

1.2 데이터 쓰기 실패


데이터 전송 중 write() 함수가 실패합니다.

  • 원인: 버스 충돌, 슬레이브의 쓰기 명령 거부
  • 처리 방법:
  1. 슬레이브가 활성화되어 있는지 확인
  2. errno 값을 확인하여 원인 분석

1.3 데이터 읽기 실패


데이터 수신 중 read() 함수가 실패합니다.

  • 원인: 슬레이브 응답 없음, 잘못된 레지스터 주소
  • 처리 방법:
  1. 레지스터 주소 설정 확인
  2. 슬레이브 디바이스 상태 점검

2. 오류 감지 및 복구 코드

2.1 슬레이브 주소 설정 오류 처리

if (ioctl(i2c_fd, I2C_SLAVE, addr) < 0) {
    perror("Failed to set the I2C slave address");
    close(i2c_fd);
    exit(1); // 적절한 복구 절차를 추가할 수 있음
}

2.2 데이터 쓰기 오류 처리

if (write(i2c_fd, data_to_write, sizeof(data_to_write)) != sizeof(data_to_write)) {
    perror("Failed to write to the I2C device");
    // 재시도 로직 추가 가능
}

2.3 데이터 읽기 오류 처리

if (read(i2c_fd, data_to_read, sizeof(data_to_read)) != sizeof(data_to_read)) {
    perror("Failed to read from the I2C device");
    // 슬레이브 상태 점검 코드 추가
}

3. 타임아웃 및 재시도


I2C 통신이 응답 없이 중단되는 경우 타임아웃과 재시도 로직을 도입할 수 있습니다.

for (int attempts = 0; attempts < 3; attempts++) {
    if (write(i2c_fd, data_to_write, sizeof(data_to_write)) == sizeof(data_to_write)) {
        break; // 성공하면 반복 종료
    }
    perror("Retrying write to I2C device");
    usleep(100000); // 100ms 대기 후 재시도
}

4. 디버깅 툴 활용

  • i2cdetect: 디바이스 주소 확인
  • i2cset, i2cget: 데이터 쓰기 및 읽기 테스트
  • 로그 분석: 커널 로그(dmesg)를 통해 오류 확인

5. 하드웨어 오류 점검

  • 배선 확인: SDA, SCL 핀 연결 상태 확인
  • 풀업 저항: SDA, SCL 라인에 적절한 풀업 저항이 연결되었는지 확인
  • 디바이스 전원 상태: 슬레이브 디바이스가 정상적으로 전원 공급을 받고 있는지 점검

6. 결론


I2C 통신 오류는 다양한 원인으로 발생할 수 있으나, 올바른 초기화와 에러 핸들링, 적절한 디버깅 툴 사용을 통해 대부분의 문제를 해결할 수 있습니다. 복구 가능한 설계를 통해 시스템의 안정성과 신뢰성을 높일 수 있습니다.

유용한 I2C 유틸리티 소개

리눅스 환경에서 I2C 디바이스를 관리하고 디버깅하는 데 유용한 명령줄 유틸리티가 제공됩니다. 이 유틸리티들은 설정 확인, 데이터 전송 테스트, 디바이스 주소 검색 등을 손쉽게 수행할 수 있게 도와줍니다.

1. i2c-tools 설치


i2c-tools는 I2C 유틸리티의 집합으로, 다음 명령어를 통해 설치할 수 있습니다.

sudo apt install i2c-tools

2. 주요 유틸리티 및 사용 방법

2.1 i2cdetect


현재 연결된 I2C 디바이스의 주소를 검색합니다.

sudo i2cdetect -y 1
  • 출력: 슬레이브 디바이스의 주소가 매핑된 표 형태로 출력됩니다.
  • 옵션:
  • -y: 사용자가 매번 확인할 필요 없이 자동 실행
  • 1: I2C 버스 번호

2.2 i2cget


슬레이브 디바이스의 특정 레지스터에서 데이터를 읽습니다.

sudo i2cget -y 1 0x48 0x10
  • 매개변수:
  • 1: I2C 버스 번호
  • 0x48: 슬레이브 디바이스 주소
  • 0x10: 읽고자 하는 레지스터 주소

2.3 i2cset


슬레이브 디바이스의 특정 레지스터에 데이터를 씁니다.

sudo i2cset -y 1 0x48 0x10 0x80
  • 매개변수:
  • 0x80: 레지스터에 쓰고자 하는 값

2.4 i2cdump


슬레이브 디바이스의 모든 레지스터 값을 덤프합니다.

sudo i2cdump -y 1 0x48
  • 용도: 디바이스 레지스터 맵 확인

3. 활용 사례

3.1 디바이스 주소 확인


i2cdetect를 사용하여 연결된 I2C 디바이스의 주소를 빠르게 확인할 수 있습니다.

sudo i2cdetect -y 1

출력 예시:

     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- 48

3.2 데이터 쓰기 및 읽기

  1. 특정 레지스터에 데이터 쓰기:
   sudo i2cset -y 1 0x48 0x01 0x80
  1. 데이터 확인:
   sudo i2cget -y 1 0x48 0x01

4. 주의사항

  • 권한 문제: I2C 디바이스는 보통 루트 권한이 필요합니다. 권한 문제를 방지하려면 sudo를 사용하세요.
  • 데이터 손상 방지: 잘못된 값 쓰기는 디바이스 동작에 문제를 일으킬 수 있으므로 주의해야 합니다.

5. 결론


I2C 유틸리티는 디바이스 제어와 디버깅을 간소화해줍니다. 개발자는 이를 활용하여 디바이스 설정, 데이터 읽기 및 쓰기, 문제 진단 등을 효과적으로 수행할 수 있습니다.

I2C 실습: 온도 센서 제어

I2C 온도 센서를 제어하는 실습을 통해, I2C 통신의 실제 사용 사례를 확인해 보겠습니다. 이번 실습에서는 LM75A 온도 센서를 제어하는 방법을 설명합니다.

1. 실습 준비

1.1 하드웨어 구성

  • 센서 모델: LM75A (또는 I2C 호환 온도 센서)
  • 배선:
  • SDA: I2C 데이터 핀
  • SCL: I2C 클럭 핀
  • VCC: 센서 전원 공급 핀
  • GND: 접지

1.2 I2C 주소 확인


i2cdetect 명령어로 센서가 연결된 I2C 주소를 확인합니다.

sudo i2cdetect -y 1

출력 예시:

     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- 48

센서 주소는 0x48입니다.

2. 데이터 읽기

2.1 온도 데이터 레지스터


LM75A는 0x00 레지스터에 온도 데이터를 저장합니다. 데이터를 읽어오려면 다음 명령어를 사용할 수 있습니다.

sudo i2cget -y 1 0x48 0x00

2.2 데이터 형식


온도 데이터는 16비트로 표현되며, 상위 9비트가 온도 값을 나타냅니다.

  • 데이터 예시: 0x1A80
  • 상위 바이트: 0x1A
  • 하위 바이트: 0x80
  • 온도 값: 26°C (16진수를 10진수로 변환 후 계산)

3. C언어로 데이터 읽기


다음 코드는 C언어를 사용하여 LM75A 센서에서 온도 데이터를 읽고 변환하는 예제입니다.

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>

int main() {
    int i2c_fd;
    const char *device = "/dev/i2c-1";
    int addr = 0x48;
    unsigned char reg = 0x00;
    unsigned char data[2];

    // I2C 디바이스 열기
    if ((i2c_fd = open(device, O_RDWR)) < 0) {
        perror("Failed to open the I2C device");
        return 1;
    }

    // 슬레이브 주소 설정
    if (ioctl(i2c_fd, I2C_SLAVE, addr) < 0) {
        perror("Failed to set the I2C slave address");
        close(i2c_fd);
        return 1;
    }

    // 레지스터 설정
    if (write(i2c_fd, &reg, 1) != 1) {
        perror("Failed to write register address");
        close(i2c_fd);
        return 1;
    }

    // 데이터 읽기
    if (read(i2c_fd, data, 2) != 2) {
        perror("Failed to read data from the I2C device");
        close(i2c_fd);
        return 1;
    }

    // 온도 계산
    int temp = (data[0] << 8 | data[1]) >> 7; // 9비트 값
    printf("Temperature: %d°C\n", temp);

    close(i2c_fd);
    return 0;
}

4. 실습 결과 확인


코드를 실행하면 센서에서 읽어온 온도 값이 출력됩니다.

Temperature: 26°C

5. 실습을 통해 배운 점

  • I2C 디바이스의 주소 확인 및 초기화
  • 레지스터 접근 및 데이터 읽기
  • 데이터 형식 변환과 해석

6. 결론


이 실습은 I2C 디바이스와의 통신에 대한 실질적인 이해를 제공합니다. 온도 센서 제어는 다양한 I2C 디바이스 응용의 기본이 되며, 다른 센서 및 장치 제어로 확장할 수 있습니다.

성능 최적화와 유지보수 팁

I2C 제어 코드를 최적화하고 유지보수성을 높이기 위한 방법은 개발 효율성과 시스템 안정성을 향상시키는 데 필수적입니다. 아래는 성능을 최적화하고 코드의 유지보수성을 개선하기 위한 실질적인 팁입니다.

1. 성능 최적화

1.1 버스 사용 최적화


I2C 통신은 클럭 속도와 데이터 전송률에 민감합니다. 다음 방법으로 버스 성능을 최적화할 수 있습니다.

  • 클럭 속도 조정: I2C 버스의 기본 속도(100kHz)보다 빠른 Fast Mode(400kHz)를 사용하여 데이터 전송 속도를 높입니다.
  • 설정 방법: I2C 컨트롤러 설정 파일 또는 드라이버 설정에서 클럭 속도 조정
  • 연속 데이터 전송: 가능하면 한 번의 데이터 전송에 여러 명령과 데이터를 묶어 전송합니다.

1.2 오류 처리 최소화


오류 발생 시 통신을 반복적으로 시도하는 대신, 적절한 타임아웃과 재시도 횟수를 설정합니다.

for (int attempts = 0; attempts < MAX_RETRIES; attempts++) {
    if (write(i2c_fd, data, size) == size) {
        break; // 성공 시 종료
    }
    usleep(RETRY_DELAY); // 지연 후 재시도
}

1.3 데이터 버퍼 최적화


읽기 및 쓰기 작업 시 동일한 데이터 버퍼를 재사용하여 메모리 할당과 해제를 줄입니다.

static unsigned char buffer[MAX_BUFFER_SIZE];

2. 유지보수성 향상

2.1 코드 모듈화


I2C 작업을 수행하는 함수들을 별도의 모듈로 작성하여 재사용 가능성을 높입니다.

int i2c_write(int fd, int addr, unsigned char reg, unsigned char *data, size_t len);
int i2c_read(int fd, int addr, unsigned char reg, unsigned char *buffer, size_t len);

2.2 에러 로그 추가


오류 발생 시 명확한 로그를 기록하여 디버깅 시간을 단축합니다.

perror("I2C write failed at register 0x01");

2.3 설정 파일 도입


I2C 디바이스 주소, 클럭 속도 등 가변 설정을 하드코딩하지 않고 설정 파일로 분리하여 관리합니다.

  • : JSON, YAML 형식으로 설정 관리
{
    "i2c_bus": "/dev/i2c-1",
    "device_address": "0x48",
    "clock_speed": 400000
}

2.4 주석 및 문서화


코드에 적절한 주석을 추가하고, 함수 사용법과 데이터 형식을 문서화합니다.

/**
 * @brief I2C 슬레이브 디바이스에 데이터를 씁니다.
 * @param fd I2C 파일 디스크립터
 * @param addr 슬레이브 주소
 * @param reg 레지스터 주소
 * @param data 쓰기 데이터
 * @param len 데이터 길이
 * @return 0: 성공, -1: 실패
 */
int i2c_write(int fd, int addr, unsigned char reg, unsigned char *data, size_t len);

3. 테스트 및 디버깅

3.1 시뮬레이션 환경 구축


가상 I2C 디바이스를 사용하여 테스트 환경에서 코드를 디버깅합니다.

  • : QEMU, I2C 가상 드라이버

3.2 유닛 테스트 작성


모듈별로 유닛 테스트를 작성하여 코드 변경 시 안정성을 유지합니다.

4. 결론


성능 최적화와 유지보수성 향상을 위해 위의 방법을 적용하면 I2C 제어 코드의 효율성과 안정성을 크게 개선할 수 있습니다. 이를 통해 복잡한 프로젝트에서도 안정적으로 I2C 디바이스를 관리할 수 있습니다.

요약

이번 기사에서는 임베디드 리눅스 환경에서 C언어를 사용해 I2C 디바이스를 제어하는 방법을 다뤘습니다. I2C 프로토콜의 기본 개념부터 디바이스 초기화, 데이터 읽기 및 쓰기, 통신 오류 처리, 그리고 실습 예제와 최적화 팁까지 상세히 설명했습니다. 이를 통해 개발자는 I2C 기반의 디바이스를 효과적으로 제어하고 유지보수할 수 있는 지식을 습득할 수 있습니다.