[374] | 1 | # coding: utf-8
|
---|
| 2 | #
|
---|
| 3 | # TECS Generator
|
---|
| 4 | # Generator for TOPPERS Embedded Component System
|
---|
| 5 | #
|
---|
| 6 | # Copyright (C) 2014-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 |
|
---|
| 40 |
|
---|
| 41 | require_tecsgen_lib "HRPKernelObjectManager.rb"
|
---|
| 42 | #
|
---|
| 43 | # 各メソッドの役割りは、DomainPlugin.rb を参照のこと
|
---|
| 44 | # HRPカーネル用ドメインプラグイン
|
---|
| 45 | class HRPPlugin < DomainPlugin
|
---|
| 46 |
|
---|
| 47 | def initialize( region, name, option )
|
---|
| 48 | super
|
---|
| 49 | dbgPrint "HRPPlugin: initialize: region=#{region.get_name}, domainName=#{name}, option=#{option}\n"
|
---|
| 50 | @region = region
|
---|
| 51 | @name = name
|
---|
| 52 | case option
|
---|
| 53 | when "kernel", "user", "OutOfDomain"
|
---|
| 54 | # OK
|
---|
| 55 | @option = option
|
---|
| 56 | else
|
---|
| 57 | cdl_error( "HRPPlugin: '$1' is unacceptable domain kind, specify 'kernel' or 'user'", option )
|
---|
| 58 | @option = "kernel" # とりあえず kernel を設定しておく
|
---|
| 59 | end
|
---|
| 60 | end
|
---|
| 61 |
|
---|
| 62 | def add_through_plugin( join, current_region, next_region, through_type )
|
---|
| 63 | # join.get_owner:Cell 左辺のセル
|
---|
| 64 | # join.get_definition:Port 呼び口
|
---|
| 65 | # join.get_subscript:Integer or nil 呼び口配列の添数 (Join::@subscript の説明参照)
|
---|
| 66 | # join.get_cell:Cell 右辺のセル
|
---|
| 67 | # join.get_port_name:Symbol 受け口
|
---|
| 68 | # get_rhs_subscript:Integer or nil 受け口配列の添数 (Join::@rhs_subscript の説明参照)
|
---|
| 69 | # return []
|
---|
| 70 | dbgPrint "MyDomainPlugin: add_through_plugin: #{current_region.get_name}=>#{next_region.get_name}, #{join.get_owner.get_name}.#{join.get_definition.get_name}=>#{join.get_cell.get_name}.#{join.get_port_name}, #{through_type}\n"
|
---|
| 71 |
|
---|
| 72 | #puts "=====Join Check Start====="
|
---|
| 73 | #puts "caller: #{join.get_owner.get_name.to_s}, callee: #{join.get_cell.get_name.to_s}"
|
---|
| 74 | #puts "=====Join Check param====="
|
---|
| 75 | current_domain = current_region.get_domain_root.get_domain_type
|
---|
| 76 | next_domain = next_region.get_domain_root.get_domain_type
|
---|
| 77 | #puts current_domain.get_option.to_s
|
---|
| 78 | # if !next_domain.nil?
|
---|
| 79 | # puts next_domain.get_option.to_s
|
---|
| 80 | # else
|
---|
| 81 | # puts "next domain is nil!"
|
---|
| 82 | # end
|
---|
| 83 |
|
---|
| 84 | HRPPlugin.add_inter_domain_join_set join
|
---|
| 85 | # p join.get_cell.get_name
|
---|
| 86 | # p join.get_cell.get_real_celltype(join.get_rhs_port1).get_name
|
---|
| 87 | # if HRPKernelObjectManager.include_celltype?(join.get_cell.get_celltype.get_global_name) #oyama: get_name => get_global_name
|
---|
| 88 | if HRPKernelObjectManager.include_celltype?(join.
|
---|
| 89 | get_cell.
|
---|
| 90 | get_real_celltype(join.get_rhs_port1).
|
---|
| 91 | get_global_name) #oyama: get_name => get_global_name
|
---|
| 92 | # 結合先がカーネルオブジェクトセル
|
---|
| 93 | # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
|
---|
| 94 | # 何もしないthrough
|
---|
| 95 | # puts "***** #{join.get_cell.get_celltype.get_name} is kernel object"
|
---|
| 96 | return []
|
---|
| 97 | # return [ :HRP2SVCPlugin, "channelCelltype=tMessagebufferChannel,noClientSemaphore=true" ]
|
---|
| 98 | # elsif @end_region.is_root?
|
---|
| 99 | # elsif next_region.get_option == OutOfDomain
|
---|
| 100 | # elsif next_domain.nil?
|
---|
| 101 | elsif next_domain.get_option.to_s == "OutOfDomain"
|
---|
| 102 | # # 結合先が無所属
|
---|
| 103 | # # 何もしないthrough
|
---|
| 104 | # # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
|
---|
| 105 | # puts "***** nil"
|
---|
| 106 | return []
|
---|
| 107 | #elsif @start_region.get_param != :KERNEL_DOMAIN && @end_region.get_param == :KERNEL_DOMAIN
|
---|
| 108 | elsif current_domain.get_option.to_s != "kernel" && next_domain.get_option.to_s == "kernel"
|
---|
| 109 | # ユーザドメインからカーネルドメインへの結合
|
---|
| 110 | # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
|
---|
| 111 | # puts "***** svc"
|
---|
| 112 | return [ :HRPSVCPlugin, "" ]
|
---|
| 113 | elsif current_domain != next_domain
|
---|
| 114 | # 別のユーザドメインへの結合
|
---|
| 115 | # @plugin_body = HRP2RPCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
|
---|
| 116 | # puts "***** rpc"
|
---|
| 117 | # return [ :HRPRPCPlugin, "channelCelltype=tMessagebufferChannel,noClientSemaphore=true" ]
|
---|
| 118 | # puts "HRPPlugin:RPC:PPAllocatorSize=256"
|
---|
| 119 | return [ :HRPRPCPlugin, "noClientSemaphore=false,PPAllocatorSize=256" ]
|
---|
| 120 | else
|
---|
| 121 | # その他
|
---|
| 122 | # 何もしないthrough
|
---|
| 123 | # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
|
---|
| 124 | dbgPrint "warning: at HRP Join Check"
|
---|
| 125 | return nil
|
---|
| 126 | end
|
---|
| 127 |
|
---|
| 128 | # puts "=====Join Check End====="
|
---|
| 129 | end
|
---|
| 130 |
|
---|
| 131 | def joinable?(current_region, next_region, through_type )
|
---|
| 132 | dbgPrint "MyDomainPlugin: joinable? from #{current_region.get_name} to #{next_region.get_name} (#{through_type})\n"
|
---|
| 133 | return true
|
---|
| 134 | end
|
---|
| 135 |
|
---|
| 136 | #== ドメイン種別を返す
|
---|
| 137 | #return::Symbol :kernel, :user, :OutOfDomain
|
---|
| 138 | def get_kind
|
---|
| 139 | return @option.to_sym
|
---|
| 140 | end
|
---|
| 141 |
|
---|
| 142 | def self.gen_post_code file
|
---|
| 143 | end
|
---|
| 144 |
|
---|
| 145 | # ATT_MODを生成済みかどうか # 2017.8.27
|
---|
| 146 | @@generate_memory_module = false
|
---|
| 147 |
|
---|
| 148 | @@include_extsvc_fncd = false # 17.07.26 暫定
|
---|
| 149 | #
|
---|
| 150 | # ATT_MODの生成
|
---|
| 151 | # gen_factory実行時には,すべてのセルタイププラグインを生成済みのはずなので,
|
---|
| 152 | # カーネルAPIコードのメモリ保護を省略できる.
|
---|
| 153 | #
|
---|
| 154 | def gen_factory
|
---|
| 155 | super
|
---|
| 156 |
|
---|
| 157 | if @@include_extsvc_fncd == false
|
---|
| 158 | file = AppFile.open( "#{$gen}/tecsgen.cfg" )
|
---|
| 159 | file.print "/* HRPPlugin 001 */\n"
|
---|
| 160 | file.print "#include \"extsvc_fncode.h\"\n" ## 2017.7.26
|
---|
| 161 | file.close
|
---|
| 162 | @@include_extsvc_fncd = true
|
---|
| 163 | end
|
---|
| 164 |
|
---|
| 165 | if @@generate_memory_module == false
|
---|
| 166 |
|
---|
| 167 | # INCLUDE を出力
|
---|
| 168 | # すべてのドメインに対する cfg を先に生成しておく
|
---|
| 169 | # もし、ドメインに属するカーネルオブジェクトも、モジュールもない場合でも、cfg が出力される
|
---|
| 170 | regions = DomainType.get_domain_regions[ :HRP ]
|
---|
| 171 | file = AppFile.open( "#{$gen}/tecsgen.cfg" )
|
---|
| 172 | file.print "/* HRPPlugin 002 */\n"
|
---|
| 173 | regions.each{ |region|
|
---|
| 174 | if ! region.is_root? then
|
---|
| 175 | nsp = "#{region.get_global_name}"
|
---|
| 176 | file2 = AppFile.open( "#{$gen}/tecsgen_#{nsp}.cfg" )
|
---|
| 177 | file2.close
|
---|
| 178 | case region.get_domain_type.get_kind
|
---|
| 179 | when :kernel
|
---|
| 180 | pre = "KERNEL_DOMAIN{\n "
|
---|
| 181 | post = "}\n"
|
---|
| 182 | when :user
|
---|
| 183 | pre = "DOMAIN(#{region.get_name}){\n "
|
---|
| 184 | post = "}\n"
|
---|
| 185 | when :OutOfDomain
|
---|
| 186 | pre = ""
|
---|
| 187 | post = "\n"
|
---|
| 188 | end
|
---|
| 189 | file.puts "#{pre}INCLUDE(\"#{$gen}/tecsgen_#{nsp}.cfg\");\n#{post}"
|
---|
| 190 | end
|
---|
| 191 | }
|
---|
| 192 | file.print "/* HRPPlugin 002 end */\n\n"
|
---|
| 193 | file.close
|
---|
| 194 |
|
---|
| 195 | check_celltype_list = []
|
---|
| 196 |
|
---|
| 197 | #
|
---|
| 198 | # ATT_MODの生成
|
---|
| 199 | #
|
---|
| 200 | Cell.get_cell_list2.each { |cell|
|
---|
| 201 | # すべてのセルを走査してセルタイプをチェック
|
---|
| 202 | ct = cell.get_celltype
|
---|
| 203 | if ct.class == Celltype && check_celltype_list.include?( ct ) == false
|
---|
| 204 | # チェック済みセルタイプに登録
|
---|
| 205 | check_celltype_list << ct
|
---|
| 206 |
|
---|
| 207 | # 未チェックのセルタイプだった場合
|
---|
| 208 | # puts "check for ATT_MOD : #{ct.classget_global_name}"
|
---|
| 209 | # puts "check for ATT_MOD : #{ct.get_global_name}"
|
---|
| 210 |
|
---|
| 211 | # カーネルAPIのコード,データはメモリ保護しない # HRP3 oyama delete by Takada's request
|
---|
| 212 | # next if HRPKernelObjectManager.include_celltype?( ct.get_name )
|
---|
| 213 |
|
---|
| 214 | # 必要のないセルタイプのコード,データはメモリ保護しない
|
---|
| 215 | next if ! ct.need_generate?
|
---|
| 216 |
|
---|
| 217 | # HRPのドメインリージョンを取得
|
---|
| 218 | regions = ct.get_domain_roots
|
---|
| 219 | regions_hrp = regions[ :HRP ]
|
---|
| 220 | dbgPrint "HRP domain in #{ct.get_name}: "
|
---|
| 221 | regions_hrp.each { |reg|
|
---|
| 222 | dbgPrint reg.get_name
|
---|
| 223 | }
|
---|
| 224 | # puts ""
|
---|
| 225 |
|
---|
| 226 | # セル管理ブロックとスケルトンのメモリ保護
|
---|
| 227 | # gen_celltype_names_domain 相当の処理
|
---|
| 228 | if regions_hrp.include?( Region.get_root ) == false && regions_hrp.length > 1
|
---|
| 229 | # ドメインが複数で,OutOfDomainにセルが存在しないセルタイプの場合
|
---|
| 230 | # 共有のセル管理ブロックとスケルトンコードを登録する
|
---|
| 231 | file = AppFile.open( "#{$gen}/tecsgen.cfg" )
|
---|
| 232 | file.printf "%-60s/* HRPPlugin 003 */\n", "ATT_MOD(\"#{ct.get_global_name}_tecsgen.o\");"
|
---|
| 233 | file.close
|
---|
| 234 | end
|
---|
| 235 |
|
---|
| 236 | regions_hrp.each { |reg|
|
---|
| 237 | if reg.is_root?
|
---|
| 238 | nsp = ""
|
---|
| 239 | else
|
---|
| 240 | nsp = "_#{reg.get_global_name}"
|
---|
| 241 | end
|
---|
| 242 | file = AppFile.open( "#{$gen}/tecsgen#{nsp}.cfg" )
|
---|
| 243 | file.printf "%-50s/* HRPPlugin 004 */\n", "ATT_MOD(\"#{ct.get_global_name}#{nsp}_tecsgen.o\");"
|
---|
| 244 | file.close
|
---|
| 245 | }
|
---|
| 246 |
|
---|
| 247 | # セルタイプコードがない場合はスキップ
|
---|
| 248 | next if ct.is_all_entry_inline? && ! ct.is_active?
|
---|
| 249 |
|
---|
| 250 | # セルタイプコードのメモリ保護
|
---|
| 251 | # gen_celltype_names_domain2 相当の処理
|
---|
| 252 | if regions_hrp.include?( Region.get_root ) == true || regions_hrp.length > 1
|
---|
| 253 | # OutOfDomainにセルが存在するセルタイプの場合
|
---|
| 254 | # または,複数のドメインにセルが存在するセルタイプの場合
|
---|
| 255 | # セルタイプコードを共有するように登録する
|
---|
| 256 | file = AppFile.open( "#{$gen}/tecsgen.cfg" )
|
---|
| 257 | else
|
---|
| 258 | # OutOfDomainでない単一のドメインにセルが存在するセルタイプの場合
|
---|
| 259 | # セルタイプコードを専有するように登録する
|
---|
| 260 | file = AppFile.open( "#{$gen}/tecsgen_#{regions_hrp[0].get_global_name}.cfg" )
|
---|
| 261 | end
|
---|
| 262 |
|
---|
| 263 | file.printf "%-50s/* HRPPlugin 005 */\n", "ATT_MOD(\"#{ct.get_global_name}.o\");"
|
---|
| 264 | file.close
|
---|
| 265 | else
|
---|
| 266 | # 何もしない
|
---|
| 267 | end
|
---|
| 268 | }
|
---|
| 269 |
|
---|
| 270 | @@generate_memory_module = true
|
---|
| 271 | else
|
---|
| 272 | # 何もしない
|
---|
| 273 | end
|
---|
| 274 | end
|
---|
| 275 |
|
---|
| 276 | #----- Inter Domain Join Set -----#
|
---|
| 277 | @@inter_domain_join_set = {} #{entry_cell =>{domain_root=>count} } Hash of inter domain join
|
---|
| 278 | def self.add_inter_domain_join_set join
|
---|
| 279 | rhs_cell = join.get_cell
|
---|
| 280 | dbgPrint "--------- add_inter_domain:#{join.get_owner.get_namespace_path} => #{join.get_cell.get_namespace_path}-----\n"
|
---|
| 281 | domain_root = join.get_owner.get_region.get_domain_root # lhs cell's domain root
|
---|
| 282 | if @@inter_domain_join_set[ rhs_cell ] == nil then
|
---|
| 283 | @@inter_domain_join_set[ rhs_cell ] = []
|
---|
| 284 | end
|
---|
| 285 | # 左辺のドメインルートを記録
|
---|
| 286 | @@inter_domain_join_set[ rhs_cell ] << join
|
---|
| 287 | end
|
---|
| 288 | def self.get_inter_domain_join_set rhs_cell
|
---|
| 289 | if @@inter_domain_join_set[ rhs_cell ] then
|
---|
| 290 | @@inter_domain_join_set[ rhs_cell ].uniq!
|
---|
| 291 | else
|
---|
| 292 | @@inter_domain_join_set[ rhs_cell ] = []
|
---|
| 293 | end
|
---|
| 294 | return @@inter_domain_join_set[ rhs_cell ]
|
---|
| 295 | end
|
---|
| 296 | def self.get_inter_domain_join_roots rhs_cell
|
---|
| 297 | dbgPrint "--------- get_inter_domain #{rhs_cell.get_namespace_path} -----\n"
|
---|
| 298 | domain_roots = []
|
---|
| 299 | set = get_inter_domain_join_set rhs_cell
|
---|
| 300 | set.each{ |join|
|
---|
| 301 | dbgPrint "--------- get_inter_domain:#{join.get_owner.get_namespace_path} => #{join.get_cell.get_namespace_path}-----\n"
|
---|
| 302 | # if join.get_owner.get_region.get_domain_root.get_domain_type.get_option == "user" then
|
---|
| 303 | domain_roots << join.get_owner.get_region.get_domain_root
|
---|
| 304 | # end
|
---|
| 305 | }
|
---|
| 306 | return domain_roots.uniq
|
---|
| 307 | end
|
---|
| 308 |
|
---|
| 309 | def self.get_sac_str cell
|
---|
| 310 | domain_roots = self.get_inter_domain_join_roots cell
|
---|
| 311 | delim = ""
|
---|
| 312 | acv = ""
|
---|
| 313 | cell_domain_root = cell.get_region.get_domain_root
|
---|
| 314 | if cell_domain_root.get_domain_type.get_kind != :OutOfDomain then
|
---|
| 315 | domain_roots << cell.get_region.get_domain_root # 結合先のドメインも含める
|
---|
| 316 | end
|
---|
| 317 | domain_roots.each{ |dr|
|
---|
| 318 | case dr.get_domain_type.get_kind
|
---|
| 319 | when :kernel
|
---|
| 320 | acv += "#{delim}TACP_KERNEL"
|
---|
| 321 | delim = "|"
|
---|
| 322 | when :user
|
---|
| 323 | acv += "#{delim}TACP(#{dr.get_name})"
|
---|
| 324 | delim = "|"
|
---|
| 325 | if cell_domain_root.get_domain_type.get_kind != :OutOfDomain &&
|
---|
| 326 | dr.get_namespace_path != cell_domain_root.get_namespace_path then
|
---|
| 327 | cdl_error( "HRP9999 '$1': kernel object joined from other user domain. kernel object joined from multi-user-domain must be placed out of domain", cell.get_name )
|
---|
| 328 | end
|
---|
| 329 | when :OutOfDomain
|
---|
| 330 | if cell_domain_root.get_domain_type.get_kind == :OutOfDomain then
|
---|
| 331 | acv += "#{delim}TACP_SHARED"
|
---|
| 332 | delim = "|"
|
---|
| 333 | end
|
---|
| 334 | else
|
---|
| 335 | raise "unkown domain kind"
|
---|
| 336 | end
|
---|
| 337 | }
|
---|
| 338 | if acv == "" then
|
---|
| 339 | # 呼び先セルが無所属かつ、呼び元も無所属のみ、または結合無しの場合
|
---|
| 340 | acv = "TACP_SHARED"
|
---|
| 341 | end
|
---|
| 342 | sac_str = "{"
|
---|
| 343 | delim = ""
|
---|
| 344 | [:accessPattern1, :accessPattern2, :accessPattern3, :accessPattern4].each{ |acp|
|
---|
| 345 | init = (cell.get_attr_initializer acp).to_s
|
---|
| 346 | if init != "OMIT"
|
---|
| 347 | sac_str += delim + init
|
---|
| 348 | else
|
---|
| 349 | sac_str += delim + acv
|
---|
| 350 | end
|
---|
| 351 | delim = ", "
|
---|
| 352 | }
|
---|
| 353 | return sac_str + '}'
|
---|
| 354 | end
|
---|
| 355 | end
|
---|