source: azure_iot_hub/trunk/asp3_dcre/cfg/pass2.rb@ 389

Last change on this file since 389 was 389, checked in by coas-nagasima, 5 years ago

ビルドが通るよう更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 14.3 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TOPPERS Configurator by Ruby
4#
5# Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
6# Copyright (C) 2015-2017 by Embedded and Real-Time Systems Laboratory
7# Graduate School of Information Science, Nagoya Univ., JAPAN
8#
9# 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
10# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
12# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14# スコード中に含まれていること.
15# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18# の無保証規定を掲載すること.
19# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
21# と.
22# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
23# 作権表示,この利用条件および下記の無保証規定を掲載すること.
24# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
25# 報告すること.
26# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
27# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
28# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
29# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
30# 免責すること.
31#
32# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
34# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
35# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
36# の責任を負わない.
37#
38# $Id$
39#
40
41#
42# パス2の処理
43#
44
45#
46# パス1の生成物の読み込み
47#
48module Cfg1Out
49 #
50 # Sレコードファイルからシンボルの値を取り出す
51 #
52 def self.GetSymbolValue(symbol, size, signed)
53 if @symbolAddress.has_key?(symbol)
54 return(@cfg1SRec.get_value(@symbolAddress[symbol], size, signed))
55 else
56 return(nil)
57 end
58 end
59
60 #
61 # パス1の生成物の読み込み(メインの処理)
62 #
63 def self.Read
64 # cfg1_out.symsの読み込み
65 @symbolAddress = ReadSymbolFile(CFG1_OUT_SYMS)
66
67 # cfg1_out.srecの読み込み
68 begin
69 @cfg1SRec = SRecord.new(CFG1_OUT_SREC)
70 rescue Errno::ENOENT, Errno::EACCES => ex
71 abort(ex.message)
72 end
73
74 # マジックナンバーの取得
75 if @symbolAddress.has_key?(CFG1_MAGIC_NUM)
76 $asmLabel = ""
77 $cfg1_prefix = CFG1_PREFIX
78 elsif @symbolAddress.has_key?("_" + CFG1_MAGIC_NUM)
79 $asmLabel = "_"
80 $cfg1_prefix = "_" + CFG1_PREFIX
81 else
82 error_exit("`#{CFG1_MAGIC_NUM}' is not found in `#{CFG1_OUT_SYMS}'")
83 end
84
85 magicNumberData = @cfg1SRec.get_data(@symbolAddress \
86 [$asmLabel + CFG1_MAGIC_NUM], 4)
87 if (magicNumberData == "12345678")
88 $endianLittle = false
89 elsif (magicNumberData == "78563412")
90 $endianLittle = true
91 else
92 error_exit("`#{CFG1_MAGIC_NUM}' is invalid in `#{CFG1_OUT_SREC}'")
93 end
94
95 # 固定出力した変数の取得
96 $sizeOfSigned = GetSymbolValue($asmLabel + CFG1_SIZEOF_SIGNED, 4, false)
97
98 # 値取得シンボルの取得
99 $symbolValueTable.each do |symbolName, symbolData|
100 symbol = $cfg1_prefix + symbolName
101 if symbolData.has_key?(:BOOL)
102 value = GetSymbolValue(symbol, $sizeOfSigned, true)
103 if !value.nil?
104 # C言語の真偽値をRubyの真偽値に変換して取り込む
105 symbolData[:VALUE] = (value != 0)
106 end
107 else
108 value = GetSymbolValue(symbol, $sizeOfSigned, \
109 symbolData.has_key?(:SIGNED))
110 if !value.nil?
111 symbolData[:VALUE] = value
112 end
113 end
114 end
115
116 #
117 # ハッシュの初期化
118 #
119 $cfgData = {}
120 @objidValues = {}
121 $apiDefinition.each do |apiName, apiDef|
122 if apiDef.has_key?(:API)
123 if !$cfgData.has_key?(apiDef[:API].to_sym)
124 $cfgData[apiDef[:API].to_sym] = {}
125 end
126 end
127 apiDef[:PARAM].each do |apiParam|
128 if apiParam.has_key?(:NAME) && apiParam.has_key?(:ID_DEF)
129 @objidValues[apiParam[:NAME]] = {}
130 end
131 end
132 end
133
134 #
135 # ドメイン生成データをコンフィギュレーションデータ($cfgData)に格納
136 #
137 $cfgData[:CRE_DOM] = {}
138 $domainId.each do |domainName, domainVal|
139 domid = NumStr.new(domainVal, domainName)
140 $cfgData[:CRE_DOM][domainVal] = { :domid => domid }
141 end
142
143 ReadPhase(nil)
144 end
145
146 #
147 # パラメータの値を取り出す
148 #
149 def self.GetParamValue(paramName, param, apiIndex, index, apiParam, cfgInfo)
150 if apiParam.has_key?(:ID_DEF) # オブジェクト識別名(定義)
151 value = @objidValues[paramName][param]
152 elsif apiParam.has_key?(:ID_REF) # オブジェクト識別名(参照)
153 if @objidValues[paramName].has_key?(param)
154 value = @objidValues[paramName][param]
155 else
156 apiDef = $apiDefinition[cfgInfo[:APINAME]]
157 error("#{apiDef.has_key?(:KEYPAR) ? "E_NOEXS" : "E_ID"}: " \
158 "`#{param}' in #{cfgInfo[:APINAME]} is not defined", \
159 "#{cfgInfo[:_FILE_]}:#{cfgInfo[:_LINE_]}:")
160 value = nil
161 end
162 elsif apiParam.has_key?(:EXPTYPE) # 整数定数式パラメータ
163 if apiIndex.nil?
164 if param.is_a?(NumStr)
165 return(param)
166 else
167 return(NumStr.new(param))
168 end
169 else
170 symbol = "#{$cfg1_prefix}valueof_#{paramName}_#{apiIndex}#{index}"
171 value = GetSymbolValue(symbol, $sizeOfSigned, \
172 apiParam.has_key?(:SIGNED))
173 end
174 else # 一般定数式/文字列パラメータ
175 return(param)
176 end
177 return(NumStr.new(value, param))
178 end
179
180 #
181 # 指定したフェーズのためのパス1の生成物の読み込み
182 #
183 def self.ReadPhase(phase)
184 #
185 # オブジェクトIDの割当て
186 #
187 # 割り当てたオブジェクトIDは,@objidValuesに保持する.@objidValuesは,
188 # 2重のハッシュ(ハッシュのハッシュ)である.
189 #
190 # 具体的には,@objidValuesは,オブジェクトIDのパラメータ名(例えば,セ
191 # マフォIDであれば"semid".これを保持する変数名は,objidParamNameとす
192 # る)をキーとし,そのオブジェクトIDの割当て表(これを保持する変数名
193 # は,objidListとする)を値とするハッシュである.オブジェクトIDの割当
194 # て表は,オブジェクト名(これを保持する変数名は,objNameとする)をキー
195 # とし,そのID番号(これを保持する変数名は,objidNumberとする)を値と
196 # するハッシュである.
197 #
198 # 例えば,セマフォSEM1のID番号が1の場合には,次のように設定される.
199 # @objidValues["semid"]["SEM1"] == 1
200 #
201
202 # ID番号割り当ての前処理
203 objidParamNameList = []
204 $cfgFileInfo.each do |cfgInfo|
205 # プリプロセッサディレクティブは読み飛ばす
206 next if cfgInfo.has_key?(:DIRECTIVE)
207
208 apiDef = $apiDefinition[cfgInfo[:APINAME]]
209 # 異なるフェーズの静的APIは読み飛ばす
210 next if apiDef[:PHASE] != phase
211
212 apiIndex = cfgInfo[:INDEX]
213 if !apiIndex.nil?
214 # シンボルファイルに静的APIのインデックスが存在しなければ読み飛
215 # ばす(ifdef等で消えた静的API)
216 symbol = "#{$cfg1_prefix}static_api_#{apiIndex}"
217 next unless @symbolAddress.has_key?(symbol)
218 end
219
220 apiDef[:PARAM].each do |apiParam|
221 if apiParam.has_key?(:NAME) && apiParam.has_key?(:ID_DEF)
222 objidParamName = apiParam[:NAME]
223 objName = cfgInfo[objidParamName]
224 if $inputObjid.has_key?(objName)
225 # ID番号入力ファイルに定義されていた場合
226 @objidValues[objidParamName][objName] = $inputObjid[objName]
227 else
228 @objidValues[objidParamName][objName] = nil
229 end
230 objidParamNameList.push(objidParamName)
231 end
232 end
233 end
234
235 # ID番号の割当て処理
236 objidParamNameList.each do |objidParamName|
237 objidList = @objidValues[objidParamName]
238
239 # 未使用のID番号のリスト(使用したものから消していく)
240 unusedObjidList = (1.upto(objidList.keys.size)).to_a
241
242 # 割り当て済みのID番号の処理
243 objidList.each do |objName, objidNumber|
244 if $inputObjid.has_key?(objName)
245 objidIndex = unusedObjidList.index($inputObjid[objName])
246 if objidIndex.nil?
247 # ID番号入力ファイルで指定された値が不正
248 error_exit("value of `#{objName}' in ID input file is illegal")
249 else
250 # 未使用のID番号のリストから削除
251 unusedObjidList.delete_at(objidIndex)
252 end
253 end
254 end
255
256 # ID番号の割当て
257 objidList.each do |objName, objidNumber|
258 if objidList[objName].nil?
259 # 以下で,@objidValuesを書き換えている
260 objidList[objName] = unusedObjidList.shift
261 end
262 end
263 end
264
265 #
266 # 静的APIデータをコンフィギュレーションデータ($cfgData)に格納
267 #
268 $cfgFileInfo.each do |cfgInfo|
269 # プリプロセッサディレクティブは読み飛ばす
270 next if cfgInfo.has_key?(:DIRECTIVE)
271
272 apiDef = $apiDefinition[cfgInfo[:APINAME]]
273 # 異なるフェーズの静的APIは読み飛ばす
274 next if apiDef[:PHASE] != phase
275
276 apiSym = apiDef[:API].to_sym
277 apiIndex = cfgInfo[:INDEX]
278 if !apiIndex.nil?
279 # シンボルファイルに静的APIのインデックスが存在しなければ読み飛
280 # ばす(ifdef等で消えた静的API)
281 symbol = "#{$cfg1_prefix}static_api_#{apiIndex}"
282 next unless @symbolAddress.has_key?(symbol)
283 end
284
285 # パラメータの値をハッシュ形式に格納
286 params = {}
287 apiDef[:PARAM].each do |apiParam|
288 next unless apiParam.has_key?(:NAME)
289 paramName = apiParam[:NAME]
290 next unless cfgInfo.has_key?(paramName) # パラメータがない場合
291 paramData = cfgInfo[paramName]
292
293 if apiParam.has_key?(:LIST)
294 params[paramName.to_sym] = []
295 paramData.each.with_index(1) do |param, index|
296 params[paramName.to_sym].push(GetParamValue(paramName, param, \
297 apiIndex, "_#{index}", apiParam, cfgInfo))
298 end
299 else
300 params[paramName.to_sym] = GetParamValue(paramName, paramData, \
301 apiIndex, "", apiParam, cfgInfo)
302 end
303 end
304
305 # ドメインIDを追加
306 if cfgInfo.has_key?(:DOMAIN)
307 domainName = cfgInfo[:DOMAIN]
308 params[:domain] = $domainId[domainName]
309 end
310
311 # クラスIDを追加
312 if cfgInfo.has_key?(:CLASS)
313 if apiIndex.nil?
314 params[:class] = cfgInfo[:CLASS]
315 else
316 symbol = "#{$cfg1_prefix}valueof_CLASS_#{apiIndex}"
317 value = GetSymbolValue(symbol, $sizeOfSigned, true)
318 params[:class] = NumStr.new(value, cfgInfo[:CLASS])
319 end
320 end
321
322 # API名,ファイル名,行番号を追加
323 params[:apiname] = cfgInfo[:APINAME]
324 params[:_file_] = cfgInfo[:_FILE_]
325 params[:_line_] = cfgInfo[:_LINE_]
326
327 # 登録キーを決定する
328 if apiDef.has_key?(:KEYPAR)
329 keyParam = params[apiDef[:KEYPAR].to_sym]
330 key = keyParam.val
331 if $cfgData[apiSym].has_key?(key)
332 # 登録キーの重複
333 error("E_OBJ: #{apiDef[:KEYPAR]} `#{keyParam}' " \
334 "is duplicated in #{cfgInfo[:APINAME]}",
335 "#{cfgInfo[:_FILE_]}:#{cfgInfo[:_LINE_]}:")
336 end
337 else
338 key = $cfgData[apiSym].count + 1
339 end
340 $cfgData[apiSym][key] = params
341 end
342 end
343
344 #
345 # ID番号出力ファイルの生成
346 #
347 def self.OutputId(fileName)
348 idOutputFile = GenFile.new(fileName)
349 @objidValues.each do |objidParamName, objidList|
350 objidList.each do |objName, objidNumber|
351 idOutputFile.add("#{objName} #{objidNumber}")
352 end
353 end
354 end
355end
356
357#
358# パス2の処理
359#
360def Pass2
361 #
362 # パス1から引き渡される情報をファイルから読み込む
363 #
364 db = PStore.new(CFG1_OUT_DB)
365 db.transaction(true) do
366 $apiDefinition = db[:apiDefinition]
367 $symbolValueTable = db[:symbolValueTable]
368 $cfgFileInfo = db[:cfgFileInfo]
369 $includeFiles = db[:includeFiles]
370 $domainId = db[:domainId]
371 end
372 $cfg2Data = {}
373
374 #
375 # パス1の生成物を読み込む
376 #
377 Cfg1Out.Read()
378 abort if $errorFlag # エラー発生時はabortする
379
380 #
381 # 値取得シンボルをグローバル変数として定義する
382 #
383 DefineSymbolValue()
384
385 #
386 # 生成スクリプト(trbファイル)を実行する
387 #
388 $trbFileNames.each do |trbFileName|
389 if /^(.+):(\w+)$/ =~ trbFileName
390 trbFileName = $1
391 Cfg1Out.ReadPhase($2.to_sym)
392 end
393 IncludeTrb(trbFileName)
394 end
395
396 #
397 # ID番号出力ファイルの生成
398 #
399 if !$idOutputFileName.nil?
400 Cfg1Out.OutputId($idOutputFileName)
401 end
402
403 #
404 # パス3に引き渡す情報をファイルに生成
405 #
406 if $omitOutputDb.nil?
407 db = PStore.new(CFG2_OUT_DB)
408 db.transaction do
409 db[:apiDefinition] = $apiDefinition
410 db[:symbolValueTable] = $symbolValueTable
411 db[:cfgFileInfo] = $cfgFileInfo
412 db[:includeFiles] = $includeFiles
413 db[:cfgData] = $cfgData
414 db[:asmLabel] = $asmLabel
415 db[:endianLittle] = $endianLittle
416 db[:cfg2Data] = $cfg2Data
417 end
418 end
419end
Note: See TracBrowser for help on using the repository browser.