AUTOSAR 기반 ECU 소프트웨어를 개발하다 보면 다음과 같은 함수를 보게 된다.
- NvM_Init();
- NvM_ReadAll();
- NvM_WriteAll();
이름만 보면 어렵지 않아 보인다.
- NvM_Init() → NvM 초기화
- NvM_ReadAll() → 전체 데이터 읽기
- NvM_WriteAll() → 전체 데이터 쓰기
그런데 실제 프로젝트에서 NvM을 처음 접하면 이런 의문이 생긴다.
"도대체 RAM에 있는 데이터와 Flash에 있는 데이터는 어떤 관계인가?"
"NvM_ReadAll()은 정확히 언제 호출되지?"
"NvM_WriteAll()을 호출하면 바로 Flash에 저장되나?"
"데이터가 처음부터 존재하지 않으면 어떻게 되지?"
NvM을 이해하려면 API 하나하나를 외우기보다
ECU가 켜지고 꺼지는 과정에서 데이터가 어떻게 이동하는지를 먼저 이해하는 것이 좋다.
1. NvM은 왜 필요한가?
자동차 ECU에는 전원이 꺼져도 유지되어야 하는 데이터가 있다.
예를 들어 다음과 같은 데이터가 있다고 생각해보자.
- 차량 설정값
- 학습값
- 보정값
- 진단 저장 데이터
- 누적 데이터
예를 들어 사용자가 차량의 특정 설정을 변경했다고 하자.
VehicleSetting = 0x55
ECU가 동작하는 동안 이 값은 RAM에 존재한다.
그런데 ECU의 전원을 끄면 RAM의 데이터는 유지되지 않는다.
따라서 전원이 꺼져도 유지해야 하는 데이터라면
Flash나 EEPROM과 같은 비휘발성 메모리(Non-Volatile Memory) 에 저장해야 한다.
여기서 NvM이 등장한다.
NvM(NVRAM Manager)은 쉽게 말하면
ECU에서 사용하는 데이터를 RAM과 비휘발성 메모리 사이에서 관리해주는 AUTOSAR BSW 모듈이라고 볼 수 있다.
전체 구조를 아주 단순하게 표현하면 다음과 같다.

AUTOSAR 공식 NvM Specification에서도 NvM과 MemIf, Fee, Ea 등의 관계를 정의하고 있다.

최신 AUTOSAR CP R24-11 문서의 Figure 7.1 "NVRAM Manager interactions overview"는 NvM이 RTE, DEM, BswM, MemIf, CRC Library 등의 모듈과 어떻게 상호작용하는지를 보여주는 그림이다.
2. RAM Block과 NV Block
NvM을 이해할 때 가장 중요한 개념이 RAM Block과 NV Block이다.
예를 들어 차량 설정값(VehicleSetting)을 하나 저장한다고 해보자.
ECU가 동작할 때 Application은 이 데이터를 RAM에서 사용한다.
RAM Block
VehicleSetting
│
└── 0x55
그리고 전원이 꺼져도 유지하기 위해 NV Memory에도 데이터를 저장한다.
NV Block
VehicleSetting
│
└── 0x55
즉 같은 데이터를 두 군데에서 관리한다고 생각하면 이해하기 쉽다.

AUTOSAR 공식 문서의 Figure 1.1 "Memory Structure of Different Block Types"가 바로 이 부분을 설명할 때 유용하다.
이 그림에는 RAM Block, Administrative Block, NV Block, ROM Block, Dataset 등의 관계가 나타나 있다.

3. ECU가 켜질 때 — NvM_Init()
이제 실제 ECU의 동작을 살펴보자.
ECU에 전원이 들어오면 여러 BSW 모듈이 초기화된다.
NvM 관점에서 가장 먼저 알아야 할 함수가 NvM_Init()이다.
NvM_Init();
이 함수의 역할은 NvM 모듈 자체를 초기화하는 것이다.
쉽게 표현하면 "NvM이 이제 정상적으로 동작할 수 있도록 내부 상태를 준비한다."
AUTOSAR Specification에서는 NvM_Init()이 NvM 내부 변수, Queue, Request Flag, State Machine 등을 초기 상태로 리셋하는 서비스라고 정의한다.
NvM_Init()이 Flash 데이터를 읽는 것은 아니다.
즉, NvM_Init()을 수행했다고 해서 Flash → RAM이 이루어지는 것은 아니다.
실제 저장 데이터를 RAM으로 복원하는 것은 다음 단계인 NvM_ReadAll()이다.
4. ECU가 켜질 때 — NvM_ReadAll()
ECU가 이전에 사용되었던 ECU라고 생각해보자.
이전 주행에서 다음 값이 저장되었다.
VehicleSetting = 0x55
그리고 이 값은 NV Memory에 저장되어 있다.
ECU의 전원을 다시 켜면 RAM에는 이전 값이 그대로 존재하지 않는다.
따라서 ECU Startup 과정에서 저장되어 있던 데이터를 RAM으로 가져와야 한다.
이 역할을 하는 것이 NvM_ReadAll()이다.
NvM_ReadAll();
개념적으로는 다음과 같다.
ECU Startup → NvM_Init() → NvM_ReadAll() → NV Memory → RAM → Application
즉, NvM_ReadAll() = NV Memory에 저장되어 있던 데이터를 RAM으로 복원하는 과정이라고 생각하면 된다.

