본문으로 건너뛰기
Embedded Performance Engineering · 26/57

Peripheral Clock 분석 — PLL·Divider·Gating·DVFS

· Hawk · 4분 읽기

#한 줄 요약

“Peripheral clock = 속도 + 전력” 입니다. 분주가 SPI MHz와 UART baud를 결정합니다.

#Clock Tree — STM32H743 예

STM32H7 clock tree — HSE, PLL1/2/3, AHB/APB divider, peripheral clock source 선택

각 peripheral은 별도의 clock source를 선택할 수 있고, 이렇게 하면 power를 최적화할 수 있습니다.

#RCC Enable·Disable

__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Disable when unused → power 절약 */
__HAL_RCC_USART2_CLK_DISABLE();

Cortex-M은 reset 직후 모든 peripheral clock이 OFF 상태이므로, 사용하기 전에 반드시 활성화해야 합니다.

RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
__DSB(); // ← clock stable 대기
USART1->BRR = 1000; // safe

#SPI Clock 계산

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
/* SPI1 source = APB2 = 100 MHz
SPI_CLK = 100 / 8 = 12.5 MHz */

Prescaler는 2, 4, 8, 16, 32, 64, 128, 256 중에서 고릅니다.

BaudRatePrescalerPeriod
50 MHz/220 ns
25 MHz/440 ns
12.5 MHz/880 ns
6.25 MHz/16160 ns

SPI slave 데이터시트의 fSPI_MAX를 넘기지 않도록 합니다.

#UART Baud Rate

huart1.Init.BaudRate = 115200;
/* USART_BRR = PCLK / baud
= 100,000,000 / 115200 = 868.05...
→ 정수만 가능, fractional은 *DIV_FRACTION* 필드 */

오차:

ideal=100,000,000868=115,207\text{ideal} = \frac{100{,}000{,}000}{868} = 115{,}207

error=115,207115,200115,200=0.006%\text{error} = \frac{115{,}207 - 115{,}200}{115{,}200} = 0.006\%

3% 이내이므로 OK입니다. PLL이 깨끗한 정수 비율이면 오차가 0이 됩니다.

#Clock Gating — Linux CCF

Common Clock Framework — kernel/clk-provider.h
각 driver:
struct clk *clk = devm_clk_get(dev, "core");
clk_prepare_enable(clk);
/* peripheral 사용 */
clk_disable_unprepare(clk);

사용하지 않는 driver는 clock이 자동으로 disable되어 전력을 절약해 줍니다.

Terminal window
# 현재 상태
cat /sys/kernel/debug/clk/clk_summary

#DVFS — Dynamic Voltage·Frequency Scaling

Workload high → CPU freq ↑, voltage ↑
Workload low → CPU freq ↓, voltage ↓

Linux cpufreq:

Terminal window
# governor 설정
echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 강제 frequency
echo userspace > .../scaling_governor
echo 600000 > .../scaling_setspeed # 600 MHz

전력은 V² × f에 비례하므로, V를 약간만 줄여도 전력을 크게 절약할 수 있습니다.

#자동차 사례 — 변속·정차에 따른 DVFS

void on_idle(void) {
/* 차량 정차 — CPU 100 MHz */
set_pll(100_MHZ);
set_voltage(VDD_0_9V);
}
void on_accel(void) {
/* 가속 — CPU 600 MHz */
set_voltage(VDD_1_1V); // *먼저* voltage 올림
settle_us(100);
set_pll(600_MHZ);
}

순서는 voltage를 먼저 올리고 frequency를 나중에 올리는 것입니다. 반대로 하면 under-voltage fault가 발생합니다.

#PLL Lock Time

RCC->PLLCFGR = PLL_CONFIG;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY)) {} // ~100 µs wait
RCC->CFGR |= RCC_CFGR_SW_PLL;

PLL lock에는 수십 µs가 걸리고, power-up이나 DVFS 시점에는 그 동안 blocking됩니다. RTC backup으로 이 구간을 우회할 수 있습니다.

#CSS — Clock Security System

RCC->CR |= RCC_CR_CSSON;

HSE 실패(XTAL 깨짐)를 감지하면 자동으로 HSI로 fallback합니다. 자동차나 항공처럼 안전이 중요한 영역에서 자주 쓰입니다.

