[AUTOSAR] NvM(4.2.2)


# はじめに
AUTOSARを扱う仕事に従事していて、
NvMについて、AUTOSARの仕様（4.2.2）について確認した結果を残しておく。

仕様の要約と個人の解釈も含めて記載するため、正確な情報を入力文書を参照いただきたい。

# 入力文書
AUTOSAR 4.2.2

https://www.autosar.org/fileadmin/standards/classic/4-2/AUTOSAR_SWS_NVRAMManager.pdf

# 確認したいこと
* 「NvM」が管理するブロックには以下の3つのタイプを選択することができる。
1. NVM_BLOCK_NATIVE
1. NVM_BLOCK_REDUNDANT
1. NVM_BLOCK_DATASET

そのうち、NVM_BLOCK_DATASETの管理方法と、アクセス方法について理解する。

:::note warn
DATASET以外については省略する。
今後時間があれば追記していく。
:::

# 確認結果

:::note info
DATASETは、同じ構成の領域をコンフィグした要素数だけ管理する方法。
NvM_GetDataIndex でインデックスを取得、NvM_SetDataIndex でインデックスを指定して領域への書き込み、読み込みが可能。
:::

![スクリーンショット 2023-03-21 15.55.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/1505633e-0dd8-0e00-cb9d-82f387f568b7.png)


例えば、アプリケーションが同じデータ構造のスナップショットを複数個（〜255個）残しておきたいときなどに使う。

# 確認結果（詳細）
NvRAM Blockは、以下のように構成される。

![スクリーンショット 2023-03-05 22.26.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/8ffb94b2-feac-d148-dcf7-a4958de7f95e.png)

* NV Block
不揮発メモリに保存されるデータ。

* RAM Block
ユーザデータとCRC値（オプション）、NVブロックヘッダで構成されるRAM上の領域。
![スクリーンショット 2023-03-05 22.31.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/bdc4ea4a-8bdb-784d-1104-ad9c8086c67c.png)

* ROM Block
NVブロックが空、または破損した場合にデフォルトデータを提供するために使用される。
NvM_RestroeBlockDefaultsのAPIを使って、初期値書き込みをすることができる。

![スクリーンショット 2023-03-21 15.59.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/04b9ab49-aa78-7fd7-33ba-9e254aa97b58.png)

使い方例：
GetErrorStatusをして異常だったときに、このAPIを使って初期値に書き換える。


* Administrative Block
NVRAMブロックの必須部分である。
アプリケーションからは見えないもので、NvMモジュールがRAMブロックとNVRAMブロック自体のセキュリティと管理目的のために排他的に使用するものとする。
※排他的の意味がよくわからん。
属性、ステータス(valid or invalid)などの情報を持つ。
DATASETとして使う場合のインデックス情報はここに含まれる。
書き込み保護については属性にもつ。



7.1.4.6 Dataset NVRAM block
データセットNVRAMブロックは、等しいサイズのデータブロックの配列（NV/ROM）である。
* NV Blocks: 1..(m<256)
※NV Blocksの要素数はコンフィグレーションで設定可能。
* RAM Blocks: 1
* ROM Blocks: 0..n
* Administrative Blocks:1

![スクリーンショット 2023-03-05 22.41.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/b05870a8-0a22-c751-e7ca-5927f24fbfcf.png)

ユーザー（アプリケーション）は、一度にこれらの要素のうちの正確に1つをアクセスすることができる。
他の管理方法と同様に、実データ、ヘッダー（オプション）とCRC（オプション）で構成される。
構成データセット（NV+ROMブロック）の総数は、1～255の範囲でなければならない。


# API Configuration class
限られたハードウェア資源に適応させるために、3つの異なるAPI構成クラスを定義。
API configuration class 3：指定された全てのAPIコールが利用可能。最大限の機能をサポート。   

API configuration class 2：APIコールの中間的なセットが利用可能。

API configuration class 1：特に、ハードウェア資源が非常に限られているシステムとのマッチングのため最小セットのみを提供。

以下の図の赤い枠がclass2、青い枠がclass1です。
![スクリーンショット 2023-03-05 23.20.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/b96c45b6-5c12-af1d-0291-eeaf4d3ccc11.png)

class1は、できることがだいぶ絞られていて、キューイングできない、即時書き込みできない、DATASETには対応できない。


# 関係するAPI
* NvM_SetDataIndex
特定のデータセットにアクセスするためのインデックスを設定するAPI。

![スクリーンショット 2023-03-05 23.29.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/7c9b3329-7dc2-4b65-12d9-460f2842be59.png)


* NvM_GetDataIndex
現在のデータセットにアクセスするためのインデックスを取得するAPI。
DATASETでないブロック（NATIVE/REDUNDUNT）のときはDataIndexPtrの中身は0を返す（戻り値はE_NOT_OK）。

![スクリーンショット 2023-03-05 23.31.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/42174ab5-2d81-7db7-9cbe-36d8c98f999f.png)

# アクセス方法
9章に記載してあるシーケンス図のうち、不揮発メモリブロックの読み込み、書き込みに関わる箇所を抜粋する。

## 単一ブロック書き込み（ポーリング）
NvM_WriteBlockで書き込み要求後、NvM_MainFunctionで不揮発メモリに書き込まれる。
その後、ユーザーはNvM_GetErrorStatusで状態を監視し、書き込みが完了したか確認できる。
ブロックのステータスは、「NvM_RequestResultType」で定義されている。

![スクリーンショット 2023-03-21 16.03.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/f3477ca1-dddd-2084-de94-9397f671894e.png)

## 単一ブロック書き込み（コールバック）
ユーザーへの通知方法はコールバック通知を選択することができる。

![スクリーンショット 2023-03-21 16.03.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/56440eff-e00d-68bd-3d79-25399fd09127.png)

CSインターフェースとしては、8.2.1.4 NvM_NotifyJobFinishedのOperation「JobFinished」が用意されている。
これでどのJobが完了したかどうかがわかるようになっている。

![スクリーンショット 2023-03-21 16.18.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/79c74876-32e5-0327-7923-4c957dfc778c.png)


## 複数ブロックアクセス
NvMにはブロック毎に、ReadAll対象 or WriteAll対象かどうか選択できる。
起動時に不揮発メモリからまとめて取得するときにNvM_ReadAllを呼び出したり、シャットダウン時にNvM_WriteAllを呼び出してキャッシュRAMの値を不揮発メモリに書き込む、などの使い方ができる。

![スクリーンショット 2023-03-21 16.04.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/fc54bbbd-9031-afca-a55a-cf1649b97f43.png)

* WriteAll用パラメータ
![スクリーンショット 2023-03-21 16.22.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/94ee8e2e-e49c-22d1-c2d3-f4752c484afa.png)

* ReadAll用パラメータ
![スクリーンショット 2023-03-21 16.23.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/200b726f-924a-3796-d1e3-b2412c762ec4.png)
![スクリーンショット 2023-03-21 16.23.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/0343e2a0-4602-dfca-a0ea-f93b31286fa5.png)