# Zephyr OS가 올라간 라즈베리 파이 피코 2에 SparkFun 9DoF IMU I2C로 연결하기 (리눅스 환경) - 파트 3

**URL:** <https://forum.digikey.com/t/zephyr-os-2-sparkfun-9dof-imu-i2c-3/67158>\
**Category:** 기술 조언\
**Tags:** raspberry-pi, embedded, evaluation-boards, tech-tips\
**Created:** [March 27, 2026, 2:16pm UTC](https://forum.digikey.com/t/zephyr-os-2-sparkfun-9dof-imu-i2c-3/67158 "2026-03-27T14:16:11Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brian\_Lee](https://sea2.discourse-cdn.com/digikey/user_avatar/forum.digikey.com/brian_lee/32/12387_2.png) [@Brian\_Lee](https://forum.digikey.com/u/Brian_Lee)\
**Post date:** [March 27, 2026, 2:16pm UTC](https://forum.digikey.com/t/zephyr-os-2-sparkfun-9dof-imu-i2c-3/67158/1 "2026-03-27T14:16:11Z")

</div>

[이전 게시글](https://forum.digikey.com/t/zephyr-os-2-sparkfun-9dof-imu-i2c-2/64252)에서는 [라즈베리 파이 피코 2](https://www.digikey.kr/ko/products/detail/raspberry-pi/SC1631/24627136)에 [SparkFun의 9DoF IMU ICM-20948 평가 기판](https://www.digikey.kr/ko/products/detail/sparkfun-electronics/15335/10279707)을 연결하고 Zephyr OS 셸에서 I2C 슬레이브 주소를 스캔하는 방법을 설명하였다면, 이번 글에서는 피코 2에서 Zephyr OS 기반 애플리케이션을 빌드하는 과정과 이를 위해 필요한 필수 파일 및 디렉터리 구조에 대해 설명하겠습니다. 먼저, 피코 2의 출력을 확인하는 데 사용할 minicom 터미널을 실행합니다. Zephyr OS 애플리케이션은 피코 2에서 실행됩니다.

```auto
$ minicom -D /dev/ttyACM0

Welcome to minicom 2.8

OPTIONS: I18n 
Port /dev/ttyACM0, 12:41:43

Press CTRL-A Z for help on special keys

```

Zephyr 디렉터리 내에 **myproject** 라는 폴더를 생성한 다음, 해당 폴더 안에 다음 파일들을 생성합니다.

CMake 파일 (파일명 **CMakeLists.txt** )

```auto
cmake_minimum_required(VERSION 3.25.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(i2c_scanner)
target_sources(app PRIVATE src/main.c)

```

Zephyr OS 설정 파일 (파일명 **prj.conf** )

```auto
CONFIG_I2C=y

```

Zephyr OS 오버레이 파일 (파일명 **RP2350.overlay** , I2C 포트 정의 - 본 예제에서는 피코 2의 I2C0)

```auto
/ {
    aliases {
        scan-i2c = &i2c0;
    };
};

```

**main.c** 프로그램 (새로운 하위 폴더 src 내에 위치)

```auto
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/sys/printk.h>

#define CONFIG_I2C_SCAN_ADDR_START 0x00
#define CONFIG_I2C_SCAN_ADDR_STOP 0x99

static const struct device *scan_dev = DEVICE_DT_GET(DT_ALIAS(scan_i2c));

int main(void)
{
    k_sleep(K_SECONDS(5));
    if (!scan_dev) {
        printk("I2C: Device driver not found.\n");
        return -1;
    }

    printk(" ***Digikey I2C scanner started*** \n");
    printk("Board: %s\n", CONFIG_BOARD);
    printk("I2C device: %s\n", scan_dev->name);

    /* Print pin information if available in devicetree */

    if (!device_is_ready(scan_dev)) {
        printk("I2C device not ready\n");
        return -1;
    }

    printk("Digikey Scanning on I2C bus...\n\n");

    printk(" | 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f |\n");
    printk(" ****|*********************************************************************************");

    uint8_t error = 0u;
    uint8_t dst;
    uint8_t i2c_dev_cnt = 0;
    struct i2c_msg msgs[1];
    msgs[0].buf = &dst;
    msgs[0].len = 1U;
    msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
    uint16_t slave_addr = 0;

    /* Use the full range of I2C address for display purpose */
    for (uint16_t x = 0; x <= 0x7f; x++) {
        /* New line every 0x10 address */
        if (x % 0x10 == 0) {
            printk("|\n0x%02x| ",x);
        }
        /* Range the test with the start and stop value configured in the kconfig */
        if (x >= CONFIG_I2C_SCAN_ADDR_START && x <= CONFIG_I2C_SCAN_ADDR_STOP)	{
            /* Send the address to read from */
            error = i2c_transfer(scan_dev, &msgs[0], 1, x);
                /* I2C device found on current address */
                if (error == 0) {
                    printk("0x%02x ",x);
                    slave_addr = x;
                    ++i2c_dev_cnt;
                }
                else {
                    printk("#### ");
                }
        } else {
            /* Scan value out of range, not scanned */
            printk(" ");
        }
        k_sleep(K_MSEC(15));
    }
    printk("|\n");
    printk("\nI2C device(s) found on the bus by Digikey: %d\nScanning complete!\n\n", i2c_dev_cnt);
    
}

```

**myproject** 폴더의 전체 구조는 다음과 같습니다.

```auto
|-- CMakeLists.txt
|-- prj.conf
|-- RP2350.overlay
`-- src
    `-- main.c

```

이제 **RP2350.overlay** 파일을 사용하여 피코 2용 Zephyr OS 애플리케이션을 다음과 같이 빌드합니다.

```auto
(venv) $ west build -p always -b rpi_pico2/rp2350a/m33 -S cdc-acm-console -- -DCONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y -DEXTRA_DTC_OVERLAY_FILE=RP2350.overlay

```

다음은 디지키에서 구매 가능한 [평가용 브레드보드](https://www.digikey.kr/ko/products/detail/busboard-prototype-systems/BB830/19200392)에 [또 다른 게시글](https://forum.digikey.com/t/linux-os-sparkfun-usb/65007)에서 소개한 [SparkFun 8채널 USB 로직 분석기](https://www.digikey.kr/ko/products/detail/sparkfun-electronics/18627/15842546)와 함께 실제 구성한 사진입니다.

 ![20251014_125232](https://global.discourse-cdn.com/digikey/original/3X/d/8/d85ea5868a5390736a2e4bedd9c90fc788bfba5c.jpeg)

아래 사진과 같이, 피코 2의 I2C 버스인 PIN6 (I2C0 SDA), PIN7 (I2C0 SCL), 그리고 PIN38 (GND)을 모니터링하기 위해 [Qwiic 케이블](https://www.digikey.kr/ko/products/detail/sparkfun-electronics/15081/9770723)을 사용하였습니다.

 ![image](https://global.discourse-cdn.com/digikey/original/3X/8/f/8fdf14476a42a3b3bef0111638e46ab3625e4634.png)

로직 분석기를 I2C 버스 신호인 SCL, SDA와 GND에 연결하였지만, 긴 케이블로 인해 1차 등가 RC 시정수가 증가하고, I2C 버스에 왜곡이 발생할 수 있어서 최적의 연결 방법은 아닙니다. 이제 Zephyr OS 애플리케이션을 빌드하고 피코 2에 플래시 합니다.

```auto
(venv) $ west flash --runner uf2

```

minicom 터미널에서는 피코 2의 출력이 아래와 같이 표시될 것입니다.

```auto
***Booting Zephyr OS build v4.2.0-5176-ge5838ffc2176***
 ***Digikey I2C scanner started***
Board: rpi_pico2
I2C device: i2c@40090000
Digikey Scanning on I2C bus...

    | 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f |
****|********************************************************************************* |
0x00| #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### |
0x10| #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### |
0x20| #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### |
0x30| #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### |
0x40| #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### |
0x50| #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### |
0x60| #### #### #### #### #### #### #### #### #### 0x69 #### #### #### #### #### #### |
0x70| #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### |

I2C device(s) found on the bus by Digikey: 1
Scanning complete!

```

피코 2에서 실행중인 Zephyr OS 애플리케이션이 I2C 슬레이브 주소를 0x69로 정상적으로 인식하였으며, [이전 글](https://forum.digikey.com/t/zephyr-os-2-sparkfun-9dof-imu-i2c-2/64252)에서 사용된 I2C 장치 i2c@40090000와도 일치합니다. 이를 검증하기 위해 [SparkFun 8채널 USB 로직 분석기](https://www.digikey.kr/ko/products/detail/sparkfun-electronics/18627/15842546)를 2채널만 표시하도록 구성하고, 샘플링 속도는 4 MHz, 샘플 수는 1억으로 설정하였으며, 그리고 I2C 프로토콜 디코더를 사용하도록 구성하였습니다. 다음 I2C 버스 스냅샷은 Zephyr OS 프로그램을 리셋하는 동안 로직 분석기로 캡처한 것입니다. 첫 번째 캡처는 앞서 설명한 Zephyr OS **main.c** 프로그램이 수행한 I2C 주소 스캔 전체 시퀀스를 보여줍니다.

 ![image](https://global.discourse-cdn.com/digikey/original/3X/e/2/e25b5dbc8bfaa6192201cdbaacde65907d510e37.png)

피코 2가 전송한 I2C 메시지를 확대해 보면, 0xB0 I2C 슬레이브 주소를 스캔한 경우 I2C 슬레이브 장치로부터 응답이 없음을 나타내는 NACK (아래 그림에서 빨간색)를 확인할 수 있습니다.

 ![image](https://global.discourse-cdn.com/digikey/original/3X/b/f/bf956ef1f6112532cb5f7bbda9f6e0093bcd5037.png)

마지막으로 주소가 0x69인 I2C 슬레이브 장치가 감지된 경우를 확인해 보면, Zephyr OS가 실행중인 피코 2에 ACK (아래 그림에서 보라색)가 반환된 것을 확인할 수 있습니다.

 ![image](https://global.discourse-cdn.com/digikey/original/3X/c/e/ced68e74d390fb81f1523f45fdd903c1c0f4d815.png)

이로써 라즈베리 파이 피코 2를 기반으로 Zephyr OS I2C 인터페이스를 구성하고 SparkFun의 9DoF IMU Qwiic 플랫폼 평가 보드와 연동하는 과정이 모두 완료되었습니다.

좋은 하루 보내세요!

  
  

영문 원본: [Zephyr OS on Raspberry Pico 2 I2C interface to SPARKFUN 9DOF IMU (Linux) Part 3](https://forum.digikey.com/t/zephyr-os-on-raspberry-pico-2-i2c-interface-to-sparkfun-9dof-imu-linux-part-3/61294)
