source: EcnlProtoTool/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2SVCPlugin.rb@ 321

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

文字コードを設定

  • 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#++
38
39# mikan through plugin: namespace が考慮されていない
40# これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必要がある
41# tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl
42
43# 以下を仮定(制限事項)
44# 呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
45# 有符号、無符号でサイズが同じ
46
47class SVCManage
48 # TODO: デフォルトの拡張サービスコール分を予約しておく
49 # デフォルトの拡張サービスコール(syslogなど)もコンポーネント化するまで
50 @@id = 20
51 @@func_ids = {}
52 def self.get_func_id func_name
53 return @@func_ids[ func_name ]
54 end
55 def self.set_func_id func_name
56 @@func_ids[ func_name ] = self.assign_id
57 puts @@func_ids[ func_name ]
58 end
59 def self.include_func_id? func_name
60 return @@func_ids.has_key?( func_name )
61 end
62 def self.get_id
63 return @@id
64 end
65 def self.set_id id
66 @@id = id
67 end
68 def self.assign_id
69 @@id += 1
70 return @@id
71 end
72end
73
74#
75# 拡張サービスコールを用いたドメイン間通信の
76# throughプラグイン
77# HRP2ドメインプラグインによって挿入される
78#
79class HRP2SVCPlugin < ThroughPlugin
80
81 #=== RPCPlugin の initialize
82 # 説明は ThroughPlugin (plugin.rb) を参照
83 @@generated_celltype_header = {}
84
85 def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell )
86 super
87 @ct_name_body = "#{@ct_name}SVCBody_#{@next_cell.get_name}_#{@next_cell_port_name}".to_sym
88 @ct_name = "#{@ct_name}SVCCaller_#{@next_cell.get_name}_#{@next_cell_port_name}".to_sym
89 @cell_name_body = "#{@cell_name}SVCBody".to_sym
90 @cell_name = "#{@cell_name}SVCCaller".to_sym
91 puts "%%%% "
92 p @next_cell.get_name
93 p @caller_cell.get_name
94 end
95
96 #=== NamespacePath を得る
97 # 生成するセルの namespace path を生成する
98 def get_cell_namespace_path
99# nsp = @region.get_namespace.get_namespace_path
100 nsp = @start_region.get_namespace_path
101 return nsp.append( @cell_name )
102 end
103
104 def gen_plugin_decl_code( file )
105
106 # このセルタイプ(同じシグニチャ)は既に生成されているか?
107 if !HRP2KernelObjectPlugin.include_celltype?(@next_cell.get_celltype)
108 if @@generated_celltype[ @ct_name_body ] == nil then
109 @@generated_celltype[ @ct_name_body ] = [ self ]
110 file2 = CFile.open( "#{$gen}/#{@ct_name_body}.cdl", "w" )
111 file2.print <<EOT
112[active]
113celltype #{@ct_name_body} {
114 call #{@signature.get_name} #{@call_port_name};
115};
116EOT
117 file2.close
118 else
119 @@generated_celltype[ @ct_name_body ] << self
120 end
121 file.print "import( \"#{$gen}/#{@ct_name_body}.cdl\" );\n"
122 end
123
124 # このセルタイプ(同じシグニチャ)は既に生成されているか?
125 if @@generated_celltype[ @ct_name ] == nil then
126 @@generated_celltype[ @ct_name ] = [ self ]
127 file2 = CFile.open( "#{$gen}/#{@ct_name}.cdl", "w" )
128 if !HRP2KernelObjectPlugin.include_celltype?(@next_cell.get_celltype)
129 file2.print <<EOT
130celltype #{@ct_name} {
131 entry #{@signature.get_name} #{@entry_port_name};
132};
133EOT
134 else
135 # TODO inlineにした方が効率がよいが,tecsgenの生成したヘッダファイルの
136 # 読込順のためにエラーとなる
137 file2.print <<EOT
138celltype #{@ct_name} {
139 //[inline] entry #{@signature.get_name} #{@entry_port_name};
140 entry #{@signature.get_name} #{@entry_port_name};
141 call #{@signature.get_name} #{@call_port_name};
142};
143EOT
144 end
145
146 file2.close
147 else
148 @@generated_celltype[ @ct_name ] << self
149 end
150 file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
151
152=begin
153 # TODO: send. receive 対応
154 send_receive = []
155 if @signature != nil then
156 @signature.each_param{ |fd,param|
157 dir =param.get_direction
158 case dir
159 when :SEND, :RECEIVE
160 send_receive << [ dir, fd, param ]
161 end
162 }
163 end
164=end
165
166=begin
167composite #{@ct_name} {
168 entry #{@signature.get_name} #{@entry_port_name};
169 call #{@signature.get_name} #{@call_port_name};
170
171 cell #{@ct_name}Client #{@cell_name}Client{
172 };
173
174 [active]
175 cell #{@ct_name}Server #{@cell_name}Server{
176 #{@call_port_name} => composite.#{@call_port_name};
177 };
178
179 composite.#{@entry_port_name} => #{@cell_name}.#{@entry_port_name};
180};
181=end
182
183 end
184
185 #=== through cell コードを生成
186 #
187 #
188 def gen_through_cell_code( file )
189 #require "HRP2Cache"
190
191 gen_plugin_decl_code( file )
192
193 if !HRP2KernelObjectPlugin.include_celltype?(@next_cell.get_celltype)
194 # セルを探す
195 # path =["::",@next_cell.get_name] # mikan namespace
196 # cell = Namespace.find( path )
197 # cell = Namespace.find( @next_cell.get_namespace_path )
198
199 ##### クライアント側のセルの生成 #####
200 # file.print "[domain(HRP2, \"trusted\")]"
201 nest = @start_region.gen_region_str_pre file
202 nest_str = " " * nest
203
204 # クライアント側チャンネルの生成
205 # 拡張サービスコール呼出し
206 file.print <<EOT
207#{nest_str} // Client Side Channel
208#{nest_str} cell #{@ct_name} #{@cell_name}{
209#{nest_str} };
210
211EOT
212
213 @start_region.gen_region_str_post file
214 file.print "\n\n"
215
216 ##### サーバー側のセルの生成 #####
217 nest = @end_region.gen_region_str_pre file
218 nest_str = " " * nest
219
220 # サーバー側チャンネルの生成
221 # 拡張サービスコール本体
222 file.print <<EOT
223
224#{nest_str} // Server Side Channel
225#{nest_str} cell #{@ct_name_body} #{@cell_name_body}{
226#{nest_str} #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name};
227#{nest_str} };
228EOT
229
230 @end_region.gen_region_str_post file
231
232 file2 = AppFile.open( "#{$gen}/tecsgen.cfg" )
233 file2.print "\n/* Generated by HRP2SVCPlugin */\n\n"
234 file2.print <<EOT
235#include "#{@ct_name_body}_factory.h"
236EOT
237 file2.close
238 else
239
240 ##### クライアント側のセルの生成 #####
241 nest = @start_region.gen_region_str_pre file
242 nest_str = " " * nest
243
244 # クライアント側チャンネルの生成
245 # 拡張サービスコール呼出し
246 file.print <<EOT
247#{nest_str} // Client Side Channel
248#{nest_str} cell #{@ct_name} #{@cell_name}{
249#{nest_str} #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name};
250#{nest_str} };
251
252EOT
253
254 @start_region.gen_region_str_post file
255 file.print "\n\n"
256
257 end
258 end
259
260 #=== 受け口関数の本体(C言語)を生成する
261 # 通常であれば、ジェネレータは受け口関数のテンプレートを生成する
262 # プラグインの場合、変更する必要のないセルタイプコードを生成する
263 #file:: FILE 出力先ファイル
264 #b_singleton:: bool true if singleton
265 #ct_name:: Symbol
266 #global_ct_name:: string
267 #sig_name:: string
268 #ep_name:: string
269 #func_name:: string
270 #func_global_name:: string
271 #func_type:: class derived from Type
272 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 )
273 puts "generate ep_func for #{ct_name}"
274
275 if !HRP2KernelObjectPlugin.include_celltype?(@next_cell.get_celltype)
276 # 拡張サービスコール呼出し
277 if ! func_type.get_type.kind_of?( VoidType ) then
278 file.print( " #{func_type.get_type_str} retval;\n" )
279 end
280
281 if ! b_singleton then
282
283 file.print <<EOT
284 #{ct_name}_CB *p_cellcb;
285 if( VALID_IDX( idx ) ){
286 p_cellcb = #{global_ct_name}_GET_CELLCB(idx);
287 }else{
288 /* エラー処理コードをここに記述 */
289 }
290
291EOT
292 end
293
294 # p "celltype_name, sig_name, func_name, func_global_name"
295 # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
296
297 delim = ""
298 if ! func_type.get_type.kind_of?( VoidType ) then
299 file.print( " retval = (#{func_type.get_type_str})" )
300 else
301 file.print( " " )
302 end
303
304 #file.print( "#{@call_port_name}_#{func_name}(" )
305 # svcid = SVCManage.assign_id
306 new_func = false
307 if SVCManage.include_func_id?( "#{@ct_name_body}_#{func_name}" ) == false
308 new_func = true
309 SVCManage.set_func_id( "#{@ct_name_body}_#{func_name}" )
310 end
311 svcid = SVCManage.get_func_id( "#{@ct_name_body}_#{func_name}" )
312 #file.print( "cal_svc( #{@ct_name_body}_#{func_name}" )
313 file.print( "cal_svc( #{svcid.to_s}" )
314
315 # if ( ! b_singleton ) then
316 # file.print( " tecs_this" )
317 # delim = ","
318 # end
319
320 i = 0
321 params.each{ |param|
322 delim = ","
323 file.printf( "#{delim} #{param.get_name}" )
324 i += 1
325 }
326
327 while(i < 5) do
328 delim = ","
329 file.printf( "#{delim} 0" )
330 i += 1
331 end
332
333 file.print( " );\n" )
334
335 if ! func_type.get_type.kind_of?( VoidType ) then
336 file.print( " return retval;\n" )
337 end
338
339 # 拡張サービスコール本体
340 if new_func
341 file2 = AppFile.open( "#{$gen}/#{@ct_name_body}.c" )
342
343# if @@generated_celltype_header[ @ct_name_body ].nil?
344# @@generated_celltype_header[ @ct_name_body ] = true
345# p @@generated_celltype_header[ @ct_name_body ]
346# file2.print <<EOT
347# /*
348# * このファイルは tecsgen により自動生成されました
349# * このファイルを編集して使用することは、意図されていません
350# */
351# /* #[<PREAMBLE>]#
352# * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
353# * tecsmerge によるマージに使用されます
354# *
355# * #[</PREAMBLE>]# */
356#
357# /* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
358# #include "#{@ct_name_body}_tecsgen.h"
359#
360# #ifndef E_OK
361# #define E_OK 0 /* success */
362# #define E_ID (-18) /* illegal ID */
363# #endif
364#
365# EOT
366# end
367
368 if func_type.get_type.kind_of?( VoidType ) then
369 retval_assign = ""
370 retval_return = ""
371 else
372 retval_assign = "retval = (ER_UINT)"
373 retval_return = "retval"
374 end
375
376 file2.print <<EOT
377ER_UINT
378#{@ct_name_body}_#{func_name}(intptr_t par1, intptr_t par2, intptr_t par3, intptr_t par4, intptr_t par5, ID cdmid)
379{
380 #{@ct_name_body}_CB *p_cellcb;
381#if 0
382 if( VALID_IDX( idx ) ){
383 p_cellcb = #{@ct_name_body}_GET_CELLCB(idx);
384 }else{
385 /* エラー処理コードをここに記述 */
386 }
387#else
388 p_cellcb = NULL;
389#endif
390
391 ER_UINT retval = 0;
392
393EOT
394
395 num = 1
396 params.each{ |param|
397 if param.get_declarator.get_ptr_level > 0 then
398 if param.get_direction == :IN then
399 file2.print <<EOT
400 if(prb_mem((void *)par#{num.to_s}, sizeof(#{param.get_type.get_type_str}), TSK_SELF, TPM_READ) != E_OK){
401 return E_MACV;
402 }
403EOT
404
405 elsif param.get_direction == :OUT then
406 file2.print <<EOT
407 if(prb_mem((void *)par#{num.to_s}, sizeof(#{param.get_type.get_type_str}), TSK_SELF, TPM_WRITE) != E_OK){
408 return E_MACV;
409 }
410EOT
411
412 end
413 end
414 num += 1
415 }
416
417 file2.print" #{retval_assign}#{@call_port_name}_#{func_name}("
418
419 delim = ""
420 num = 1
421 params.each{ |param|
422 file2.print "#{delim}"
423 delim = ", "
424 file2.print "(#{param.get_type.get_type_str})"
425 file2.print "par" + num.to_s
426 file2.print param.get_type.get_type_str_post
427 num += 1
428 }
429
430 file2.print ");\n"
431
432 if !func_type.get_type.kind_of?( VoidType ) then
433 file2.print "\n return #{retval_return};\n"
434 end
435 file2.print "}\n\n"
436
437 file2.close
438
439 file2 = AppFile.open( "#{$gen}/tecsgen.cfg" )
440 file2.print "\n/* Generated by HRP2SVCPlugin */\n\n"
441 # TODO: スタックサイズは適当
442 file2.print <<EOT
443KERNEL_DOMAIN{
444 DEF_SVC( #{svcid.to_s}, { TA_NULL, #{@ct_name_body}_#{func_name}, 256 } );
445}
446EOT
447 file2.close
448
449 file2 = AppFile.open( "#{$gen}/#{@ct_name_body}_factory.h" )
450 file2.print "\n/* Generated by HRP2SVCPlugin */\n\n"
451 file2.print <<EOT
452extern ER_UINT #{@ct_name_body}_#{func_name}(intptr_t par1, intptr_t par2, intptr_t par3, intptr_t par4, intptr_t par5, ID cdmid);
453EOT
454 file2.close
455 end
456 else
457 # カーネルドメインのセルは特別なことは何もせず,普通に呼び出す
458 super
459 end
460 end
461end
462
463
Note: See TracBrowser for help on using the repository browser.