A2LファイルとSレコードファイルを選択し、任意のROM値をグラフ化するツールをjavascriptで作成してみました。最初にA2Lファイルを読み込み、パラメータ情報を取得し、その後に対応したSレコードファイルを読み込み、値を取得して、グラフ表示するというものです。
これで、適合ソフトを起動しなくても、適合値が確認できます。
ツールは下です。
A2LとHEXファイルからデータを読み込むjavascript
作りこんでないので、どのようなケースでも動くという訳ではありません。
とりあえず、サンプルのA2LとHEXファイルから値を取得するところまでやってみたというレベルですが、ともあれツール開発のベースにはなるんではないかと思います。
サンプルのA2LとSレコードファイルは下からダウンロードしてください
ちなみにデータのグラフ化はD3.jsを使用してます。下がツールの動作画面です。右上のボタンでA2LとHEXファイルを読み込み、データを表示します。
D3.jsの使い方は以下に簡単にまとめてますので、参考にしてください。
A2Lファイルってなによ?
A2Lファイルとは、マイコンで書き込まれているプログラムの内部変数情報を格納しているフォーマットです。自動車業界が中心となって、つくられたASAMという団体が、推奨してます。
実験とかする時にプログラム内のROMとかRAMがECUによらず、標準化したフォーマットで定義されていれば、環境変わっても同じツールからアクセスできるから便利だよねっていうのが推奨されている理由です。
定義されている情報としては、変数のラベル名、データ型、変数の形式(定数か、テーブルか、マップか)、値が保存されているアドレスなどがあります。
Sレコードファイルってなによ?
モトローラが決めたデータフォーマットでプログラムのバイナリ情報を格納してます。ASCIIテキストで、メモ帳でも開けます。
上のようなHEXデータがずらーっと複数行定義されています。茶色の部分がメモリアドレスになっていて、緑字の値がそこのアドレスに格納されているデータになります。
ちなみにヘッダのS3は、アドレス空間が32bitであるという意味です。
対抗する仕様として、intel hexがありますね。
適合値の読み込みの流れ
なので、”ABC”というパラメータの値を取得する場合、A2Lファイルから、まず、ABCというラベル名を持つパラメータを検索して、パラメータの先頭アドレスやデータ型、データタイプ(定数がテーブルか)などの情報を取得。そのデータをもとにHEXファイルから実際の値を取得するという感じの流れになります。
A2Lファイルのフォーマット
ファイルの基本構成は下の通りです。
/begin PROJECT
/begin HEADER
/* Project description */
/end HEADER
/begin MODULE /* Specific Device description*/
/begin MOD_PAR
/* Control unit management data */
/end MOD_PAR
/begin MOD_COMMON
/* Module-wide (ECU specific) definitions */
/end MOD_COMMON
/begin CHARACTERISTIC
/* Adjustable objects */
/end CHARACTERISTIC
/begin CHARACTERISTIC
/end CHARACTERISTIC
/begin AXIS_PTS
/* Axis points objects */
/end AXIS_PTS
/begin AXIS_PTS
/end AXIS_PTS
...
/begin MEASUREMENT
/* Measurement objects */
/end MEASUREMENT
/begin MEASUREMENT
/end MEASUREMENT
...
/begin COMPU_METHOD
/* Conversion method */
/end COMPU_METHOD
/begin COMPU_METHOD
.
/end COMPU_METHOD
/begin COMPU_TAB
/* Conversion tables */
/end COMPU_TAB
/begin COMPU_TAB
/end COMPU_TAB
...
/begin FUNCTION
/* Function allocations */
/end FUNCTION
/begin FUNCTION
/end FUNCTION
そもそもA2Lファイル自体は、適合ツールなどが出力してくれるので、これらを一から作成することはまずないと思います。なので、全体の説明は省略します。今回は、適合値を読み込むツールを作成するのが目的ですから、そこに関係する箇所のみ説明していきます。
適合値 スカラ定数
スカラ定数は、A2Lファイル内では、下のように定義されてます。適合値はCHARACTERISTICブロック内で記述します。
/begin CHARACTERISTIC
const1 "comment"
VALUE
0xCC278
CONST_UW
0
METHOD1
0.000000000E+000
2.559960938E+004
/begin FUNCTION_LIST
M_SPDLIM0000_1001_02
/end FUNCTION_LIST
/end CHARACTERISTIC
2行目のconst1がラベル名、3行目のVALUEがスカラ定数であることを示します。その次は値が格納されるメモリアドレス。次がデータ型で、ここではunsigned wordです。A2Lを生成するツールによっては、このデータ型の標記がかわるので、こういう場合は、javascriptのほうで、修正作業が必要です。また、今回作成のプログラムはレコードレイアウト指定をしているような場合は想定外としてますので、要注意です。
METHOD1というのは、HEXから物理値に変換するメソッド名になっていて、別の箇所で処理内容が定義されています。その下の二つの数値は物理値が取りうる最小と最大の値です。
物理変換式
ファイル内でCOMPU_METHODで定義されているブロックに物理変換用のメソッドが定義されてます。
/begin COMPU_METHOD
METHOD1 ""
RAT_FUNC
"%12.1"
"rpm"
COEFFS 0 1 -0.000000E+0 0 0 3.906250E-1
/end COMPU_METHOD
METHOD1というのが変換メソッド名、RAT_FUNCというのは有理関数を使用した変換となり、COEFFS (左からa , b , c , d , e , fと定義)の値をつかって、下式で変換します。
INT = (axx + bx +c) / (dxx +ex +f)
ちなみに、INT:メモリの値、xが物理値です。
%12.1 は表示用フォーマットになります。具体的には、
%[表示全体の桁数].[少数点以下の桁数]
になります。変換には他に文字列変換などありますが、今回は考えないことにします。
rpmは表示する単位です。
適合値 1次元マップ
テーブル値の場合は、VALUEではなくCURVEになります。そのほかは同じです。軸情報はAXIS_DESCRに定義します。COM_AXISというのは他の適合値でも共通で使えるようなデータであることを指します。
/begin CHARACTERISTIC
table1 ""
CURVE
0xCAC94
TABLE_UW
0
METHOD2
0.000000000E+000
2.621400000E+006
/begin FUNCTION_LIST
M_FOXHT00000_1007_00
/end FUNCTION_LIST
/begin AXIS_DESCR
COM_AXIS
axis_X
METHOD3
14
-3.000000000E+001
2.090625000E+002
AXIS_PTS_REF ax1
/end AXIS_DESCR
/end CHARACTERISTIC
axis_XがX軸パラメータのラベル名、MEHOD3は変換メソッド名、14がブレークポイント数、下の二つの数値は軸の値の最小/最大になります。
軸パラメータは別途下のように定義します。定義の内容はこれまでと同じです。
/begin AXIS_PTS
ax1 ""
0xCAEDC
axis_X
X_UB
0
METHOD3
14
-3.000000000E+001
2.090625000E+002
/begin FUNCTION_LIST
M_FOXHT00000_1007_00
/end FUNCTION_LIST
/end AXIS_PTS
適合値 二次元マップ
マップ値の場合は、MAPと指示します。基本、テーブルと設定は同じですが、軸は二つ分定義されます。
/begin CHARACTERISTIC
MAP1 ""
MAP
0xC7070
TABLE_UB
0
METHOD4
-2.250000000E+001
6.714843750E+001
/begin FUNCTION_LIST
M_ANR0000000_1005_00
/end FUNCTION_LIST
/begin AXIS_DESCR
COM_AXIS
axis_X2
METHOD5
5
0.000000000E+000
1.249980927E+002
AXIS_PTS_REF ax2
/end AXIS_DESCR
/begin AXIS_DESCR
COM_AXIS
axis_Y2
METHOD1
10
0.000000000E+000
2.559960938E+004
AXIS_PTS_REF ay2
/end AXIS_DESCR
/end CHARACTERISTIC
それ以上の3次元、4次元マップもA2Lで定義方法が決まっていますが、あまり多次元マップは頻繁にでてこないので、説明は、省略します。
Sレコードファイルで値を検索する
例えば、アドレス0XC022Cでデータサイズが1バイトの適合値の値をSレコードファイルから取得する場合が以下です。各行の先頭アドレスからオフセットアドレスを求め、該当するバイトを求めます。
2バイトデータの場合はどうか?
複数バイトの時は、バイトオーダに気をつけます。今回のサンプルコードはリトルエンディアンでデコードしてます。
テーブルデータの場合はどうか?
下図のようにテーブルデータは下位のアドレスからx1, x2, x3, … と定義されます。
マップデータの場合はどうか?
マップデータの並び順は、(x1,y1), (x2,y1), … , (x1,y2), (x2,y2), … , (x1, y3), (x2, y3), …となります。xとyは、A2LファイルでのAXIS_PTSの定義順でx, yになります。