AUTOSAR Specification에서도 NvM_ReadAll()을 multi-block read request로 정의하며,
Startup 시 NV 데이터를 RAM으로 로딩하는 용도로 사용한다.
5. NvM_ReadAll이 끝나면
ReadAll이 완료되면 Application이 사용할 RAM 데이터가 준비된다.
예를 들어:
NV Memory
AutoDoorLock = 1
↓ NvM_ReadAll()
RAM
AutoDoorLock = 1
이후 Application은 일반적으로 RAM의 데이터를 사용한다.
즉 ECU가 정상적으로 동작하는 동안에는 Application → RAM 이라는 관계를 생각하면 된다.
Flash를 매번 직접 읽으면서 Application을 동작시키는 구조가 아니다.
6. ECU가 동작하는 동안 RAM 데이터가 변경된다
이제 ECU가 정상적으로 동작한다고 해보자.
처음에는:
RAM = 1
NV = 1
이었다.
그런데 Application에서 설정값을 변경했다.
RAM = 0
NV = 1
이 상황은 충분히 발생할 수 있다.
왜냐하면 RAM 값이 변경되었다고 해서 NV Memory가 즉시 변경되는 것은 아니기 때문이다.
따라서 이 상태에서 ECU 전원을 바로 꺼버리면 다음 부팅에서 다시 1이 읽힐 수 있다.
그렇다면 ECU가 종료되기 전에 RAM의 변경 내용을 NV Memory에 저장해야 한다.
7. ECU가 꺼질 때 — NvM_WriteAll()
이때 사용하는 대표적인 API가
NvM_WriteAll();
이다.
역할은 간단하다.
ECU Shutdown 과정에서 필요한 RAM Block의 데이터를 NV Memory에 저장한다.
예를 들어 현재 상태가:
RAM = 0
NV = 1
이라면
NvM_WriteAll()
RAM = 0
│
▼
NV Memory = 0
가 되도록 동기화한다.

AUTOSAR Specification에서도 NvM_WriteAll()은
Shutdown 과정에서 permanent RAM Block의 내용을 대응하는 NV Block과 동기화하는 multi-block request로 정의한다.
8. 실제 ECU Shutdown 흐름
ECU가 꺼지는 과정을 간단하게 표현하면:

그리고 다음에 ECU가 다시 켜지면

이렇게 되면서 이전에 저장했던 데이터가 복원된다.
9. ReadAll과 WriteAll을 연결해서 보면
여기까지 이해했다면 NvM의 핵심 흐름은 사실 간단하다.

이 그림 하나만 기억해도 NvM의 가장 기본적인 동작은 이해할 수 있다.
10. 실무에서 NvM 문제를 만났을 때
예를 들어 개발 중 다음과 같은 문제가 발생했다고 해보자.
"RAM 값은 변경되는데 ECU를 껐다 켜면 다시 이전 값으로 돌아온다."
이 경우 다음과 같은 순서로 생각하면 된다.
RAM 값이 정말 변경되었는가?
│
▼
NvM이 변경 사실을 알고 있는가?
│
▼
Write 요청이 발생했는가?
│
▼
NvM_WriteAll / WriteBlock 처리됐는가?
│
▼
Fee / Flash Write가 성공했는가?
│
▼
Write 완료 전에 ECU가 꺼지지 않았는가?
│
▼
다음 부팅에서 NvM_ReadAll이 수행됐는가?
│
▼
Read된 NV Data가 정상인가?
이렇게 접근하면 NvM 문제를 RAM → NvM → MemIf → Fee → Flash → 다시 ReadAll이라는 흐름으로 추적할 수 있다.
11. 최종적으로 기억해야 할 그림
NvM을 처음 공부한다면 복잡한 API보다 이 그림 하나를 먼저 기억하는 것을 추천한다.
ECU Startup
│
▼
NvM_Init()
│
▼
NvM_ReadAll()
│
▼
NV Memory
│
▼
RAM
│
▼
Application
│
│
데이터 변경
│
▼
RAM
│
▼
NvM_WriteAll()
│
▼
NV Memory
│
▼
ECU OFF
한마디로 정리하면:
ECU가 켜질 때는 NV → RAM
ECU가 꺼질 때는 RAM → NV
이다. 그리고 이 사이에서 NvM이 데이터의 상태와 저장/복원 작업을 관리한다.
정리
AUTOSAR NvM을 처음 접하면 NvM_Init(), NvM_ReadAll(), NvM_WriteAll() 등 여러 개념이 한꺼번에 등장하기 때문에 어렵게 느껴진다. 하지만 ECU의 생명주기를 기준으로 생각하면 훨씬 간단하다. 결국 NvM의 핵심은 "RAM에서 사용하는 데이터를 전원이 꺼져도 유지할 수 있도록 NV Memory와 동기화하는 것"이라고 볼 수 있다.
'mobilgene > NvM' 카테고리의 다른 글
| [NvM] NvM 데이터를 실제로 어떻게 쓰는가 (초기화 코드로 보는 사용 방법) (0) | 2026.04.24 |
|---|---|
| [NvM] NvM 주요 API 완전 정리 (Read / Write / GetErrorStatus 동작 방식) (0) | 2026.04.24 |
| [NvM] NvM Block 설정 방법 (RAM Block / CRC / Redundant / ReadAll / WriteAll 완전 이해) (0) | 2026.04.24 |
| [NvM] NvM 설정 구조와 NvM Common 설정 방법 (주요 항목 설명까지) (0) | 2026.04.24 |
| [NvM] NvM이란 무엇인가? (Block / Job / Queue 구조 완전 이해) (0) | 2026.04.23 |