source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tecsgen/tecslib/plugin/SharedOpaqueRPCPlugin.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: 13.1 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
40require_tecsgen_lib "lib/GenOpaqueMarshaler.rb"
41require_tecsgen_lib "lib/GenParamCopy.rb"
42
43#= SharedOpaqueRPC プラグイン
44# SharedOpaqueRPC チャンネルを生成する
45# プラグイン引数は GenTransparentMarshaler 参照
46
47# mikan through plugin: namespace が考慮されていない
48# これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必要がある
49# tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl
50
51# 以下を仮定(制限事項)
52# 呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
53# 有符号、無符号でサイズが同じ
54
55class SharedOpaqueRPCPlugin < ThroughPlugin
56
57 # チャンネルを共有するプラグインオブジェクトへのハッシュリスト
58 @@shared_channel_list = {} # { chan_name => [ Plugin_obj0, Plugin_Obj1, ... ] }
59
60 attr_reader :cell_name, :start_region, :end_region
61 include GenOpaqueMarshaler
62 include GenParamCopy
63
64 # SharedOpaqueRPCPlugin 専用のオプション
65 SharedOpaqueRPCPluginArgProc = RPCPluginArgProc.dup # 複製を作って元を変更しないようにする
66 SharedOpaqueRPCPluginArgProc[ "sharedChannelName" ] = Proc.new { |obj,rhs| obj.set_sharedChannelName rhs }
67
68 #=== RPCPlugin の initialize
69 # 説明は ThroughPlugin (plugin.rb) を参照
70 def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
71 super
72 initialize_opaque_marshaler
73 @entry_port_name = :"eClientEntry" # Marshaler の受け口名 (through セルの入り口)
74
75 # オプション:GenOpaqueMarshaler 参照
76 @plugin_arg_check_proc_tab = SharedOpaqueRPCPluginArgProc
77 @sharedChannelName = nil
78 parse_plugin_arg
79 check_opener_code
80 check_PPAllocator
81
82 @shared_channel_ct_name = :"tSharedOpaqueRPCPluginChannel_tTDR"
83 @shared_channel_server_ct_name = :"#{@shared_channel_ct_name}_Server"
84 @shared_channel_client_ct_name = :"#{@shared_channel_ct_name}_Client"
85 @shared_channel_ct_file_name = "#{$gen}/#{@shared_channel_ct_name}.cdl"
86 if @sharedChannelName == nil then
87 cdl_error( "'sharedChannelName' option: mandatory")
88 else
89 @shared_channel_cell = @sharedChannelName
90 end
91
92 if @@shared_channel_list[ @shared_channel_cell ] == nil then
93 @@shared_channel_list[ @shared_channel_cell ] = [ self ]
94 else
95 @@shared_channel_list[ @shared_channel_cell ] << self
96 end
97 @sub_channel_no = ( @@shared_channel_list[ @shared_channel_cell ].length ) -1
98
99 prev_start = @@shared_channel_list[ @shared_channel_cell ][0].start_region
100 if @start_region != prev_start then
101 # 初出と start リージョン不一致 (初出は、自分自身とチェックされる。無駄だが小さいので放置)
102 cdl_error( "SharedRPCPlugin: start region mismatch current: #{@region.get_name} previous: #{prev_start.get_name}")
103 end
104
105 prev_end = @@shared_channel_list[ @shared_channel_cell ][0].end_region
106 if @end_region != prev_end then
107 # 初出と end リージョン不一致 (初出は、自分自身とチェックされる。無駄だが小さいので放置)
108 cdl_error( "SharedRPCPlugin: end region mismatch current: #{@region.get_name} previous: #{prev_end.get_name}")
109 end
110
111 end
112
113 # def set_through_info( start_region, end_region, through_type )
114 # super
115 # end
116
117 #=== プラグイン引数 sharedChannelCell のチェック
118 def set_sharedChannelName( rhs )
119 @sharedChannelName = rhs
120 # path = [ "::", rhs ]
121 # obj = Namespace.find( path )
122 # if ! obj.instance_of?( Cell ) then
123 # cdl_error( "SharedOpaqueRPCPlugin: sharedChannelName '#{rhs}' not cell" )
124 # end
125 end
126
127 def gen_plugin_decl_code( file )
128
129 # このセルタイプ(同じシグニチャ)は既に生成されているか?
130 if @@generated_celltype[ @shared_channel_server_ct_name ] == nil then
131 @@generated_celltype[ @shared_channel_server_ct_name ] = [ self ]
132 else
133 @@generated_celltype[ @shared_channel_server_ct_name ] << self
134 end
135
136 gen_marshaler_celltype
137
138 # 同じ内容を二度書く可能性あり (AppFile は不可)
139
140 if @PPAllocatorSize then
141 alloc_call_port = " call sPPAllocator cPPAllocator;\n"
142 alloc_call_port_join = " cPPAllocator => composite.cPPAllocator;\n"
143 else
144 alloc_call_port = ""
145 alloc_call_port_join = ""
146 end
147
148 f = CFile.open( @shared_channel_ct_file_name, "w" )
149 # 同じ内容を二度書く可能性あり (AppFile は不可)
150
151 f.print <<EOT
152
153/* Shared Channel Celltype for Client */
154composite #{@shared_channel_client_ct_name} {
155 entry sTDR eTDR;
156 entry sSemaphore eSemaphore[];
157 call sChannel cClientChannel;
158
159 cell tTDR TDR {
160 cChannel => composite.cClientChannel;
161 };
162 cell tSemaphore Semaphore {
163 count = 1;
164 attribute = C_EXP("TA_NULL");
165 };
166 cell tRPCSharedChannelMan SharedChannelMan{
167 cSemaphore = Semaphore.eSemaphore;
168 cClientSideTDR = TDR.eTDR;
169 };
170 composite.eSemaphore => SharedChannelMan.eSemaphore;
171 composite.eTDR => TDR.eTDR;
172};
173
174/* Shared Channel Celltype for Server */
175[active]
176composite #{@shared_channel_server_ct_name} {
177 entry sTDR eTDR;
178 call sChannel cServerChannel;
179 call sUnmarshalerMain cUnmarshalAndCallFunction[];
180 call sServerChannelOpener cOpener;
181 attr {
182 PRI priority;
183 };
184
185 cell tTDR TDR {
186 cChannel => composite.cServerChannel;
187 };
188 cell tRPCSharedTaskMainWithOpener RPCSharedTaskMain {
189 cUnmarshalAndCallFunction => composite.cUnmarshalAndCallFunction;
190 cServerSideTDR = TDR.eTDR;
191 cOpener => composite.cOpener;
192 };
193 cell tTask Task {
194 cBody = RPCSharedTaskMain.eMain;
195 taskAttribute = C_EXP("TA_ACT");
196 stackSize = 4096;
197 priority = composite.priority;
198 };
199 composite.eTDR => TDR.eTDR;
200};
201
202EOT
203 f.close
204
205 end
206
207 #=== through cell コードを生成
208 #
209 #
210 def gen_through_cell_code( file )
211
212 gen_plugin_decl_code( file )
213
214 file.print <<EOT
215
216import( "#{@marshaler_celltype_file_name}" );
217import( "#{@shared_channel_ct_file_name}" );
218EOT
219
220# nest = @caller_cell.get_region.gen_region_str_pre file
221 nest = @start_region.gen_region_str_pre file
222 indent_str = " " * nest
223 nest_str = " " * nest
224 if @next_cell_port_subscript then
225 subscript = '[' + @next_cell_port_subscript.to_s + ']'
226 else
227 subscript = ""
228 end
229
230 # セルを探す
231 # path =["::",@next_cell.get_name]
232 # cell = Namespace.find( path )
233 cell = Namespace.find( @next_cell.get_namespace_path )
234
235 # 共有される通信チャンネルの生成のプロトタイプ宣言
236 file.print <<EOT
237#{indent_str}cell #{@shared_channel_client_ct_name} #{@shared_channel_cell};
238EOT
239
240 # マーシャラセルの生成(アロケータコードの生成から)
241 # アロケータの指定があるか?
242 if cell.get_allocator_list.length > 0 then
243
244 file.print "#{indent_str}[allocator("
245
246 delim = ""
247 cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc|
248
249 alloc_str = alloc.to_s
250 subst = @substituteAllocator[alloc_str.to_sym]
251
252 if subst then
253 alloc_str = subst[2]+"."+subst[3]
254 end
255
256 file.print delim
257 delim = ",\n#{indent_str} " # 最終行には出さない
258
259 if subsc then # 配列添数
260 subsc_str = '[#{subsc}]'
261 else
262 subsc_str = ""
263 end
264
265 eport = @entry_port_name #RPCの受け口名に変更
266 file.print "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc_str}"
267 end
268
269 file.puts ")]"
270 end
271
272 # マーシャラセル本体生成
273 file.print <<EOT
274/* OpaqueRPC Marshaler Cell */
275#{indent_str}cell #{@marshaler_celltype_name} #{@cell_name} {
276#{indent_str} cTDR = #{@shared_channel_cell}.eTDR;
277#{indent_str} cLockChannel = #{@shared_channel_cell}.eSemaphore[#{@sub_channel_no}];
278#{indent_str}};
279EOT
280 # @caller_cell.get_region.gen_region_str_post file
281 @start_region.gen_region_str_post file
282
283 # アンマーシャラセルの出力
284 # セル本体の生成
285 nest = @end_region.gen_region_str_pre file
286
287 file.print <<EOT
288/* Server Channel Cell prototype */
289#{indent_str}cell #{@shared_channel_server_ct_name} #{@sharedChannelName}_Server;
290
291EOT
292
293 # PPAllocator が必要か?
294 if @PPAllocatorSize then
295 if @sub_channel_no == 0 then
296 file.print <<EOT
297#{indent_str}cell tPPAllocator PPAllocator_#{@shared_channel_cell}{
298#{indent_str} heapSize = #{@PPAllocatorSize};
299#{indent_str}};
300EOT
301 end
302
303 ppallocator_join = "#{indent_str} cPPAllocator = PPAllocator_#{@shared_channel_cell}.ePPAllocator;\n"
304 else
305 ppallocator_join = ""
306 end
307
308 file.print <<EOT
309#{indent_str}cell #{@unmarshaler_celltype_name} #{@cell_name}_Server {
310#{indent_str} cTDR = #{@shared_channel_cell}_Server.eTDR;
311#{indent_str} cServerCall = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
312#{ppallocator_join}#{indent_str}};
313EOT
314 @end_region.gen_region_str_post file
315
316 end
317
318 #=== post コード(CDL) を生成
319 # プラグインの後のコードを生成
320 #file:: File:
321 def self.gen_post_code( file )
322
323 file.print "/* '#{self.name}' post code */\n"
324
325 @@shared_channel_list.each{ |chan_name,plugin_obj_array|
326 file.print "/* '#{chan_name}' shared channel */\n"
327 plugin_obj_array[0].gen_post_code( file, plugin_obj_array )
328 }
329
330 end
331
332 #=== post コード(CDL) を生成
333 # 共有チャンネルを生成する
334 # このメソッドは、チャンネルを共有する最初のプラグインオブジェクトのみ呼び出される
335 def gen_post_code( file, plugin_obj_array )
336
337 # 共有されている通信チャンネルの生成
338 # 各プラグインインスタンスでは @shared_channel_ct_name として記憶している
339 # region = @caller_cell.get_region
340 nest = @start_region.gen_region_str_pre file
341 indent_str = " " * nest
342 file.print <<EOT
343#{indent_str}cell #{@shared_channel_client_ct_name} #{@sharedChannelName} {
344#{indent_str} cClientChannel = #{@clientChannelCell}.eC0;
345#{indent_str}};
346EOT
347 @start_region.gen_region_str_post file
348
349 nest = @end_region.gen_region_str_pre file
350 indent_str = " " * nest
351 file.print "#{indent_str}cell #{@shared_channel_server_ct_name} #{@sharedChannelName}_Server {\n"
352 file.print <<EOT
353#{indent_str} cServerChannel = #{@serverChannelCell}.eC1;
354#{indent_str} cOpener = #{@serverChannelCell}.eOpener;
355EOT
356 plugin_obj_array.each{ |po|
357 file.print <<EOT
358#{indent_str} cUnmarshalAndCallFunction[] = #{po.cell_name}_Server.eService;
359EOT
360 }
361 file.printf <<EOT
362#{indent_str} priority = #{@taskPriority};
363#{indent_str}};
364EOT
365 @end_region.gen_region_str_post file
366
367 end
368end
369
370
Note: See TracBrowser for help on using the repository browser.