BLE 하드웨어 구조
BLE(Bluetooth Low Energy)는 저전력 근거리 무선 통신 프로토콜이다. Classic Bluetooth와 같은 2.4GHz ISM 대역을 쓰지만, 전력 소모를 극단적으로 줄인 별도 프로토콜이다. 이 문서는 하드웨어 계층(PHY, Link Layer)과 MCU 구조를 다룬다. 연결/데이터 교환을 담당하는 GAP/GATT는 별도 문서에서 다룬다.
프로토콜 스택
┌─────────────────────────┐
│ Host (Software) │
│ ┌─────────┬──────────┐ │
│ │ GAP │ GATT │ │
│ ├─────────┼──────────┤ │
│ │ ATT │ SMP │ │
│ ├─────────┴──────────┤ │
│ │ L2CAP │ │
│ └────────────────────┘ │
├─────────────────────────┤
│ HCI │
├─────────────────────────┤
│ Controller (Hardware) │
│ ┌────────────────────┐ │
│ │ Link Layer │ │
│ ├────────────────────┤ │
│ │ Physical Layer │ │
│ └────────────────────┘ │
└─────────────────────────┘
- Controller — 전파 송수신 + 링크 관리. SoC 안의 라디오 하드웨어가 담당
- Host — 데이터 구조화, 보안, 프로파일. MCU 소프트웨어로 실행
- HCI — 둘 사이 인터페이스. 단일 칩이면 함수 호출, 분리 구조(예: STM32WB)면 IPCC/UART/SPI
Controller의 물리적 제약(채널 수, PHY 종류, 패킷 크기)이 앱의 throughput, 도달 거리, 전력 소모를 결정한다.
Physical Layer
주파수와 채널
2.400–2.4835 GHz ISM 대역에 40개 채널이 2MHz 간격으로 배치된다.
채널: 37 0 1 2 3 ... 10 38 11 ... 36 39
MHz: 2402 2426 2480
↑ ADV ↑ ADV ↑ ADV
- Advertising 채널 3개 (37, 38, 39) — 2402, 2426, 2480 MHz. Wi-Fi 채널 1, 6, 11 사이에 배치되어 간섭을 최소화
- Data 채널 37개 (0–36) — 연결 후 데이터 교환용. AFH(Adaptive Frequency Hopping)로 간섭 채널을 자동 회피
Wi-Fi와 같은 보드에서 BLE를 쓸 때, advertising은 Wi-Fi 채널 사이에 있어 비교적 안전하다. Data 채널은 AFH가 알아서 피한다. STM32WB처럼 BLE 단독 칩이면 신경 쓸 필요 없다.
PHY 종류와 선택 기준
| PHY | 데이터 레이트 | 실측 범위 | BLE 버전 | 언제 쓰는가 |
|---|---|---|---|---|
| LE 1M | 1 Mbps | ~100m | 4.0+ | 기본값. 대부분의 경우 이걸 쓴다 |
| LE 2M | 2 Mbps | ~80m | 5.0+ | OTA, 대용량 전송. 전력도 오히려 절약 |
| LE Coded S2 | 500 Kbps | ~200m | 5.0+ | 장거리. 코딩 게인으로 수신 감도 향상 |
| LE Coded S8 | 125 Kbps | ~400m | 5.0+ | 최장거리. 감도 +12dB |
변조 방식은 GFSK (Gaussian Frequency-Shift Keying). LE 1M과 2M은 같은 GFSK이고, 심볼 레이트만 다르다.
LE 2M이 전력을 절약하는 이유: 같은 데이터를 절반 시간에 보내므로, 라디오 on 시간이 줄어든다. throughput이 중요한 시나리오에서 LE 2M을 먼저 고려한다.
LE Coded의 trade-off: S8에서 같은 데이터를 보내면 8배 시간이 걸리고, 전력도 8배 소모된다. 배터리 디바이스에서 장거리를 써야 한다면 전송 주기를 극단적으로 낮추는 설계가 필요하다.
패킷 구조
┌──────────┬──────────┬─────────┬────────┐
│ Preamble │ Access │ PDU │ CRC │
│ 1-2B │ Address │ 2-257B │ 3B │
│ │ 4B │ │ │
└──────────┴──────────┴─────────┴────────┘
- Advertising PDU: 최대 37B payload (BLE 4.x), 255B (BLE 5.0 Extended Advertising)
- Data PDU: 최대 27B payload (BLE 4.0-4.1), 251B (BLE 4.2+ DLE)
ATT 페이로드 기준으로 기본 20바이트만 보낼 수 있다 (MTU 23 - ATT 헤더 3). BLE 4.2+ Data Length Extension(DLE)을 쓰면 한 패킷에 최대 251바이트까지 가능하다.
throughput 계산 (LE 1M, DLE, CI=7.5ms):
- connection event당 최대 6패킷 × 251B ≈ 1,506B
- 1초 = 133 intervals → 이론 ~200KB/s, 실측 100-150KB/s
Link Layer
상태 머신
┌──▶ Advertising ──┐
│ │ CONNECT_REQ 수신
Standby ──────────┼──▶ Scanning ▼
│ Connection
└──▶ Initiating ──┘
CONNECT_REQ 전송
Connection → Standby (연결 종료/타임아웃)
- Standby — 라디오 off. 전력 소모 없음
- Advertising — 3개 advertising 채널에 순차적으로 패킷 전송
- Scanning — advertising 채널에서 수신. Passive(듣기만) / Active(Scan Request 전송)
- Initiating — 특정 advertiser를 찾으면
CONNECT_REQ전송 - Connection — data 채널에서 양방향 데이터 교환
Connection Parameters
연결이 성립되면 3개 파라미터가 동작을 결정한다.
| 파라미터 | 범위 | 역할 |
|---|---|---|
| Connection Interval (CI) | 7.5ms – 4s | 데이터 교환 주기 |
| Slave Latency | 0 – 499 intervals | 데이터 없을 때 건너뛸 수 있는 interval 수 |
| Supervision Timeout | 100ms – 32s | 이 시간 동안 응답 없으면 연결 끊김 |
시나리오별 권장 설정:
| 시나리오 | CI | Latency | Timeout | 이유 |
|---|---|---|---|---|
| 실시간 제어 (리모컨) | 7.5-15ms | 0 | 2s | 즉각 반응 |
| 센서 주기 보고 | 500ms-1s | 4-9 | 6s | 전력 절약 우선 |
| 배터리 + 가끔 알림 | 1-2s | 10 | 20s | 최소 전력 |
| OTA 업데이트 | 7.5ms | 0 | 4s | 최대 throughput |
Peripheral이 Connection Parameter Update Request로 변경을 요청할 수 있지만, 최종 결정은 Central이 한다. iOS는 특히 제약이 많아서, 요청한 값이 거부될 수 있다.
Frequency Hopping
연결 후 data 채널(37개)을 매 connection event마다 바꾼다. 다음 채널 = (현재 + hopIncrement) mod 37. hopIncrement는 CONNECT_REQ에서 결정된다.
AFH(Adaptive Frequency Hopping)가 간섭이 심한 채널을 맵에서 제거한다. 최소 2개 채널은 유지해야 한다.
STM32WB 하드웨어 아키텍처
STM32WB 시리즈는 BLE를 위한 듀얼 코어 구조다.
┌──────────────────────┐ ┌──────────────────────┐
│ Cortex-M4 (App) │ │ Cortex-M0+ (Radio) │
│ ┌──────────────────┐ │ │ ┌──────────────────┐ │
│ │ User Application │ │ │ │ Link Layer │ │
│ ├──────────────────┤ │ │ ├──────────────────┤ │
│ │ BLE Host │ │ │ │ PHY + Radio │ │
│ │ (GAP/GATT/L2CAP) │ │ │ └──────────────────┘ │
│ └──────────────────┘ │ └──────────────────────┘
└──────────────────────┘
| 코어 | 역할 | 클럭 | 메모리 |
|---|---|---|---|
| Cortex-M4 | 앱 + BLE Host | 최대 64MHz | Flash 1MB, SRAM1 256KB |
| Cortex-M0+ | BLE Controller (PHY+LL) | 최대 32MHz | 공유 SRAM2 사용 |
코어 간 통신: IPCC
두 코어는 IPCC(Inter-Processor Communication Controller) + 공유 SRAM2로 통신한다.
M4 ──[HCI Command]──→ SRAM2 ──[IPCC IRQ]──→ M0+
M4 ←─[HCI Event]──── SRAM2 ←─[IPCC IRQ]── M0+
- M4가 HCI 커맨드를 SRAM2 지정 영역에 쓴다
- IPCC 채널로 인터럽트를 건다
- M0+가 깨어나서 처리하고, 결과를 SRAM2에 쓴다
- IPCC로 M4에 알린다
M0+ Wireless Stack
M0+에는 ST 제공 pre-compiled binary를 flash한다. 소스 코드가 없다.
| 바이너리 | 기능 | 용도 |
|---|---|---|
BLE_Stack_full | 모든 BLE 기능 | Central + Peripheral, Extended ADV |
BLE_Stack_light | Peripheral만 | 메모리 절약이 필요할 때 |
BLE_HCILayer | HCI만 | 외부 Host 스택 사용 시 |
초기화 순서
/* main.c */
/* 1. 하드웨어 초기화 */
HAL_Init();
SystemClock_Config();
MX_IPCC_Init(); /* IPCC 먼저 */
/* 2. Transport Layer — M4↔M0+ 통신 채널 설정 */
TL_Init();
SHCI_C2_BLE_Init(&ble_init_param); /* M0+에 BLE 파라미터 전달 */
/* 3. BLE Host 초기화 */
aci_gatt_init();
aci_gap_init(GAP_PERIPHERAL_ROLE, ...);
/* 4. 서비스 등록 후 Advertising 시작 */
Custom_STM_Init();
Adv_Request();
SHCI_C2_BLE_Init의 파라미터로 최대 연결 수, ATT MTU, GATT 속성 수 등을 설정한다. 이 값들이 M0+의 SRAM2 할당량을 결정하므로, 부족하면 런타임에 서비스 등록이 silent fail한다.
용도별 하드웨어 설정
BLE 하드웨어의 어떤 기능을 어떻게 조합하느냐에 따라 용도가 달라진다.
비콘 (Advertising Only)
연결 없이 advertising 패킷만 브로드캐스트. 가장 단순한 구조.
- 하드웨어 설정:
ADV_NONCONN_IND타입, advertising interval 100ms~10s - 용도: iBeacon/Eddystone 위치 서비스, 센서 브로드캐스트
- BLE 5.0 Extended Advertising: payload 255B까지 확장. 더 많은 데이터를 연결 없이 전송
- 전력: Connection overhead가 없으므로 가장 효율적. 코인 배터리로 수년 동작
/* STM32WB — 비연결 advertising 설정 */
aci_gap_set_discoverable(
ADV_NONCONN_IND, /* 연결 불가, 브로드캐스트 전용 */
160, /* min interval: 100ms (160 × 0.625ms) */
160, /* max interval */
CFG_BLE_ADDRESS_TYPE,
NO_WHITE_LIST_USE,
sizeof(local_name), (uint8_t *)local_name,
sizeof(svc_uuid_list), svc_uuid_list,
0, 0);
센서 네트워크 (저빈도 연결)
센서 → 게이트웨이로 주기적 데이터 전송.
- 하드웨어 설정: CI 1-4s, Slave Latency 4-9, LE 1M PHY
- 데이터 방식: Notification으로 Server(센서)가 push
- 전력: Slave Latency로 데이터 없는 interval을 건너뛰어 전력 절약
/* 연결 후 저전력 파라미터 요청 */
struct ble_gap_upd_params params = {
.itvl_min = 800, /* 1000ms (800 × 1.25ms) */
.itvl_max = 1600, /* 2000ms */
.latency = 4, /* 4 interval 건너뛰기 가능 */
.supervision_timeout = 600, /* 6초 */
};
실시간 제어 (고빈도 연결)
리모컨, 게임패드, 모터 제어 등 즉각 반응이 필요한 경우.
- 하드웨어 설정: CI 7.5-15ms, Slave Latency 0, LE 2M PHY 권장
- LE 2M 이점: 같은 CI에서 라디오 on 시간이 반으로 줄어 전력 절약 + latency 감소
- 전력: 높지만, 대부분 전원 연결 디바이스이므로 문제없음
/* 최소 latency 설정 */
struct ble_gap_upd_params params = {
.itvl_min = 6, /* 7.5ms (6 × 1.25ms) */
.itvl_max = 12, /* 15ms */
.latency = 0, /* 모든 interval에서 응답 */
.supervision_timeout = 200, /* 2초 */
};
/* LE 2M PHY 요청 */
ble_gap_set_prefered_le_phy(conn,
BLE_GAP_LE_PHY_2M_MASK, /* TX */
BLE_GAP_LE_PHY_2M_MASK, /* RX */
0);
대용량 전송 (OTA)
펌웨어 업데이트 등 최대 throughput이 필요한 경우.
- 하드웨어 설정: CI 7.5ms + DLE(251B) + LE 2M + MTU 247
- 실측 throughput: LE 2M + DLE로 ~200KB/s 가능
- 패턴: 전송 시작 전 파라미터를 올리고, 완료 후 원래 값으로 복귀
장거리 (LE Coded PHY)
농업 센서, 넓은 창고 모니터링 등 400m+ 도달이 필요한 경우.
- 하드웨어 설정: LE Coded S8, CI 1-4s
- 제약: throughput 125Kbps. 소량 데이터만 가능
- 전력: S8은 라디오 on 시간이 8배이므로, 전송 주기를 극단적으로 낮춰야 한다
/* LE Coded S8 요청 */
ble_gap_set_prefered_le_phy(conn,
BLE_GAP_LE_PHY_CODED_MASK,
BLE_GAP_LE_PHY_CODED_MASK,
BLE_GAP_LE_PHY_CODED_S8); /* S8: 125Kbps, 최장거리 */
메모
- 동시 연결 수
- Data 채널이 37개라고 37개 연결이 되는 건 아니다. BLE는 시분할(TDMA)로 여러 연결을 관리
- 동시 연결 수는 Link Layer의 스케줄링 능력에 의존. STM32WB는 최대 8개
- TX Power 설정
- 대부분의 BLE 칩은 -20dBm ~ +8dBm 범위. STM32WB55는 최대 +6dBm, nRF52840은 +8dBm
- 올리면 범위 증가, 전력 소모 증가. 보통 0dBm이 적절한 균형점
- 실내 환경에서는 TX power보다 장애물/반사가 범위를 더 크게 좌우한다
- SRAM2 관리 (STM32WB)
- SRAM2는 M0+ 바이너리 + 공유 버퍼로 사용된다. 앱에서 SRAM2를 건드리면 BLE 스택이 깨진다
SHCI_C2_BLE_Init의 max connections, ATT MTU 등이 SRAM2 사용량을 결정- 파라미터를 과하게 잡으면 M0+가 메모리 부족으로 silent fail. 디버깅이 어렵다
- DLE(Data Length Extension) 적용
- DLE는 양쪽 디바이스 모두 지원해야 한다. 연결 후
aci_gatt_exchange_config로 MTU negotiation - iOS/Android는 기본적으로 DLE를 지원하지만, 일부 구형 스마트폰은 안 된다
- DLE 없이는 20B/패킷이므로, 대용량 전송 시 throughput 차이가 10배 이상
- DLE는 양쪽 디바이스 모두 지원해야 한다. 연결 후