ターゲットにダウンロードされるモジュール(データ)には、必ず同じ形式のヘッダが付きます。
モジュールの種別にはPOUコード、リソースコンフィギュレーションテーブルなどがあります。通常、これらは個々のスペースまたはマルチスペース(ターゲットのシステムレイヤの用語です)に相当します。
以下のCのstrRdccModulId構造体( "dsys0df2.h" で定義されています)が、このヘッダに相当します。
typedef struct { | |
char psTgtName[16], | /* ターゲット名。ヌルターミネートした文字列。 */ |
uint32 luRdccVers, | /* フォーマットのバージョン。現在の番号=4 */ |
uint32 luRDtaBaseCrc, | /* モジュールが所属するリソースのCRC。リソースを一意に識別するためのものです */ |
uint32 luModulCrc, | /* モジュールのCRC演算結果。内容のの整合性を確認するために使用します */ |
uint32 luParam, | /* 追加のパラメータ 以下のように使用します。
|
uint32 luModulSize, | /* モジュールの合計サイズ(ヘッダ部分を含む) */ |
uint32 luDataSize, | /* モジュールのサイズ(ヘッダ部分を含まない) */ |
uint32 luPCRNameOfs, | /* プロジェクト名/コンフィギュレーション名/リソース名の格納位置で、モジュールの先頭からのオフセットです。
|
uint32 luModNameOfs, | /* モジュール名の格納位置で、モジュールの先頭からのオフセットです。
他のモジュール名に関しては、ワークベンチのインタフェースリファレンス(ProTic.doc)を参照して下さい。 */ |
uint32 luDataOfs, | /* モジュールを構成するデータのの格納位置。モジュールの先頭からのオフセットです。 */ |
uint32 luModulCmpDate, | /* モジュールのコンパイル日時。Ver.4.10では未実装です。 */ |
uint32 luModulCmpVers, | /* モジュールのコンパイルバージョン。Ver.4.10では未実装です。 */ |
uint32 luModulUsVers | /* ユーザ定義バージョン番号。Ver.4.10では未実装です。 */ |
} strRdccModulId; |
CRCの演算は、下記のアルゴリズムにて行います。
/**************************************************************************** function : resCrcCalculate description : crc計算の実行 warning : ****************************************************************************/ uint32 resCrcCalculate ( void* pvDataAdd, /* In: CRC計算対象データの先頭アドレス */ uint32 luDataSze /* In: データサイズ */ ) /* Returns: 計算したCRC */ { uint32 luCrc; uint32 luMem1; uint32 luCnt1, luCnt2; luCrc = 0xffffffffUL; for (luCnt1=0; luCnt1<luDataSze; luCnt1++) { luCrc ^= (uint32)(((uchar*)pvDataAdd)[luCnt1]); for (luCnt2=1; luCnt2<=8; luCnt2++) { luMem1 = luCrc; luCrc /= 2; if (luMem1 & 1) luCrc ^= 0xa000a001; } } return (luCrc); } |
サンプルプログラム
下記はモジュールデータの整合性をチェックするプログラムの一例です。
モジュールの先頭のアドレスを void* pvModulAdd 、
モジュールの合計サイズを uint32 luModulSz とします。
pModulId = (strRdccModulId*)pvModulAdd; if ( (luModulSz < sizeof(strRdccModulId)) | | (luModulSz < pModulId->luModulSize) | | (luModulSz < pModulId->luDataSize) | | (luModulSz < pModulId->luPCRNameOfs) | | (luModulSz < pModulId->luModNameOfs) | | (luModulSz < pModulId->luDataOfs) ) { /* データのサイズが不一致 */ } pvModDtaAdd = (uchar*)pvModulAdd + pModulId->luDataOfs; luModDtaSze = pModulId->luDataSize; if ( resCrcCalculate(pvModDtaAdd, luModDtaSze) != pModulId->luModulCrc ) { /* データのCRCが不一致 */ } |