void NMI_Handler(void) {
if (RCC->CIR & RCC_CIR_CSSF) {
log_fault();
reset_or_fallback();
}
}

#Sleep·Stop·Standby — Cortex-M

/* Sleep — CPU off, peripheral on */
__WFI();
/* Stop — clock off, RAM 유지 */
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
/* Standby — 모든 것 off, RAM 잃음 */
HAL_PWR_EnterSTANDBYMode();

각 모드는 wakeup latency와 트레이드오프 관계입니다.

ModeWakeupCurrent
Sleep0 µs5 mA
Stop~10 µs200 µA
Standby~200 µs (reset)1 µA

#ESP32 — Light Sleep·Deep Sleep

/* Light sleep — 1 ms wakeup, RTC 유지 */
esp_light_sleep_start();
/* Deep sleep — 수 µA */
esp_deep_sleep_start();
/* → 깨어나면 reset에 가까움 (RTC RAM만 유지) */

IoT 센서는 99% deep sleep + 1% active 패턴으로 배터리를 수 년 단위로 끌고 갑니다.

#Linux 측정 — powertop·turbostat

Terminal window
sudo powertop --auto-tune
# 자동으로 전력 절약 설정 권장
turbostat
# CPU package power·core frequency·C-state residency

#자주 하는 실수

⚠️ Clock enable 안 하고 register access

USART1->CR1 = USART_CR1_UE; // ← fault: clock 미활성

__HAL_RCC_USART1_CLK_ENABLE()를 먼저 호출해야 합니다.

⚠️ DVFS 시 voltage·frequency 순서 잘못

set_pll(600_MHZ); // → under-voltage fault
set_voltage(VDD_1_1V);

상승할 때는 voltage를 먼저, frequency를 나중에 올립니다. 하강할 때는 반대로 frequency를 먼저 내립니다.

⚠️ Stop mode에서 USB·Ethernet 동작 기대

Stop은 모든 PLL을 끄기 때문에 USB와 Ethernet이 멈춥니다. 이런 peripheral을 살려두려면 Sleep만 사용해야 합니다.

⚠️ CSS 비활성

XTAL이 깨지면 system이 hang하므로, CSS를 enable해서 자동 fallback이 동작하게 해야 합니다.

#정리

  • Clock tree는 HSE/HSI → PLL → AHB → APB → peripheral 순서로 흐릅니다.
  • Peripheral clock을 enable한 뒤에 register에 접근해야 합니다.
  • SPI와 UART baud는 prescaler로 맞춥니다.
  • DVFS는 워크로드에 따라 V와 f를 동적으로 조정해서 V² × f만큼 전력을 절약합니다.
  • PLL lock에는 수십 µs가 걸립니다.
  • Sleep, Stop, Standby는 wakeup latency와 current 사이의 트레이드오프를 만듭니다.

다음 편은 Power vs Performance를 다룹니다.

#관련 항목

