Files
VesiScan-Basic_Zephyr/manual/nrf_connect_vscode_manual.md
2026-04-12 19:16:14 +09:00

660 lines
16 KiB
Markdown

---
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;
}
---
<!-- _paginate: false -->
<!-- _backgroundColor: #003087 -->
<!-- _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 = <NRF_PSEL(TWIM_SCL, 1, 14)>,
<NRF_PSEL(TWIM_SDA, 1, 15)>;
};
};
&i2c0 {
status = "okay";
clock-frequency = <I2C_BITRATE_STANDARD>;
};
```
## 충돌 방지 — 기본 주변장치 비활성화
```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 = <NRF_SAADC_AIN2>;
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 <zephyr/logging/log.h>
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()`로 직접 참조 가능
---
<!-- _backgroundColor: #003087 -->
<!-- _color: white -->
# 요약 & 체크리스트
## 새 프로젝트 시작 시 확인 사항
- [ ] nRF Connect Extension Pack 설치
- [ ] SDK + Toolchain 버전 설치 (Toolchain Manager)
- [ ] Board 선택하여 Build Configuration 추가
- [ ] `CMakeLists.txt`에 모든 `.c` 파일 등록
- [ ] `prj.conf`에 필요한 기능 `CONFIG_XXX=y`로 활성화
- [ ] `.overlay` 파일명 = 보드 이름과 일치 확인
- [ ] 핀 충돌 확인 (기본 주변장치 비활성화 필요 시)
- [ ] Build → Flash → RTT 로그로 동작 확인
---
<!-- _backgroundColor: #003087 -->
<!-- _color: white -->
<!-- _paginate: false -->
# 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 선택*