--- marp: true theme: default paginate: true backgroundColor: #ffffff style: | section { font-family: 'Noto Sans KR', 'Apple SD Gothic Neo', sans-serif; font-size: 22px; } h1 { color: #00a9ce; font-size: 42px; border-bottom: 3px solid #00a9ce; padding-bottom: 10px; } h2 { color: #003087; font-size: 32px; } h3 { color: #555; font-size: 26px; } code { background: #f4f4f4; padding: 2px 6px; border-radius: 4px; font-size: 18px; } pre { background: #1e1e1e; color: #d4d4d4; border-radius: 8px; padding: 16px; font-size: 16px; } .columns { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; } ul li { margin-bottom: 6px; } table { font-size: 18px; width: 100%; } th { background: #00a9ce; color: white; } --- # nRF Connect for VS Code ## 완전 입문 가이드 **설치 → 프로젝트 생성 → 파일 구조 이해 → 빌드 & 플래싱** --- # 목차 1. **nRF Connect SDK 개요** 2. **개발 환경 설치** 3. **첫 프로젝트 만들기** 4. **핵심 파일 구조** - `CMakeLists.txt` - `prj.conf` (Kconfig) - `.overlay` (Device Tree) 5. **빌드 & 플래싱** 6. **디버깅 (RTT / J-Link)** 7. **실제 프로젝트 예시 (VesiScan)** --- # 1. nRF Connect SDK 개요 ## nRF Connect SDK란? Nordic Semiconductor의 **nRF 시리즈 MCU**를 위한 공식 개발 환경 - **기반**: Zephyr RTOS + 자체 미들웨어 레이어 - **지원 칩**: nRF52 / nRF53 / nRF91 / nRF54 시리즈 - **VS Code 확장**: nRF Connect for VS Code Extension Pack ``` nRF Connect SDK ├── Zephyr RTOS ← 코어 OS (스케줄러, 드라이버 등) ├── nrfxlib ← Nordic 전용 라이브러리 (BLE, LTE 등) ├── mcuboot ← 부트로더 └── 내 프로젝트 코드 ``` > **핵심 개념**: 내 코드는 SDK 위에 "앱" 형태로 올라감 > SDK 자체는 수정하지 않음 → `west` 도구로 관리 --- # 2. 개발 환경 설치 (1/3) ## 필요한 소프트웨어 | 소프트웨어 | 역할 | 다운로드 | |---|---|---| | VS Code | 코드 편집기 | code.visualstudio.com | | nRF Connect Extension Pack | VS Code 확장 묶음 | VS Code 마켓플레이스 | | nRF Connect SDK | Zephyr + Nordic 라이브러리 | 확장에서 자동 설치 | | J-Link | 플래싱 / 디버깅 드라이버 | segger.com | --- # 2. 개발 환경 설치 (2/3) ## VS Code 확장 설치 1. VS Code 실행 → Extensions (`Cmd+Shift+X` / `Ctrl+Shift+X`) 2. **"nRF Connect for VS Code Extension Pack"** 검색 후 설치 3. 설치되는 확장 목록: ``` nRF Connect for VS Code Extension Pack ├── nRF Connect ← 메인 확장 (빌드, 플래싱, 디버그) ├── nRF DeviceTree ← .overlay 파일 자동완성 / 검사 ├── nRF Kconfig ← prj.conf 자동완성 / 검사 └── nRF Terminal ← 시리얼/RTT 터미널 ``` --- # 2. 개발 환경 설치 (3/3) ## SDK 설치 (Toolchain Manager) 1. VS Code 좌측 사이드바 → **nRF Connect 아이콘** 클릭 2. **"Install Toolchain"** → 원하는 SDK 버전 선택 (예: `v2.6.0`) 3. 자동으로 다음을 다운로드: - ARM GCC 툴체인 - west (Python 기반 빌드/패키지 도구) - nRF Connect SDK 소스 > **설치 경로 예시 (macOS)** > `~/ncs/v2.6.0/` → SDK 소스 > `~/ncs/toolchains/` → GCC, west 등 --- # 3. 첫 프로젝트 만들기 (1/2) ## 방법 A: Sample에서 시작 (추천) 1. 사이드바 → **nRF Connect** 패널 2. **"Create a new application"** 클릭 3. 옵션 선택: - **Copy a sample**: SDK 내 샘플을 복사해서 시작 - **Blank application**: 빈 프로젝트 생성 ``` 추천 시작 샘플: ├── zephyr/samples/basic/blinky ← GPIO LED 기초 ├── zephyr/samples/bluetooth/peripheral_uart ← BLE NUS └── nrf/samples/bluetooth/nordic_uart_service ← Nordic BLE ``` --- # 3. 첫 프로젝트 만들기 (2/2) ## 방법 B: Build Configuration 추가 1. **"Add Build Configuration"** 클릭 2. **Board** 선택 (예: `nrf52840dk_nrf52840`) 3. 설정 확인 후 **Build** 클릭 ## 프로젝트 최소 구성 ``` my_project/ ├── CMakeLists.txt ← 빌드 대상 소스 파일 목록 ├── prj.conf ← Kconfig: 기능 ON/OFF 스위치 ├── src/ │ └── main.c ← 진입점 └── boards/ ← (선택) 보드별 오버레이 └── nrf52840dk_nrf52840.overlay ``` --- # 4. CMakeLists.txt ## 역할 > **빌드 시스템에게 "무엇을 컴파일할지" 알려주는 파일** ## 기본 구조 ```cmake # 최소 CMake 버전 요구 cmake_minimum_required(VERSION 3.20.0) # Zephyr SDK 찾기 (필수 - 항상 이 줄이 있어야 함) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) # 프로젝트 이름 project(vesiscan) # 헤더 파일 검색 경로 추가 target_include_directories(app PRIVATE src src/ble src/drivers/battery ) # 컴파일할 소스 파일 목록 target_sources(app PRIVATE src/main.c src/parser.c src/ble/ble_service.c ) ``` --- # 4. CMakeLists.txt - 핵심 포인트 ## 자주 쓰는 명령어 | 명령어 | 역할 | |---|---| | `find_package(Zephyr ...)` | **필수** - Zephyr 빌드 시스템 로드 | | `project(이름)` | 프로젝트 이름 설정 | | `target_sources(app PRIVATE ...)` | 컴파일할 .c 파일 추가 | | `target_include_directories(app PRIVATE ...)` | 헤더 검색 경로 추가 | | `target_compile_definitions(app PRIVATE ...)` | 전처리기 매크로 정의 | ## 주의사항 - `app`은 Zephyr에서 정의한 고정 타겟 이름 → 변경 불가 - 새 `.c` 파일을 만들면 **반드시 이 파일에 추가** 해야 컴파일됨 - 헤더(`.h`)는 추가 불필요, 소스(`.c`)만 등록 --- # 4. prj.conf (Kconfig) ## 역할 > **Zephyr 커널 & 드라이버 기능을 ON/OFF 하는 설정 파일** > "어떤 기능을 활성화할지" 결정하는 스위치 모음 ## 구조 예시 (VesiScan 기반) ```ini # GPIO 활성화 CONFIG_GPIO=y # 로깅 (RTT로 출력) CONFIG_LOG=y CONFIG_LOG_BACKEND_RTT=y CONFIG_USE_SEGGER_RTT=y # BLE 스택 CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_DEVICE_NAME="VB026030000" # BLE NUS (Nordic UART Service) CONFIG_BT_NUS=y # ADC (배터리 측정) CONFIG_ADC=y # I2C (IMU 센서) CONFIG_I2C=y ``` --- # 4. prj.conf - 값의 종류 ## Kconfig 값 타입 | 타입 | 예시 | 설명 | |---|---|---| | `bool` | `CONFIG_GPIO=y` / `=n` | 켜기 / 끄기 | | `string` | `CONFIG_BT_DEVICE_NAME="MyDevice"` | 문자열 | | `int` | `CONFIG_HEAP_MEM_POOL_SIZE=2048` | 정수 | | `hex` | `CONFIG_FLASH_BASE_ADDRESS=0x0` | 16진수 | ## 팁 - `=y` → 기능 활성화, `=n` → 비활성화 - nRF Kconfig 확장 설치 시 **자동완성** 지원 - 잘못된 `CONFIG_` 이름은 **빌드 시 경고** 발생 - 의존 관계 있음: `CONFIG_BT_NUS=y` 하려면 `CONFIG_BT=y` 필요 --- # 4. .overlay (Device Tree) — 개요 ## Device Tree란? > **하드웨어 구성을 코드 없이 선언하는 데이터 포맷** > "어떤 핀에 무엇이 연결되어 있는지" 알려주는 하드웨어 지도 ``` .overlay 파일 위치: boards/nrf52840dk_nrf52840.overlay ↑ 이 이름이 빌드 보드와 일치해야 자동으로 적용됨 ``` ## 기본 문법 ```dts /* 노드 수정 */ &노드이름 { 속성이름 = <값>; status = "okay"; /* 활성화 */ status = "disabled"; /* 비활성화 */ }; /* 새 노드 추가 */ / { 내이름: 노드이름 { compatible = "gpio-leds"; gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; }; }; ``` --- # 4. .overlay — GPIO 핀 설정 ## LED & 버튼 정의 (VesiScan 예시) ```dts / { led { compatible = "gpio-leds"; /* LED_BLE: GPIO0 12번 핀, Active Low */ LED_BLE: LED_BLE { gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; label = "Green LED"; }; /* FUNCTION_LED: GPIO0 29번 핀, Active Low */ FUNCTION_LED: FUNCTION_LED { gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; label = "Orange LED"; }; }; pin { compatible = "gpio-keys"; /* 전원 홀드 핀: GPIO0 8번, Active High */ PWR_HOLD: PWR_HOLD { gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; }; }; }; ``` --- # 4. .overlay — I2C 핀 재설정 ## I2C 핀을 기본값에서 변경 (VesiScan IMU 예시) ```dts /* I2C0 핀 재설정: SCL=P1.14, SDA=P1.15 */ &i2c0_default { group1 { psels = , ; }; }; &i2c0 { status = "okay"; clock-frequency = ; }; ``` ## 충돌 방지 — 기본 주변장치 비활성화 ```dts /* P0.08이 UART0 RX와 충돌 → UART0 비활성화 */ &uart0 { status = "disabled"; }; ``` --- # 4. .overlay — ADC 채널 설정 ## 배터리 전압 측정 ADC (VesiScan 예시) ```dts &adc { status = "okay"; #address-cells = <1>; #size-cells = <0>; /* AIN2 = P0.04, 배터리 전압 측정 */ channel@2 { reg = <2>; zephyr,gain = "ADC_GAIN_1_6"; /* 1/6 게인 */ zephyr,reference = "ADC_REF_INTERNAL"; /* 0.6V 기준 */ zephyr,input-positive = ; zephyr,resolution = <12>; /* 12비트 */ zephyr,oversampling = <2>; /* 4x 오버샘플링 */ }; }; / { /* 코드에서 ADC 채널 참조용 */ zephyr,user { io-channels = <&adc 2>; }; }; ``` --- # 4. 파일 구조 요약 ## 세 파일의 관계 ``` ┌─────────────────────────────────────────────────┐ │ 내 프로젝트 │ │ │ │ CMakeLists.txt → "어떤 파일을 컴파일하나?" │ │ │ │ prj.conf → "어떤 기능을 켜나?" │ │ (Kconfig) BLE, I2C, ADC, LOG 등 │ │ │ │ .overlay → "하드웨어가 어떻게 연결됐나?" │ │ (Device Tree) 핀 번호, 주소, 설정 등 │ └─────────────────────────────────────────────────┘ ↓ 빌드 시 Zephyr가 모두 합쳐서 컴파일 ``` | 파일 | 변경 시 영향 | 자동완성 확장 | |---|---|---| | `CMakeLists.txt` | 새 파일 추가/제거 | 없음 | | `prj.conf` | 기능 활성화/비활성화 | nRF Kconfig | | `.overlay` | 핀/주변장치 설정 | nRF DeviceTree | --- # 5. 빌드 & 플래싱 ## VS Code에서 빌드 1. 사이드바 → **nRF Connect** 패널 2. **APPLICATIONS** 섹션에서 프로젝트 확인 3. **Build** 버튼 (망치 아이콘) 클릭 ``` 빌드 결과물 위치: build/ ├── zephyr/ │ ├── zephyr.hex ← 플래싱용 HEX 파일 │ ├── zephyr.elf ← 디버깅용 ELF 파일 │ └── zephyr.bin ← 바이너리 └── CMakeFiles/ ← 빌드 캐시 ``` ## 플래싱 1. J-Link 또는 DK 보드를 USB로 연결 2. **Flash** 버튼 클릭 3. `west flash` 명령도 가능: ```bash west flash --runner jlink ``` --- # 5. 빌드 에러 해결 팁 ## 자주 발생하는 에러 | 에러 메시지 | 원인 | 해결 | |---|---|---| | `undefined reference to ...` | .c 파일이 CMakeLists에 없음 | `target_sources`에 추가 | | `Kconfig warning: ...` | 잘못된 CONFIG 이름 | 철자 확인, 의존성 확인 | | `DTS error: ...` | .overlay 문법 오류 | nRF DeviceTree 확장으로 확인 | | `No boards found` | 보드 이름 불일치 | overlay 파일명 = 보드 이름 | | `west not found` | Toolchain 설정 안 됨 | nRF Connect 패널에서 SDK 재설치 | --- # 6. 디버깅 — RTT ## Segger RTT (Real-Time Transfer) > UART 없이 J-Link를 통해 **실시간 로그** 출력 ### prj.conf 설정 ```ini CONFIG_LOG=y CONFIG_LOG_BACKEND_RTT=y CONFIG_USE_SEGGER_RTT=y CONFIG_RTT_CONSOLE=y CONFIG_UART_CONSOLE=n ← UART 비활성화 ``` ### 코드에서 사용 ```c #include LOG_MODULE_REGISTER(my_module, LOG_LEVEL_DBG); void my_func(void) { LOG_INF("동작 시작"); LOG_DBG("디버그 값: %d", value); LOG_ERR("에러 발생!"); } ``` ### 로그 확인 VS Code 사이드바 → **nRF Terminal** → **Start Terminal with New Configuration** → RTT 선택 --- # 6. 디버깅 — GDB ## VS Code 중단점 디버깅 1. `.elf` 파일이 `build/zephyr/zephyr.elf`에 있어야 함 2. VS Code 상단 **Debug** 버튼 (▶ 아이콘 옆 벌레) 3. 또는 **nRF Connect** 패널 → **Debug** 버튼 ### 가능한 작업 - 중단점 설정/해제 - 변수 값 실시간 확인 - 스택 추적 (Call Stack) - 레지스터 / 메모리 뷰 > **팁**: `CMakeLists.txt`에 `-O0` 최적화 옵션 없어도 > Zephyr 디버그 빌드 (`-DCONF_FILE=prj.conf` + Debug 모드)로 자동 설정됨 --- # 7. 실제 프로젝트 예시 — VesiScan ## 프로젝트 구조 ``` VesiScan-Basic_zephyr/ ├── CMakeLists.txt ← 빌드 설정 ├── prj.conf ← GPIO, BLE, ADC, I2C, RTT ├── boards/ │ └── nrf52840dk_nrf52840.overlay ← 핀 설정 └── src/ ├── main.c ← 메인 루프 ├── parser.c / .h ← 데이터 파싱 ├── power_control.c / .h ← 전원 관리 ├── ble/ │ └── ble_service.c / .h ← BLE NUS 서비스 └── drivers/ ├── battery/battery_adc.c ← 배터리 ADC ├── led/led_control.c ← LED 제어 └── imu/imu_i2c.c ← ICM42670P IMU ``` --- # 7. VesiScan — 활성화된 기능 정리 ## prj.conf 기준 활성화 기능 ``` VesiScan 기능 스택 │ ├── 하드웨어 │ ├── GPIO → LED, 전원버튼, 전원홀드 │ ├── I2C → ICM42670P IMU (P1.14/P1.15) │ └── ADC → 배터리 전압 (AIN2 = P0.04) │ ├── 통신 │ └── BLE → NUS (Nordic UART Service) │ ├── Device Name: "VB026030000" │ ├── MTU: 247 bytes │ └── TX Power: +8 dBm │ └── 디버그 └── RTT → Segger J-Link RTT 로그 ``` --- # 7. VesiScan — .overlay 핀 맵 요약 ## 핀 배치 한눈에 보기 | 핀 | 방향 | 기능 | 코드 참조 | |---|---|---|---| | P0.08 | 출력 | 전원 홀드 래치 | `PWR_HOLD` | | P1.08 | 입력 | 전원 버튼 | `BUTTON_CHECK` | | P0.12 | 출력 | BLE LED (녹색) | `LED_BLE` | | P0.29 | 출력 | 기능 LED (주황) | `FUNCTION_LED` | | P0.04 | 아날로그 | 배터리 ADC (AIN2) | `io-channels` | | P1.14 | I2C | IMU SCL | `i2c0` | | P1.15 | I2C | IMU SDA | `i2c0` | > **overlay의 노드 라벨** (`LED_BLE`, `PWR_HOLD` 등)을 코드에서 > `DT_ALIAS()` / `DT_NODELABEL()`로 직접 참조 가능 --- # 요약 & 체크리스트 ## 새 프로젝트 시작 시 확인 사항 - [ ] nRF Connect Extension Pack 설치 - [ ] SDK + Toolchain 버전 설치 (Toolchain Manager) - [ ] Board 선택하여 Build Configuration 추가 - [ ] `CMakeLists.txt`에 모든 `.c` 파일 등록 - [ ] `prj.conf`에 필요한 기능 `CONFIG_XXX=y`로 활성화 - [ ] `.overlay` 파일명 = 보드 이름과 일치 확인 - [ ] 핀 충돌 확인 (기본 주변장치 비활성화 필요 시) - [ ] Build → Flash → RTT 로그로 동작 확인 --- # Thank you **nRF Connect for VS Code 매뉴얼** 작성 기준 프로젝트: **VesiScan-Basic_zephyr** SDK 버전: nRF Connect SDK v2.x / Zephyr RTOS --- *이 문서는 Marp를 이용해 PPT로 내보낼 수 있습니다.* *VS Code에서 Marp for VS Code 확장 설치 후* *`Export Slide Deck` → PPTX / PDF / HTML 선택*