Embedded Performance Engineering · 27 of 57

  1. 1Embedded Performance Engineering — 임베디드 성능 엔지니어링 시리즈 소개
  2. 2임베디드 성능 분석 방법론 — Measure → Analyze → Optimize 사이클
  3. 3성능 지표 정의 — Latency·Throughput·Utilization 분석
  4. 4성능 측정의 기본 — Wall-Clock·CPU Cycle·Instruction Count
  5. 5성능 데이터 통계적 분석 — Percentile·Histogram·평균의 함정
  6. 6실시간 성능 분석 — WCET·Jitter·Deadline Miss 측정
  7. 7임베디드 벤치마킹 기초 — 재현성·Warmup·노이즈 제거
  8. 8성능 모델링 — Amdahl·Gustafson·Roofline Model 적용
  9. 9프로파일링 기법 개요 — Sampling vs Instrumentation·PGO·LTO
  10. 10CPU 파이프라인 분석 — 5-stage·Cortex-M·Cortex-A 비교
  11. 11Pipeline Stall 분석 — Data·Structural·Control Hazard·Forwarding
  12. 12Branch Prediction 분석 — Static·2-bit·BTB·BHT·Mispredict 비용
  13. 13Speculative Execution 분석 — OoO·Reorder Buffer·Register Renaming
  14. 14CPU Cache 기초 — L1·L2·L3·Set Associative·Replacement Policy
  15. 15Cache Miss 3C Model 분석 — Compulsory·Capacity·Conflict
  16. 16Cache Line 최적화 — Alignment·Prefetch·False Sharing 처리
  17. 17메모리 대역폭 분석 — STREAM·Roofline·Bus Saturation 측정
  18. 18SIMD·NEON 활용 — 128-bit Vector·Auto-Vectorization·SVE/SVE2
  19. 19PMU·HPM 하드웨어 카운터 분석 — 정밀 성능 진단
  20. 20임베디드 Bus Architecture — AHB·AXI·CHI 진화와 5-Channel
  21. 21Bus Contention 진단 — Arbitration·QoS·Starvation 측정
  22. 22DMA 성능 최적화 — Burst·Scatter-Gather·Chain·Cache 일관성
  23. 23DMA vs CPU Copy 성능 비교 — Break-even·Setup Overhead 실측
  24. 24Interrupt Latency 분석 — 진입·종료·Tail-Chaining·Late Arrival
  25. 25Interrupt Storm 처리 — NAPI·Rate-Limit·Polling 전환
  26. 26MMIO 접근 성능 — Cache Policy·Write-Combining·Volatile·Barrier
  27. 27Peripheral Clock 분석 — PLL·Divider·Gating·DVFS
  28. 28Power vs Performance 트레이드오프 — DVFS·Race-to-Idle·Big.LITTLE
  29. 29Thermal Throttling 분석 — Junction Temp·Trip Point·냉각
  30. 30CXL Interconnect 분석 — AI 시대 메모리 대역폭 확장
  31. 31Concurrency 기초 — Concurrency vs Parallelism·Race·Memory Model
  32. 32False Sharing 진단 — Cache Line Ping-Pong·Padding·측정
  33. 33Lock Contention 분석 — Wait·Hold·Convoy·측정 기법
  34. 34Spinlock 성능 분석 — Spin-Wait vs Context Switch·Ticket·MCS
  35. 35Mutex 성능 분석 — Futex·Adaptive·Priority Inheritance
  36. 36Reader-Writer Lock 성능 — Reader/Writer Priority·RCU·Seqlock
  37. 37Lock-Free 자료구조 성능 — CAS·ABA·Hazard Pointer·Epoch Reclamation
  38. 38Memory Ordering 분석 — Acquire·Release·Seq-Cst·ARM Relaxed Model
  39. 39Cache Coherency 프로토콜 — MESI·MOESI·Snoop·Directory
  40. 40SMP 성능 분석 — Per-Core·Affinity·Load Balance·Scalability
  41. 41Linux perf 기초 — stat·record·report 활용
  42. 42Linux perf 고급 — Raw Event·Tracepoint·perf script
  43. 43ftrace 활용 — function·function_graph·latency tracer
  44. 44eBPF·bpftrace 동적 트레이싱 — 커널 무수정 관측
  45. 45Flamegraph 분석 — On-CPU·Off-CPU·Differential
  46. 46ARM DS·Lauterbach 분석 — Hardware Trace 전문 도구
  47. 47Bare-metal 프로파일링 — GPIO·DWT·SysTick·ITM 활용
  48. 48NVIDIA Nsight Systems — GPU·NPU 포함 시스템 분석
  49. 49모던 프로파일러 비교 — Tracy·Hotspot·uftrace·Coz
  50. 50연속 프로파일링 — Parca·Pixie·Pyroscope·Tetragon
  51. 51실전 사례 — ISR Latency 100µs Deadline Miss 추적
  52. 52실전 사례 — Matrix Multiply가 예상의 10배 느린 이유
  53. 53실전 사례 — 8-core가 4-core를 넘으면 throughput이 떨어지는 이유
  54. 54실전 사례 — 카메라 1080p 60fps가 30fps로 떨어지는 이유
  55. 55CXL.mem 지연·대역폭 실측 — Direct·Switch·Pooled 토폴로지 비교
  56. 56CXL 성능 프로파일링 도구 — cxl-cli·DAMON·perf-mem 활용
  57. 57실전 사례 — CXL.mem 추가로 LLM inference KV cache 처리량 회복