
임베디드 시스템의 이해 3번째 편이다.
시스템에서 사용하는 메모리들과 CPU의 동작 방식에 관한 개념이 많다.
메모리 계층은 정보처리기사 준비할 때 대략적으로 공부했고
이렇게 상세하게 배우는 건 처음이다.
시간 여유가 된다면 교재 내용도 쭉 정리해보고 싶다.
요구사항에 최적화된 MCU
목적에 맞게 CPU 성능/주변장치/메모리 등이 통합된 칩을 선택
임베디드 시스템은 조작·제어 중심, 저전력·소형화에 중점
운영체제(리눅스, RTOS 등) 가용성 및 주변 HW지원도 중요
마이크로프로세서 vs 마이크로컨트롤러
마이크로프로세서(MPU)
CPU 코어만 포함, 주변장치·메모리 별도
고성능, 범용 컴퓨터에 주로 사용 (PC dominant era)
마이크로컨트롤러(MCU)
CPU + 메모리(RAM/ROM) + 입출력(I/O) 등이 한 칩에 집적
저전력, 소형·실시간 제어, 임베디드용에 최적화 (Embedded dominant era)
컴퓨터 시스템 구성 요소
CPU, 메모리(RAM/ROM/Flash), 입출력장치(I/O), 버스
버스 요소 및 종류
버스는 여러 개의 장치들이 연결되는 선들의 집합
버스의 폭은 전달하는 정보량과 비례
Address Bus(주소 버스)
CPU에서 메모리 또는 장치의 위치를 지정하는 선
단방향으로 작동(16비트면 64KB 주소)
Data Bus(데이터 버스)
양방향으로 장치와 데이터를 주고받는 선
동시 전송 데이터 수는 버스의 폭과 같음
Control Bus(제어 버스)
칩 선택, 입출력 방향, 클럭 등 제어 신호 전달
Internal/External Bus
내부 버스: 칩/보드 내부 신호 전달
외부 버스: 칩/보드 외부 장치와 연결하는 신호
Bus Handshaking
master(slave 제어)와 slave(명령 대기)간 통신 시 호환성과 안정성을 위한 신호 프로토콜
HW/ SW Handshaking, bus master(mcu) 주도
bus 사이클 완성을 위해 필수
시스템 메모리
휘발성(volatile)
전원을 끄면 데이터가 소멸됨
DRAM, SRAM
비휘발성(non-volatile, NV)
전원을 꺼도 데이터가 유지되어 저장용으로 쓰임
ROM, Flash, HDD
ROM
Read-Only Memory, 읽기 전용 메모리
Mask ROM, PROM(1회 쓰기 가능), EPROM(자외선에 지워짐), EEPROM(전기를 통해 지움), Flash(자주 사용)
Flash Memory 형태
NOR type
코드 저장, 안정적, A/D/C 버스 인터페이스, 대용량 어려움
NAND type
대용량, bad block 많음, ALE/CLE/DATA8 인터페이스
메모리 맵
CPU가 접근할 수 있는 주소 공간을 나누고 각 메모리/주변장치가 어느 영역에 연결되어 있는지를 정의한 구조
메모리 맵 덕분에 CPU가 특정 주소에 접근할 때 실제 어느 메모리 칩(혹은 디바이스)이 동작할지 결정됨
(예: 0x00000000~0x0007FFFF → 내부 SRAM, 0x08000000~0x080FFFFF → Flash, 0x40000000~0x4000FFFF → 주변장치 등에서 메모리 주소 할당)
Chip Select
하나의 MCU/CPU가 여러 개의 외부 메모리나 장치를 사용할 때, 특정 주소 영역에 접근 시 해당 디바이스(칩)의 활성화/사용을 제어하는 신호
보통 CS 혹은 CE(Chip Enable)라고 표기
칩 셀렉트가 활성화되면 해당 칩과 데이터를 주고받을 수 있음
보통 active low(낮으면 활성)로 동작하고, 비활성화 시에는 해당 칩의 입출력은 실질적으로 비연결 상태
주소 디코더(Address Decoder)와 CS 관계
주소 디코더 회로가 CPU 주소 버스의 상위 비트를 해석하여 칩 셀렉트 신호를 만듦
여러 칩이 겹치지 않게 선택적으로 활성화
32bit 주소 중 상위 2비트에 따라
00 - RAM0의 CS 활성화
01 - RAM1의 CS 활성화
10 - ROM CS 활성화
11 - Peripheral CS 활성화
메모리 맵과 Chip Select의 연결 방식
메모리 맵의 각 영역에 대응하여, 디코더와 칩 셀렉트 신호가 해당 Memory/Device에 자동으로 연결됨
CPU가 0x20000000~0x20FFF_FFFF 영역에 R/W를 하면 LCD_CS가 활성화되어 해당 장치를 제어할 수 있음
ASIC
맞춤형 회로(IC) 설계
일반적으로 마이크로프로세서 코어와 간단한 주변 장치, 결합 회로를 구성하는 데 사용
생산된 ASIC 칩의 내용을 변경할 수 없음
마스크 제작 비용은 크지만, 마스크를 제작하고 나면 낮은 단가로 칩 양산 가능
메모리 계층 구조
속도와 가격에 따라 계층을 구분
레지스터 → 캐시 → RAM → 저장장치(HDD, SSD)
상위 계층일수록 속도가 빠르고, 용량은 작으며, 가격은 높음
데이터 배치 원칙
자주 사용하는 데이터(명령, 변수 등)는 빠른 메모리(레지스터, 캐시)에 위치
덜 자주 사용하는 데이터는 느리고 큰 메모리(RAM, 저장장치)에 위치
메모리 계층 구조의 구현 방식
지역성(Locality)의 이점 활용
빠른 메모리(캐시)와 큰 용량의 메모리(RAM, 저장장치)를 조합해 효율과 가격 경쟁력을 높임
값싼 메모리로 전체 용량을 확장하고, 빠른 메모리로 속도를 보장
구현 예시
프로세서 내부 구조: core(계산), load/store unit(메모리 접근), fetch unit(명령 로딩)
CPU의 Fetch Unit이 인스트럭션을 캐시에 저장했다가 core로 바로 전달
Load/Store Unit이 RAM에서 데이터를 받아오며, 공간적 지역성을 이용해 근처 주소 블록을 캐시에 임시 저장
지역성(Locality)의 종류
시간적 지역성(temporal locality)
최근에 접근한 데이터/명령을 가까운 미래에도 재접근할 가능성이 높음
(예: 반복문, 함수 호출 등에서 동일 변수/데이터 반복 사용)
공간적 지역성(spatial locality)
특정 주소를 접근할 때, 그 근처 주소도 곧 접근할 확률이 높음
(예: 배열 원소 순차 접근, 인접 변수 사용 등)
파이프라인(프로세서의 명령 실행 단계)
프로세서는 명령어 하나를 여러 단계로 나누어 동시에 처리해 성능을 향상시킴
IF (Instruction Fetch)
명령어를 메모리에서 읽어오는 단계
예: PC(Program Counter) 지정 위치에서 명령어를 가져옴
FU(Function Unit)에서 실행 제어
ID (Instruction Decode)
가져온 명령어를 해독하여 연산 종류, 레지스터/주소 등에 대한 정보 추출
디코더(Decoder)에서 작동
IE (Instruction Execute)
해독된 명령어에 따라 실제 연산(ALU/연산장치)이 수행되는 단계
MA (Memory Access)
연산 결과가 메모리와 관련 있을 경우(로드/스토어) 메모리 접근 수행
LS(Load/Store Unit)에서 처리
WR (Write Back)
연산 결과를 레지스터나 메모리에 저장하는 단계
파이프라인 단계별 예시
3-stage pipeline : IF → ID → IE
5-stage pipeline : IF → ID → IE → MA → WR (ARM Cortex-M 등 대표적 구조)
7/8/12-stage pipeline : 고성능 CPU(ARM Cortex-A, x86 등)에서 적용, 순서는 IF, ID, IE, MA, WR + 추가 캐시/예측/분기 등 다양한 세부 스테이지 포함
캐시
자주 접근하는 명령어/데이터를 CPU 가까이에 저장, 지역성(시간·공간적)을 활용해 성능 향상
데이터를 더 먼 메모리까지 가지 않고 빠르게 쓸 수 있음
Direct Mapped Cache (단일 연관)
메모리 주소 일부로 캐시 인덱스를 산출, 지정 위치에만 데이터 저장
각 캐시 줄에 tag·validity flag(유효성) 추가, 태그/주소 일치하면 hit
단점: 캐시 위치 충돌(같은 주소가 오면 기존 데이터 덮어쓰기)
Associative Mapping Cache (완전 연관)
데이터가 캐시 어느 줄에든 저장 가능, 태그 전체 비교(search)
저장 위치에 제한이 없어서 유연하지만 속도·관리 비용 증대
Set-Associative Cache (예: 2-way)
캐시를 여러 개의 세트로 나눔, 각 세트에 n개의 웨이(way) 보유
동일 인덱스 주소는 여러 way 중 하나에 저장
victim counter는 어느 way에서 데이터를 교체할지 결정
교체(victim selection)는 random, cyclic(round robin), LRU(최근 사용 안 된 것) 등으로 결정
SRAM (Static RAM)
각 비트 저장에 6개의 트랜지스터(Tr)로 구성
Word Line/Bit Line 배열, Word Line으로 Bit Line의 셀 선택
꾸준히 전원을 공급받으면 데이터 보존, 별도 리프레시 필요 없음
속도가 빠르고, 구조가 복잡·비싸기 때문에 용량은 작음, 주로 CPU 캐시에 사용
DRAM (Dynamic RAM)
각 비트 저장에 1개의 트랜지스터+1개의 커패시터(Cap)로 구성, Word Line/Bit Line 구조
읽기(Destructive READ) 후 데이터가 사라져서, 데이터를 복구(Write-back) 필요
데이터가 그저 놔둬도 사라지므로 주기적 Refresh(복구) 필요
구조가 단순해 저렴하고 대용량 구축 유리, 주로 시스템 메인 메모리로 사용
속도는 SRAM에 비해 느림
MPU (Memory Protection Unit)
메모리 영역별 물리적 접근 제어, 프로그램이 보호지역 침범을 사전에 방지
메모리를 여러 구역(region)으로 분할, 접근 허용 여부 결정
RTos에서 주로 사용
MMU (Memory Management Unit)
MPU 기능 + 가상 메모리(VA, Virtual Address) 관리 지원
가상 주소를 실제 물리 주소로 변환, 접근 제어 포함
Translation Table(TT): 주소 변환 정보 저장, 리눅스 등 OS에서는 Page Table이라고 부름
프로세스마다 별도의 TT관리(P1, P2 등)
GPos(리눅스, 윈도우)에서 주로 사용
변수의 속성
범위(scope)
변수나 함수가 읽히고 쓰일 수 있는 코드 영역
local scope: 함수나 블록 내부에서만 사용
global scope: 파일 전체에서 사용 가능
생명 주기(life time)
변수가 메모리에 머무는 시간 구간
지역 변수는 함수 호출~종료까지, 전역 변수/정적 변수는 프로그램 전체 수행 동안 존재
기본 초기값(default initial value)
변수의 기본 초기값을 설정
저장 클래스(Storage class)의 종류와 특징
auto
기본 지역 변수, 스택(실행 시 RAM)에 저장, 함수 끝나면 소멸
register
CPU 레지스터에 저장되어 주소를 구할 수 없음
컴파일러가 최적화상 무시할 수도 있음
static
함수 내에서 값 유지(지역 scope, 정적 lifetime), 전역 변수처럼 프로그램 종료까지 메모리에 존재, 기본값은 0(data 섹션 또는 bss)
extern
외부의 전역 변수 참조, 여러 파일에 걸쳐 공유, 정적 lifetime
변수 저장 위치
스택(stack): 자동/지역 변수
data 영역: 초기값 있는 전역/정적 변수
bss 영역: 초기값 없는 전역/정적 변수
레지스터: register 변수
volatile 키워드
프로그램 외부에서 변수의 값이 바뀔 수 있다는 정보를 컴파일러에게 전달
메모리 최적화 작업 대신 항상 변수 값을 직접 읽고 씀
예: 하드웨어 레지스터 접근, 인터럽트·병렬 처리가 변수 값을 바꿀 수 있는 경우
#define rWDTCON (*((volatile unsigned int *) 0x200000))