AUTOSAR CP設計ノウハウ

# はじめに
社会人になり、8年くらい車載ソフトウェア開発に従事してます。
車載OS（AUTOSAR CP）が搭載されている製品開発が多いので、せっかくならこれまで経験したことを踏まえて、初心者の方向けに最低限必要となる考え方、概念を備忘録として残しておく。

# AUTOSAR Layered Architecture
AUTOSARのアーキテクチャについては、以下のLayeredSoftwareArchitectureを参照してほしい。
ここでは簡単に記載する。

https://www.autosar.org/fileadmin/standards/R23-11/CP/AUTOSAR_CP_EXP_LayeredSoftwareArchitecture.pdf

AUTOSARはApplication Layer、Runtime Environment(RTE)、Basic Software(BSW)の3層構造になっている。
簡単に言うと、RTEはBSWの違いを隠蔽し、BSWはマイコンの違いを隠蔽する。

![スクリーンショット 2024-02-18 10.22.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/d6de87d7-d095-0ca7-9f82-b2473c6278a8.png)

## Virtual Functional Bus（VFB）
Application Layerに搭載するアプリケーション（SW-C）は、RTEのIFで通信するという約束事さえ守っていれば、環境の違いは隠蔽されているため、どのECUに割り当てても機能実現することができる。
そのようなメカニズムをVirtual Functional Bus（VFB）という。

https://www.autosar.org/fileadmin/standards/R23-11/CP/AUTOSAR_CP_EXP_VFB.pdf

以下のイメージ図にあるように、一つの箱がSW-C、SW-Cにくっついている三角や丸の箱がPortというRTEのIFを意味している。
アプリケーション開発者は、どのようなSW-Cで何を実現し、SW-C⇔SW-C間、SW-C⇔BSW間でどんなIFを使ってやり取りするかを設計する。
その後、ECUにSW-Cをマッピングしていく。

![スクリーンショット 2024-02-18 10.37.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/0de37bab-d963-c012-0cf5-c20996f693a3.png)

例としてECU1とECU3で繋がっているポートは一番よく使う「sender-receiver」ポートで、
簡単にいうとデータ送受信をするためのIFである。
上記VFBのドキュメントにアイコンの意味などは記載されているので参照してほしい。
「SeatHeatingControl」はsender-receiverのreceiver側なので、データが欲しい。だが、どのECU・どのSW-Cからデータ受信するかは意識していない（RTEが隠蔽している）ため、
図の例であればECU3に搭載されている「PowerManagement」からデータを受信する。
このとき、図には記載されていないがECU間がCANで繋がっているなら、以下のようにデータが流れていくことだろう。

ECU3:
「PowerManagement」→RTE→Com→PduR→CanIf→Can
↓
CAN Bus
↓
ECU1:
Can→CanIf→PduR→Com→RTE→「SeatHeatingControl」

また、ECU内に「PowerManagement」をマッピングしたならば以下のように繋がるだろう。

ECU1:
「PowerManagement」→RTE→「SeatHeatingControl」

このように、SW-CはRTEを介すことで、どこからどうデータを送受信するかは意識せず開発できる。
つまり、OEMはSW-C設計時に、汎用的に使える情報・機能や他アプリから受領する情報はRTE IFを使う設計にして、サプライヤーに要求を出すことで、競争領域である自社のアプリケーション開発に集中できる。
これこそがAUTOSARの非競争領域は協力して作り上げて、競争領域に集中できるというコンセプトである。

# Basic Software(BSW)
![スクリーンショット 2024-02-18 11.39.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/292a291f-3a1a-3494-f0cb-467fc225f47d.png)

BSWはさらに以下のように細かくレイヤーが分けられる。
* Services Layer：SW-Cに高レベルなサービスを提供する層。マイコン非依存。
* ECU Abstraction Layer：「Services Layer」に「Microcontroller Abstraction Layer」の違いを隠蔽したIFを提供。
* Microcontroller Abstraction Layer：マイコン依存のドライバ。
* Complex Drivers：上記のレイヤ構造は無視した、なんでもあり層。ハードウェアにもアクセスできるし、Rte IFを持つこともできる。なんでもできる分扱いには注意。

レイヤーをさらに分解すると以下になる。
![スクリーンショット 2024-02-18 12.04.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/b57190af-bf4a-64f0-de87-133252956425.png)

さらに、機能別に縦に分類してxxxStackと呼ぶ。
例えば、通信系の「Communication Services」「COM HW Abstr」「Communication Drivers」の総称を、「Communication Stack」と呼ぶ。

CryptoStackについては、R22-11にはなるが以下の記事で紹介しているので参照してほしい。

https://qiita.com/issykatsu/items/cc3715e7591ae8f52fda

MemoryStackのService Layerに位置する「NvM」の仕様については以下の記事を参照してほしい。

https://qiita.com/issykatsu/items/c614ff7a9291ec37a842

## BSWのコンフィグレーション
AUTOSARのコンセプトとして非競争領域であるものは協力して生産し、コストを下げるという考え方に基づき、
非競争領域である基本機能は設定可能なパラメーターが定められていて、
設計者は、パラメータを選択可能な範囲から選択することでソフトウェアを構築することができる。

AUTOSARベンダーは、定められたパラメータからコードを自動生成するツールを用意しており、
サプライヤー（or OEM）はそのツールを使ってパラメータを設計・選択するだけで、BSWを構築できる。（一部ユーザー実装が必要な場合もあるが）

