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