[Embedded] 임베디드 시스템의 이해 ③

예빈·2025년 11월 27일

Embedded/Linux

목록 보기
4/21


0️⃣ 들어가며

임베디드 시스템의 이해 3번째 편이다.
시스템에서 사용하는 메모리들과 CPU의 동작 방식에 관한 개념이 많다.
메모리 계층은 정보처리기사 준비할 때 대략적으로 공부했고
이렇게 상세하게 배우는 건 처음이다.
시간 여유가 된다면 교재 내용도 쭉 정리해보고 싶다.


1️⃣ 학습 내용

임베디드 시스템 아키텍처

MCU와 프로세서 선택 및 구분

  • 요구사항에 최적화된 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)

      특정 주소를 접근할 때, 그 근처 주소도 곧 접근할 확률이 높음

      (예: 배열 원소 순차 접근, 인접 변수 사용 등)

파이프라인과 캐시(CACHE) 메모리

  • 파이프라인(프로세서의 명령 실행 단계)

    프로세서는 명령어 하나를 여러 단계로 나누어 동시에 처리해 성능을 향상시킴

    • 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 vs DRAM
    • 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에 비해 느림

  • MMU와 MPU
    • 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))

0개의 댓글