source: atk2-sc3_fl850f1l/utils/abrex/abrex.rb@ 117

Last change on this file since 117 was 117, checked in by ertl-ishikawa, 9 years ago

ATK2-SC3 1.3.2 FL850F1L(RH850F1L)依存部(GCC/GHS/CCRH)を追加

File size: 35.3 KB
Line 
1#!ruby -Ke
2#
3# ABREX
4# AUTOSAR BSW and RTE XML Generator
5#
6# Copyright (C) 2013-2015 by Center for Embedded Computing Systems
7# Graduate School of Information Science, Nagoya Univ., JAPAN
8# Copyright (C) 2014-2015 by AISIN COMCRUISE Co., Ltd., JAPAN
9# Copyright (C) 2013-2015 by FUJI SOFT INCORPORATED, JAPAN
10# Copyright (C) 2014-2015 by NEC Communication Systems, Ltd., JAPAN
11# Copyright (C) 2013-2015 by Panasonic Advanced Technology Development Co., Ltd., JAPAN
12# Copyright (C) 2013-2014 by Renesas Electronics Corporation, JAPAN
13# Copyright (C) 2014-2015 by SCSK Corporation, JAPAN
14# Copyright (C) 2013-2015 by Sunny Giken Inc., JAPAN
15# Copyright (C) 2013-2015 by TOSHIBA CORPORATION, JAPAN
16# Copyright (C) 2013-2015 by Witz Corporation
17#
18# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
19# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
20# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
21# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
22# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
23# スコード中に含まれていること.
24# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
25# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
26# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
27# の無保証規定を掲載すること.
28# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
29# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
30# と.
31# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
32# 作権表示,この利用条件および下記の無保証規定を掲載すること.
33# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
34# 報告すること.
35# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
36# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
37# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
38# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
39# 免責すること.
40#
41# 本ソフトウェアは,AUTOSAR(AUTomotive Open System ARchitecture)仕
42# 様に基づいている.上記の許諾は,AUTOSARの知的財産権を許諾するもので
43# はない.AUTOSARは,AUTOSAR仕様に基づいたソフトウェアを商用目的で利
44# 用する者に対して,AUTOSARパートナーになることを求めている.
45#
46# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
47# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
48# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
49# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
50# の責任を負わない.
51#
52# $Id: abrex.rb 8481 2014-03-07 03:54:06Z shigihara $
53#
54
55if ($0 == __FILE__)
56 TOOL_ROOT = File.expand_path(File.dirname(__FILE__) + "/")
57 $LOAD_PATH.unshift(TOOL_ROOT)
58end
59
60require "pp"
61require "yaml"
62require "optparse"
63require "kconv.rb"
64require "rexml/document.rb"
65include REXML
66
67######################################################################
68# 定数定義
69######################################################################
70VERSION = "1.1.0"
71VER_INFO = " Generated by ABREX Ver. #{VERSION} "
72XML_ROOT_PATH = "/AUTOSAR/EcucDefs/"
73XML_EDITION = "4.2.0"
74XML_SNAME = "SHORT-NAME"
75XML_PARAM = "PARAMETER-VALUES"
76XML_REFER = "REFERENCE-VALUES"
77XML_SUB = "SUB-CONTAINERS"
78XML_AUTOSAR_FIXED_ATT = {"xmlns" => "http://autosar.org/schema/r4.0",
79 "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
80 "xsi:schemaLocation" => "http://autosar.org/schema/r4.0 AUTOSAR_4-0-3_STRICT.xsd"}
81
82# パラメータデータ型種別格納ハッシュ
83# (これ以外はすべてECUC-NUMERICAL-PARAM-VALUE)
84XML_VALUE_TYPE = {"ECUC-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE",
85 "ECUC-FOREIGN-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE",
86 "ECUC-SYMBOLIC-NAME-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE",
87 "ECUC-INSTANCE-REFERENCE-DEF" => "ECUC-INSTANCE-REFERENCE-VALUE",
88 "ECUC-CHOICE-REFERENCE-DEF" => "ECUC-CHOICE-REFERENCE-DEF",
89 "ECUC-ENUMERATION-PARAM-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
90 "ECUC-STRING-PARAM-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
91 "ECUC-MULTILINE-STRING-PARAM-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
92 "ECUC-FUNCTION-NAME-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
93 "ECUC-LINKER-SYMBOL-DEF" => "ECUC-TEXTUAL-PARAM-VALUE"}
94
95# インスタンス参照型の特別コンテナ
96XML_INSTANCE_REF_CONTAINER = {"EcucPartitionSoftwareComponentInstanceRef" =>
97 {"CONTEXT-ELEMENT-REF" => "ROOT-SW-COMPOSITION-PROTOTYPE",
98 "TARGET-REF" => "SW-COMPONENT-PROTOTYPE"}}
99
100######################################################################
101# YAML → XML 実行機能
102######################################################################
103def YamlToXml(aArgData, sEcuExtractRef)
104 # 各パラメータのデータ型定義(-pオプションで生成したものを使用する)
105 sFileName = "#{TOOL_ROOT}/param_info.yaml"
106 if (!File.exist?(sFileName))
107 abort("#{sFileName} not found !!")
108 end
109 hParamInfo = YAML.load_file(sFileName)
110 # ハッシュでない(YAMLでない)場合エラー
111 if (!hParamInfo.is_a?(Hash))
112 abort("not YAML file !! [#{sFileName}]")
113 end
114
115 # 外部参照先のデータ型格納ハッシュを分離
116 $hForeignRefType = hParamInfo.delete(:FOREIGN_REF_TYPE)
117
118 # インスタンス参照先のデータ型を保持
119 $aInstanceRefType = hParamInfo["ECUC-INSTANCE-REFERENCE-DEF"]
120
121 # コンテナ名変換テーブル
122 $hEcuc = {}
123 $hDest = {}
124
125 hParamInfo.each{|sType, aParam|
126 aParam.each{|sName|
127 if (XML_VALUE_TYPE.has_key?(sType))
128 $hEcuc[sName] = XML_VALUE_TYPE[sType]
129 else
130 $hEcuc[sName] = "ECUC-NUMERICAL-PARAM-VALUE"
131 end
132 $hDest[sName] = sType
133 }
134 }
135
136 # 参照型のパラメータ一覧
137 $hReferenceParam = hParamInfo["ECUC-REFERENCE-DEF"] + hParamInfo["ECUC-FOREIGN-REFERENCE-DEF"] + hParamInfo["ECUC-SYMBOLIC-NAME-REFERENCE-DEF"] + hParamInfo["ECUC-INSTANCE-REFERENCE-DEF"]
138
139 # 与えられた全YAMLをマージする
140 hYaml = {}
141 sArxmlName = nil
142 aArgData.each{|sFileName|
143 # ファイルが存在しない場合エラー
144 if (!File.exist?(sFileName))
145 abort("Argument error !! [#{sFileName}]")
146 end
147
148 # 出力ファイル名作成(複数ある場合,最初のファイル名を採用する)
149 if (File.extname(sFileName) == ".yaml")
150 if (sArxmlName.nil?())
151 sArxmlName = File.dirname(sFileName) + "/" + File.basename(sFileName, ".yaml") + ".arxml"
152 end
153 else
154 abort("not YAML file name !! [#{sFileName}]")
155 end
156
157 hTmpData = YAML.load(File.read(sFileName).toutf8())
158 # ハッシュでない(YAMLでない)場合エラー
159 if (!hTmpData.is_a?(Hash))
160 abort("not YAML file !! [#{sFileName}]")
161 end
162
163 # 読み込んだデータをマージしていく
164 YamlToXml_merge_hash(hYaml, hTmpData)
165 }
166
167 cXmlInfo = Document.new()
168 cXmlInfo.add(XMLDecl.new("1.0", "UTF-8"))
169 REXML::Comment.new(VER_INFO, cXmlInfo)
170 cXmlAutosar = cXmlInfo.add_element("AUTOSAR", XML_AUTOSAR_FIXED_ATT)
171 cXmlArPackages = cXmlAutosar.add_element("AR-PACKAGES")
172
173 # IMPLEMENTATION-DATA-TYPE格納ハッシュを分離して先に登録
174 hImplDataType = hYaml.delete("IMPLEMENTATION-DATA-TYPE")
175 if (!hImplDataType.nil?())
176 cXmlArPackage = cXmlArPackages.add_element("AR-PACKAGE")
177 cXmlArPackage.add_element(XML_SNAME).add_text("ImplementationDataTypes")
178 cXmlElements = cXmlArPackage.add_element("ELEMENTS")
179 hImplDataType.each{|sShortName, hData|
180 cXmlEcucModuleConfVal = cXmlElements.add_element("IMPLEMENTATION-DATA-TYPE")
181 cXmlEcucModuleConfVal.add_element(XML_SNAME).add_text(sShortName)
182 cXmlEcucModuleConfVal.add_element("CATEGORY").add_text(hData["CATEGORY"])
183 }
184 end
185
186 aModulePaths = []
187 hYaml.each{|sPackageName, hPackageData|
188 cXmlArPackage = cXmlArPackages.add_element("AR-PACKAGE")
189 cXmlArPackage.add_element(XML_SNAME).add_text(sPackageName)
190 cXmlElements = cXmlArPackage.add_element("ELEMENTS")
191
192 hPackageData.each{|sEcucModuleName, hEcucModuleData|
193 aModulePaths.push("/#{sPackageName}/#{sEcucModuleName}")
194 cXmlEcucModuleConfVal = cXmlElements.add_element("ECUC-MODULE-CONFIGURATION-VALUES")
195 cXmlEcucModuleConfVal.add_element(XML_SNAME).add_text(sEcucModuleName)
196 cXmlEcucModuleConfVal.add_element("DEFINITION-REF", {"DEST" => "ECUC-MODULE-DEF"}).add_text(XML_ROOT_PATH + sEcucModuleName)
197 cXmlEcucModuleConfVal.add_element("ECUC-DEF-EDITION").add_text(XML_EDITION)
198 cXmlEcucModuleConfVal.add_element("IMPLEMENTATION-CONFIG-VARIANT").add_text("VARIANT-PRE-COMPILE")
199 cXmlContainers = cXmlEcucModuleConfVal.add_element("CONTAINERS")
200
201 # 各パラメータ用コンテナを作成する
202 hEcucModuleData.each{|sShortName, hParamInfo|
203 # DefinitionRef補完
204 if (!hParamInfo.has_key?("DefinitionRef"))
205 hParamInfo["DefinitionRef"] = sShortName
206 end
207
208 cContainer = YamlToXml_make_container(sShortName, hParamInfo, XML_ROOT_PATH + sEcucModuleName)
209 cXmlContainers.add_element(cContainer)
210 }
211 }
212 }
213
214 # ECU-EXTRACT-REF指定がある場合、<ECUC-VALUE-COLLECTION>を追加する
215 if (!sEcuExtractRef.nil?())
216 cXmlArPackage = cXmlArPackages.add_element("AR-PACKAGE")
217 cXmlArPackage.add_element(XML_SNAME).add_text("EcucValueCollection")
218 cXmlElements = cXmlArPackage.add_element("ELEMENTS")
219 cXmlEcucValueCollection = cXmlElements.add_element("ECUC-VALUE-COLLECTION")
220 cXmlEcucValueCollection.add_element(XML_SNAME).add_text("EcucValueCollection")
221 cXmlEcucValueCollection.add_element("ECU-EXTRACT-REF", {"DEST" => "SYSTEM"}).add_text(sEcuExtractRef)
222 cXmlEcucValues = cXmlEcucValueCollection.add_element("ECUC-VALUES")
223 aModulePaths.each{|sPath|
224 cTemp = cXmlEcucValues.add_element("ECUC-MODULE-CONFIGURATION-VALUES-REF-CONDITIONAL")
225 cTemp.add_element("ECUC-MODULE-CONFIGURATION-VALUES-REF", {"DEST" => "ECUC-MODULE-CONFIGURATION-VALUES"}).add_text(sPath)
226 }
227 end
228
229 # XML文字列生成
230 sXmlCode = String.new()
231 cXmlInfo.write(sXmlCode, 2, false)
232
233 # XML宣言の属性のコーテーションをダブルに出来ない(?)ため,ここで置換する
234 sXmlCode.gsub!("'", "\"")
235
236 # ダブルコーテーションが&quot;に変換されるのを抑止できない(?)ため,ここで置換する
237 sXmlCode.gsub!("&quot;", "\"")
238
239 # 値を定義する部分だけインデントを入れないように出来ない(?)ため,ここで置換する
240 sXmlCode.gsub!(/>\n[\s]+([\w\.\[\]\(\)\+-\/\*~&;\s]*?)\n[\s]+</, ">\\1<")
241
242 # XMLDeclのコンストラクタではEUC-JPを指定出来ない(?)ため,ここで文字コードを置換する
243 sXmlCode.sub!("UTF-8", "EUC-JP")
244
245 # インデントをタブに出来ない(?)ため,ここで置換する
246 sXmlCode.gsub!(" ", "\t")
247
248 # ファイル出力
249 #puts(sXmlCode)
250 File.open(sArxmlName, "w") {|io|
251 io.puts(sXmlCode)
252 }
253
254 puts("Generated #{sArxmlName}")
255end
256
257# ハッシュマージ関数
258def YamlToXml_merge_hash(hBase, hAdd)
259 hAdd.each{|sKey, xVal|
260 # 追加先にキーが存在しなければ,そのまま追加するのみ
261 if (!hBase.has_key?(sKey))
262 hBase[sKey] = xVal
263 # 同じキーで値が違う場合
264 elsif (hBase[sKey] != hAdd[sKey])
265 # ハッシュ同士であれば,再帰で追加
266 if (hBase[sKey].is_a?(Hash) && hAdd[sKey].is_a?(Hash))
267 YamlToXml_merge_hash(hBase[sKey], hAdd[sKey])
268 # 追加先が配列であれば,配列に合わせて追加
269 elsif (hBase[sKey].is_a?(Array))
270 if (hAdd[sKey].is_a?(Array))
271 hBase[sKey].concat(hAdd[sKey])
272 else
273 hBase[sKey].push(hAdd[sKey])
274 end
275 # 追加先が配列でなければ,配列にしてから追加
276 elsif (hAdd[sKey].is_a?(Array))
277 hBase[sKey] = [hBase[sKey]]
278 hBase[sKey].concat(hAdd[sKey])
279 # どちらも配列でない場合,配列として両方をマージ
280 else
281 hBase[sKey] = [hBase[sKey]]
282 hBase[sKey].push(hAdd[sKey])
283 end
284 else
285 # 同じパラメータの場合,何もしない
286 end
287 }
288end
289
290# コンテナ作成関数
291def YamlToXml_make_container(sShortName, hParamInfo, sPath)
292 # 一律"ECUC-CONTAINER-VALUE"を入れた状態で初期化
293 cContainer = Element.new().add_element("ECUC-CONTAINER-VALUE")
294
295 # ショートネーム追加
296 cContainer.add_element(XML_SNAME).add_text(sShortName)
297
298 # コンテナまでのパス追加
299 cContainer.add_element("DEFINITION-REF", {"DEST" => "ECUC-PARAM-CONF-CONTAINER-DEF"}).add_text("#{sPath}/#{hParamInfo["DefinitionRef"]}")
300
301 # 各パラメータ設定(パラメータが無い場合は不要)
302 hCheck= {}
303 if (hParamInfo.size() != 1)
304 hCheck[XML_PARAM] = false
305 hCheck[XML_REFER] = false
306 hCheck[XML_SUB] = false
307
308 # まず参照型,サブコンテナ以外を生成(AUTOSARスキーマ制約)
309 hParamInfo.each{|sParamName, sahValue|
310 if ((sParamName == "DefinitionRef") || (sahValue.is_a?(Hash)))
311 next
312 end
313
314 # 参照型,サブコンテナ以外のパラメータ
315 if (!$hReferenceParam.include?(sParamName))
316 # パラメータ名チェック
317 if (!$hEcuc.has_key?(sParamName) || !$hDest.has_key?(sParamName))
318 abort("Unknown parameter: #{sParamName}")
319 end
320
321 if (hCheck[XML_PARAM] == false)
322 cContainer.add_element(XML_PARAM)
323 hCheck[XML_PARAM] = true
324 end
325
326 # 多重度*対応
327 aTemp = []
328 if (sahValue.is_a?(Array))
329 aTemp = sahValue
330 else
331 aTemp.push(sahValue)
332 end
333 aTemp.each{|sVal|
334 cParamContainer_ = Element.new()
335 cParamContainer = cParamContainer_.add_element($hEcuc[sParamName])
336 cParamContainer.add_element("DEFINITION-REF", {"DEST" => $hDest[sParamName]}).add_text("#{sPath}/#{hParamInfo["DefinitionRef"]}/#{sParamName}")
337 cParamContainer.add_element("VALUE").add_text(sVal.to_s())
338 cContainer.elements[XML_PARAM].add_element(cParamContainer)
339 }
340 end
341 }
342
343 # 次に参照型を生成(AUTOSARスキーマ制約)
344 hParamInfo.each{|sParamName, sahValue|
345 if ((sParamName == "DefinitionRef") || (sahValue.is_a?(Hash)))
346 next
347 end
348
349 # インスタンス参照型の場合
350 if ($aInstanceRefType.include?(sParamName))
351 if (!sahValue.is_a?(Array))
352 abort("#{sParamName} must be Array !!")
353 end
354 # 未サポートコンテナは生成できないためエラーとする
355 if (!XML_INSTANCE_REF_CONTAINER.has_key?(sParamName))
356 abort("#{sParamName} is not supported !!")
357 end
358 if (hCheck[XML_REFER] == false)
359 cContainer.add_element(XML_REFER)
360 hCheck[XML_REFER] = true
361 end
362
363 # 多重度*対応(2次元配列かチェック)
364 aTemp = []
365 if (sahValue[0].is_a?(Array))
366 aTemp = sahValue
367 else
368 aTemp.push(sahValue)
369 end
370 aTemp.each{|aVal|
371 cParamContainer_ = Element.new()
372 cParamContainer = cParamContainer_.add_element($hEcuc[sParamName])
373 cParamContainer.add_element("DEFINITION-REF", {"DEST" => $hDest[sParamName]}).add_text("#{sPath}/#{hParamInfo["DefinitionRef"]}/#{sParamName}")
374 cInstanceRef = cParamContainer.add_element("VALUE-IREF")
375 aVal.each{|hVal|
376 XML_INSTANCE_REF_CONTAINER[sParamName].each{|sParam, sDest|
377 if (hVal.has_key?(sParam))
378 cInstanceRef.add_element(sParam, {"DEST" => sDest}).add_text(hVal[sParam].to_s())
379 end
380 }
381 }
382 cContainer.elements[XML_REFER].add_element(cParamContainer)
383 }
384
385 # 参照型の場合
386 elsif ($hReferenceParam.include?(sParamName))
387 if (hCheck[XML_REFER] == false)
388 cContainer.add_element(XML_REFER)
389 hCheck[XML_REFER] = true
390 end
391
392 # 多重度*対応
393 aTemp = []
394 if (sahValue.is_a?(Array))
395 aTemp = sahValue
396 else
397 aTemp.push(sahValue)
398 end
399 aTemp.each{|sVal|
400 cParamContainer_ = Element.new()
401 cParamContainer = cParamContainer_.add_element($hEcuc[sParamName])
402 cParamContainer.add_element("DEFINITION-REF", {"DEST" => $hDest[sParamName]}).add_text("#{sPath}/#{hParamInfo["DefinitionRef"]}/#{sParamName}")
403 if (!$hForeignRefType.nil? && $hForeignRefType.has_key?(sParamName))
404 cParamContainer.add_element("VALUE-REF", {"DEST" => $hForeignRefType[sParamName]}).add_text(sVal.to_s())
405 else
406 cParamContainer.add_element("VALUE-REF", {"DEST" => "ECUC-CONTAINER-VALUE"}).add_text(sVal.to_s())
407 end
408 cContainer.elements[XML_REFER].add_element(cParamContainer)
409 }
410 end
411 }
412
413 # 最後にサブコンテナを生成
414 hParamInfo.each{|sParamName, sahValue|
415 if ((sParamName == "DefinitionRef") || (!sahValue.is_a?(Hash)))
416 next
417 end
418
419 if (hCheck[XML_SUB] == false)
420 cContainer.add_element(XML_SUB)
421 hCheck[XML_SUB] = true
422 end
423
424 # DefinitionRef補完
425 if (!sahValue.has_key?("DefinitionRef"))
426 sahValue["DefinitionRef"] = sParamName
427 end
428
429 # 再帰でサブコンテナを作成する
430 cContainer.elements[XML_SUB].add_element(YamlToXml_make_container(sParamName, sahValue, "#{sPath}/#{hParamInfo["DefinitionRef"]}"))
431 }
432 end
433
434 return cContainer
435end
436
437
438######################################################################
439# XML → YAML 実行機能
440######################################################################
441def XmlToYaml(sFirstFile, aExtraFile)
442 aExtraFile.unshift(sFirstFile)
443 aExtraFile.each{|sFileName|
444 # ファイルが存在しない場合エラー
445 if (!File.exist?(sFileName))
446 abort("Argument error !! [#{sFileName}]")
447 end
448
449 # 出力ファイル名作成
450 if (File.extname(sFileName) == ".arxml")
451 sYamlName = File.dirname(sFileName) + "/" + File.basename(sFileName, ".arxml") + ".yaml"
452 else
453 abort("not ARXML file !! [#{sFileName}]")
454 end
455
456 # XMLライブラリでの読み込み
457 cXmlData = REXML::Document.new(open(sFileName))
458
459 hResult = {}
460
461 cXmlData.elements.each("AUTOSAR/AR-PACKAGES/AR-PACKAGE"){|cElement1|
462 cElement1.elements.each("ELEMENTS/ECUC-MODULE-CONFIGURATION-VALUES"){|cElement2|
463 sPackageName = cElement1.elements["SHORT-NAME"].text()
464 if (!hResult.has_key?(sPackageName))
465 hResult[sPackageName] = {}
466 end
467
468 sModuleName = cElement2.elements["SHORT-NAME"].text()
469 hResult[sPackageName][sModuleName] = {}
470
471 cElement2.elements.each("CONTAINERS/ECUC-CONTAINER-VALUE"){|cElement3|
472 XmlToYaml_parse_parameter(cElement3, hResult[sPackageName][sModuleName])
473 }
474 }
475 }
476
477 # YAMLファイル出力
478 open(sYamlName, "w") do |io|
479 YAML.dump(hResult, io)
480 end
481
482 # YAML整形処理
483 # ・先頭の区切り文字削除
484 # ・コーテーションの削除
485 # ・配列のインデント整列
486 sFileData = File.read(sYamlName)
487 sFileData.gsub!(/^---$/, "")
488 sFileData.gsub!("'", "")
489 sFileData.gsub!(/^(\s+)-(\s.*)$/, "\\1 -\\2")
490 File.write(sYamlName, sFileData)
491
492 puts("Generated #{sYamlName}")
493 }
494end
495
496# コンテナパース関数
497def XmlToYaml_parse_parameter(cElement, hTarget)
498 sParamShortName = cElement.elements["SHORT-NAME"].text()
499 sParamDefName = cElement.elements["DEFINITION-REF"].text().split("/")[-1]
500 hTarget[sParamShortName] = {}
501 if (sParamShortName != sParamDefName)
502 hTarget[sParamShortName]["DefinitionRef"] = sParamDefName
503 end
504
505 # パラメータ
506 cElement.elements.each("PARAMETER-VALUES"){|cElementC|
507 ["ECUC-NUMERICAL-PARAM-VALUE", "ECUC-TEXTUAL-PARAM-VALUE"].each{|sParamValue|
508 cElementC.elements.each(sParamValue){|cElementG|
509 sName = cElementG.elements["DEFINITION-REF"].text().split("/")[-1]
510 sValue = cElementG.elements["VALUE"].text()
511 # 複数多重度対応
512 if (hTarget[sParamShortName].has_key?(sName))
513 if (hTarget[sParamShortName][sName].is_a?(Array))
514 # 既に複数ある場合は配列に追加
515 hTarget[sParamShortName][sName].push(sValue)
516 else
517 # 1つだけ定義されていた場合は配列に変更
518 sTemp = hTarget[sParamShortName][sName]
519 hTarget[sParamShortName][sName] = [sTemp, sValue]
520 end
521 else
522 hTarget[sParamShortName][sName] = sValue
523 end
524 }
525 }
526 }
527
528 # 参照,外部参照,選択参照
529 cElement.elements.each("REFERENCE-VALUES/ECUC-REFERENCE-VALUE"){|cElementC|
530 sName = cElementC.elements["DEFINITION-REF"].text().split("/")[-1]
531 if (cElementC.elements["VALUE-REF"].nil?)
532 abort("<VALUE> is not found in '#{sParamShortName}'")
533 end
534 sValue = cElementC.elements["VALUE-REF"].text()
535 # 複数多重度対応
536 if (hTarget[sParamShortName].has_key?(sName))
537 if (hTarget[sParamShortName][sName].is_a?(Array))
538 # 既に複数ある場合は配列に追加
539 hTarget[sParamShortName][sName].push(sValue)
540 else
541 # 1つだけ定義されていた場合は配列に変更
542 sTemp = hTarget[sParamShortName][sName]
543 hTarget[sParamShortName][sName] = [sTemp, sValue]
544 end
545 else
546 hTarget[sParamShortName][sName] = sValue
547 end
548 }
549
550 # インスタンス参照
551 cElement.elements.each("REFERENCE-VALUES/ECUC-INSTANCE-REFERENCE-VALUE"){|cElementC|
552 sName = cElementC.elements["DEFINITION-REF"].text().split("/")[-1]
553 hTarget[sParamShortName][sName] = []
554 hTarget[sParamShortName][sName].push({"CONTEXT-ELEMENT-REF" => cElementC.elements["VALUE-IREF"].elements["CONTEXT-ELEMENT-REF"].text()})
555 hTarget[sParamShortName][sName].push({"TARGET-REF" => cElementC.elements["VALUE-IREF"].elements["TARGET-REF"].text()})
556 }
557
558 # サブコンテナ(再帰呼出し)
559 cElement.elements.each("SUB-CONTAINERS/ECUC-CONTAINER-VALUE"){|cElementC|
560 XmlToYaml_parse_parameter(cElementC, hTarget[sParamShortName])
561 }
562end
563
564
565######################################################################
566# AUTOSARパラメータ情報ファイル作成
567######################################################################
568def MakeParamInfo(sFileName)
569 # ファイルが存在しない場合エラー
570 if (!File.exist?(sFileName))
571 abort("Argument error !! [#{sFileName}]")
572 end
573
574 sParamFileName = File.dirname(sFileName) + "/param_info.yaml"
575
576 # 読み込み対象モジュール
577 aTargetModule = ["Rte", "Os", "Com", "PduR", "CanIf", "Can", "EcuC", "EcuM", "WdgM", "WdgIf", "Wdg", "Dem"]
578
579 # XMLライブラリでの読み込み
580 cXmlData = REXML::Document.new(open(sFileName))
581
582 # 外部参照先のデータ型格納ハッシュ
583 $hForeignRefType = {}
584
585 # パース結果格納ハッシュ初期化(NCES仕様コンテナは予め設定)
586 sNcesContainer = <<-EOS
587ECUC-ENUMERATION-PARAM-DEF:
588 - OsViolationHandlingLevel
589 - OsTimingProtectionLevel
590 - OsMemoryProtectionLevel
591 - OsMemorySectionInitialize
592 - OsIsrInterruptSource
593 - OsInterCoreInterruptInterruptSource
594 - OsSpinlockLockMethod
595 - WdgTriggerMode
596 - WdgTimeoutReaction
597ECUC-INTEGER-PARAM-DEF:
598 - OsMasterCoreId
599 - OsHookStackSize
600 - OsHookStackStartAddress
601 - OsHookStackCoreAssignment
602 - OsOsStackSize
603 - OsOsStackStartAddress
604 - OsOsStackCoreAssignment
605 - OsNonTrustedHookStackSize
606 - OsNonTrustedHookStackStartAddress
607 - OsNonTrustedHookStackCoreAssignment
608 - OsTaskStackSize
609 - OsTaskStackStartAddress
610 - OsTaskSystemStackSize
611 - OsTaskSystemStackStartAddress
612 - OsIsrInterruptNumber
613 - OsIsrInterruptPriority
614 - OsIsrStackSize
615 - OsTrustedFunctionStackSize
616 - OsInterCoreInterruptStackSize
617 - OsInterCoreInterruptStackStartAddress
618 - OsMemoryRegionStartAddress
619 - OsMemoryRegionSize
620 - OsMemoryAreaSize
621 - OsStandardMemoryCoreAssignment
622 - OsIsrMaxFrequency
623 - WdgWindowOpenRate
624ECUC-STRING-PARAM-DEF:
625 - OsIncludeFileName
626 - OsMemoryRegionName
627 - OsMemoryAreaStartAddress
628 - OsMemorySectionName
629 - OsMemoryModuleName
630 - OsLinkSectionName
631 - OsIocPrimitiveDataType
632 - OsIocIncludeFile
633ECUC-BOOLEAN-PARAM-DEF:
634 - OsMemoryRegionWriteable
635 - OsMemoryAreaWritable
636 - OsMemoryAreaReadable
637 - OsMemoryAreaExecutable
638 - OsMemoryAreaCacheable
639 - OsMemoryAreaDevice
640 - OsMemorySectionWritable
641 - OsMemorySectionReadable
642 - OsMemorySectionExecutable
643 - OsMemorySectionShort
644 - OsMemorySectionCacheable
645 - OsMemorySectionDevice
646 - OsMemorySectionExport
647 - OsMemoryModuleExport
648 - OsTaskOsInterruptLockMonitor
649 - OsTaskResourceLockMonitor
650ECUC-REFERENCE-DEF:
651 - OsStandardMemoryRomRegionRef
652 - OsStandardMemoryRamRegionRef
653 - OsAppStandardMemoryRomRegionRef
654 - OsAppStandardMemoryRamRegionRef
655 - OsMemorySectionMemoryRegionRef
656 - OsLinkSectionMemoryRegionRef
657 - OsResourceLinkedResourceRef
658 - OsCounterIsrRef
659 - OsAppMemorySectionRef
660 - OsAppMemoryModuleRef
661 - OsAppMemoryAreaRef
662 - OsAppInterCoreInterruptRef
663 - OsInterCoreInterruptAccessingApplication
664 - OsInterCoreInterruptResourceRef
665 - WdgMOsCounterRef
666 - OsSystemCycleTimeWindowRef
667ECUC-FLOAT-PARAM-DEF:
668 - OsSystemCycleTime
669 - OsSystemCycleTimeWindowStart
670 - OsSystemCycleTimeWindowLength
671 - OsOsInterruptLockBudget
672 - OsResourceLockBudget
673 - WdgTimeout
674 - WdgTriggerInterruptPeriod
675EOS
676 $hResult = YAML.load(sNcesContainer)
677
678 cXmlData.elements.each("AUTOSAR/AR-PACKAGES/AR-PACKAGE/AR-PACKAGES/AR-PACKAGE/ELEMENTS/ECUC-MODULE-DEF"){|cElement1|
679 # 対象モジュールのみを処理する
680 if (!aTargetModule.include?(cElement1.elements["SHORT-NAME"].text()))
681 next
682 end
683
684 cElement1.elements.each("CONTAINERS/ECUC-PARAM-CONF-CONTAINER-DEF"){|cElement2|
685 MakeParamInfo_parse_parameter(cElement2)
686 }
687 }
688
689 # パラメータ名でソートと重複除去
690 hResultSort = {}
691 $hResult.each{|sType, aParam|
692 hResultSort[sType] = aParam.uniq().sort()
693 }
694
695 # 外部参照先のデータ型格納ハッシュを結合
696 if (!$hForeignRefType.empty?())
697 hResultSort[:FOREIGN_REF_TYPE] = $hForeignRefType
698 end
699
700 # RteSoftwareComponentInstanceRefは外部参照とインスタンス参照の
701 # 両方に含まれるが,外部参照として扱う
702 hResultSort["ECUC-INSTANCE-REFERENCE-DEF"].delete("RteSoftwareComponentInstanceRef")
703
704 # YAMLファイル出力
705 open(sParamFileName, "w") do |io|
706 YAML.dump(hResultSort, io)
707 end
708
709 puts("Generated #{sParamFileName}")
710end
711
712# サブコンテナ再帰パース関数
713def MakeParamInfo_parse_sub_container(cElement)
714 # "ECUC-PARAM-CONF-CONTAINER-DEF"が登場するまで再帰する
715 cElement.elements.each{|cElementC|
716 # CHOICEはさらにネストする
717 if (cElementC.name == "ECUC-CHOICE-CONTAINER-DEF")
718 MakeParamInfo_parse_sub_container(cElementC)
719 elsif (cElementC.name == "ECUC-PARAM-CONF-CONTAINER-DEF")
720 MakeParamInfo_parse_parameter(cElementC)
721 else
722 MakeParamInfo_parse_sub_container(cElementC)
723 end
724 }
725end
726
727# コンテナパース関数
728def MakeParamInfo_parse_parameter(cElement)
729 # パラメータ
730 cElement.elements.each("PARAMETERS"){|cElementC|
731 cElementC.elements.each{|cElementG|
732 # 初出のデータ型処理
733 if (!$hResult.has_key?(cElementG.name))
734 $hResult[cElementG.name] = []
735 end
736
737 # 取得したパラメータ名を格納する
738 $hResult[cElementG.name].push(cElementG.elements["SHORT-NAME"].text())
739 }
740 }
741
742 # 参照
743 cElement.elements.each("REFERENCES/ECUC-REFERENCE-DEF"){|cElementC|
744 $hResult["ECUC-REFERENCE-DEF"].push(cElementC.elements["SHORT-NAME"].text())
745 }
746
747 # 外部参照
748 cElement.elements.each("REFERENCES/ECUC-FOREIGN-REFERENCE-DEF"){|cElementC|
749 # 初出のデータ型処理
750 if (!$hResult.has_key?("ECUC-FOREIGN-REFERENCE-DEF"))
751 $hResult["ECUC-FOREIGN-REFERENCE-DEF"] = []
752 end
753 $hResult["ECUC-FOREIGN-REFERENCE-DEF"].push(cElementC.elements["SHORT-NAME"].text())
754 $hForeignRefType[cElementC.elements["SHORT-NAME"].text()] = cElementC.elements["DESTINATION-TYPE"].text()
755 }
756
757 # 選択参照
758 cElement.elements.each("REFERENCES/ECUC-CHOICE-REFERENCE-DEF"){|cElementC|
759 # 初出のデータ型処理
760 if (!$hResult.has_key?("ECUC-CHOICE-REFERENCE-DEF"))
761 $hResult["ECUC-CHOICE-REFERENCE-DEF"] = []
762 end
763 $hResult["ECUC-CHOICE-REFERENCE-DEF"].push(cElementC.elements["SHORT-NAME"].text())
764 }
765
766 # シンボル参照
767 cElement.elements.each("REFERENCES/ECUC-SYMBOLIC-NAME-REFERENCE-DEF"){|cElementC|
768 # 初出のデータ型処理
769 if (!$hResult.has_key?("ECUC-SYMBOLIC-NAME-REFERENCE-DEF"))
770 $hResult["ECUC-SYMBOLIC-NAME-REFERENCE-DEF"] = []
771 end
772 $hResult["ECUC-SYMBOLIC-NAME-REFERENCE-DEF"].push(cElementC.elements["SHORT-NAME"].text())
773 }
774
775 # インスタンス参照
776 cElement.elements.each("REFERENCES/ECUC-INSTANCE-REFERENCE-DEF"){|cElementC|
777 # 初出のデータ型処理
778 if (!$hResult.has_key?("ECUC-INSTANCE-REFERENCE-DEF"))
779 $hResult["ECUC-INSTANCE-REFERENCE-DEF"] = []
780 end
781 $hResult["ECUC-INSTANCE-REFERENCE-DEF"].push(cElementC.elements["SHORT-NAME"].text())
782 }
783
784 # サブコンテナ(再帰呼出し)
785 cElement.elements.each("SUB-CONTAINERS"){|cElementC|
786 MakeParamInfo_parse_sub_container(cElementC)
787 }
788end
789
790
791######################################################################
792# ジェネレータ用csvファイルの生成
793######################################################################
794def MakeCsv(sFileName, sTargetModule)
795 # ファイルが存在しない場合エラー
796 if (!File.exist?(sFileName))
797 abort("Argument error !! [#{sFileName}]")
798 end
799
800 sCsvFileName = File.dirname(sFileName) + "/" + sTargetModule + ".csv"
801
802 # XMLライブラリでの読み込み
803 cXmlData = REXML::Document.new(open(sFileName))
804
805 $hResult = {}
806 $sNowContainer = ""
807
808 cXmlData.elements.each("AUTOSAR/AR-PACKAGES/AR-PACKAGE/AR-PACKAGES/AR-PACKAGE/ELEMENTS/ECUC-MODULE-DEF"){|cElement1|
809 # 対象モジュールのみを処理する
810 if (cElement1.elements["SHORT-NAME"].text() != sTargetModule)
811 next
812 end
813
814 cElement1.elements.each("CONTAINERS/ECUC-PARAM-CONF-CONTAINER-DEF"){|cElement2|
815 $sContainer = cElement2.elements["SHORT-NAME"].text()
816 $hResult[$sContainer] = MakeCsv_add_parameter_info(cElement2, nil)
817 MakeCsv_parse_parameter(cElement2)
818 }
819 }
820
821 sModulePath = "/AUTOSAR/EcucDefs/#{sTargetModule}"
822 sCsvData = "#{sModulePath},,,1\n"
823
824 hDataTypeTable = {"ECUC-REFERENCE-DEF" => "REF",
825 "ECUC-FOREIGN-REFERENCE-DEF" => "REF",
826 "ECUC-CHOICE-REFERENCE-DEF" => "REF",
827 "ECUC-SYMBOLIC-NAME-REFERENCE-DEF" => "REF",
828 "ECUC-INSTANCE-REFERENCE-DEF" => "REF",
829 "ECUC-BOOLEAN-PARAM-DEF" => "BOOLEAN",
830 "ECUC-INTEGER-PARAM-DEF" => "INT",
831 "ECUC-FUNCTION-NAME-DEF" => "FUNCTION",
832 "ECUC-ENUMERATION-PARAM-DEF" => "ENUM",
833 "ECUC-STRING-PARAM-DEF" => "STRING",
834 "ECUC-FLOAT-PARAM-DEF" => "FLOAT",
835 "ECUC-LINKER-SYMBOL-DEF" => "STRING",
836 nil => ""}
837
838 $hResult.each{|sParam, aInfo|
839 if (!hDataTypeTable.has_key?(aInfo[0]))
840 abort("[#{__FILE__}] #{__LINE__}: #{aInfo[0]}")
841 end
842 if ((aInfo[1] == "1") && (aInfo[2] == "1"))
843 sCsvData += "#{sModulePath}/#{sParam},#{sParam.split("/")[-1]},#{hDataTypeTable[aInfo[0]]},1\n"
844 else
845 sCsvData += "#{sModulePath}/#{sParam},#{sParam.split("/")[-1]},#{hDataTypeTable[aInfo[0]]},#{aInfo[1]},#{aInfo[2]}\n"
846 end
847 }
848
849 File.open(sCsvFileName, "w") {|io|
850 io.puts(sCsvData)
851 }
852
853 puts("Generated #{sCsvFileName}")
854end
855
856# パラメータ情報追加関数
857def MakeCsv_add_parameter_info(cElement, sName = cElement.name)
858 # パラメータ毎に,型・多重度下限,上限の情報を取得
859 sLower = nil
860 if (!cElement.elements["LOWER-MULTIPLICITY"].nil?)
861 sLower = cElement.elements["LOWER-MULTIPLICITY"].text()
862 else
863 abort("[#{__FILE__}] #{__LINE__}")
864 end
865 sUpper = nil
866 if (!cElement.elements["UPPER-MULTIPLICITY"].nil?)
867 sUpper = cElement.elements["UPPER-MULTIPLICITY"].text()
868 elsif (!cElement.elements["UPPER-MULTIPLICITY-INFINITE"].nil? && (cElement.elements["UPPER-MULTIPLICITY-INFINITE"].text() == "true"))
869 sUpper = "*"
870 else
871 abort("[#{__FILE__}] #{__LINE__}")
872 end
873
874 return [sName, sLower, sUpper]
875end
876
877# サブコンテナ再帰パース関数
878def MakeCsv_parse_sub_container(cElement)
879 # "ECUC-PARAM-CONF-CONTAINER-DEF"が登場するまで再帰する
880 cElement.elements.each{|cElementC|
881 # CHOICEはさらにネストする
882 if (cElementC.name == "ECUC-CHOICE-CONTAINER-DEF")
883 $sContainer += "/#{cElementC.elements["SHORT-NAME"].text()}"
884 $hResult[$sContainer] = MakeCsv_add_parameter_info(cElementC, nil)
885 MakeCsv_parse_sub_container(cElementC)
886
887 aTemp = $sContainer.split("/")
888 aTemp.pop()
889 $sContainer = aTemp.join("/")
890 elsif (cElementC.name == "ECUC-PARAM-CONF-CONTAINER-DEF")
891 $sContainer += "/#{cElementC.elements["SHORT-NAME"].text()}"
892 $hResult[$sContainer] = MakeCsv_add_parameter_info(cElementC, nil)
893 MakeCsv_parse_parameter(cElementC)
894
895 aTemp = $sContainer.split("/")
896 aTemp.pop()
897 $sContainer = aTemp.join("/")
898 else
899 MakeCsv_parse_sub_container(cElementC)
900 end
901 }
902end
903
904# コンテナパース関数
905def MakeCsv_parse_parameter(cElement)
906 # パラメータ
907 cElement.elements.each("PARAMETERS"){|cElementC|
908 cElementC.elements.each{|cElementG|
909 sParamName = "#{$sContainer}/#{cElementG.elements["SHORT-NAME"].text()}"
910 $hResult[sParamName] = MakeCsv_add_parameter_info(cElementG)
911 }
912 }
913
914 # 参照
915 cElement.elements.each("REFERENCES/ECUC-REFERENCE-DEF"){|cElementC|
916 sParamName = "#{$sContainer}/#{cElementC.elements["SHORT-NAME"].text()}"
917 $hResult[sParamName] = MakeCsv_add_parameter_info(cElementC)
918 }
919
920 # 外部参照
921 cElement.elements.each("REFERENCES/ECUC-FOREIGN-REFERENCE-DEF"){|cElementC|
922 sParamName = "#{$sContainer}/#{cElementC.elements["SHORT-NAME"].text()}"
923 $hResult[sParamName] = MakeCsv_add_parameter_info(cElementC)
924 }
925
926 # 選択参照
927 cElement.elements.each("REFERENCES/ECUC-CHOICE-REFERENCE-DEF"){|cElementC|
928 sParamName = "#{$sContainer}/#{cElementC.elements["SHORT-NAME"].text()}"
929 $hResult[sParamName] = MakeCsv_add_parameter_info(cElementC)
930 }
931
932 # シンボルネーム参照
933 cElement.elements.each("REFERENCES/ECUC-SYMBOLIC-NAME-REFERENCE-DEF"){|cElementC|
934 sParamName = "#{$sContainer}/#{cElementC.elements["SHORT-NAME"].text()}"
935 $hResult[sParamName] = MakeCsv_add_parameter_info(cElementC)
936 }
937
938 # インスタンス参照
939 cElement.elements.each("REFERENCES/ECUC-INSTANCE-REFERENCE-DEF"){|cElementC|
940 sParamName = "#{$sContainer}/#{cElementC.elements["SHORT-NAME"].text()}"
941 $hResult[sParamName] = MakeCsv_add_parameter_info(cElementC)
942 }
943
944 # サブコンテナ(再帰呼出し)
945 cElement.elements.each("SUB-CONTAINERS"){|cElementC|
946 MakeCsv_parse_sub_container(cElementC)
947 }
948end
949
950
951######################################################################
952# オプション処理
953######################################################################
954lMode = :YamlToXml
955sEcuExtractRef = nil
956cOpt = OptionParser.new(banner="Usage: abrex.rb [options]... [yaml|xml files]...", 18)
957cOpt.version = VERSION
958sOptData = nil
959sBswName = nil
960cOpt.on("-i XML_FILE", "ARXML to YAML conversion") {|xVal|
961 sOptData = xVal
962 lMode = :XmlToYaml
963}
964cOpt.on("-p XML_FILE", "Generate 'param_info.yaml' from AUTOSAR Ecu Configuration Parameters file") {|xVal|
965 sOptData = xVal
966 lMode = :MakeParamInfo
967}
968cOpt.on("-c XML_FILE", "Generate '{BSW_NAME}.csv' from AUTOSAR Ecu Configuration Parameters file") {|xVal|
969 sOptData = xVal
970 lMode = :MakeCsv
971}
972cOpt.on("-b BSW_NAME", "set a BSW Module Name (for '-c' additional optipn)") {|xVal|
973 sBswName = xVal
974 lMode = :MakeCsv
975}
976cOpt.on("-e ECU-EXTRACT-REF", "set a ECU-EXTRACT-REF path if <ECUC-VALUE-COLLECTION> is needed") {|xVal|
977 sEcuExtractRef = xVal
978 lMode = :YamlToXml
979}
980cOpt.on("-v", "--version", "show version information"){
981 puts(cOpt.ver())
982 exit(1)
983}
984cOpt.on("-h", "--help", "show help (this)"){
985 puts(cOpt.help())
986 exit(1)
987}
988
989begin
990 aArgData = cOpt.parse(ARGV)
991rescue OptionParser::ParseError
992 puts(cOpt.help())
993 exit(1)
994end
995
996if (((lMode == :YamlToXml) && aArgData.empty?()) ||
997 ((lMode != :YamlToXml) && sOptData.nil?()))
998 puts(cOpt.help())
999 exit(1)
1000end
1001
1002if ((lMode == :MakeCsv) && sBswName.nil?())
1003 puts(cOpt.help())
1004 exit(1)
1005end
1006
1007
1008######################################################################
1009# オプションに従って各処理を実行
1010######################################################################
1011case lMode
1012 when :YamlToXml
1013 YamlToXml(aArgData, sEcuExtractRef)
1014 when :XmlToYaml
1015 XmlToYaml(sOptData, aArgData)
1016 when :MakeParamInfo
1017 MakeParamInfo(sOptData)
1018 when :MakeCsv
1019 MakeCsv(sOptData, sBswName)
1020end
Note: See TracBrowser for help on using the repository browser.