本コラムでは、ルネサス製MCALのPortとDioを使って、HSBRH850F1K100に搭載されているLEDを点灯/消灯する事例を紹介します。
ルネサス製MCALに関する基本情報や開発環境については「ルネサスエレクトロニクス社製MCALの使用方法」をご参照ください。
※本コラムは、ルネサスエレクトロニクス社の許可を得て公開しています。
LED
HSBRH850F1K100には、LED1~LED4の4つのLEDが搭載されています。HSBRH850F1K100の取扱説明書に書かれているように、LEDの結線、仕様は以下となっています。つまり、PortによりP8_4~P8_7を汎用出力ポートとして初期化し、Dioにより対象ポートのLOW/HIGHを操作すればよいということになります。
対象LED | 端子番号 | 端子名 | 使い方 |
---|---|---|---|
LED1 | 45 | P8_4 | LOW出力で点灯 |
LED2 | 46 | P8_5 | |
LED3 | 47 | P8_6 | |
LED4 | 48 | P8_7 |
なお、TOPPERS/ATK2(以下、ATK2)のHSBRH850F1K100向けコードでは、上記ポートの初期化処理が含まれてしまっているので、Portによるポート設定の振舞いを確認するために、ATK2を使用する場合は削除もしくはコメントアウトする必要があります。具体的には、target_config.cに実装されている関数target_port_initializeの冒頭の処理(PM8、P8の設定)が該当します。
Port
コンフィギュレーション
PortのEcucDefsは、<インストールフォルダ>\X1X\F1x\modules\port\definition\4.2.2\F1K\R422_PORT_F1K.arxmlに定義されています。arxmlはテキストエディタでも内容を確認できますが、ArtopなどのAUTOSARツールを使用することで右図のように、簡単に確認することができます。なお、本コラムで用いる"EcucDefs"等のコンフィギュレーションに関する用語の意味は「Basic Softwareのコンフィギュレーション仕様の仕組み」をご参照ください。
ルネサス製Portでは、AUTOSAR仕様で規定されているコンテナ/AUTOSAR/EcucDefs/Port/PortConfigSet/PortContainerは使用されず、同じ階層に各ポートグループ用の設定コンテナが用意されています。例えば、今回LEDで使用するポートグループ8(P8)は、コンテナ/Renesas/EcucDefs_Port/Port/PortConfigSet/PortGroup8で設定します。PortGroup8コンテナには、さらに各ポートを設定するサブコンテナとしてPortPin0~PortPin12というコンテナが含まれています。具体的に、LED1(P8_4)を汎用出力ポートとするコンフィギュレーションをYAML形式(※1)で記載すると以下のようになります。(該当パラメータの抜粋となります)
Port: PortConfigSet: PortGroup8: PortPin4: PortPinDirection: PORT_PIN_OUT # 出力モード PortPinInitialMode: DIO_PFC_PFCE_PMCSR # ポートモード
※1 YAML形式によるEcucValsの表記については「ABREXの使い方」をご参照ください。
上記コンフィギュレーションでは、PortPinDirectionで出力ポートとし、PortPinInitialModeでポートモードを指定していますが、PortPin4コンテナには他にもいくつかパラメータが存在します。各パラメータの意味や設定可能な値についても、すべてEcucDefsに定義されていますので、右図のようにAUTOSARツールで各パラメータの情報を確認することが可能です。
モジュール毎のマニュアルには、各パラメータの意味までは記載されていませんので、コンフィギュレーションを行う際は、EcucDefsに定義された情報が参考になります。
ジェネレータ実行
ジェネレータ実行時には、EcucVals以外にもいくつか入力ファイルが必要となります。Portのジェネレータマニュアル(R20UT3874EJ0106-AUTOSAR.pdf)のFigure 3-1(右図)に書かれているように、具体的には以下の4つとなります。
- [1] ECU Configuration Description File
- [2] Translation XML File
- チップ固有のヘッダファイルへのパスを定義するファイルです。(拡張子はtrxml)
- サンプルファイルが<インストールフォルダ>\X1X\F1x\common_family\generatorに格納されています。
- 今回使用するチップは、R7F7015813AFPですので、ジェネレータを実行するフォルダから、以下のファイルへの相対パス情報を定義する必要があります。
- <インストールフォルダ>\X1X\F1x\common_family\generator\F1K\F1K_translation_701581.h
- <インストールフォルダ>\X1X\F1x\common_family\include\ghs\dr7f701581_0.h
- 本コラム作成時に使用した具体的なTranslation XML Fileは以下となります。
<?xml version="1.0" encoding="utf-8"?> <PATH-DETAILS> <TRANSLATION-FILE-PATH> <R7F701581><インストールフォルダまでの相対パス>\renesas\X1X\F1x\common_family\generator\F1K\F1K_translation_701581.h</R7F701581> </TRANSLATION-FILE-PATH> <DEVICE-FILE-PATH> <R7F701581><インストールフォルダまでの相対パス>\renesas\X1X\F1x\common_family\include\ghs\dr7f701581_0.h</R7F701581> </DEVICE-FILE-PATH> </PATH-DETAILS>
- ジェネレータを実行するフォルダからの相対パスが変わらなければ、上記ファイルを1つ用意しておけば、全モジュールで共通して使用できます。
- [3] BSWMDT File
- "BSWMDT"は、BSW Module Description Templateの略で、対象BSWの情報を定義したファイルとなります。
- Portに含まれる排他エリアやMemorySectionといった情報が定義されています。
- Port用のBSWMDT Fileは、以下に用意されています。
- <インストールフォルダ>\X1X\F1x\modules\port\generator\R422_PORT_F1x_BSWMDT.arxml
- [4] Configuration XML File
- コマンドライン実行時のオプション設定用ファイルです。(拡張子はcfgxml)
- ジェネレータ実行時に指定しなければ、Port_X1x.exeと同じフォルダにあるデフォルトのPort_X1x.cfgxmlが使用されますので、本コラム作成時は未指定としました。
実装
Portは、コンフィギュレーションに応じてポートを設定するモジュールなので、動的にポートの設定を変更しない限りは、Port_Initにより初期化を行うのみとなります。Port_Initの引数は、ハードウェアやMCAL実装に依存して定義される構造体型であるPort_ConfigTypeへのポインタとなります。ルネサス製Portでは、ジェネレータで生成したPort_PBcfg.cに対象の構造体が生成されます。また、Port_Cfg.hに以下のマクロが定義されますので、こちらをPort_Initの引数として使用することができます。
/* Configuration Set Handles */ #define PortConfigSet (&Port_GstConfiguration[0])
具体的には、以下のように初期化処理にてPort_Initを呼び出すのみです。AUTOSARでは、EcuM等を用いて各BSWを初期化しますが、本コラムではOSとMCALのみ使用するため、以下の例では、OSのスタートアップフックから呼び出しています。
#include "Port.h" : void StartupHook(void) { : Port_Init(PortConfigSet); : }
上記のPort_Init呼出し前後で、P8_4~P8_7用のポート関連レジスタが正しく変化することを確認することで、コンフィギュレーションが正しいことを確認することができます。
Dio
コンフィギュレーション
DioのEcucDefsは、<インストールフォルダ>\X1X\F1x\modules\dio\definition\4.2.2\F1K\R422_DIO_F1K.arxmlに定義されています。ルネサス製Dioは、ほぼAUTOSAR仕様で規定されているコンテナ/パラメータ構成のままとなっていますが、以下の点でPortのコンフィギュレーションと呼び方が異なっているので注意が必要です。
- Portにおいて"ポートグループ(PortGroup)"と呼んでいたものは、Dioでは"ポート(DioPort)"となります。
- Portにおいて"ポートピン(PortPin)"と呼んでいたものは、Dioでは"チャネル(DioChannel)"となります。
- Dioでは、いくつかのチャネル(DioChannel)をまとめて操作するためのグループを、"チャネルグループ(DioChannelGroup)"と呼びます。
また、ルネサス製Dioでは、識別子に関するパラメータの扱いがAUTOSAR仕様と異なっているの注意が必要です。AUTOSAR仕様では、ポート、チャネル、チャネルグループの識別子を以下のパラメータで設定すると規定されていますが、ルネサス製Dioではこれらのパラメータは使用されません。多重度の都合上、EcucValsでの設定は必須ですが、設定しても読み飛ばされます。これらのパラメータを用いずに、どのように識別するかは、後述の実装の節で説明します。
- ポート(DioPort):/AUTOSAR/EcucDefs/Dio/DioConfig/DioPort/DioPortId
- チャネル(DioChannel):/AUTOSAR/EcucDefs/Dio/DioConfig/DioPort/DioChannel/DioChannelId
- チャネルグループ(DioChannelGroup):/AUTOSAR/EcucDefs/Dio/DioConfig/DioPort/DioChannelGroup/DioChannelGroupIdentification
P8_4~P8_7向けのコンフィギュレーションをYAML形式(※2)で記載すると以下のようになります。(該当パラメータの抜粋となります)
Dio: DioConfig: DioPort_Group8: DefinitionRef: DioPort DioPortId: 8 # 使用されない DioPortName: PORTGROUP_8_BITS_0_TO_12 P8_4: DefinitionRef: DioChannel DioChannelId: 4 # 使用されない DioChannelBitPosition: 4 P8_5: DefinitionRef: DioChannel DioChannelId: 5 # 使用されない DioChannelBitPosition: 5 P8_6: DefinitionRef: DioChannel DioChannelId: 6 # 使用されない DioChannelBitPosition: 6 P8_7: DefinitionRef: DioChannel DioChannelId: 7 # 使用されない DioChannelBitPosition: 7 LED_CHANNEL_GROUP: DefinitionRef: DioChannelGroup DioPortMask: 0xF0 DioPortOffset: 4 DioChannelGroupIdentification: LED_GROUP_ID # 使用されない
※2 YAML形式によるEcucValsの表記については「ABREXの使い方」をご参照ください。
DioPortNameとDioChannelBitPositionは、ルネサス製Dio独自のパラメータです。DioPortNameは、マイコン上のどのポートグループ(PortGroup)/ポートピン(PortPin)に対する設定かを選択するパラメータで、DioChannelBitPositionはポート関連レジスタの対応するビット位置を設定するパラメータとなります。
ジェネレータ実行
Port同様、Dioのジェネレータ実行時も、入力情報として以下の4つが必要となります。
- [1] ECU Configuration Description File
- Dio向けのEcucValsを指定します。
- 複数モジュール向けのEcucValsを1つのarxmlで定義しても問題ありません。
- [2] Translation XML File
- ジェネレータを実行するフォルダからの相対パスが同じであれば、Portのジェネレータで使用したものと同じファイルを使用できます。
- [3] BSWMDT File
- Dio用のBSWMDT Fileは、以下に用意されています。
- <インストールフォルダ>\X1X\F1x\modules\port\generator\R422_PORT_F1x_BSWMDT.arxml
- Dio用のBSWMDT Fileは、以下に用意されています。
- Port同様、省略可能です。
Dioのジェネレータマニュアル(R20UT3862EJ0105-AUTOSAR.pdf)のFigure 3-1(右図)には、出力ファイルの1つとしてDio_PBcfg.cが記載されていますが、このファイルは生成されません。
実装
まず、前述のEcucValsを入力としてジェネレータを実行すると、ポート、チャネル、チャネルグループの識別子は、Dio_Cfg.hに以下のように定義されます。
/* DIO Port Configuration Handles */ #define DioConf_DioPort_DioPort_Group8 (Dio_PortType)0 : /* DIO Channel Configuration Handles */ #define DioConf_DioChannel_P8_4 (Dio_ChannelType)0 #define DioConf_DioChannel_P8_5 (Dio_ChannelType)1 #define DioConf_DioChannel_P8_6 (Dio_ChannelType)2 #define DioConf_DioChannel_P8_7 (Dio_ChannelType)3 : /* DIO Channel Group Configuration Handles */ #define DioConf_DioChannelGroup_LED_CHANNEL_GROUP (&Dio_GstChannelGroupData[0])
上記のマクロは、SymbolicNameValue属性が付いたパラメータに対して生成されるものとなります。AUTOSARのパラメータは、SymbolicNameValue属性を付与することができ、EcucDefsで<SYMBOLIC-NAME-VALUE>がtrueとなっているパラメータがその対象となります。SymbolicNameValue属性が付いているパラメータに対しては、以下の命名規則でマクロを定義すると規定されています(※3)。
- マクロ名:<モジュール名>Conf_<親コンテナ名>_<親コンテナのショートネーム>
- 値:対象パラメータの設定値
今回の例では、DioChannelIdにそれぞれ4~7を設定しているので、AUTOSAR仕様に従えば、マクロの値も4~7となるはずですが、実際の出力では0~3となっています。同様に、DioPortIdも8を設定していますが、0が出力されています。DioChannelIdやDioPortIdは、Dioが提供するAPIの引数として使用される値になるものですが、以下のようにDioのマニュアル(R20UT3861EJ0108-AUTOSAR.pdf:Table4-3)では、EcucValsの設定値ではなく、SymbolicNameValue属性で生成されたマクロを使用することになっています。
これは、0からの連番で識別子を付与することで、Dioモジュール内の処理を最適化しているためと思われます。元々AUTOSARには、最適化のために識別子を0からの連番で設定する制約を設けていることもあるので、Dioもその制約を設ければよいものと思われますが、現状は設定値を読み捨てて、ジェネレータで値を付与するようになっています。なお、ルネサス製MCALの他のモジュールでは、0からの連番制約となっているものもあるので注意が必要です。
DioChannelGroupIdentificationについてはもう少し複雑です。DioChannelGroupIdentificationは、チャネルグループの識別子であり、チャネルグループ単位で操作するAPI(Dio_ReadChannelGroup等)の引数となるものです。これらのAPIの引数に与える識別子は、整数ではなくDio_ChannelGroupType型の構造体へのポインタとなっています。Dio_ChannelGroupType型には、DioChannelGroupコンテナで設定する値と同様、マスクやオフセットの値が含まれます。AUTOSAR仕様によると、EcucValsのDioChannelGroupIdentificationには、ユーザが事前に定義したDio_ChannelGroupType型の構造体データへのポインタを文字列で指定することになっています。しかし、ルネサス製Dioでは、DioChannelGroupIdentificationが読み捨てられ、対象のチャネルグループ用のDio_ChannelGroupType型の構造体データをジェネレータで生成し、そのデータへのポインタをSymbolicNameValue属性のマクロで定義するようになっています。具体的には、Dio_Lcfg.cに以下のようにDio_GstChannelGroupDataというデータが生成され、前述のDio_Cfg.hにあるように、DioConf_DioChannelGroup_LED_CHANNEL_GROUPマクロが以下のデータへのポインタとして定義されます。
/* Data Structure of DIO Port Channel Group Configuration */ CONST(Dio_ChannelGroupType, DIO_CONST) Dio_GstChannelGroupData[DIO_CHANNEL_GROUP_ARRAY_SIZE] = { /* Index: 0 - LED_CHANNEL_GROUP */ { /* usMask */ 0x00F0U, /* ucOffset */ 0x04U, /* ucPortIndex */ 0x00U } };
以上から、ルネサス製Dioにおいては、各API呼出し時に指定する識別子として、SymbolicNameValue属性のマクロを指定する必要があります。今回操作するLEDはLOW出力で点灯、HIGH出力で消灯となりますので、Dioを使用したLED制御の実装は以下のようになります。
#include "Dio.h" void sample(void) { /* Dio_WritePortにより、LED1のみ点灯 */ Dio_WritePort(DioConf_DioPort_DioPort_Group8, (Dio_PortLevelType)~0x10U); /* Dio_WriteChannelにより、LED2のみ点灯する */ Dio_WriteChannel(DioConf_DioChannel_P8_4, 1U); Dio_WriteChannel(DioConf_DioChannel_P8_5, 0U); Dio_WriteChannel(DioConf_DioChannel_P8_6, 1U); Dio_WriteChannel(DioConf_DioChannel_P8_7, 1U); /* Dio_WriteChannelGroupにより、LED3のみ点灯する */ Dio_WriteChannelGroup(DioConf_DioChannelGroup_LED_CHANNEL_GROUP, (Dio_PortLevelType)~0x04U); }
Dio_WritePortではポート(DioPort)全体を操作するのに対し、Dio_WriteChannelGroupでは設定したオフセットも含めたビット位置に対するチャネルグループ(DioChannelGroup)だけを操作するので、第2引数で与えるビット位置が変わることに注意が必要です。
なお、AUTOSARのR4.2.2では、Dio_Initが削除されており、Dioの初期化は不要となります。
※3 「Specification of ECU Configuration」の[TPS_ECUC_02108]参照。
動作確認
前述のDioによる実装を用いて、1秒に1回点灯するLEDを切り替えるサンプルプログラムを実行した様子が以下となります。
以上から、ルネサス製のPortとDioが正しく動作することを確認できました。