16 KiB
marp, theme, paginate, backgroundColor, style
| marp | theme | paginate | backgroundColor | style |
|---|---|---|---|---|
| true | default | true | 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
완전 입문 가이드
설치 → 프로젝트 생성 → 파일 구조 이해 → 빌드 & 플래싱
목차
- nRF Connect SDK 개요
- 개발 환경 설치
- 첫 프로젝트 만들기
- 핵심 파일 구조
CMakeLists.txtprj.conf(Kconfig).overlay(Device Tree)
- 빌드 & 플래싱
- 디버깅 (RTT / J-Link)
- 실제 프로젝트 예시 (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 확장 설치
- VS Code 실행 → Extensions (
Cmd+Shift+X/Ctrl+Shift+X) - "nRF Connect for VS Code Extension Pack" 검색 후 설치
- 설치되는 확장 목록:
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)
- VS Code 좌측 사이드바 → nRF Connect 아이콘 클릭
- "Install Toolchain" → 원하는 SDK 버전 선택 (예:
v2.6.0) - 자동으로 다음을 다운로드:
- ARM GCC 툴체인
- west (Python 기반 빌드/패키지 도구)
- nRF Connect SDK 소스
설치 경로 예시 (macOS)
~/ncs/v2.6.0/→ SDK 소스~/ncs/toolchains/→ GCC, west 등
3. 첫 프로젝트 만들기 (1/2)
방법 A: Sample에서 시작 (추천)
- 사이드바 → nRF Connect 패널
- "Create a new application" 클릭
- 옵션 선택:
- 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 추가
- "Add Build Configuration" 클릭
- Board 선택 (예:
nrf52840dk_nrf52840) - 설정 확인 후 Build 클릭
프로젝트 최소 구성
my_project/
├── CMakeLists.txt ← 빌드 대상 소스 파일 목록
├── prj.conf ← Kconfig: 기능 ON/OFF 스위치
├── src/
│ └── main.c ← 진입점
└── boards/ ← (선택) 보드별 오버레이
└── nrf52840dk_nrf52840.overlay
4. CMakeLists.txt
역할
빌드 시스템에게 "무엇을 컴파일할지" 알려주는 파일
기본 구조
# 최소 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 기반)
# 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
↑ 이 이름이 빌드 보드와 일치해야 자동으로 적용됨
기본 문법
/* 노드 수정 */
&노드이름 {
속성이름 = <값>;
status = "okay"; /* 활성화 */
status = "disabled"; /* 비활성화 */
};
/* 새 노드 추가 */
/ {
내이름: 노드이름 {
compatible = "gpio-leds";
gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
};
};
4. .overlay — GPIO 핀 설정
LED & 버튼 정의 (VesiScan 예시)
/ {
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 예시)
/* 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>;
};
충돌 방지 — 기본 주변장치 비활성화
/* P0.08이 UART0 RX와 충돌 → UART0 비활성화 */
&uart0 {
status = "disabled";
};
4. .overlay — ADC 채널 설정
배터리 전압 측정 ADC (VesiScan 예시)
&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에서 빌드
- 사이드바 → nRF Connect 패널
- APPLICATIONS 섹션에서 프로젝트 확인
- Build 버튼 (망치 아이콘) 클릭
빌드 결과물 위치:
build/
├── zephyr/
│ ├── zephyr.hex ← 플래싱용 HEX 파일
│ ├── zephyr.elf ← 디버깅용 ELF 파일
│ └── zephyr.bin ← 바이너리
└── CMakeFiles/ ← 빌드 캐시
플래싱
- J-Link 또는 DK 보드를 USB로 연결
- Flash 버튼 클릭
west flash명령도 가능:
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 설정
CONFIG_LOG=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y
CONFIG_UART_CONSOLE=n ← UART 비활성화
코드에서 사용
#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 중단점 디버깅
.elf파일이build/zephyr/zephyr.elf에 있어야 함- VS Code 상단 Debug 버튼 (▶ 아이콘 옆 벌레)
- 또는 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 선택