source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPRPCPlugin.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.2 KB
Line 
1# coding: utf-8
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2018 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
40require_tecsgen_lib "lib/GenOpaqueMarshaler.rb"
41require_tecsgen_lib "lib/GenParamCopy.rb"
42
43#= HRPRPCPlugin プラグイン
44# スループラグイン (through)
45# ・OpaqueMarshalerPlugin を使用してマーシャラセルタイプを生成する
46# ・マーシャラ、TDR、チャンネル、メッセージバッファを生成する
47#
48class HRPRPCPlugin < ThroughPlugin
49
50 include GenOpaqueMarshaler
51 include GenParamCopy
52
53 # RPCPlugin 専用のオプション
54 HRPRPCPluginArgProc = RPCPluginArgProc.dup # 複製を作って元を変更しないようにする
55 HRPRPCPluginArgProc[ "noClientSemaphore" ] = Proc.new { |obj,rhs| obj.set_noClientSemaphore rhs }
56 HRPRPCPluginArgProc[ "semaphoreCelltype" ] = Proc.new { |obj,rhs| obj.set_semaphoreCelltype rhs }
57 @@isFirstInstance = true
58
59 #=== RPCPlugin の initialize
60 # 説明は ThroughPlugin (plugin.rb) を参照
61 def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
62 super
63 @b_noClientSemaphore = false
64 @semaphoreCelltype = "tSemaphore"
65 initialize_opaque_marshaler
66
67 # オプション:GenOpaqueMarshaler 参照
68 @plugin_arg_check_proc_tab = HRPRPCPluginArgProc
69 parse_plugin_arg
70
71 @rpc_channel_celltype_name = "tRPCPlugin_#{@TDRCelltype}_#{@channelCelltype}_#{@signature.get_name}"
72 @rpc_channel_celltype_file_name = "#{$gen}/#{@rpc_channel_celltype_name}.cdl"
73
74 if @signature.get_context == "non-task" then
75 cdl_error( "HRP9999 RPC cannot be applied to non-task context signature '$1'", @signature.get_name )
76 elsif @signature.get_context == "any" then
77 cdl_info( "HRP9999 RPC is applied to any context signature '$1'", @signature.get_name )
78 end
79
80 if @signature.need_PPAllocator?(true) then
81 if @PPAllocatorSize == nil then
82 cdl_error( "HRP9999 PPAllocatorSize must be speicified for pointer argments" )
83 # @PPAllocatorSize = 0 # 仮に 0 としておく (cdl の構文エラーを避けるため)
84 end
85 elsif @PPAllocatorSize then
86 cdl_warning( "HRP9999 PPAllocatorSize speicified in spite of PPAllocator unnecessary" )
87 @PPAllocatorSize = nil
88 end
89
90# @signature.each_param{ |func_decl, param_decl|
91# if func_decl.get_type.is_oneway? then
92# if ( param_decl.get_size || param_decl.get_count ) && param_decl.get_string then
93# cdl_error( "array of string not supported for oneway function in Transparent RPC" ) # mikan 文字列の配列
94# elsif param_decl.get_string == -1 then
95# cdl_error( "length unspecified string is not permited for oneway function in Transparent RPC" ) # mikan 長さ未指定文字列
96# end
97# end
98# }
99
100 #
101 # tecsgen/tecs/rpcにincludeパスを通す
102 # #include "tecs_rpc.h" を実現するために必要
103 # 大山:削除 Makefile.tecsgen に vpath, INCLUDES を入れるのは、よくない考え
104 # TECSGEN.add_search_path で Makefile_templ に入れるのがよい
105 # if @@isFirstInstance
106 # f = AppFile.open( "#{$gen}/Makefile.tecsgen" )
107 # f.puts "INCLUDES := $(INCLUDES) -I $(TECSPATH) -I $(TECSPATH)/rpc"
108 # f.puts "vpath %.c $(TECSPATH) $(TECSPATH)/rpc"
109 # f.close()
110 # @@isFirstInstance = false
111 # end
112 end
113
114 #=== plugin の宣言コード (celltype の定義) 生成
115 def gen_plugin_decl_code( file )
116
117 ct_name = "#{@ct_name}_#{@channelCelltype}"
118
119 # このセルタイプ(同じシグニチャ)は既に生成されているか?
120 if @@generated_celltype[ ct_name ] == nil then
121 @@generated_celltype[ ct_name ] = [ self ]
122 else
123 @@generated_celltype[ ct_name ] << self
124 return
125 end
126
127 f = CFile.open( @rpc_channel_celltype_file_name, "w" )
128 # 同じ内容を二度書く可能性あり (AppFile は不可)
129
130 f.print <<EOT
131import( <rpc.cdl> );
132import( <tMessageBufferCEP.cdl> );
133generate( OpaqueMarshalerPlugin, #{@signature.get_namespace_path}, "" );
134
135composite tOpaqueMarshaler_#{@signature.get_global_name}_through {
136 entry #{@signature.get_namespace_path} eThroughEntry;
137 call sTDR cTDR;
138 [optional]
139 call sSemaphore cLockChannel;
140 [optional]
141 call sRPCErrorHandler cErrorHandler;
142
143 cell tOpaqueMarshaler_#{@signature.get_global_name} Marshaler{
144 cTDR => composite.cTDR;
145 cLockChannel => composite.cLockChannel;
146 cErrorHandler => composite.cErrorHandler;
147 };
148 composite.eThroughEntry => Marshaler.eClientEntry;
149};
150
151EOT
152
153 f.close
154 end
155
156 #=== through cell コードを生成
157 #
158 #
159 def gen_through_cell_code( file )
160
161 gen_plugin_decl_code( file )
162 file.print <<EOT
163import( <#{@rpc_channel_celltype_file_name}> );
164EOT
165
166 case @start_region.get_domain_root.get_domain_type.get_kind
167 when :kernel
168 tacp_str = "\"TACP_KERNEL"
169 when :user
170 tacp_str = "\"TACP(#{@start_region.get_domain_root.get_name})"
171 when :OutOfDomain
172 tacp_str = "\"TACP_SHARED"
173 end
174 # p "end_region=#{@end_region.get_name} kind=#{@end_region.get_domain_root.get_domain_type.get_kind}"
175 case @end_region.get_domain_root.get_domain_type.get_kind
176 when :kernel
177 tacp_str += "|TACP_KERNEL\""
178 when :user
179 tacp_str += "|TACP(#{@end_region.get_domain_root.get_name})\""
180 when :OutOfDomain
181 tacp_str += "|TACP_SHARED\""
182 end
183 nest_str = ""
184 file.print <<EOT
185#{nest_str} // MessageBuffer client=>server
186#{nest_str} cell tMessageBuffer #{@clientChannelCell}Body0{
187#{nest_str} maxMessageSize = 64; /* This value must be same as MessageBufferCEP's buffer size */
188#{nest_str} bufferSize = 128;
189#{nest_str} accessPattern1 = C_EXP( #{tacp_str} );
190#{nest_str} accessPattern2 = C_EXP( #{tacp_str} );
191#{nest_str} accessPattern3 = C_EXP( #{tacp_str} );
192#{nest_str} accessPattern4 = C_EXP( #{tacp_str} );
193#{nest_str} };
194EOT
195 file.print <<EOT
196
197#{nest_str} // MessageBuffer server=>client
198#{nest_str} cell tMessageBuffer #{@clientChannelCell}Body1{
199#{nest_str} maxMessageSize = 64; /* This value must be same as MessageBufferCEP's buffer size */
200#{nest_str} bufferSize = 128;
201#{nest_str} accessPattern1 = C_EXP( #{tacp_str} );
202#{nest_str} accessPattern2 = C_EXP( #{tacp_str} );
203#{nest_str} accessPattern3 = C_EXP( #{tacp_str} );
204#{nest_str} accessPattern4 = C_EXP( #{tacp_str} );
205#{nest_str} };
206EOT
207
208 ##### クライアント側のセルの生成 #####
209 nest = @start_region.gen_region_str_pre file
210 nest_str = " " * nest
211
212 # セマフォの生成
213 if @b_noClientSemaphore == false then
214 file.print <<EOT
215#{nest_str} // Semaphore for Multi-task use ("specify noClientSemaphore" option to delete this)
216#{nest_str} cell #{@semaphoreCelltype} #{@serverChannelCell}_Semaphore{
217#{nest_str} initialCount = 1;
218#{nest_str} };
219EOT
220 end
221
222 # クライアント側チャンネル (tMessageBufferCEP)の生成
223 # チャンネルは必ずリージョン下にあるので、 '::' でつなぐ (でなければ、ルートリージョンにないかチェックが必要)
224
225 file.print <<EOT
226#{nest_str} // Client Side Channel
227#{nest_str} cell tMessageBufferCEP #{@clientChannelCell}_CEP{
228#{nest_str} cMessageBuffer0 = #{@clientChannelCell}Body0.eMessageBuffer;
229#{nest_str} cMessageBuffer1 = #{@clientChannelCell}Body1.eMessageBuffer;
230#{nest_str} };
231
232#{nest_str} // Client Side TDR
233#{nest_str} cell tTDR #{@clientChannelCell}_TDR{
234#{nest_str} cChannel = #{@clientChannelCell}_CEP.eChannel;
235#{nest_str} };
236
237#{nest_str} // Marshaler
238EOT
239
240 # セマフォの結合文
241 if @b_noClientSemaphore == false then
242 semaphore = "#{nest_str} cLockChannel = #{@serverChannelCell}_Semaphore.eSemaphore;\n"
243 else
244 semaphore = ""
245 end
246
247 ### クライアント側チャンネル (マーシャラ+TDR)の生成 ###
248 cell = @next_cell
249 # アロケータの指定があるか?
250 if cell.get_allocator_list.length > 0 then
251
252 file.print nest_str
253 file.print "[allocator("
254
255 delim = ""
256 cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc|
257
258 alloc_str = alloc.to_s
259 subst = @substituteAllocator[alloc_str.to_sym]
260 if subst then
261 alloc_str = subst[2]+"."+subst[3]
262 end
263
264 file.print delim
265 delim = ",\n" # 最終行には出さない
266
267 if subsc then # 配列添数
268 subsc_str = '[#{subsc}]'
269 else
270 subsc_str = ""
271 end
272
273 eport = "eThroughEntry" #RPCの受け口名に変更
274 file.print nest_str
275 file.print "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc_str}"
276 end
277
278 file.puts ")]"
279 end
280
281 if @clientErrorHandler then
282 clientErrorHandler_str = "#{nest_str} cErrorHandler = #{@clientErrorHandler};\n"
283 else
284 clientErrorHandler_str = ""
285 end
286
287 file.print <<EOT
288#{nest_str} cell tOpaqueMarshaler_#{@signature.get_global_name}_through #{@cell_name} {
289#{nest_str} cTDR = #{@clientChannelCell}_TDR.eTDR;
290#{clientErrorHandler_str}#{semaphore}#{nest_str} };
291EOT
292 ### END: クライアント側チャンネル (マーシャラ+TDR)の生成 ###
293 @start_region.gen_region_str_post file
294 file.print "\n\n"
295
296 ##### サーバー側のセルの生成 #####
297 nest = @end_region.gen_region_str_pre file
298 nest_str = " " * nest
299
300 if @serverErrorHandler then
301 serverErrorHandler_str = "#{nest_str} cErrorHandler = #{@serverErrorHandler};\n"
302 else
303 serverErrorHandler_str = ""
304 end
305
306 if @b_genOpener then
307 opener = "#{nest_str} cOpener = #{@serverChannelCell}.eOpener;\n"
308 else
309 opener = ""
310 end
311
312 # サーバー側チャンネル (tMessageBufferCEP)
313 if @PPAllocatorSize then
314 alloc_cell =<<EOT
315
316#{nest_str} cell tPPAllocator #{@serverChannelCell}_PPAllocator {
317#{nest_str} heapSize = #{@PPAllocatorSize};
318#{nest_str} };
319EOT
320 alloc_call_port_join = "#{nest_str} cPPAllocator = #{@serverChannelCell}_PPAllocator.ePPAllocator;\n"
321 else
322 alloc_cell = ""
323 alloc_call_port_join = ""
324 end
325
326 file.print <<EOT
327#{nest_str} // Server Side Channel
328#{nest_str} cell tMessageBufferCEP #{@serverChannelCell}_CEP{
329#{nest_str} cMessageBuffer0 = #{@clientChannelCell}Body1.eMessageBuffer;
330#{nest_str} cMessageBuffer1 = #{@clientChannelCell}Body0.eMessageBuffer;
331#{nest_str} };
332EOT
333
334 # サーバー側TDR
335 file.print <<EOT
336
337#{nest_str} // Server Side TDR
338#{nest_str} cell tTDR #{@serverChannelCell}_TDR{
339#{nest_str} cChannel = #{@serverChannelCell}_CEP.eChannel;
340#{nest_str} };
341EOT
342
343 if @next_cell_port_subscript then
344 subscript = '[' + @next_cell_port_subscript.to_s + ']'
345 else
346 subscript = ""
347 end
348
349 # サーバー側チャンネル (アンマーシャラ)
350 file.print <<EOT
351#{alloc_cell}
352#{nest_str} // Unmarshaler
353#{nest_str} cell tOpaqueUnmarshaler_#{@signature.get_global_name} #{@serverChannelCell}_Unmarshaler {
354#{nest_str} cTDR = #{@serverChannelCell}_TDR.eTDR;
355#{nest_str} cServerCall = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
356#{alloc_call_port_join}#{serverErrorHandler_str}#{nest_str} };
357EOT
358
359 # サーバー側タスクメイン
360 file.print <<EOT
361
362#{nest_str} // Unmarshaler Task Main
363#{nest_str} cell #{@taskMainCelltype} #{@serverChannelCell}_TaskMain {
364#{nest_str} cMain = #{@serverChannelCell}_Unmarshaler.eService;
365#{opener}#{nest_str} };
366EOT
367
368 # サーバー側タスク
369 file.print <<EOT
370
371#{nest_str} // Unmarshaler Task
372#{nest_str} cell #{@taskCelltype} #{@serverChannelCell}_Task {
373#{nest_str} cTaskBody = #{@serverChannelCell}_TaskMain.eMain;
374#{nest_str} priority = #{@taskPriority};
375#{nest_str} stackSize = #{@stackSize};
376#{nest_str} attribute = C_EXP( "TA_ACT" ); /* mikan : marshaler task starts at beginning */
377#{nest_str} };
378EOT
379 @end_region.gen_region_str_post file
380 end
381
382
383 #=== プラグイン引数 noClientSemaphore のチェック
384 def set_noClientSemaphore rhs
385 rhs = rhs.to_sym
386 if rhs == :true then
387 @b_noClientSemaphore = true
388 elsif rhs == :false then
389 @b_noClientSemaphore = false
390 else
391 cdl_error( "RPCPlugin: specify true or false for noClientSemaphore" )
392 end
393 end
394
395 #=== プラグイン引数 semaphoreCelltype のチェック
396 def set_semaphoreCelltype rhs
397 @semaphoreCelltype = rhs.to_sym
398 nsp = NamespacePath.analyze( @semaphoreCelltype.to_s )
399 obj = Namespace.find( nsp )
400 if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
401 cdl_error( "RPCPlugin: semaphoreCelltype '#{rhs}' not celltype or not defined" )
402 end
403 end
404
405 #=== NamespacePath を得る
406 # 生成するセルの namespace path を生成する
407 def get_cell_namespace_path
408# nsp = @region.get_namespace.get_namespace_path
409 nsp = @start_region.get_namespace_path
410 return nsp.append( @cell_name )
411 end
412
413end
414
415
Note: See TracBrowser for help on using the repository browser.