source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tecsgen/tecslib/plugin/ThroughPlugin.rb@ 374

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

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 15.3 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2014 by TOPPERS Project
7#--
8# 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
9# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
10# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
11# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13# スコード中に含まれていること.
14# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
16# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
17# の無保証規定を掲載すること.
18# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
19# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
20# と.
21# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22# 作権表示,この利用条件および下記の無保証規定を掲載すること.
23# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
24# 報告すること.
25# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
26# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
27# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
28# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
29# 免責すること.
30#
31# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
33# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
34# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
35# の責任を負わない.
36#
37# $Id$
38#++
39
40# mikan through plugin: namespace が考慮されていない
41
42#== スループラグインの共通の親クラス かつ (何もせず)スルーするセルを挿入するスループラグイン
43# スループラグインは ThroughPlugin の子クラスとして定義する
44class ThroughPlugin < Plugin
45#@cell_name:: Symbol 生成するセル名(複数セルを生成する場合、受け口側のセル)
46#@plugin_arg_str:: string through で指定された引数
47#@next_cell:: Cell 呼び口を結合するセル
48#@next_cell_port_name:: Symbol 呼び口を結合する受口の名前
49#@next_cell_port_subscript::Nil|Integer 呼び口を結合する受口の配列添数.受け口配列でない場合 nil
50#@signature:: Signature シグニチャ
51#@celltype:: Celltype 呼び先のセルのセルタイプ. through が連接する場合、最終的な呼び先のセルのセルタイプ
52#@entry_port_name::Symbol 生成するセルの受け口名 "eThroughEntry"
53#@call_port_name:: Symbol 生成するセルの呼び口名 "cCall"
54#@ct_name:: Symbol 生成するセルのセルタイプ名 "t#{self.class.name}_#{@signature.get_global_name}"
55#@plugin_arg_list:: Hash プラグイン引数をパースした結果のハッシュ変数
56#@caller_cell:: Cell 呼び元のセル.through プラグインが連接する場合では、最も呼び元のセル.($source$)
57# through プラグインが合流するケースでは、1つ目の呼び元セルのみ引数として与えられる
58# 従って TracePlugin の呼び元の判別に利用する場合は、異なる呼び元から呼ばれる可能性があることに注意しなくてはならない
59#@callee_cell:: Cell 呼び先のセル($destination$)
60#@plugin_arg_check_proc_tab:: [string => Proc] プラグイン引数名⇒チェック関数
61# 以下の変数は、initialize ではなく、後から設定される
62#@start_@region:: Region 始まりのリージョン: caller_cell のリージョンとは異なる可能性がある ($start_region$)
63#@end_region:: Region 終わりのリージョン: next_cell のリージョンとは異なる可能性がある ($end_region$)
64#@region:: Region @start_region と @end_region のいずれかで、cell を置くのが好ましいリージョン ($preferred_region$)
65#@through_type:: Symbol :THROUGH, :TO_THROUGH, :IN_THROUGH, :OUT_THROUGH のいずれか
66
67 # この Plugin が生成したセルタイプのリスト
68 @@generated_celltype = {}
69
70 #=== ThroughPlugin の初期化
71 # through が指定された時点で生成が行われる
72 # 初期化では、指定された引数を記録するに留める
73 #cell_name:: Symbol 生成すべきセル名(受口側)
74 #plugin_arg:: string through で指定された引数
75 #next_cell:: Cell 呼び口を接続するセル
76 #next_cell_port_name:: Symbol 呼び口を接続する受口の名前
77 #next_cell_port_subscript:: Nil|Integer 呼び口を接続する受口配列添数
78 #signature:: Signature シグニチャ
79 #celltype:: Celltype セルタイプ (呼び先のセルのセルタイプ)
80 #caller_cell:: Cell 呼び元のセル.@caller_cell の項を参照
81 def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
82 super()
83 @cell_name = cell_name # 生成すべきセル名(受け口側のセル名)
84 # この呼び先に別セルを生成する場合、この名前を接頭辞とすべき
85 @next_cell = next_cell # 呼び先のセル
86 @next_cell_port_name = next_cell_port_name
87 @next_cell_port_subscript = next_cell_port_subscript
88 @signature = signature
89 @entry_port_name = :"eThroughEntry"
90 @call_port_name = :"cCall"
91 @ct_name = :"t#{self.class.name}_#{@signature.get_global_name}"
92 @celltype = celltype
93 @plugin_arg_str = plugin_arg
94 @plugin_arg_list = {} # プラグイン引数をパースした結果のハッシュ変数
95 @caller_cell = caller_cell
96 Join.set_through_info self # 引数で渡らない(後から追加された)ものは set_through_info で設定される
97 print( "#{self.class.name}.new( '#{cell_name}', '#{plugin_arg}', '#{next_cell.get_name}', '#{next_cell_port_name}', #{celltype.get_name} )\n" )
98 end
99
100 #=== 情報を設定する
101 # 共有チャンネルの場合 caller_cell, next_cell のいずれの region でもないケースがある
102 # 後から追加したので initialize の引数ではなく、別メソッドで設定
103 # このメソッドは、オーバーライドしないでください
104 # Join と ThrougPlugin の間の連絡用で、今後とも引数が追加される可能性があるため
105 # このメソッドは V1.C.0.34 で位置が移動され、ThroughPlugin#initialize で呼び出される
106 def set_through_info( start_region, end_region, through_type, join, callee_cell, count )
107 @start_region = start_region
108 @end_region = end_region
109 @through_type = through_type
110 @join = join
111 @callee_cell = callee_cell
112 @count = count
113
114 # preferred_region の設定
115 case through_type
116 when :IN_THROUGH, :THROUGH
117 @region = end_region
118 when :OUT_THROUGH, :TO_THROUGH
119 @region = start_region
120 else
121 raise "Unknown through_type #{through_type}"
122 end
123 end
124
125 #=== セルの名前を得る
126 def get_cell_name
127 @cell_name
128 end
129
130 #=== NamespacePath を得る
131 # 生成するセルの namespace path を生成する
132 def get_cell_namespace_path
133# nsp = @region.get_namespace.get_namespace_path
134 nsp = @region.get_namespace_path
135 return nsp.append( @cell_name )
136 end
137
138 #=== 生成されたセルの受け口の名前を得る
139 def get_through_entry_port_name
140 @entry_port_name
141 end
142
143 #=== 生成されたセルの受け口配列添数を得る
144 def get_through_entry_port_subscript
145 @entry_port_subscript
146 end
147
148 #=== 宣言コードの生成
149 # typedef, signature, celltype など(cell 以外)のコードを生成
150 # 重複して生成してはならない(すでに生成されている場合は出力しないこと)
151 #file:: FILE 生成するファイル
152 def gen_plugin_decl_code( file )
153
154 # このセルタイプ(同じシグニチャ)は既に生成されているか?
155 if @@generated_celltype[ @ct_name ] == nil then
156 @@generated_celltype[ @ct_name ] = [ self ]
157 else
158 @@generated_celltype[ @ct_name ] << self
159 return
160 end
161
162 file2 = CFile.open( "#{$gen}/#{@ct_name}.cdl", "w" )
163
164 send_receive = []
165 if @signature != nil then
166 @signature.each_param{ |fd,param|
167 dir =param.get_direction
168 case dir
169 when :SEND, :RECEIVE
170 send_receive << [ dir, fd, param ]
171 end
172 }
173 end
174
175 file2.print <<EOT
176celltype #{@ct_name} {
177EOT
178
179 if send_receive.length > 0 then
180 file2.print " [ allocator(\n"
181 delim = ""
182 send_receive.each { |a|
183 file2.print "#{delim}\t#{a[1].get_name}.#{a[2].get_name}<=#{@call_port_name}.#{a[1].get_name}.#{a[2].get_name}"
184 delim = ",\n"
185 }
186 file2.print "\n )]\n"
187 end
188
189 file2.print <<EOT
190 entry #{@signature.get_namespace_path} #{@entry_port_name};
191 call #{@signature.get_namespace_path} #{@call_port_name};
192};
193EOT
194 file2.close
195
196 file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
197 end
198
199 #=== CDL ファイルの生成
200 #file:: FILE 生成するファイル
201 def gen_cdl_file( file )
202 gen_plugin_decl_code( file )
203 gen_through_cell_code( file )
204 end
205
206 #=== セルコードの生成
207 # through 指定により生じるセルコード(CDL)を生成する
208 #file:: FILE 生成するファイル
209 def gen_through_cell_code( file )
210
211 nest = @region.gen_region_str_pre file
212 nest_str = " " * nest
213
214 file.print <<EOT
215#{nest_str}cell #{@ct_name} #{@cell_name} {
216#{nest_str} #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name};
217#{nest_str}};
218EOT
219 @region.gen_region_str_post file
220
221 end
222
223 #=== 後ろのコードを生成
224 #プラグインの後ろのコード (CDL) を生成
225 #file:: File:
226 def self.gen_post_code( file )
227 # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
228 # file.print "/* '#{self.class.name}' post code */\n"
229 end
230
231 #=== 受け口関数の本体(C言語)を生成する
232 # 通常であれば、ジェネレータは受け口関数のテンプレートを生成する
233 # プラグインの場合、変更する必要のないセルタイプコードを生成する
234 #file:: FILE 出力先ファイル
235 #b_singleton:: bool true if singleton
236 #ct_name:: Symbol
237 #global_ct_name:: string
238 #sig_name:: string
239 #ep_name:: string
240 #func_name:: string
241 #func_global_name:: string
242 #func_type:: class derived from Type
243 def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
244
245 ret_type = func_type.get_type
246 b_ret_void = ret_type.is_void?
247
248 if ! b_ret_void then
249 file.print( " #{ret_type.get_type_str} retval;\n" )
250 end
251
252 if ! b_singleton then
253
254 file.print <<EOT
255 #{ct_name}_CB *p_cellcb;
256 if( VALID_IDX( idx ) ){
257 p_cellcb = #{global_ct_name}_GET_CELLCB(idx);
258 }else{
259 /* エラー処理コードをここに記述 */
260 }
261
262EOT
263 end
264
265 # p "celltype_name, sig_name, func_name, func_global_name"
266 # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
267
268 delim = ""
269 if ! b_ret_void then
270 file.print( " retval = " )
271 end
272
273 file.print( "#{@call_port_name}_#{func_name}(" )
274
275# if ( ! b_singleton ) then
276# file.print( " tecs_this" )
277# delim = ","
278# end
279
280 params.each{ |param|
281 file.printf( "#{delim} #{param.get_name}" )
282 delim = ","
283 }
284
285 file.print( " );\n" )
286
287 if ! b_ret_void then
288 file.print( " return retval;\n" )
289 end
290 end
291
292 #=== Through プラグインの引数の名前を置換する
293 def check_plugin_arg( ident, rhs )
294 rhs = subst_name rhs
295 super( ident, rhs )
296 end
297
298 #=== ThroughPlugin#名前の置換
299 # プラグインオプション引数内の文字列を置換する
300 # $source$ … 呼び元のセル名
301 # $destination$ … 呼び先のセル名
302 # $SOURCE$ … 呼び元のセル名 (リージョン名を '_' で連結した global_name)
303 # $DESTINATION$ … 呼び先のセル名 (リージョン名を '_' で連結した global_name)
304 # $next$ … 次のセル名
305 # 複数の through がつながっている場合、すぐ後ろに来るもの
306 # $NEXT$ … 次のセル名 (リージョン名を '_' で連結した global_name)
307 # 複数の through がつながっている場合、すぐ後ろに来るもの
308 # $start_region$ … $source$ のセルの存在する region (global_name)
309 # $end_region$ … $destination$ のセルの存在する region (global_name)
310 # $preferred_region$ … 適切な region (global_name), start_region または end_region
311 # $count$ … region 間の through の適用数
312 # $$ … $ に置換
313 def subst_name( str )
314 # セル名の置換
315 str = str.gsub( /(^|[^\$])\$source\$/, "\\1#{@caller_cell.get_name}" )
316 str = str.gsub( /(^|[^\$])\$destination\$/, "\\1#{@callee_cell.get_name}" )
317 str = str.gsub( /(^|[^\$])\$SOURCE\$/, "\\1#{@caller_cell.get_global_name}" )
318 str = str.gsub( /(^|[^\$])\$DESTINATION\$/, "\\1#{@callee_cell.get_global_name}" )
319 str = str.gsub( /(^|[^\$])\$next\$/, "\\1#{@next_cell.get_name}" )
320 str = str.gsub( /(^|[^\$])\$NEXT\$/, "\\1#{@next_cell.get_global_name}" )
321 # region 名の置換
322 str = str.gsub( /(^|[^\$])\$start_region\$/, "\\1#{@start_region.get_global_name}" )
323 str = str.gsub( /(^|[^\$])\$end_region\$/, "\\1#{@end_region.get_global_name}" )
324 str = str.gsub( /(^|[^\$])\$preferred_region\$/, "\\1#{@region.get_global_name}" )
325 str = str.gsub( /(^|[^\$])\$count\$/, "\\1#{@count}" )
326
327 str = str.gsub( /\$\$/, "\$" ) # $$ を $ に置換
328
329 return str
330 end
331
332 def show_tree( indent )
333 indent.times { print " " }
334 puts "Plugin: celltype: #{@ct_name} cell: #{@cell_name}"
335 (indent+1).times { print " " }
336 puts "next: signature: #{@signature.get_namespace_path} call = #{@next_cell.get_name}.#{@next_cell_port_name}"
337 end
338end
339
Note: See TracBrowser for help on using the repository browser.