source: asp3_wo_tecs/trunk/kernel/kernel.trb@ 304

Last change on this file since 304 was 304, checked in by ertl-honda, 7 years ago

コンフィギュレータをruby版に変更

File size: 15.3 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 572 2016-02-01 14:40:09Z 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.append(<<EOS)
73/* kernel_cfg.h */
74#ifndef TOPPERS_KERNEL_CFG_H
75#define TOPPERS_KERNEL_CFG_H
76
77EOS
78
79#
80# kernel_cfg.cのå…
81ˆé ­éƒ¨åˆ†ã®ç”Ÿæˆ
82#
83$kernelCfgC = GenFile.new("kernel_cfg.c")
84$kernelCfgC.append(<<EOS)
85/* kernel_cfg.c */
86#include "kernel/kernel_int.h"
87#include "kernel_cfg.h"
88
89#if !(TKERNEL_PRID == 0x0007U && (TKERNEL_PRVER & 0xf000U) == 0x3000U)
90#error The kernel does not match this configuration file.
91#endif
92
93EOS
94
95#
96# インクルードディレクティブ(#include)
97#
98$kernelCfgC.comment_header("Include Directives")
99$includeFiles.each do |file|
100 $kernelCfgC.add("#include #{file}")
101end
102$kernelCfgC.add()
103
104#
105# スタック領域の確保関数
106#
107# スタック領域の定義分と,スタック領域のサイズ記述をé…
108åˆ—で返す.
109#
110unless defined? AllocStack()
111 def AllocStack(stack, size)
112 # 大きい方に丸めたサイズで確保する[NGKI1050][NGKI3220]
113 $kernelCfgC.add("static STK_T #{stack}[COUNT_STK_T(#{size})];")
114 return("ROUND_STK_T(#{size})")
115 end
116end
117
118#
119# カーネルオブジェクトに関する情
120報の生成(仮想クラス)
121#
122class KernelObject
123 def initialize(obj, object, obj_s = obj)
124 @obj = obj
125 @OBJ = obj.tr("a-z", "A-Z")
126 @object = object
127 @obj_s = obj_s
128 @OBJ_S = obj_s.tr("a-z", "A-Z")
129 @objid = (obj + "id").to_sym
130 @api = "CRE_#{@OBJ}".to_sym
131 end
132
133 def generate()
134 # kernel_cfg.hの生成
135 $kernelCfgH.add("#define TNUM_#{@OBJ}ID\t#{$cfgData[@api].size}")
136
137 # オブジェクトのID番号のマクロ定義の生成
138 $cfgData[@api].sort.each do |id, params|
139 $kernelCfgH.add("#define #{params[@objid]}\t#{params[@objid].val}")
140 end
141 $kernelCfgH.add()
142
143 # オブジェクトのID番号を保持する変数
144 if $USE_EXTERNAL_ID
145 $cfgData[@api].sort.each do |id, params|
146 $kernelCfgC.add("const ID #{params[@objid]}_id" \
147 " = #{params[@objid].val};")
148 end
149 $kernelCfgC.add()
150 end
151
152 # オブジェクトID番号の最大値
153 $kernelCfgC.add2("const ID _kernel_tmax_#{@obj}id" \
154 " = (TMIN_#{@OBJ}ID + TNUM_#{@OBJ}ID - 1);")
155
156 # データ構造
157 if $cfgData[@api].size > 0
158 # 事前準備(エラーチェック,メモリ領域の生成)
159 $cfgData[@api].sort.each do |id, params|
160 prepare(id, params)
161 end
162
163 # オブジェクトå…
164¨ä½“に対して必
165要なメモリ領域の生成(オプション)
166 if respond_to?(:generateData)
167 generateData()
168 end
169
170 # オブジェクト初期化ブロックの生成
171 $kernelCfgC.add("const #{@OBJ_S}INIB _kernel_#{@obj_s}inib_table" \
172 "[TNUM_#{@OBJ}ID] = {")
173 $cfgData[@api].sort.each_with_index do |(id, params), index|
174 $kernelCfgC.add(",") if index > 0
175 $kernelCfgC.append("\t{ " + generateInib(id, params) + " }")
176 end
177 $kernelCfgC.add
178 $kernelCfgC.add2("};")
179
180 # オブジェクト管理ブロックの生成
181 $kernelCfgC.add2("#{@OBJ_S}CB _kernel_#{@obj_s}cb_table" \
182 "[TNUM_#{@OBJ}ID];")
183
184 # オブジェクト初期化関数の追加
185 $initializeFunctions.push("_kernel_initialize_#{@object}();")
186 else
187 # オブジェクトが1つもない場合
188 $kernelCfgC.add("TOPPERS_EMPTY_LABEL(const #{@OBJ_S}INIB, " \
189 "_kernel_#{@obj_s}inib_table);")
190 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(#{@OBJ_S}CB, " \
191 "_kernel_#{@obj_s}cb_table);")
192 end
193 end
194end
195
196#
197# 通知ハンドラの生成関数
198#
199def generateNotifyHandler(id, params, objid)
200 # パラメータを変数に格納
201 nfymode = params[:nfymode]
202 nfymode1 = nfymode & 0x0f
203 nfymode2 = nfymode & ~0x0f
204 par1 = params[:par1]
205 par2 = params[:par2]
206
207 # 通知処理のパラメータ数による補正処理
208 if nfymode == $TNFY_HANDLER || nfymode1 == $TNFY_SETVAR \
209 || nfymode1 == $TNFY_SETFLG \
210 || nfymode1 == $TNFY_SNDDTQ
211 # 通知処理のパラメータが2つの場合
212 numpar = 2
213 epar1 = params[:par3]
214 epar2 = params[:par4]
215 else
216 # 通知処理のパラメータが1つの場合
217 numpar = 1
218 epar1 = params[:par2]
219 epar2 = params[:par3]
220 end
221
222 # パラメータ数のチェック
223 if (numpar == 2 && par2.nil?) || (nfymode2 != 0 && epar1.nil?) \
224 || (nfymode2 == $TENFY_SETFLG && epar2.nil?)
225 # パラメータが足りない場合
226 error_api(params, "too few parameters for nfymode `#{nfymode}'" \
227 " in #{params[:apiname]} of #{params[objid]}")
228 elsif (nfymode2 == 0 && !epar1.nil?) \
229 || (nfymode2 != $TENFY_SETFLG && !epar2.nil?)
230 # パラメータが多すぎる場合
231 error_api(params, "too many parameters for nfymode `#{nfymode}'" \
232 " in #{params[:apiname]} of #{params[objid]}")
233 elsif nfymode == $TNFY_HANDLER
234 # タイムイベントハンドラの呼出し
235 funcname = "(NFYHDR)(#{par2})"
236 else
237 # 通知ハンドラの関数名
238 funcname = "_kernel_nfyhdr_#{params[objid]}"
239
240 # エラー通知のための変数のアドレスとオブジェクトIDを格納する
241 # 変数の生成(エラーチェックのために必
242要)
243 if nfymode2 == $TENFY_SETVAR || nfymode2 == $TENFY_INCVAR
244 $kernelCfgC.add2("intptr_t *const #{funcname}_p_evar =" \
245 " (intptr_t *)(#{epar1});")
246 elsif nfymode2 == $TENFY_ACTTSK || nfymode2 == $TENFY_WUPTSK
247 $kernelCfgC.add2("const ID #{funcname}_etskid = #{epar1};")
248 elsif nfymode2 == $TENFY_SIGSEM
249 $kernelCfgC.add2("const ID #{funcname}_esemid = #{epar1};")
250 elsif nfymode2 == $TENFY_SETFLG
251 $kernelCfgC.add2("const ID #{funcname}_eflgid = #{epar1};")
252 elsif nfymode2 == $TENFY_SNDDTQ
253 $kernelCfgC.add2("const ID #{funcname}_edtqid = #{epar1};")
254 end
255
256 # 関数のå…
257ˆé ­éƒ¨åˆ†ã®ç”Ÿæˆ
258 $kernelCfgC.add("static void")
259 $kernelCfgC.add("#{funcname}(intptr_t exinf)")
260 $kernelCfgC.add("{")
261
262 if nfymode2 == 0
263 # エラー通知がない場合
264 errorCode = "(void) "
265 else
266 # エラー通知がある場合
267 $kernelCfgC.add2("\tER\tercd;")
268 errorCode = "ercd = "
269 end
270
271 # イベント通知処理の処理
272 if nfymode1 == $TNFY_SETVAR && nfymode2 == 0
273 # 変数の設定
274 $kernelCfgC.add("\t*((intptr_t *) exinf) = (#{par2});")
275 elsif nfymode1 == $TNFY_INCVAR && nfymode2 == 0
276 # 変数のインクリメント
277 $kernelCfgC.add("\t(void) loc_cpu();")
278 $kernelCfgC.add("\t*((intptr_t *) exinf) += 1;")
279 $kernelCfgC.add("\t(void) unl_cpu();")
280 elsif nfymode1 == $TNFY_ACTTSK
281 # タスクの起動
282 $kernelCfgC.add("\t#{errorCode}act_tsk((ID) exinf);")
283 elsif nfymode1 == $TNFY_WUPTSK
284 # タスクの起床
285 $kernelCfgC.add("\t#{errorCode}wup_tsk((ID) exinf);")
286 elsif nfymode1 == $TNFY_SIGSEM
287 # セマフォの返却
288 $kernelCfgC.add("\t#{errorCode}sig_sem((ID) exinf);")
289 elsif nfymode1 == $TNFY_SETFLG
290 # イベントフラグのセット
291 $kernelCfgC.add("\t#{errorCode}set_flg(((ID) exinf), #{par2});")
292 elsif nfymode1 == $TNFY_SNDDTQ
293 # データキューへの送信
294 $kernelCfgC.add("\t#{errorCode}psnd_dtq(((ID) exinf), #{par2});")
295 else
296 error_illegal_id("E_PAR", params, :nfymode, objid)
297 end
298
299 if nfymode2 != 0
300 # エラー通知処理の処理
301 $kernelCfgC.add("\tif (ercd != E_OK) {")
302
303
304 if nfymode2 == $TENFY_SETVAR
305 # 変数の設定
306 $kernelCfgC.add("\t\t*#{funcname}_p_evar = (intptr_t) ercd;")
307 elsif nfymode2 == $TENFY_INCVAR
308 # 変数のインクリメント
309 $kernelCfgC.add("\t\t(void) loc_cpu();")
310 $kernelCfgC.add("\t\t*#{funcname}_p_evar += 1;")
311 $kernelCfgC.add("\t\t(void) unl_cpu();")
312 elsif nfymode2 == $TENFY_ACTTSK
313 # タスクの起動
314 $kernelCfgC.add("\t\t(void) act_tsk(#{funcname}_etskid);")
315 elsif nfymode2 == $TENFY_WUPTSK
316 # タスクの起床
317 $kernelCfgC.add("\t\t(void) wup_tsk(#{funcname}_etskid);")
318 elsif nfymode2 == $TENFY_SIGSEM
319 # セマフォの返却
320 $kernelCfgC.add("\t\t(void) sig_sem(#{funcname}_esemid);")
321 elsif nfymode2 == $TENFY_SETFLG
322 # イベントフラグのセット
323 $kernelCfgC.add("\t\t(void) set_flg(#{funcname}_eflgid, #{epar2});")
324 elsif nfymode2 == $TENFY_SNDDTQ
325 # データキューへの送信
326 $kernelCfgC.add("\t\t(void) psnd_dtq(#{funcname}_edtqid," \
327 " (intptr_t) ercd);")
328 else
329 error_illegal_id("E_PAR", params, :nfymode, objid)
330 end
331 $kernelCfgC.add("\t}")
332 end
333
334 # 関数の末尾部分の生成
335 $kernelCfgC.add2("}")
336 end
337 return(funcname)
338end
339
340#
341# 各機能モジュールのコンフィギュレーション
342#
343$initializeFunctions = []
344IncludeTrb("kernel/task.trb")
345IncludeTrb("kernel/semaphore.trb")
346IncludeTrb("kernel/eventflag.trb")
347IncludeTrb("kernel/dataqueue.trb")
348IncludeTrb("kernel/pridataq.trb")
349IncludeTrb("kernel/mutex.trb")
350IncludeTrb("kernel/mempfix.trb")
351IncludeTrb("kernel/cyclic.trb")
352IncludeTrb("kernel/alarm.trb")
353IncludeTrb("kernel/interrupt.trb")
354IncludeTrb("kernel/exception.trb")
355
356#
357# 非タスクコンテキスト用のスタック領域
358#
359$kernelCfgC.comment_header("Stack Area for Non-task Context")
360
361if $cfgData[:DEF_ICS].size() == 0
362 # DEF_ICSがない場合のデフォルト値の設定
363 if $DEFAULT_ISTK.nil?
364 # スタック領域の自動割付け
365 istksz = AllocStack("_kernel_istack", "DEFAULT_ISTKSZ")
366 istk = "_kernel_istack"
367 else
368 istksz = "DEFAULT_ISTKSZ"
369 istk = "DEFAULT_ISTK"
370 end
371else
372 # 静的API「DEF_ICS」が複数ある(E_OBJ)[NGKI3216]
373 if $cfgData[:DEF_ICS].size() > 1
374 error("E_OBJ: too many DEF_ICS")
375 end
376
377 # DEF_ICSがある場合の処理
378 params = $cfgData[:DEF_ICS].values[0]
379
380 # istkszがターゲット定義の最小値(TARGET_MIN_ISTKSZ,未定義の場合は1)
381 # よりも小さい場合(E_PAR)[NGKI3254]
382 if params[:istksz] <= $TARGET_MIN_ISTKSZ
383 error_wrong("E_PAR", params, :istksz, "too small")
384 end
385
386 if (params[:istk] == "NULL")
387 # スタック領域の自動割付け
388 istksz = AllocStack("_kernel_istack", params[:istksz])
389 istk = "_kernel_istack"
390 else
391 # istkszがスタック領域のサイズとして正しくない場合(E_PAR)[NGKI3222]
392 if (params[:istksz] & ($CHECK_STKSZ_ALIGN - 1)) != 0
393 error_wrong("E_PAR", params, :istksz, "not aligned")
394 end
395
396 istksz = "(#{params[:istksz]})"
397 istk = "(void *)(#{params[:istk]})"
398 end
399end
400
401$kernelCfgC.append(<<EOS)
402const size_t _kernel_istksz = #{istksz};
403STK_T *const _kernel_istk = #{istk};
404
405#ifdef TOPPERS_ISTKPT
406STK_T *const _kernel_istkpt = TOPPERS_ISTKPT(#{istk}, #{istksz});
407#endif /* TOPPERS_ISTKPT */
408
409EOS
410
411#
412# タイムイベント管理
413#
414$kernelCfgC.comment_header("Time Event Management")
415$kernelCfgC.append(<<EOS)
416TMEVTN _kernel_tmevt_heap[1 + TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];
417
418EOS
419
420#
421# 各モジュールの初期化関数
422#
423$kernelCfgC.comment_header("Module Initialization Function")
424$kernelCfgC.append(<<EOS)
425void
426_kernel_initialize_object(void)
427{
428EOS
429$initializeFunctions.each do |func|
430 $kernelCfgC.add("\t#{func}")
431end
432$kernelCfgC.add2("}")
433
434#
435# 初期化ルーチン機能
436#
437#
438$kernelCfgC.comment_header("Initialization Routine")
439
440# エラーチェック
441$cfgData[:ATT_INI].each do |id, params|
442 # iniatrが無効の場合(E_RSATR)[NGKI3241]
443 #(TA_NULLでない場合)
444 if (params[:iniatr] != 0)
445 error_illegal_sym("E_RSATR", params, :iniatr, :inirtn)
446 end
447end
448
449# 初期化ルーチンの実行関数の生成
450$kernelCfgC.append(<<EOS)
451void
452_kernel_call_inirtn(void)
453{
454EOS
455$cfgData[:ATT_INI].each do |id, params|
456 $kernelCfgC.add("\t((INIRTN)(#{params[:inirtn]}))" \
457 "((intptr_t)(#{params[:exinf]}));")
458end
459$kernelCfgC.add2("}")
460
461#
462# 終了処理ルーチン機能
463#
464$kernelCfgC.comment_header("Termination Routine")
465
466# エラーチェック
467$cfgData[:ATT_TER].each do |id, params|
468 # teratrが無効の場合(E_RSATR)[NGKI3248]
469 #(TA_NULLでない場合)
470 if (params[:teratr] != 0)
471 error_illegal_sym("E_RSATR", params, :teratr, :terrtn)
472 end
473end
474
475# 終了処理ルーチンの実行関数の生成
476$kernelCfgC.append(<<EOS)
477void
478_kernel_call_terrtn(void)
479{
480EOS
481$cfgData[:ATT_TER].reverse_each do |id, params|
482 $kernelCfgC.add("\t((TERRTN)(#{params[:terrtn]}))" \
483 "((intptr_t)(#{params[:exinf]}));")
484end
485$kernelCfgC.add2("}")
486
487#
488# kernel_cfg.hの末尾部分の生成
489#
490$kernelCfgH.append(<<EOS)
491
492#endif /* TOPPERS_KERNEL_CFG_H */
493EOS
Note: See TracBrowser for help on using the repository browser.