source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tecsgen/tecslib/plugin/TracePlugin.rb@ 352

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

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 17.0 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
40class TracePlugin < ThroughPlugin
41#@cellEntry_list::[ "Cell.eEntry", "Cell2.eEntry2", ... ]
42#@b_generate::bool : true : TracePlugin を生成する必要がある
43
44 #=== TracePlugin の initialize
45 # 説明は ThroughPlugin (plugin.rb) を参照
46 def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell )
47
48 @maxArrayDisplay = 16
49 @cellEntry_list = []
50 @probeName = ""
51 @b_generate = false
52 @b_displayTime = false
53 @kernelCelltype = :"tKernel"
54 @syslogCelltype = :"tSysLog"
55
56 super
57 @plugin_arg_check_proc_tab = TracePluginArgProc
58 parse_plugin_arg
59
60 if @cellEntry_list.length > 0 then
61 @cellEntry_list.each{ |ce|
62 if "#{next_cell.get_name}.#{next_cell_port_name}".to_sym == ce.to_sym
63 @b_generate = true
64 end
65 }
66 else
67 @b_generate = true
68 end
69
70 if @b_generate == false then
71 # 元々呼び出すセルに結合するものとする
72 @entry_port_name = next_cell_port_name
73 @cell_name = next_cell.get_name
74 end
75 end
76
77 #=== 宣言コードの生成
78 # typedef, signature, celltype など(cell 以外)のコードを生成
79 # 重複して生成してはならない(すでに生成されている場合は出力しないこと)
80 #file:: FILE 生成するファイル
81 def gen_plugin_decl_code( file )
82
83 # このセルタイプ(同じシグニチャ)は既に生成されているか?
84 if @@generated_celltype[ @ct_name ] == nil then
85 @@generated_celltype[ @ct_name ] = [ self ]
86 else
87 @@generated_celltype[ @ct_name ] << self
88 return
89 end
90
91 file2 = CFile.open( "#{$gen}/#{@ct_name}.cdl", "w" )
92
93 send_receive = []
94 if @signature != nil then
95 @signature.each_param{ |fd,param|
96 dir =param.get_direction
97 case dir
98 when :SEND, :RECEIVE
99 send_receive << [ dir, fd, param ]
100 end
101 }
102 end
103
104 file2.print <<EOT
105celltype #{@ct_name} {
106EOT
107
108 if send_receive.length > 0 then
109 file2.print " [ allocator(\n"
110 delim = ""
111 send_receive.each { |a|
112 file2.print "#{delim}\t#{a[1].get_name}.#{a[2].get_name}<=#{@call_port_name}.#{a[1].get_name}.#{a[2].get_name}"
113 delim = ",\n"
114 }
115 file2.print "\n )]\n"
116 end
117
118 file2.print <<EOT
119 entry #{@signature.get_namespace_path} #{@entry_port_name};
120 call #{@signature.get_namespace_path} #{@call_port_name};
121 attr{
122 char_t *probeName_str = "";
123 char_t *from_str = "";
124 };
125 require #{@syslogCelltype}.eSysLog;
126 require #{@kernelCelltype}.eKernel;
127};
128EOT
129# char_t *cell_port_name_str = "";
130
131 file2.close
132
133 file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
134 end
135
136 def gen_through_cell_code( file )
137
138 gen_plugin_decl_code( file )
139
140 if @b_generate != false then
141 nest = @region.gen_region_str_pre file
142 indent_str = " " * nest
143
144 if @probeName then
145 probeName_str = "#{indent_str} probeName_str = \"" + @probeName + ": \";\n"
146 else
147 probeName_str = ""
148 end
149 if @caller_cell then
150 caller_cell_str = "#{indent_str} from_str = \"#{@caller_cell.get_name}\";\n"
151 else
152 caller_cell_str = ""
153 end
154
155 file.print <<EOT
156#{indent_str}cell #{@ct_name} #{@cell_name} {
157#{indent_str} #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name};
158#{probeName_str}#{caller_cell_str}#{indent_str}};
159EOT
160# cell_port_name_str = \"#{@next_cell.get_name}.#{@next_cell_port_name}\";
161 @region.gen_region_str_post file
162 end
163
164 end
165
166 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 )
167
168 if ! func_type.get_type.is_void? then
169 file.print( "\t#{func_type.get_type_str}\tretval;\n" )
170 end
171
172 file.print( "\tSYSUTM\tutime;\n" )
173
174 if ! b_singleton then
175
176 file.print <<EOT
177\t#{ct_name}_CB *p_cellcb;
178\tif( VALID_IDX( idx ) ){
179\t\tp_cellcb = #{global_ct_name}_GET_CELLCB(idx);
180\t}else{
181\t\t/* put code here for error */
182\t}
183
184EOT
185 end
186
187# p "celltype_name, sig_name, func_name, func_global_name"
188# p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
189
190
191 file.print <<EOT
192\tgetMicroTime( &utime );
193\tsyslog( LOG_INFO, \"Enter: %sTime=%d: #{@next_cell.get_name}.#{@next_cell_port_name}.#{func_name} calledFrom: %s\", ATTR_probeName_str, utime, ATTR_from_str );
194EOT
195
196 print_params( params, file, 0, :IN )
197
198 delim = ""
199 if ! func_type.get_type.is_void? then
200 file.print( "\tretval = " )
201 else
202 file.print( "\t" )
203 end
204
205 file.print( "#{@call_port_name}_#{func_name}(" )
206
207 params.each{ |param|
208 file.printf( "#{delim} #{param.get_name}" )
209 delim = ","
210 }
211 file.print( " );\n" )
212
213 file.print <<EOT
214\tgetMicroTime( &utime );
215\tsyslog( LOG_INFO, \"Leave: %sTime=%d: #{@next_cell.get_name}.#{@next_cell_port_name}.#{func_name}\", ATTR_probeName_str, utime );
216EOT
217
218 print_params( params, file, 0, :OUT )
219
220 if( ! func_type.get_type.is_void? ) then
221 print_param( "retval", func_type.get_type, file, 0, :RETURN, func_type.get_type.get_type_str, nil, nil)
222 file.print( "\treturn retval;\n" )
223 end
224
225 end
226
227 def print_params( params, file, nest, direction )
228 params.each{ |param|
229 dir = param.get_direction
230 if( direction == :IN )then
231 case dir
232 when :IN, :INOUT, :SEND
233 print_param( param.get_name, param.get_type, file, nest, dir, param.get_type.get_type_str, nil, nil )
234 end
235 else
236 case dir
237 when :OUT, :INOUT
238 print_param( param.get_name, param.get_type, file, nest, dir, param.get_type.get_type_str, nil, nil )
239 when :RECEIVE
240 outer = "*"
241 outer2 = nil
242 print_param( param.get_name, param.get_type.get_referto, file, nest, dir,
243 param.get_type.get_referto.get_type_str, outer, outer2 )
244 end
245 end
246 }
247 end
248
249 def print_param( name, type, file, nest, direction, type_str, outer, outer2, name_list = nil )
250 indent = " " * ( nest + 1 )
251
252 case type
253 when DefinedType
254 print_param( name, type.get_type, file, nest, direction, type_str, outer, outer2, name_list )
255 when VoidType
256 when BoolType
257 file.print( "#{indent}syslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %d;\", #{outer}#{name}#{outer2} );\n" )
258 when IntType
259 file.print <<EOT
260#{indent}if( sizeof(#{outer}#{name}#{outer2}) > sizeof(int_t) )
261#{indent}\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %ld;\", (long)#{outer}#{name}#{outer2} );
262#{indent}else
263#{indent}\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %d;\", #{outer}#{name}#{outer2} );
264EOT
265# file.print( "#{indent}syslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %ld;\", (long)#{outer}#{name}#{outer2} );\n" )
266 when FloatType
267 file.print( "#{indent}syslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %g;\", (double)#{outer}#{name}#{outer2} );\n" )
268 when EnumType # mikan EnumType
269
270 when StructType
271 members_decl =type.get_members_decl
272 if outer || outer2
273 outer = "(#{outer}#{name}#{outer2})."
274 else
275 outer = "#{name}."
276 end
277 members_decl.get_items.each { |m|
278 print_param( m.get_name, m.get_type, file, nest, direction, m.get_type.get_type_str, outer, nil, members_decl )
279 }
280 when FuncType # mikan FuncType
281 when ArrayType # mikan ArrayType
282 when PtrType
283
284 se = type.get_size
285 ce = type.get_count
286 max_loop = @maxArrayDisplay
287 loop_count = nil
288
289 if se then
290 loop_count = "(((#{se.to_str( name_list, outer, outer2 )})>#{max_loop}) ? #{max_loop} : (#{se.to_str( name_list, outer, outer2 )}))"
291 file.print( "#{indent}syslog( LOG_INFO, \"#{indent}size_is(#{se.to_str( name_list, outer, outer2 )})=%d\", #{se.to_str( name_list, outer, outer2 )} );\n" )
292 size = "#{se.to_str( name_list, outer, outer2 )}"
293 elsif ce then
294 loop_count = "(((#{ce.to_str( name_list, outer, outer2 )})>#{max_loop}) ? #{max_loop} : (#{ce.to_str( name_list, outer, outer2 )})) "
295 file.print( "#{indent}syslog( LOG_INFO, \"#{indent}count_is(#{ce.to_str( name_list, outer, outer2 )})=%d\", #{ce.to_str( name_list, outer, outer2 )} );\n" )
296 size = "#{ce.to_str( name_list, outer, outer2 )}"
297 end
298
299 # mikan PtrType: string
300
301 referto = type.get_referto
302 type0 = type
303 type = referto
304 type_str = type.get_type_str
305 if type.kind_of?( DefinedType ) then
306 type = type.get_original_type
307 end
308
309 if type0.is_nullable? then
310 nest += 1
311 indent0 = indent
312 outer0 = outer
313 outer20 = outer2
314 indent += " "
315 file.print"#{indent0}if( #{outer}#{name}#{outer2} ){\n"
316 end
317
318 if loop_count == nil then
319 case type
320 when StructType
321 members = type.get_members_decl
322 if outer || outer2
323 outer = "(#{outer}#{name}#{outer2})->"
324 else
325 outer = "#{name}->"
326 end
327 outer2 = nil
328 members.get_items.each { |m|
329 print_param( m.get_name, m.get_type, file, nest, direction, m.get_type.get_type_str, outer, outer2, members )
330 }
331 when FuncType # mikan FuncType
332 when ArrayType # mikan ArrayType
333 when BoolType, IntType, FloatType, EnumType, PtrType
334 outer = "*#{outer}"
335 outer2 = "#{outer2}"
336 print_param( name, type, file, nest, direction, type_str, outer, outer2 )
337 end
338 else # loop_count != nil
339 if type.kind_of?( PtrType ) || type.kind_of?( StructType ) then
340 num_per_loop = 1
341 else
342 num_per_loop = 4
343 end
344
345 file.print <<EOT
346#{indent}{
347#{indent}\tint i__#{nest}, loop_count__ = #{loop_count};
348#{indent}\tfor( i__#{nest} = 0; i__#{nest} < loop_count__; i__#{nest}+=#{num_per_loop} ){
349EOT
350
351 case type
352 when StructType
353 members = type.get_members_decl
354 if outer || outer2
355 outer = "(#{outer}#{name}#{outer2})[i__#{nest}]."
356 else
357 outer = "#{name}[i__#{nest}]."
358 end
359 members.get_items.each { |m|
360 print_param( m.get_name, m.get_type, file, nest + 1, direction, m.get_type.get_type_str, outer, nil, members )
361 }
362 when FuncType # mikan FuncType
363 when ArrayType # mikan ArrayType
364
365 when BoolType, FloatType
366 if outer || outer2
367 outer = "(#{outer}"
368 outer2 = "#{outer2})"
369 end
370
371 file.print <<EOT
372#{indent}\t\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{name}[%d]: %d %d %d %d\",
373#{indent}\t\t\t\ti__#{nest}, #{outer}#{name}#{outer2}[i__#{nest}], #{outer}#{name}#{outer2}[i__#{nest}+1], #{outer}#{name}#{outer2}[i__#{nest}+2], #{outer}#{name}#{outer2}[i__#{nest}+3] );
374EOT
375 when IntType
376 if outer || outer2
377 outer = "(#{outer}"
378 outer2 = "#{outer2})"
379 end
380
381 file.print <<EOT
382#{indent}\t\tif( sizeof(#{outer}#{name}#{outer2}) > sizeof(int_t) )
383#{indent}\t\t\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{name}[%d]: %02x %02x %02x %02x\",
384#{indent}\t\t\t\t\ti__#{nest}, #{outer}#{name}#{outer2}[i__#{nest}], #{outer}#{name}#{outer2}[i__#{nest}+1], #{outer}#{name}#{outer2}[i__#{nest}+2], #{outer}#{name}#{outer2}[i__#{nest}+3] );
385#{indent}\t\telse
386#{indent}\t\t\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{name}[%d]: %02lx %02lx %02lx %02lx\",
387#{indent}\t\t\t\t\ti__#{nest}, #{outer}#{name}#{outer2}[i__#{nest}], #{outer}#{name}#{outer2}[i__#{nest}+1], #{outer}#{name}#{outer2}[i__#{nest}+2], #{outer}#{name}#{outer2}[i__#{nest}+3] );
388EOT
389
390 when PtrType
391 # type = type.get_referto
392 if outer || outer2
393 outer = "(#{outer}"
394 outer2 = "#{outer2})[i__#{nest}]"
395 else
396 outer = ""
397 outer2 = "[i__#{nest}]"
398 end
399 print_param( name, type, file, nest + 1, direction, type_str, outer, outer2 )
400 end
401
402 file.print <<EOT
403#{indent}\t} /* for ( i__#{nest} ) */
404#{indent}\tif( i__#{nest} < #{size} )
405#{indent}\t\tsyslog( LOG_INFO, \"#{indent}(%d elements are omitted)\", #{size} - i__#{nest} );
406#{indent}\telse if( i__#{nest} > #{size} )
407#{indent}\t\tsyslog( LOG_INFO, \"#{indent}(last %d elements are void)\", i__#{nest} - #{size} );
408#{indent}}
409EOT
410 end # loop_count == nil
411
412 if type0.is_nullable? then
413 file.print <<EOT
414#{indent0}} else {
415#{indent0} syslog( LOG_INFO, \"#{indent0}[#{direction}]#{outer0}#{name}#{outer20} = NULL\" );
416#{indent0}}
417EOT
418 end
419 end
420 end
421
422 # プラグイン引数名と Proc
423 TracePluginArgProc = {
424 "maxArrayDisplay" => Proc.new { |obj,rhs| obj.set_maxArrayDisplay rhs },
425 "cellEntry" => Proc.new { |obj,rhs| obj.set_cellEntry rhs },
426 "probeName" => Proc.new { |obj,rhs| obj.set_probeName rhs },
427 "displayTime" => Proc.new { |obj,rhs| obj.set_displayTime rhs },
428 "kernelCelltype" => Proc.new { |obj,rhs| obj.set_kernelCelltype rhs },
429 "syslogCelltype" => Proc.new { |obj,rhs| obj.set_syslogCelltype rhs },
430 }
431
432 def set_maxArrayDisplay rhs
433 @maxArrayDisplay = rhs
434 end
435
436 def set_cellEntry rhs
437 ces = rhs.to_s.split /\s*,\s*/
438 ces.each{ |ce|
439 if ce =~ /^[A-Za-z_]\w*\.[A-Za-z_]\w*$/ then
440 # OK
441 else
442 cdl_error( "#{ce}: TracePlugin arg not in \"symbol.symbol\" form" )
443 end
444 }
445 @cellEntry_list.concat ces
446 end
447
448 def set_probeName rhs
449 @probeName = rhs.to_s
450 end
451
452 def set_displayTime rhs
453 if rhs.to_s == "true"
454 @b_diplayTime = true
455 elsif rhs.to_s == "false"
456 @b_diplayTime = false
457 else
458 cdl_error( "displayTime : #{rhs} unsuitable: specify true or false" )
459 end
460 end
461
462 #=== プラグイン引数 tKernel のチェック
463 def set_kernelCelltype( rhs )
464 @kernelCelltype = rhs.to_sym
465 nsp = NamespacePath.analyze( @kernelCelltype.to_s )
466 obj = Namespace.find( nsp )
467 if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
468 cdl_error( "TracePlugin: kernelCelltype '#{rhs}' not celltype or not defined" )
469 end
470 end
471
472 #=== プラグイン引数 tSyslog のチェック
473 def set_syslogCelltype( rhs )
474 @syslogCelltype = rhs.to_sym
475 nsp = NamespacePath.analyze( @syslogCelltype.to_s )
476 obj = Namespace.find( nsp )
477 if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
478 cdl_error( "TracePlugin: syslogCelltype '#{rhs}' not celltype or not defined" )
479 end
480 end
481
482end
483
484
Note: See TracBrowser for help on using the repository browser.