고전적으로 메모리는 크게 두 가지로 분류가능하다.
ROM(Read Only Memory)과 RAM(Random Access Memory)이다. 말 그대로로만 보면 ROM은 쓸수 없고 읽을수만 있는 메모리다. RAM은 읽고 쓸 수 있는 메모리다. 하지만 이 정의는 맞지 않다. 데이터를 쓸 수 있는 ROM이 대부분이다. 쓰기에 제약이 존재한다는 정도로 이해하면 된다.
그래서 통상적으로 임베디드 디바이스에서 ROM은 소프트웨어와 고정된 데이터를 저장하는 용도로, RAM은 수시로 값이 바뀌는 데이터를 저장하는 용도로 쓰인다. 아래 그림을 보고 이해하는게 가장 좋을 듯 싶다.
보통 ROM 유형의 메모리는 쓸수 있는 회수가 한정되어 있다. 극단적인 예로 Masking ROM은 생산할때 아예 데이터가 고정되어서 출하되므로, 읽기만 가능할뿐 데이터를 쓸 수 없는 메모리다. ROM이라는 이름에 가장 맞는 메모리 타입이다.
OTP ROM은 사용자가 데이터를 쓸 수 있지만, 한번 쓰면 끝이다. OTP는 임베디드 디바이스의 보안에서 유용하게 사용되는 메모리 타입이다. SoC들은 거의 대부분 내부에 OTP ROM을 가지고 있어서, 주요한 데이터를 이 OTP ROM에 저장한다. 예를 들어 시스템의 암호화 키나 일련번호(serial number)를 제품생산시 OTP ROM에 쓰고 제품의 라이프 사이클 동안 계속 사용할 수 있다.
쓸수 있는 회수가 늘어날수록 활용도 역시 높아진다. 통상 Flash memory 타입은 보통 10만번 정도 쓸수 있다. RAM 역시 무한정 쓸수 있는 것은 아니다. 하지만 다른 장치와 비교하면 반영구적이라고 봐도 된다. 쓰기 수명이 긴 것들이 통상적으로 쓰기 속도 역시 빠르다.
임베디드 세계에서 많이 쓰이고 있는 대표적인 메모리 장치에 대해 핵심만 살펴보자.
읽고 쓸 수 있는 가장 성능이 후진 ROM이라고 보면 된다.
현업에서 EEPROM과 NVRAM을 혼용해서 용어를 사용하는데, 엄밀히 두개는 다른 메모리다.
EEPROM은 그냥 추상적으로 작은 플래쉬메모리 개념으로 이해하면 된다.
임베디드 디바이스에서 많이 사용되는 플래쉬 메모리 타입이다. NAND에 비해 안정적이다. 읽는 시간이 NAND에 비해 빠르므로 한번 저장해두고 잘 변경하지 않는 데이터나 소프트웨어 코드의 저장에 적합하다.
NOR에 비해 데이터를 쓰는 시간이 빠르다. 하지만 불량섹터(bad sector)가 발생할수 있는 등의 안정성 측면에서는 NOR flash에 뒤진다.
여기서 잠깐 플래쉬 섹터(flash sector)의 개념에 대해 알아볼 필요가 있다.
플래쉬 메모리는 읽을때는 RAM과 마찬가지로 임의의 주소를 읽을 수 있지만, 데이터는 그냥 무작위로 쓸수 없다. 데이터를 쓰기 위해서는 데이터를 쓰려는 주소가 속해있는 섹터를 먼저 지워야 한다. 통상 하나의 플래쉬 섹터는 수십 KB의 공간으로 구성된다. 통상적인 NOR flash의 한 섹터 크기는 128KB다.
다시 말해 단지 데이터 한바이트를 저장할때에도 128KB의 하나의 섹터를 전부 지워야 한다.
더 정확히 설명하면 특정주소에 데이터를 쓰려면 우선 해당 주소의 섹터의 128KB 데이터를 전부 읽은다음, 128KB 데이터중 변경하고자 하는 데이터를 바꾼 다음, 변경된 128KB 데이터 전체를 해당 섹터에 쓰면 된다.
이는 매우 비효율적이고 또한 속도면에서도 불리하다. 그래서 사용되는 것이 FTL(Flash Translation Layer)다. 쉽게 얘기해서 중간에 캐시(cache)와 같은 구조를 만들어서 플래쉬를 하드디스크를 사용하는 것처럼 해주는 기술이다. 이렇게 함으로써 사용자 입장에서는 그냥 임의의 주소에 무작위로 데이터를 쓸수 있는 것처럼 보일 수 있다.
계속 다른 유형의 메모리 기기에 대해 알아보자.
스마트기기가 보편화로 개인사용자가 다루는 데이터의 크기가 날로 늘어남에 따라 개발된 메모리타입이다. 단순히 설명하면 eMMC는 NAND flash 메모리에 NAND controller를 내장한 메모리장치다. NOR flash나 NAND flash 모두 해당 플래쉬를 제어할 수 있는 플래쉬 컨트롤러를 칩셋(SoC)에서 지원해줘야 사용가능한 유형들이었다. 하지만 eMMC는 컨트롤러를 안에 내장하고 있어서 더 최적화된 성능을 가진다.
메모리는 크기가 커질수록 가격이 비싸지는데, 해당 임베디드 기기에서 필요로 하는 ROM 메모리의 크기에 따라 적합한 메모리 선택이 필요하다. 가격적인 측면을 고려할때 보통 다음과 같은 순서로 메모리를 선택하게 된다.
NOR 플래쉬(보통 64MB 이하) < NAND 플래쉬(대략 64MB ~ 512MB) < eMMC
메모리의 선택은 크기와 가격만으로 선택하는 것은 아니지만, 어쨌든 임베디드 메모리에서는 매우 중요한 요소다.
eMMC보다 용량이 더 크고 빠른(다만 가격은 올라가겠죠잉?) 메모리가 필요할때 사용할 수 있다. HDD와 플래쉬메모리, 그리고 RAM의 짬뽕이라고 보면 되지 않을까 싶다. 내부저장장치는 플래쉬가 사용되는데, 이를 제어하는 컨트롤러가 있고 RAM 버퍼를 사용해서 성능을 높이고 디스크처럼 사용이 가능하다.
이제까지 PC의 저장장치로 사용되어온 하드디스크다. 물리적인 크기가 크고, 속도도 느려서 이제 SSD로 많이 대체되는 추세다. 임베디드 기기에서도 HDD는 많이 사용되지 않는다. PVR이나 DVR처럼 녹화된 영상과 같이 대용량의 데이터 저장이 필요한 기기에서 사용된다.
이제 RAM에 대해 알아보자. RAM은 DDR이 압도적으로 많이 사용된다. 나머지는 용어만 간단히 살펴보고 넘어가자.
SRAM(Static RAM) - 초창기 유형. 요즘 안쓰이니까 몰라도 된다
DRAM(Dynamic RAM) - 요즘 쓰이는 RAM의 원형이다
SDRAM(Synchronous DRAM) - DRAM을 발전시킨 타입이라고만 알고 넘어가자
이건 또 SDRAM을 발전시킨 타입의 RAM으로 오늘날 보편적으로 사용되는 RAM 타입이다.
메모리 기술은 계속 발전하므로 더 고차원적인 RAM들이 있지만, 기술과 가격등의 이유로 현재 압도적으로 많이 쓰이는 RAM이라고 보면 된다. 흔히 줄여서 DDR이라고 부른다. 뒤에 붙는 숫자가 버전인데 현재는 DDR3를 지나 DDR4도 임베디드기기에서 많이 쓰이고 있다.
DDR은 double data rate로 말 그대로 date rate가 두배라는 것이다. 클럭(Clock)보다 대역폭(bandwidth)이 두배 더 크다. SDRAM보다 성능이 두배 뛰어난 셈이다. 그래서 기존 SDRAM을 SDR(Single data rate) SDRAM으로 부르기도 한다. 예를 들어, 클럭이 933MHz인 SDR 의 data rate는 933이지만 DDR 의 경우에는 1866이 되는 것이다.
RAM은 전원이 꺼지면 데이터가 사라진다. SRAM과 달리 DRAM은 전원이 들어오고 있을때도 리프레시(refresh)를 해야 데이터가 사라지지 않는다. 이는 캐패시터의 방전땜에 그렇다는데, 나도 잘 모르고 여러분도 몰라도 된다.
어쨌든 DRAM은 매우 예민한 메모리다. DRAM에 약간의 결함이 있거나 최적화가 되어 있지 않으면 임베디드기기의 동작에 치명적인 문제를 일으킬 수 있다. 메모리는 말 그대로 데이터가 보관되는 곳인데, DRAM이 오동작해서 데이터가 훼손되거나 유실되면 임베디드 기기 역시 오동작할수밖에 없다. 보통 DDR에 문제가 생기는 경우, 단순한 오동작에 그치지 않고 시스템이 다운(Hangup)된다거나 크래쉬(crash)되는 경우가 태반이다.
행업, 크래쉬 등 시스템이 말 그대로 죽는 문제에 대해서는 Ch14의 임베디드 크로스 플랫폼 디버깅 챕터에서 다룰 예정이다. (아직 까마득하구만....)
여하튼 메모리의 초기화는 아주아주 중요하다. 버뜨, 임베디드 소프트웨어 개발자가 전부 메모리초기화에 대해 걱정하고 관여할 필요는 없다. 메모리는 칩셋(SoC) 제공회사에서 튜닝해주는 것이 일반적이다. 해당 칩셋에 호환되는 메모리들이 있고, 칩셋의 특성에 맞도록 메모리 역시 초기화가 필요하다.
알아서 해준다고 전혀 모르면 안되니까 일반적인 것들은 알고 있는 것이 좋다.
그럼 어디까지 일반적인 것들인가?
그것은 어떤 게발업무를 하느냐에 따라 다르다. 기기의 부팅과 초기화를 담당하는 부트로더(Bootloader) 개발자라면 메모리 튜닝에 대해서는 다른 개발자보다 더 많이 알고 있어야 하는 것이 당연하다.
RAM에 배터리를 달아서 데이터가 날라가지 않도록 만든 메모리타입이다. 보통 소용량이고 빈번한 데이터억세스가 요구되는 메모리가 필요할때 사용된다. 임베디드 기기에서 소용량의 사용자 정보를 저장하는 용도로 많이 활용된다.