source: EcnlProtoTool/trunk/asp3_dcre/kernel/kernel.trb@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 17.5 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TOPPERS/ASP Kernel
4# Toyohashi Open Platform for Embedded Real-Time Systems/
5# Advanced Standard Profile Kernel
6#
7# Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
8# Copyright (C) 2015,2016 by Embedded and Real-Time Systems Laboratory
9# Graduate School of Information Science, Nagoya Univ., JAPAN
10#
11# 上記著作権者
12は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14# 変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
16# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18# スコード中に含まれていること.
19# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20# 用できる形で再é…
21å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
22å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
23# 者
24マニュアルなど)に,上記の著作権表示,この利用条件および下記
25# の無保証規定を掲載すること.
26# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27# 用できない形で再é…
28å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
29# と.
30# (a) 再é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
32マニュアルなど)に,上記の著
33# 作権表示,この利用条件および下記の無保証規定を掲載すること.
34# (b) 再é…
35å¸ƒã®å½¢æ…
36‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
37# 報告すること.
38# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
39# 害からも,上記著作権者
40およびTOPPERSプロジェクトをå…
41è²¬ã™ã‚‹ã“と.
42# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
43# 由に基づく請求からも,上記著作権者
44およびTOPPERSプロジェクトを
45# å…
46è²¬ã™ã‚‹ã“と.
47#
48# 本ソフトウェアは,無保証で提供されているものである.上記著作権者
49お
50# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
51# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
52# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
53# の責任を負わない.
54#
55# $Id: kernel.trb 716 2016-03-31 06:16:23Z ertl-hiro $
56#
57
58#
59# コンフィギュレータのパス2の生成スクリプト
60#
61
62#
63# タイムスタンプファイルの指定
64#
65$timeStampFileName = "kernel_cfg.timestamp"
66
67#
68# kernel_cfg.hのå…
69ˆé ­éƒ¨åˆ†ã®ç”Ÿæˆ
70#
71$kernelCfgH = GenFile.new("kernel_cfg.h")
72$kernelCfgH.add(<<EOS)
73/* kernel_cfg.h */
74#ifndef TOPPERS_KERNEL_CFG_H
75#define TOPPERS_KERNEL_CFG_H
76EOS
77
78#
79# kernel_cfg.cのå…
80ˆé ­éƒ¨åˆ†ã®ç”Ÿæˆ
81#
82$kernelCfgC = GenFile.new("kernel_cfg.c")
83$kernelCfgC.add(<<EOS)
84/* kernel_cfg.c */
85#include "kernel/kernel_int.h"
86#include "kernel_cfg.h"
87
88#if !(TKERNEL_PRID == 0x0007U && (TKERNEL_PRVER & 0xf000U) == 0x3000U)
89#error The kernel does not match this configuration file.
90#endif
91EOS
92
93#
94# インクルードディレクティブ(#include)
95#
96$kernelCfgC.comment_header("Include Directives")
97$includeFiles.each do |file|
98 $kernelCfgC.add("#include #{file}")
99end
100$kernelCfgC.add()
101
102#
103# スタック領域の確保関数
104#
105# スタック領域の定義分と,スタック領域のサイズ記述をé…
106åˆ—で返す.
107#
108unless defined? AllocStack()
109 def AllocStack(stack, size)
110 # 大きい方に丸めたサイズで確保する[NGKI1050][NGKI3220]
111 $kernelCfgC.add("/*static*/ STK_T #{stack}[COUNT_STK_T(#{size})];")
112 return("ROUND_STK_T(#{size})")
113 end
114end
115
116#
117# カーネルオブジェクトに関する情
118報の生成(仮想クラス)
119#
120class KernelObject
121 def initialize(obj, object, obj_s = obj)
122 @obj = obj
123 @OBJ = obj.tr("a-z", "A-Z")
124 @object = object
125 @obj_s = obj_s
126 @OBJ_S = obj_s.tr("a-z", "A-Z")
127 @objid = (obj + "id").to_sym
128 @api = "CRE_#{@OBJ}".to_sym
129 @inibList = { "#{@OBJ_S}INIB" => "a#{@obj_s}inib_table"}
130 end
131
132 def generate()
133 # AID_@OBJの処理
134 numAutoObjid = 0
135 $cfgData["AID_#{@OBJ}".to_sym].each do |key, params|
136 numAutoObjid += params["no#{@obj}".to_sym]
137 end
138 numObjid = $cfgData[@api].size + numAutoObjid
139
140 # kernel_cfg.hの生成
141 $kernelCfgH.add("#define TNUM_#{@OBJ}ID\t#{numObjid}")
142
143 # オブジェクトのID番号のマクロ定義の生成
144 $cfgData[@api].sort.each do |key, params|
145 $kernelCfgH.add("#define #{params[@objid]}\t#{params[@objid].val}")
146 end
147 $kernelCfgH.add()
148
149 # オブジェクトのID番号を保持する変数
150 if $USE_EXTERNAL_ID
151 $cfgData[@api].sort.each do |key, params|
152 $kernelCfgC.add("const ID #{params[@objid]}_id" \
153 " = #{params[@objid].val};")
154 end
155 $kernelCfgC.add()
156 end
157
158 # 静的に生成されたオブジェクトの数
159 $kernelCfgC.add("#define TNUM_S#{@OBJ}ID\t#{$cfgData[@api].size}")
160
161 # オブジェクトID番号の最大値
162 $kernelCfgC.add("const ID _kernel_tmax_#{@obj}id" \
163 " = (TMIN_#{@OBJ}ID + TNUM_#{@OBJ}ID - 1);")
164 $kernelCfgC.add2("const ID _kernel_tmax_s#{@obj}id" \
165 " = (TMIN_#{@OBJ}ID + TNUM_S#{@OBJ}ID - 1);")
166
167 # データ構造
168 if $cfgData[@api].size > 0
169 # 事前準備(エラーチェック,メモリ領域の生成)
170 $cfgData[@api].sort.each do |key, params|
171 prepare(key, params)
172 end
173
174 # オブジェクトå…
175¨ä½“に対して必
176要なメモリ領域の生成(オプション)
177 if respond_to?(:generateData)
178 generateData()
179 end
180
181 # オブジェクト初期化ブロックの生成
182 $kernelCfgC.add("const #{@OBJ_S}INIB _kernel_#{@obj_s}inib_table" \
183 "[TNUM_S#{@OBJ}ID] = {")
184 $cfgData[@api].sort.each_with_index do |(key, params), index|
185 $kernelCfgC.add(",") if index > 0
186 $kernelCfgC.append("\t{ " + generateInib(key, params) + " }")
187 end
188 $kernelCfgC.add
189 $kernelCfgC.add2("};")
190 else
191 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const #{@OBJ_S}INIB, " \
192 "_kernel_#{@obj_s}inib_table);")
193 end
194
195 # 動的生成オブジェクト用のオブジェクト初期化ブロック
196 @inibList.each do |type, array|
197 if numAutoObjid > 0
198 $kernelCfgC.add2("#{type} _kernel_#{array}[#{numAutoObjid}];")
199 else
200 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(#{type}, _kernel_#{array});")
201 end
202 end
203
204 if numObjid > 0
205 # オブジェクト管理ブロックの生成
206 $kernelCfgC.add2("#{@OBJ_S}CB _kernel_#{@obj_s}cb_table" \
207 "[TNUM_#{@OBJ}ID];")
208
209 # オブジェクト初期化関数の追加
210 $initializeFunctions.push("_kernel_initialize_#{@object}();")
211 else
212 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(#{@OBJ_S}CB, " \
213 "_kernel_#{@obj_s}cb_table);")
214 end
215 end
216end
217
218#
219# 通知ハンドラの生成関数
220#
221def generateNotifyHandler(key, params, objid)
222 # パラメータを変数に格納
223 nfymode = params[:nfymode]
224 nfymode1 = nfymode & 0x0f
225 nfymode2 = nfymode & ~0x0f
226 par1 = params[:par1]
227 par2 = params[:par2]
228
229 # 通知処理のパラメータ数による補正処理
230 if nfymode == $TNFY_HANDLER || nfymode1 == $TNFY_SETVAR \
231 || nfymode1 == $TNFY_SETFLG \
232 || nfymode1 == $TNFY_SNDDTQ
233 # 通知処理のパラメータが2つの場合
234 numpar = 2
235 epar1 = params[:par3]
236 epar2 = params[:par4]
237 else
238 # 通知処理のパラメータが1つの場合
239 numpar = 1
240 epar1 = params[:par2]
241 epar2 = params[:par3]
242 end
243
244 # パラメータ数のチェック
245 if (numpar == 2 && par2.nil?) || (nfymode2 != 0 && epar1.nil?) \
246 || (nfymode2 == $TENFY_SETFLG && epar2.nil?)
247 # パラメータが足りない場合
248 error_api(params, "too few parameters for nfymode `#{nfymode}' " \
249 "in %apiname of %#{objid}")
250 elsif (nfymode2 == 0 && !epar1.nil?) \
251 || (nfymode2 != $TENFY_SETFLG && !epar2.nil?)
252 # パラメータが多すぎる場合
253 error_api(params, "too many parameters for nfymode `#{nfymode}' " \
254 "in %apiname of %#{objid}")
255 elsif nfymode == $TNFY_HANDLER
256 # タイムイベントハンドラの呼出し
257 funcname = "(NFYHDR)(#{par2})"
258 else
259 # 通知ハンドラの関数名
260 funcname = "_kernel_nfyhdr_#{params[objid]}"
261
262 # エラー通知のための変数のアドレスとオブジェクトIDを格納する
263 # 変数の生成(エラーチェックのために必
264要)
265 if nfymode2 == $TENFY_SETVAR || nfymode2 == $TENFY_INCVAR
266 $kernelCfgC.add2("intptr_t *const #{funcname}_p_evar =" \
267 " (intptr_t *)(#{epar1});")
268 elsif nfymode2 == $TENFY_ACTTSK || nfymode2 == $TENFY_WUPTSK
269 $kernelCfgC.add2("const ID #{funcname}_etskid = #{epar1};")
270 elsif nfymode2 == $TENFY_SIGSEM
271 $kernelCfgC.add2("const ID #{funcname}_esemid = #{epar1};")
272 elsif nfymode2 == $TENFY_SETFLG
273 $kernelCfgC.add2("const ID #{funcname}_eflgid = #{epar1};")
274 elsif nfymode2 == $TENFY_SNDDTQ
275 $kernelCfgC.add2("const ID #{funcname}_edtqid = #{epar1};")
276 end
277
278 # 関数のå…
279ˆé ­éƒ¨åˆ†ã®ç”Ÿæˆ
280 $kernelCfgC.add("static void")
281 $kernelCfgC.add("#{funcname}(intptr_t exinf)")
282 $kernelCfgC.add("{")
283
284 if nfymode2 == 0
285 # エラー通知がない場合
286 errorCode = "(void) "
287 else
288 # エラー通知がある場合
289 $kernelCfgC.add2("\tER\tercd;")
290 errorCode = "ercd = "
291 end
292
293 # イベント通知処理の処理
294 if nfymode1 == $TNFY_SETVAR && nfymode2 == 0
295 # 変数の設定
296 $kernelCfgC.add("\t*((intptr_t *) exinf) = (#{par2});")
297 elsif nfymode1 == $TNFY_INCVAR && nfymode2 == 0
298 # 変数のインクリメント
299 $kernelCfgC.add("\t(void) loc_cpu();")
300 $kernelCfgC.add("\t*((intptr_t *) exinf) += 1;")
301 $kernelCfgC.add("\t(void) unl_cpu();")
302 elsif nfymode1 == $TNFY_ACTTSK
303 # タスクの起動
304 $kernelCfgC.add("\t#{errorCode}act_tsk((ID) exinf);")
305 elsif nfymode1 == $TNFY_WUPTSK
306 # タスクの起床
307 $kernelCfgC.add("\t#{errorCode}wup_tsk((ID) exinf);")
308 elsif nfymode1 == $TNFY_SIGSEM
309 # セマフォの返却
310 $kernelCfgC.add("\t#{errorCode}sig_sem((ID) exinf);")
311 elsif nfymode1 == $TNFY_SETFLG
312 # イベントフラグのセット
313 $kernelCfgC.add("\t#{errorCode}set_flg(((ID) exinf), #{par2});")
314 elsif nfymode1 == $TNFY_SNDDTQ
315 # データキューへの送信
316 $kernelCfgC.add("\t#{errorCode}psnd_dtq(((ID) exinf), #{par2});")
317 else
318 error_illegal_id("E_PAR", params, :nfymode, objid)
319 end
320
321 if nfymode2 != 0
322 # エラー通知処理の処理
323 $kernelCfgC.add("\tif (ercd != E_OK) {")
324
325
326 if nfymode2 == $TENFY_SETVAR
327 # 変数の設定
328 $kernelCfgC.add("\t\t*#{funcname}_p_evar = (intptr_t) ercd;")
329 elsif nfymode2 == $TENFY_INCVAR
330 # 変数のインクリメント
331 $kernelCfgC.add("\t\t(void) loc_cpu();")
332 $kernelCfgC.add("\t\t*#{funcname}_p_evar += 1;")
333 $kernelCfgC.add("\t\t(void) unl_cpu();")
334 elsif nfymode2 == $TENFY_ACTTSK
335 # タスクの起動
336 $kernelCfgC.add("\t\t(void) act_tsk(#{funcname}_etskid);")
337 elsif nfymode2 == $TENFY_WUPTSK
338 # タスクの起床
339 $kernelCfgC.add("\t\t(void) wup_tsk(#{funcname}_etskid);")
340 elsif nfymode2 == $TENFY_SIGSEM
341 # セマフォの返却
342 $kernelCfgC.add("\t\t(void) sig_sem(#{funcname}_esemid);")
343 elsif nfymode2 == $TENFY_SETFLG
344 # イベントフラグのセット
345 $kernelCfgC.add("\t\t(void) set_flg(#{funcname}_eflgid, #{epar2});")
346 elsif nfymode2 == $TENFY_SNDDTQ
347 # データキューへの送信
348 $kernelCfgC.add("\t\t(void) psnd_dtq(#{funcname}_edtqid," \
349 " (intptr_t) ercd);")
350 else
351 error_illegal_id("E_PAR", params, :nfymode, objid)
352 end
353 $kernelCfgC.add("\t}")
354 end
355
356 # 関数の末尾部分の生成
357 $kernelCfgC.add2("}")
358 end
359 return(funcname)
360end
361
362#
363# 各機能モジュールのコンフィギュレーション
364#
365$initializeFunctions = []
366IncludeTrb("kernel/task.trb")
367IncludeTrb("kernel/semaphore.trb")
368IncludeTrb("kernel/eventflag.trb")
369IncludeTrb("kernel/dataqueue.trb")
370IncludeTrb("kernel/pridataq.trb")
371IncludeTrb("kernel/mutex.trb")
372IncludeTrb("kernel/mempfix.trb")
373IncludeTrb("kernel/cyclic.trb")
374IncludeTrb("kernel/alarm.trb")
375IncludeTrb("kernel/interrupt.trb")
376IncludeTrb("kernel/exception.trb")
377
378#
379# 非タスクコンテキスト用のスタック領域
380#
381$kernelCfgC.comment_header("Stack Area for Non-task Context")
382
383if $cfgData[:DEF_ICS].size == 0
384 # DEF_ICSがない場合のデフォルト値の設定
385 if $DEFAULT_ISTK.nil?
386 # スタック領域の自動割付け
387 istksz = AllocStack("_kernel_istack", "DEFAULT_ISTKSZ")
388 istk = "_kernel_istack"
389 else
390 istksz = "DEFAULT_ISTKSZ"
391 istk = "DEFAULT_ISTK"
392 end
393else
394 # 静的API「DEF_ICS」が複数ある(E_OBJ)[NGKI3216]
395 if $cfgData[:DEF_ICS].size > 1
396 error("E_OBJ: too many DEF_ICS")
397 end
398
399 # DEF_ICSがある場合の処理
400 params = $cfgData[:DEF_ICS][1]
401
402 # パラメータが省略された時のデフォルト値の設定
403 params[:istk] ||= "NULL"
404
405 # istkszがターゲット定義の最小値(TARGET_MIN_ISTKSZ,未定義の場合は1)
406 # よりも小さい場合(E_PAR)[NGKI3254]
407 if params[:istksz] < $TARGET_MIN_ISTKSZ
408 error_wrong("E_PAR", params, :istksz, "too small")
409 end
410
411 if params[:istk] == "NULL"
412 # スタック領域の自動割付け
413 istksz = AllocStack("_kernel_istack", params[:istksz])
414 istk = "_kernel_istack"
415 else
416 # istkszがスタック領域のサイズとして正しくない場合(E_PAR)[NGKI3222]
417 if (params[:istksz] & ($CHECK_STKSZ_ALIGN - 1)) != 0
418 error_wrong("E_PAR", params, :istksz, "not aligned")
419 end
420
421 istksz = "(#{params[:istksz]})"
422 istk = "(void *)(#{params[:istk]})"
423 end
424end
425
426$kernelCfgC.add(<<EOS)
427const size_t _kernel_istksz = #{istksz};
428STK_T *const _kernel_istk = #{istk};
429
430#ifdef TOPPERS_ISTKPT
431STK_T *const _kernel_istkpt = TOPPERS_ISTKPT(#{istk}, #{istksz});
432#endif /* TOPPERS_ISTKPT */
433EOS
434
435#
436# カーネルが割り付けるメモリ領域
437#
438$kernelCfgC.comment_header("Memory Area Allocated by Kernel")
439
440if $cfgData[:DEF_KMM].size == 0
441 # DEF_KMMがない場合のデフォルト値の設定
442 kmmsz = "0"
443 kmm = "NULL"
444else
445 # 静的API「DEF_KMM」が複数ある(E_OBJ)
446 if ($cfgData[:DEF_KMM].size > 1)
447 error("E_OBJ: too many DEF_KMM")
448 end
449
450 # DEF_KMMがある場合の処理
451 params = $cfgData[:DEF_KMM][1]
452
453 # パラメータが省略された時のデフォルト値の設定
454 params[:kmm] ||= "NULL"
455
456 # kmmszが0の場合(E_PAR)
457 if params[:kmmsz] == 0
458 error_wrong("E_PAR", params, :kmmsz, "zero")
459 end
460
461 if params[:kmm] == "NULL"
462 # カーネルが割り付けるメモリ領域の自動割付け
463 $kernelCfgC.add("static MB_T _kernel_memory" \
464 "[TOPPERS_COUNT_SZ(#{params[:kmmsz]}, sizeof(MB_T))];")
465 kmmsz = "TOPPERS_ROUND_SZ(#{params[:kmmsz]}, sizeof(MB_T))"
466 kmm = "_kernel_memory"
467 else
468 # kmmszがカーネルが割り付けるメモリ領域のサイズとして正しくない場合
469 # (E_PAR)
470 if (params[:kmmsz] & ($CHECK_MB_ALIGN - 1)) != 0
471 error_wrong("E_PAR", params, :kmmsz, "not aligned")
472 end
473
474 kmmsz = "(#{params[:kmmsz]})"
475 kmm = "(void *)(#{params[:kmm]})"
476 end
477end
478
479$kernelCfgC.add(<<EOS)
480const size_t _kernel_kmmsz = #{kmmsz};
481MB_T *const _kernel_kmm = #{kmm};
482EOS
483
484#
485# タイムイベント管理
486#
487$kernelCfgC.comment_header("Time Event Management")
488$kernelCfgC.add(<<EOS)
489TMEVTN _kernel_tmevt_heap[1 + TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];
490EOS
491
492#
493# 各モジュールの初期化関数
494#
495$kernelCfgC.comment_header("Module Initialization Function")
496$kernelCfgC.append(<<EOS)
497void
498_kernel_initialize_object(void)
499{
500EOS
501$initializeFunctions.each do |func|
502 $kernelCfgC.add("\t#{func}")
503end
504$kernelCfgC.add2("}")
505
506#
507# 初期化ルーチン機能
508#
509$kernelCfgC.comment_header("Initialization Routine")
510
511# エラーチェック
512$cfgData[:ATT_INI].each do |key, params|
513 # iniatrが無効の場合(E_RSATR)[NGKI3241]
514 #(TA_NULLでない場合)
515 if (params[:iniatr] != $TA_NULL)
516 error_illegal_sym("E_RSATR", params, :iniatr, :inirtn)
517 end
518end
519
520# 初期化ルーチンの実行関数の生成
521$kernelCfgC.append(<<EOS)
522void
523_kernel_call_inirtn(void)
524{
525EOS
526$cfgData[:ATT_INI].each do |key, params|
527 $kernelCfgC.add("\t((INIRTN)(#{params[:inirtn]}))" \
528 "((intptr_t)(#{params[:exinf]}));")
529end
530$kernelCfgC.add2("}")
531
532#
533# 終了処理ルーチン機能
534#
535$kernelCfgC.comment_header("Termination Routine")
536
537# エラーチェック
538$cfgData[:ATT_TER].each do |key, params|
539 # teratrが無効の場合(E_RSATR)[NGKI3248]
540 #(TA_NULLでない場合)
541 if (params[:teratr] != $TA_NULL)
542 error_illegal_sym("E_RSATR", params, :teratr, :terrtn)
543 end
544end
545
546# 終了処理ルーチンの実行関数の生成
547$kernelCfgC.append(<<EOS)
548void
549_kernel_call_terrtn(void)
550{
551EOS
552$cfgData[:ATT_TER].reverse_each do |key, params|
553 $kernelCfgC.add("\t((TERRTN)(#{params[:terrtn]}))" \
554 "((intptr_t)(#{params[:exinf]}));")
555end
556$kernelCfgC.add2("}")
557
558#
559# kernel_cfg.hの末尾部分の生成
560#
561$kernelCfgH.append(<<EOS)
562#endif /* TOPPERS_KERNEL_CFG_H */
563EOS
Note: See TracBrowser for help on using the repository browser.