source: azure_iot_hub/trunk/asp3_dcre/tecsgen/tecslib/plugin/OpaqueRPCPlugin.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: 11.2 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# 以下を仮定(制限事項)
41# 呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
42# 有符号、無符号でサイズが同じ
43
44require_tecsgen_lib "lib/GenOpaqueMarshaler.rb"
45require_tecsgen_lib "lib/GenParamCopy.rb"
46
47class OpaqueRPCPlugin < ThroughPlugin
48
49 include GenOpaqueMarshaler
50 include GenParamCopy
51
52 # OpaqueRPCPlugin 専用のオプション
53 OpaqueRPCPluginArgProc = RPCPluginArgProc.dup # 複製を作って元を変更しないようにする
54 OpaqueRPCPluginArgProc[ "noClientSemaphore" ] = Proc.new { |obj,rhs| obj.set_noClientSemaphore rhs }
55
56 #=== RPCPlugin の initialize
57 # 説明は ThroughPlugin (plugin.rb) を参照
58 def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
59 super
60 @b_noClientSemaphore = false
61 initialize_opaque_marshaler
62
63 @plugin_arg_check_proc_tab = OpaqueRPCPluginArgProc
64 parse_plugin_arg
65 check_opener_code
66 check_PPAllocator
67
68 print "OpaqueRPCPlugin: #{@clientChannelCell}\n"
69
70 @rpc_server_channel_celltype_name = "tOpaqueRPCPlugin_#{@TDRCelltype}_#{@serverChannelCelltype}_#{@signature.get_global_name}"
71 @rpc_server_channel_celltype_file_name = "#{$gen}/#{@rpc_server_channel_celltype_name}.cdl"
72 @rpc_client_channel_celltype_name = "tOpaqueRPCPlugin_#{@TDRCelltype}_#{@clientChannelCelltype}_#{@signature.get_global_name}"
73 @rpc_client_channel_celltype_file_name = "#{$gen}/#{@rpc_client_channel_celltype_name}.cdl"
74 end
75
76 def gen_plugin_decl_code( file )
77
78 gen_marshaler_celltype
79
80 # チャンネル composite セルタイプの生成
81 # ここで生成された CDL ファイルは、tecsgen が直接 import するのではなく
82 # セルコードの CDL から import される
83
84 f = CFile.open( @rpc_client_channel_celltype_file_name, "w" )
85 # 同じ内容を二度書く可能性あり (AppFile は不可)
86
87 f.print <<EOT
88import( "#{@marshaler_celltype_file_name}" );
89
90/* RPC Client side composite celltype */
91composite #{@rpc_client_channel_celltype_name} {
92 /* marshaler entry port */
93 entry #{@signature.get_namespace_path} eThroughEntry;
94 call sChannel cChannel;
95 [optional]
96 call sRPCErrorHandler cErrorHandler;
97 [optional]
98 call sSemaphore cLockChannel;
99
100 cell #{@TDRCelltype} TDR {
101 cChannel => composite.cChannel;
102 };
103 cell #{@marshaler_celltype_name} Marshaler{
104 cTDR = TDR.eTDR;
105 cErrorHandler => composite.cErrorHandler;
106 cLockChannel => composite.cLockChannel;
107 };
108
109 composite.eThroughEntry => Marshaler.eClientEntry;
110};
111EOT
112 f.close
113
114 if @PPAllocatorSize then
115 alloc_cell = " cell tPPAllocator PPAllocator {\n heapSize = #{@PPAllocatorSize};\n };\n"
116 alloc_call_port_join = " cPPAllocator = PPAllocator.ePPAllocator;\n"
117 else
118 alloc_cell = ""
119 alloc_call_port_join = ""
120 end
121
122 f = CFile.open( @rpc_server_channel_celltype_file_name, "w" )
123 # 同じ内容を二度書く可能性あり (AppFile は不可)
124
125 f.print <<EOT
126import( "#{@marshaler_celltype_file_name}" );
127
128/* RPC Server side composite celltype */
129composite #{@rpc_server_channel_celltype_name} {
130 /* Interface */
131 call #{@signature.get_namespace_path} #{@call_port_name};
132 call sChannel cChannel;
133 [optional]
134 call sRPCErrorHandler cErrorHandler;
135 entry sUnmarshalerMain eService;
136
137 /* Implementation */
138 cell #{@TDRCelltype} TDR {
139 cChannel => composite.cChannel;
140 };
141#{alloc_cell} cell #{@unmarshaler_celltype_name} Unmarshaler{
142 cTDR = TDR.eTDR;
143 cErrorHandler => composite.cErrorHandler;
144 cServerCall => composite.#{@call_port_name};
145#{alloc_call_port_join} };
146 composite.eService => Unmarshaler.eService;
147};
148EOT
149
150 f.close
151 end
152
153 #=== through cell コードを生成
154 #
155 #
156 def gen_through_cell_code( file )
157
158 gen_plugin_decl_code( file )
159
160 # セルを探す
161 # path =["::",@next_cell.get_name] # mikan namespace
162 # cell = Namespace.find( path )
163 cell = Namespace.find( @next_cell.get_namespace_path )
164
165 file.print <<EOT
166import( "#{@rpc_client_channel_celltype_file_name}" );
167import( "#{@rpc_server_channel_celltype_file_name}" );
168
169EOT
170
171 ##### クライアント側のセルの生成 #####
172 nest = @start_region.gen_region_str_pre file
173 nest_str = " " * nest
174
175 # セマフォの生成
176 if @b_noClientSemaphore == false then
177 file.print <<EOT
178
179#{nest_str} // Semaphore for Multi-task use ("specify noClientSemaphore" option to delete this)
180#{nest_str} cell #{@semaphoreCelltype} #{@serverChannelCell}_Semaphore{
181#{nest_str} #{@semaphoreInitializer}
182#{nest_str} };
183EOT
184 end
185
186 # クライアント側チャンネル (TINET, Socket など)の生成
187 file.print <<EOT
188#{nest_str} // Client Side Channel
189#{nest_str} cell #{@clientChannelCelltype} #{@clientChannelCell}{
190#{nest_str} #{@clientChannelInitializer}
191#{nest_str} };
192
193#{nest_str} // Marshaler
194EOT
195
196 # セマフォの結合文
197 if @b_noClientSemaphore == false then
198 semaphore = "#{nest_str} cLockChannel = #{@serverChannelCell}_Semaphore.eSemaphore;\n"
199 else
200 semaphore = ""
201 end
202
203 ### クライアント側チャンネル (マーシャラ+TDR)の生成 ###
204 # アロケータの指定があるか?
205 if cell.get_allocator_list.length > 0 then
206
207 file.print nest_str
208 file.print "[allocator("
209
210 delim = ""
211 cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc|
212
213 alloc_str = alloc.to_s
214 subst = @substituteAllocator[alloc_str.to_sym]
215 if subst then
216 alloc_str = subst[2]+"."+subst[3]
217 end
218
219 file.print delim
220 delim = ",\n" # 最終行には出さない
221
222 if subsc then # 配列添数
223 subsc_str = '[#{subsc}]'
224 else
225 subsc_str = ""
226 end
227
228 eport = "eThroughEntry" #RPCの受け口名に変更
229 file.print nest_str
230 file.print "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc_str}"
231 end
232
233 file.puts ")]"
234 end
235
236 if @clientErrorHandler then
237 clientErrorHandler_str = "#{nest_str} cErrorHandler = #{@clientErrorHandler};\n"
238 else
239 clientErrorHandler_str = ""
240 end
241
242 file.print <<EOT
243#{nest_str} cell #{@rpc_client_channel_celltype_name} #{@cell_name} {
244#{nest_str} cChannel = #{@clientChannelCell}.eC0;
245#{clientErrorHandler_str}#{semaphore}#{nest_str} };
246
247EOT
248 ### END: クライアント側チャンネル (マーシャラ+TDR)の生成 ###
249
250 @start_region.gen_region_str_post file
251 file.print "\n\n"
252
253 ##### サーバー側のセルの生成 #####
254 nest = @end_region.gen_region_str_pre file
255 nest_str = " " * nest
256 if @next_cell_port_subscript then
257 subscript = '[' + @next_cell_port_subscript.to_s + ']'
258 else
259 subscript = ""
260 end
261
262 if @serverErrorHandler then
263 serverErrorHandler_str = "#{nest_str} cErrorHandler = #{@serverErrorHandler};\n"
264 else
265 serverErrorHandler_str = ""
266 end
267
268 if @b_genOpener then
269 opener = "#{nest_str} cOpener = #{@serverChannelCell}.eOpener;\n"
270 else
271 opener = ""
272 end
273
274 # サーバー側チャンネル (TINET, Socket など)
275 file.print <<EOT
276
277#{nest_str} // Server Side Channel
278#{nest_str} cell #{@serverChannelCelltype} #{@serverChannelCell}{
279#{nest_str} #{@serverChannelInitializer}
280#{nest_str} };
281EOT
282
283 # サーバー側チャンネル (アンマーシャラ+TDR)
284 file.print <<EOT
285
286#{nest_str} // Unmarshaler
287#{nest_str} cell #{@rpc_server_channel_celltype_name} #{@serverChannelCell}_Unmarshaler {
288#{nest_str} cChannel = #{@serverChannelCell}.eC1;
289#{nest_str} #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
290#{serverErrorHandler_str}#{nest_str} };
291EOT
292
293 # サーバー側タスクメイン
294 file.print <<EOT
295
296#{nest_str} // Unmarshaler Task Main
297#{nest_str} cell #{@taskMainCelltype} #{@serverChannelCell}_TaskMain {
298#{nest_str} cMain = #{@serverChannelCell}_Unmarshaler.eService;
299#{opener}#{nest_str} };
300EOT
301
302 # サーバー側タスク
303 file.print <<EOT
304
305#{nest_str} // Unmarshaler Task
306#{nest_str} cell #{@taskCelltype} #{@serverChannelCell}_Task {
307#{nest_str} cBody = #{@serverChannelCell}_TaskMain.eMain;
308#{nest_str} priority = #{@taskPriority};
309#{nest_str} stackSize = #{@stackSize};
310#{nest_str} taskAttribute = C_EXP( "TA_ACT" ); /* mikan : marshaler task starts at beginning */
311#{nest_str} };
312EOT
313 @end_region.gen_region_str_post file
314 end
315
316 #=== プラグイン引数 noClientSemaphore のチェック
317 def set_noClientSemaphore rhs
318 rhs = rhs.to_sym
319 if rhs == :true then
320 @b_noClientSemaphore = true
321 elsif rhs == :false then
322 @b_noClientSemaphore = false
323 else
324 cdl_error( "RPCPlugin: specify true or false for noClientSemaphore" )
325 end
326 end
327end
328
329
Note: See TracBrowser for help on using the repository browser.