임베디드 면접 용어 사전
메모리·아키텍처memory map

메모리 맵

주소 공간에 플래시·SRAM·주변장치 레지스터를 배치한 지도. 임베디드에서는 주변장치도 주소로 접근한다.

CPU가 보는 하나의 주소 공간에 플래시·RAM·주변장치가 각각 구역을 차지하도록 배치한 것(memory-mapped I/O).

핵심 발상 — 주변장치도 메모리처럼 보인다

*(volatile uint32_t *)0x40020014 = 0x20;   // GPIOA의 5번 핀을 켠다

이 코드는 메모리에 값을 쓰는 것처럼 생겼지만 실제로는 GPIO 하드웨어를 조작한다. 그 주소에는 RAM이 없고 GPIO 컨트롤러가 연결되어 있다.

왜 이렇게 하나 — 별도의 I/O 명령(x86의 in/out)이 필요 없어진다. 포인터 하나로 하드웨어를 다룰 수 있으니 C 언어만으로 드라이버를 쓸 수 있다. ARM을 비롯한 대부분의 임베디드 아키텍처가 이 방식이다.

Cortex-M의 표준 배치

0xFFFFFFFF ┌───────────────────┐
           │ Vendor specific   │
0xE0000000 ├───────────────────┤
           │ Private Peripheral│  ← NVIC, SysTick, SCB, 디버그
0xA0000000 ├───────────────────┤
           │ External Device   │
0x60000000 ├───────────────────┤
           │ External RAM      │  ← 외부 SDRAM (FSMC/FMC)
0x40000000 ├───────────────────┤
           │ Peripheral        │  ← GPIO, UART, TIM, ADC …
0x20000000 ├───────────────────┤
           │ SRAM              │  ← 변수, 스택, 힙
0x00000000 └───────────────────┘  ← 플래시 (코드, .rodata)

Cortex-M은 이 배치가 아키텍처 차원에서 고정되어 있다. 그래서 벤더가 달라도 큰 틀이 같고, 포팅이 수월하다.

주소만 봐도 알 수 있다

0x0800_0000  → 플래시. 코드가 여기서 실행된다
0x2000_0000  → SRAM. 스택 포인터가 이 범위여야 정상
0x4002_0000  → GPIO 계열 레지스터
0xE000_E010  → SysTick (Cortex-M 공통)

HardFault를 분석할 때 폴트 주소가 어느 구역인지 보면 원인이 좁혀진다. 0x00000000 근처면 NULL 포인터, 플래시 영역에 쓰기를 시도했으면 const 위반, 아무것도 없는 구역이면 잘못된 포인터 연산이다.

비트 밴딩 — Cortex-M3/M4의 특별한 기능

SRAM 0x20000000~ 의 각 비트가

  • 0x22000000~ 영역에 워드 하나씩으로 매핑된다

bit_word_addr = 0x22000000 + (byte_offset × 32) + (bit_number × 4)

// 일반 방식 — read-modify-write (원자적이지 않다)
GPIOA->ODR |= (1 << 5);

// 비트 밴딩 — 단일 쓰기 (원자적)
*(volatile uint32_t *)BITBAND(&GPIOA->ODR, 5) = 1;

비트 하나를 원자적으로 조작할 수 있어 인터럽트와의 경쟁을 피한다. 다만 Cortex-M7 이후에는 빠졌고, 대신 대부분의 주변장치가 BSRR 같은 set/clear 전용 레지스터를 제공한다.

주소 별칭(alias) — 부팅과 관련

많은 MCU가 0x00000000플래시 또는 SRAM을 매핑할 수 있다(BOOT 핀).

BOOT0 = 0 → 0x00000000 에 플래시가 보인다 (일반 부팅) BOOT0 = 1 → 시스템 메모리(내장 부트로더) 또는 SRAM

CPU는 리셋 시 무조건 0x00000000에서 벡터 테이블을 읽으므로, 무엇을 거기에 보이게 하느냐로 부팅 방식이 결정된다.

부트로더가 있는 경우 SCB->VTOR로 벡터 테이블 위치를 옮긴다.

접근 속성 — 그냥 메모리가 아니다

메모리 맵의 각 구역에는 속성이 붙는다.

속성
Device / Strongly-ordered주변장치 영역. 캐시 금지, 순서 보장
Normal일반 메모리. 캐시·재배치 허용
Execute Never (XN)코드 실행 금지

주변장치 영역이 캐시되면 안 되는 이유 — 레지스터 값은 하드웨어가 바꾸는데 캐시에 옛 값이 남아 있으면 잘못 읽는다. Cortex-M은 0x40000000 영역을 기본적으로 Device로 취급한다.

캐시가 있는 Cortex-M7에서 외부 SDRAM을 DMA 버퍼로 쓸 때 MPU로 그 구역을 non-cacheable로 설정하는 것이 흔한 작업이다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 메모리·아키텍처 — 메모리맵·MMU/MPU·캐시·DMA·엔디안·정렬