# -*- coding: utf-8 -*- # # TECS Generator # Generator for TOPPERS Embedded Component System # # Copyright (C) 2008-2014 by TOPPERS Project #-- # 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ # ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 # 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. # (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 # 権表示,この利用条件および下記の無保証規定が,そのままの形でソー # スコード中に含まれていること. # (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 # 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 # 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 # の無保証規定を掲載すること. # (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 # 用できない形で再配布する場合には,次のいずれかの条件を満たすこ # と. # (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 # 作権表示,この利用条件および下記の無保証規定を掲載すること. # (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに # 報告すること. # (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 # 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. # また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 # 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを # 免責すること. # # 本ソフトウェアは,無保証で提供されているものである.上記著作権者お # よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 # に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ # アの利用により直接的または間接的に生じたいかなる損害に関しても,そ # の責任を負わない. # # $Id$ #++ require_tecsgen_lib "lib/GenOpaqueMarshaler.rb" require_tecsgen_lib "lib/GenParamCopy.rb" #= SharedOpaqueRPC プラグイン # SharedOpaqueRPC チャンネルを生成する # プラグイン引数は GenTransparentMarshaler 参照 # mikan through plugin: namespace が考慮されていない # これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必要がある # tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl # 以下を仮定(制限事項) # 呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ # 有符号、無符号でサイズが同じ class SharedOpaqueRPCPlugin < ThroughPlugin # チャンネルを共有するプラグインオブジェクトへのハッシュリスト @@shared_channel_list = {} # { chan_name => [ Plugin_obj0, Plugin_Obj1, ... ] } attr_reader :cell_name, :start_region, :end_region include GenOpaqueMarshaler include GenParamCopy # SharedOpaqueRPCPlugin 専用のオプション SharedOpaqueRPCPluginArgProc = RPCPluginArgProc.dup # 複製を作って元を変更しないようにする SharedOpaqueRPCPluginArgProc[ "sharedChannelName" ] = Proc.new { |obj,rhs| obj.set_sharedChannelName rhs } #=== RPCPlugin の initialize # 説明は ThroughPlugin (plugin.rb) を参照 def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell ) super initialize_opaque_marshaler @entry_port_name = :"eClientEntry" # Marshaler の受け口名 (through セルの入り口) # オプション:GenOpaqueMarshaler 参照 @plugin_arg_check_proc_tab = SharedOpaqueRPCPluginArgProc @sharedChannelName = nil parse_plugin_arg check_opener_code check_PPAllocator @shared_channel_ct_name = :"tSharedOpaqueRPCPluginChannel_tTDR" @shared_channel_server_ct_name = :"#{@shared_channel_ct_name}_Server" @shared_channel_client_ct_name = :"#{@shared_channel_ct_name}_Client" @shared_channel_ct_file_name = "#{$gen}/#{@shared_channel_ct_name}.cdl" if @sharedChannelName == nil then cdl_error( "'sharedChannelName' option: mandatory") else @shared_channel_cell = @sharedChannelName end if @@shared_channel_list[ @shared_channel_cell ] == nil then @@shared_channel_list[ @shared_channel_cell ] = [ self ] else @@shared_channel_list[ @shared_channel_cell ] << self end @sub_channel_no = ( @@shared_channel_list[ @shared_channel_cell ].length ) -1 prev_start = @@shared_channel_list[ @shared_channel_cell ][0].start_region if @start_region != prev_start then # 初出と start リージョン不一致 (初出は、自分自身とチェックされる。無駄だが小さいので放置) cdl_error( "SharedRPCPlugin: start region mismatch current: #{@region.get_name} previous: #{prev_start.get_name}") end prev_end = @@shared_channel_list[ @shared_channel_cell ][0].end_region if @end_region != prev_end then # 初出と end リージョン不一致 (初出は、自分自身とチェックされる。無駄だが小さいので放置) cdl_error( "SharedRPCPlugin: end region mismatch current: #{@region.get_name} previous: #{prev_end.get_name}") end end # def set_through_info( start_region, end_region, through_type ) # super # end #=== プラグイン引数 sharedChannelCell のチェック def set_sharedChannelName( rhs ) @sharedChannelName = rhs # path = [ "::", rhs ] # obj = Namespace.find( path ) # if ! obj.instance_of?( Cell ) then # cdl_error( "SharedOpaqueRPCPlugin: sharedChannelName '#{rhs}' not cell" ) # end end def gen_plugin_decl_code( file ) # このセルタイプ(同じシグニチャ)は既に生成されているか? if @@generated_celltype[ @shared_channel_server_ct_name ] == nil then @@generated_celltype[ @shared_channel_server_ct_name ] = [ self ] else @@generated_celltype[ @shared_channel_server_ct_name ] << self end gen_marshaler_celltype # 同じ内容を二度書く可能性あり (AppFile は不可) if @PPAllocatorSize then alloc_call_port = " call sPPAllocator cPPAllocator;\n" alloc_call_port_join = " cPPAllocator => composite.cPPAllocator;\n" else alloc_call_port = "" alloc_call_port_join = "" end f = CFile.open( @shared_channel_ct_file_name, "w" ) # 同じ内容を二度書く可能性あり (AppFile は不可) f.print < composite.cClientChannel; }; cell tSemaphore Semaphore { count = 1; attribute = C_EXP("TA_NULL"); }; cell tRPCSharedChannelMan SharedChannelMan{ cSemaphore = Semaphore.eSemaphore; cClientSideTDR = TDR.eTDR; }; composite.eSemaphore => SharedChannelMan.eSemaphore; composite.eTDR => TDR.eTDR; }; /* Shared Channel Celltype for Server */ [active] composite #{@shared_channel_server_ct_name} { entry sTDR eTDR; call sChannel cServerChannel; call sUnmarshalerMain cUnmarshalAndCallFunction[]; call sServerChannelOpener cOpener; attr { PRI priority; }; cell tTDR TDR { cChannel => composite.cServerChannel; }; cell tRPCSharedTaskMainWithOpener RPCSharedTaskMain { cUnmarshalAndCallFunction => composite.cUnmarshalAndCallFunction; cServerSideTDR = TDR.eTDR; cOpener => composite.cOpener; }; cell tTask Task { cBody = RPCSharedTaskMain.eMain; taskAttribute = C_EXP("TA_ACT"); stackSize = 4096; priority = composite.priority; }; composite.eTDR => TDR.eTDR; }; EOT f.close end #=== through cell コードを生成 # # def gen_through_cell_code( file ) gen_plugin_decl_code( file ) file.print < 0 then file.print "#{indent_str}[allocator(" delim = "" cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc| alloc_str = alloc.to_s subst = @substituteAllocator[alloc_str.to_sym] if subst then alloc_str = subst[2]+"."+subst[3] end file.print delim delim = ",\n#{indent_str} " # 最終行には出さない if subsc then # 配列添数 subsc_str = '[#{subsc}]' else subsc_str = "" end eport = @entry_port_name #RPCの受け口名に変更 file.print "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc_str}" end file.puts ")]" end # マーシャラセル本体生成 file.print <