### コンフィグレーションの種類
コンフィグレーションにも以下の種類がある。

* Pre-compile time
　プリプロセス時に処理される。機能の有効/無効などコードサイズの最適化など。
  xxx_Cfg.h/.cに生成される。
* Link time
　定数などリンク時に確定
  xxx_LCfg.h/.cに生成される。
* Post-build time
　データはリフラッシュ可能な特定のメモリに配置される。
　xxx_PBCfg.h/.cに生成される。

各BSWの仕様書には、以下のように記載される。

![スクリーンショット 2024-02-18 17.06.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/af115318-1fc3-6e23-ba60-26cf358d28ea.png)

この例では、NvMのVersionInfoAPIの有効・無効を切り替えるかどうかのパラメータであるため、Pre-compile timeにチェックがついている。
このパラメータをtrueに設定したなら、NvM_Cfg.hに以下のように生成されるだろう。

```c:NvM_Cfg.h
#define NVM_VERSION_INFO_API ON
```
ややこしいのはPost-build timeのパラメータ。
このパラメータは、ビルド時には確定しないようなパラメータであったり、ビルド以降に変更される可能性のあるパラメータとなる。
それは例えば以下の場合：
・テスト用にキャリブレーション（調整）したいとき
・別ECUに搭載するコンフィグセットを手軽に用意したいとき
　例えば、高価な車種ではCAN Bus上に流れる信号が多いが、安価な車種では信号が少ない。
　そのような場合は、Post-buildのパラメータのメモリセクションを適切に切ってさえおけば、
　ビルドし直す手間なく、通信系コンポーネントのCom等のPduなどのパラメータセットを用意し、Post-build timeのパラメータ領域のみリフラッシュすれば低コストで開発可能である。

僕はPost-build timeのみをリフラッシュできるようにメモリセクションを適切に切っているプロジェクトは経験したことがない。
キャリブレーションデータを使ってビルド後に調整したり、ビルド以降に何か変更したいという要望は、
サプライヤよりOEMの都合が多く、
コンフィグレーションパラメータはOEMが指定するというよりは、サプライヤが決めることのほうが多いので、
そもそもリフラッシュする運用があまり必要とされていないのではないかと思う。

OEMがどこまでAUTOSARの仕組みを理解して設計・要求をしているかによるが、
AUTOSARのPost-build timeのパラメータを置き換えてソフトを作るだけだから、ビルドの手間なく安価にできるよね？という要望があれば、そうせざるを得ないと思う。

個人的な経験だけだが、車種毎にブランチを切ってコンフィグレーションをし直してビルドし直しているプロジェクトがほとんどではないだろうか。
本当にコンフィグレーションを使いこなしている人がもしいれば教えて欲しい。

# アクセス制限
![スクリーンショット 2024-02-18 23.23.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/0c4a3ef0-b9de-2533-e0f1-cdd776e96b43.png)

* AUTOSAR Interface：
SW-C間またはBSWモジュール間で相互に通信（情報の送受信やサービスの呼び出し）する情報を定義したIF。
アプリ間、アプリとIoHwAb、アプリとCDDの通信仕様までは標準化はされてないので、設計者が定義したPortのイメージ。
このインターフェイスは、同一ECU内での通信か他ECUとの通信かどうかは問わない。


* Standardized AUTOSAR Interface：
BSWがSW-Cに提供する標準化されたサービスのインターフェイス。
例えば、不揮発メモリにアクセスする機能を使うときに呼び出す「NvM_WriteBlock」のようなイメージ。


* Standardized Interface：
「AUTOSAR Interface」は使わないが、標準化されたAPIのこと。
違いは、常に同一ECU上にあるソフトウェアモジュール間で使用されること。この通信をネットワーク経由でルーティングはできない。
例えば、ECU Abstractionの「MemIf」と、Microcontroller Abstractionの「Flash Driver」間の通信は、同一ECU上にないといけない。

以下は、AUTOSARアーキテクチャ上のアクセス制限の概要。
![スクリーンショット 2024-02-18 23.46.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/abf2578f-738e-9348-46cd-43ae724d75df.png)

制約：

横の関係：
・μC Abstraction Layer同士のアクセスはダメ

縦の関係：
・Layerを飛ばしてμCにアクセスはダメ

・system servicesはなんでもOK

# Complex Drivers
昔はComplex Device Driverという名称だったため、「CDD」という略称で呼ばれる場合もある。本記事でもCDDと呼ぶ。

CDDは、BSWで標準化されていない機能を実装するモジュールで、
例えば、特定の割り込みやHWへの直接アクセスによる複雑なセンサ制御、アクチュエータ制御等を実現できる。

CDDを作るうえでのルール：
* AUTOSARコンポーネント(SW-C/BSW)とアクセスする場合は、「AUTOSAR Interface」を介してアクセスできるようにすること
* そのIFはリエントラントであること
* CDDからアクセスするコンポーネントは、上位層に状態管理コンポーネントが存在しないこと（上位層に伝える情報がおかしくなることを防ぐ）

このルールを守っていれば何をしても良いのだが、パーティションを分割しメモリ保護をしていない限り、たとえSW-C内で操作するグローバル変数に勝手にアクセスしようが動いてしまうためアーキテクチャが崩壊してしまう恐れがあるので注意。