임베디드 기초 5편 - 인터럽트와 NVIC: CPU를 기다리게 하지 마라

들어가며 4편에서 벡터 테이블을 다뤘다. [0]은 MSP, [1]은 Reset_Handler 주소였고, 나머지 항목들(NMI_Handler, HardFault_Handler, TIM2_IRQHandler…)은 그냥 지나쳤다. 이것들이 전부 인터럽트 핸들러다. 임베디드 코드의 상당 부분이 이 핸들러들 안에서 돌아간다. 폴링 vs 인터럽트 외부 이벤트(버튼 입력, 센서 데이터 도착 등)를 처리하는 방법은 두 가지다. 폴링 (Polling) 1 2 3 4 5 6 while (1) { if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET) { // 버튼 눌림 처리 } do_something_else(); } CPU가 주기적으로 상태를 직접 확인한다. CPU가 루프를 돌며 GPIO를 계속 읽어야 하고, 짧은 펄스나 빠른 이벤트를 놓칠 수 있다. 확인할 이벤트가 늘어날수록 반응 속도도 느려진다. ...

2026년 5월 28일 · 4 min · 서보민

임베디드 기초 4편 - ARM Cortex-M 부팅 과정: 전원 인가에서 main()까지

들어가며 3편에서 .c 파일이 .elf를 거쳐 플래시에 올라가는 빌드 과정을 정리했다. 이제 반대 방향을 볼 차례다. 플래시에 올라간 펌웨어를 MCU가 어떻게 실행하는가. 전원이 켜지는 순간 CPU는 어디서부터 코드를 시작할까? 내가 작성한 main()이 첫 번째로 실행되는 것일까? 그렇지 않다. main() 이전에 이미 여러 단계가 실행된다. ARM Cortex-M 메모리 맵 Cortex-M은 모든 제조사가 공통으로 따르는 표준 메모리 맵을 갖는다. STM32든 nRF52든 RP2040이든 코어 수준에서는 동일한 주소 배치를 사용한다. ...

2026년 5월 21일 · 4 min · 서보민

임베디드 기초 3편 - 빌드 과정: 소스 코드가 플래시에 올라가기까지

들어가며 2편에서 .text/.data/.bss 섹션과 링커 스크립트를 다뤘다. .data > RAM AT > FLASH 구문이 LMA와 VMA를 분리한다는 것까지 정리했다. 그런데 이 링커 스크립트는 누가, 언제, 어떻게 처리하는 걸까. main.c 하나를 작성하고 빌드 버튼을 누르면 어떤 일이 일어나는지 정확히 알지 못한 채로 쓰고 있었다. ARM Cortex-M 툴체인 ARM Cortex-M을 타겟으로 빌드할 때 쓰는 컴파일러는 arm-none-eabi-gcc다. 이름을 뜯어보면: arm: 타겟 아키텍처 none: 운영체제 없음 (bare-metal) eabi: Embedded ABI — 함수 호출 규약, 데이터 정렬 방식 표준 gcc: GNU Compiler Collection STM32CubeIDE나 PlatformIO 같은 IDE를 쓰면 이 툴체인이 자동으로 설정된다. 직접 Makefile이나 CMake를 구성할 때는 직접 지정해야 한다. ...

2026년 5월 14일 · 3 min · 서보민