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

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

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

File size: 14.2 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: interrupt.trb 572 2016-02-01 14:40:09Z ertl-hiro $
56#
57
58#
59# 割込み管理機能の生成スクリプト
60#
61
62#
63# kernel_cfg.hの生成
64#
65$kernelCfgH.add("#define TNUM_ISRID\t#{$cfgData[:CRE_ISR].size}")
66
67$cfgData[:CRE_ISR].sort.each do |id, params|
68 $kernelCfgH.add("#define #{params[:isrid]}\t#{params[:isrid].val}")
69end
70$kernelCfgH.add()
71
72#
73# kernel_cfg.cの生成
74#
75$kernelCfgC.comment_header("Interrupt Management Functions")
76
77#
78# トレースログマクロのデフォルト定義
79#
80$kernelCfgC.append(<<EOS)
81#ifndef LOG_ISR_ENTER
82#define LOG_ISR_ENTER(isrid)
83#endif /* LOG_ISR_ENTER */
84
85#ifndef LOG_ISR_LEAVE
86#define LOG_ISR_LEAVE(isrid)
87#endif /* LOG_ISR_LEAVE */
88
89EOS
90
91#
92# CRE_ISRで使用できる割込み番号とそれに対応する割込みハンドラ番号のデ
93# フォルト定義
94#
95if $INTNO_CREISR_VALID.nil?
96 $INTNO_CREISR_VALID = $INTNO_VALID
97end
98if $INHNO_CREISR_VALID.nil?
99 $INHNO_CREISR_VALID = $INHNO_VALID
100end
101
102#
103# CFG_INTで使用できる割込み優å…
104ˆåº¦ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå®šç¾©
105#
106if $INTPRI_CFGINT_VALID.nil?
107 $INTPRI_CFGINT_VALID = $TMIN_INTPRI.val.upto($TMAX_INTPRI.val).to_a
108end
109
110#
111# 割込み番号と割込みハンドラ番号の変換テーブルの作成
112#
113if $INTNO_CREISR_VALID.length != $INHNO_CREISR_VALID.length
114 error_exit("length of `INTNO_CREISR_VALID' is different from" \
115 " length of `INHNO_CREISR_VALID'")
116end
117$toInhnoVal = {}
118$toIntnoVal = {}
119inhno_creisr_valid = $INHNO_CREISR_VALID.dup
120$INTNO_CREISR_VALID.each do |intnoVal|
121 inhnoVal = inhno_creisr_valid.shift
122 $toInhnoVal[intnoVal] = inhnoVal
123 $toIntnoVal[inhnoVal] = intnoVal
124end
125
126#
127# 割込み要求ラインに関するエラーチェック
128#
129$cfgData[:CFG_INT].each do |id, params|
130 # intnoが割込み番号として正しくない場合(E_PAR)[NGKI2972]
131 if $INTNO_VALID.index(params[:intno]).nil?
132 error_illegal("E_PAR", params, :intno)
133 end
134
135 # intatrが無効の場合(E_RSATR)[NGKI2969]
136 #(TA_ENAINT,TA_EDGE,TARGET_INTATR以外のビットがセットされている場合)
137 if (params[:intatr] & ~($TA_ENAINT|$TA_EDGE|$TARGET_INTATR)) != 0
138 error_illegal_sym("E_RSATR", params, :intatr, :intno)
139 end
140
141 # intpriがCFG_INTに対する割込み優å…
142ˆåº¦ã¨ã—て正しくない場合(E_PAR)
143 # ï¼»NGKI2973ï¼½
144 if $INTPRI_CFGINT_VALID.index(params[:intpri]).nil?
145 error_illegal_sym("E_OBJ", params, :intpri, :intno)
146 end
147
148 # カーネル管理外に固定されているintnoに対して,intpriにTMIN_INTPRIよ
149 # りも小さい値が指定されなかった場合(E_OBJ)[NGKI2983]
150 if !$INTNO_FIX_NONKERNEL.nil?
151 if !$INTNO_FIX_NONKERNEL.index(params[:intno]).nil?
152 if params[:intpri] >= $TMIN_INTPRI
153 error_ercd("E_OBJ", params, "intno `#{params[:intno]}'" \
154 " must have higher priority than TMIN_INTPRI")
155 end
156 end
157 end
158
159 # カーネル管理に固定されているintnoに対して,intpriにTMIN_INTPRIより
160 # も小さい値が指定された場合(E_OBJ)[NGKI2984]
161 if !$INTNO_FIX_KERNEL.nil?
162 if !$INTNO_FIX_KERNEL.index(params[:intno]).nil?
163 if params[:intpri] < $TMIN_INTPRI
164 error_ercd("E_OBJ", params, "intno `#{params[:intno]}'" \
165 " must have lower or equal priority to TMIN_INTPRI")
166 end
167 end
168 end
169end
170
171#
172# 割込みハンドラに関するエラーチェック
173#
174$cfgData[:DEF_INH].each do |id, params|
175 # inhnoが割込みハンドラ番号として正しくない場合(E_PAR)[NGKI3055]
176 if $INHNO_VALID.index(params[:inhno]).nil?
177 error_illegal("E_PAR", params, :inhno)
178 end
179
180 # inhatrが無効の場合(E_RSATR)[NGKI3052]
181 #(TARGET_INHATR以外のビットがセットされている場合)
182 if (params[:inhatr] & ~$TARGET_INHATR) != 0
183 error_illegal_sym("E_RSATR", params, :inhatr, :inhno)
184 end
185
186 # カーネル管理外に固定されているinhnoに対して,inhatrにTA_NONKERNELが
187 # 指定されていない場合(E_RSATR)[NGKI3067]
188 if !$INHNO_FIX_NONKERNEL.nil?
189 if !$INHNO_FIX_NONKERNEL.index(params[:inhno]).nil?
190 if (params[:inhatr] & $TA_NONKERNEL) == 0
191 error_ercd("E_RSATR", params, "inhno `#{params[:inhno]}'" \
192 " must be non-kernel interrupt")
193 end
194 end
195 end
196
197 # カーネル管理に固定されているinhnoに対して,inhatrにTA_NONKERNELが指
198 # 定されている場合(E_RSATR)[NGKI3068]
199 if !$INHNO_FIX_KERNEL.nil?
200 if !$INHNO_FIX_KERNEL.index(params[:inhno]).nil?
201 if (params[:inhatr] & $TA_NONKERNEL) != 0
202 error_ercd("E_RSATR", params, "inhno `#{params[:inhno]}'" \
203 " must not be non-kernel interrupt")
204 end
205 end
206 end
207
208 if $toIntnoVal.has_key?(params[:inhno].val)
209 intnoVal = $toIntnoVal[params[:inhno].val]
210
211 # inhnoに対応するintnoに対するCFG_INTがない場合(E_OBJ)[NGKI3062]
212 if !$cfgData[:CFG_INT].has_key?(intnoVal)
213 error_ercd("E_OBJ", params, "intno `#{intnoVal}' corresponding to" \
214 " inhno `#{params[:inhno]}' is not configured with CFG_INT")
215 else
216 intnoParams = $cfgData[:CFG_INT][intnoVal]
217 if (params[:inhatr] & $TA_NONKERNEL) == 0
218 # inhatrにTA_NONKERNELが指定されておらず,inhnoに対応するintno
219 # に対してCFG_INTで設定された割込み優å…
220ˆåº¦ãŒTMIN_INTPRIよりも小
221 # さい場合(E_OBJ)[NGKI3065]
222 if intnoParams[:intpri] < $TMIN_INTPRI
223 error_ercd("E_OBJ", params, "intpri `#{intnoParams[:intpri]}'" \
224 " configured for inhno `#{params[:inhno]}' must" \
225 " be lower or equal to TMIN_INTPRI")
226 end
227 else
228 # inhatrにTA_NONKERNELが指定されており,inhnoに対応するintnoに
229 # 対してCFG_INTで設定された割込み優å…
230ˆåº¦ãŒTMIN_INTPRI以上である
231 # 場合(E_OBJ)[NGKI3066]
232 if intnoParams[:intpri] >= $TMIN_INTPRI
233 error_ercd("E_OBJ", params, "intpri `#{intnoParams[:intpri]}'" \
234 " configured for inhno `#{params[:inhno]}' must" \
235 " be higher than with TMIN_INTPRI")
236 end
237 end
238 end
239 end
240end
241
242#
243# 割込みサービスルーチン(ISR)に関するエラーチェックと割込みハンドラの生成
244#
245$cfgData[:CRE_ISR].sort.each do |id, params|
246 # isratrが無効の場合(E_RSATR)[NGKI2998]
247 #(TARGET_ISRATR以外のビットがセットされている場合)
248 if (params[:isratr] & ~$TARGET_ISRATR) != 0
249 error_illegal("E_RSATR", params, "isratr")
250 end
251
252 # intnoがCRE_ISRに対する割込み番号として正しくない場合(E_PAR)
253 # ï¼»NGKI3003ï¼½
254 if $INTNO_CREISR_VALID.index(params[:intno]).nil?
255 error_illegal("E_PAR", params, "intno")
256 end
257
258 # (TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合(E_PAR)
259 # ï¼»NGKI3005ï¼½
260 if !($TMIN_ISRPRI <= params[:isrpri] && params[:isrpri] <= $TMAX_ISRPRI)
261 error_illegal("E_PAR", params, "isrpri")
262 end
263end
264
265$INTNO_CREISR_VALID.each do |intnoVal|
266 inhnoVal = $toInhnoVal[intnoVal]
267
268 # 割込み番号intnoに対して登録されたISRのリストの作成
269 isrParamsList = []
270 $cfgData[:CRE_ISR].sort.each do |id, params|
271 if params[:intno] == intnoVal
272 isrParamsList.push(params)
273 end
274 end
275
276 # 割込み番号intnoに対して登録されたISRが存在する場合
277 if isrParamsList.size > 0
278 # intnoに対応するinhnoに対してDEF_INHがある場合(E_OBJ)[NGKI3013]
279 if $cfgData[:DEF_INH].has_key?(inhnoVal)
280 inhnoParams = $cfgData[:DEF_INH][inhnoVal]
281 error_ercd("E_OBJ", isrParamsList[0], \
282 "intno `#{isrParamsList[0][:intno]}' in CRE_ISR" \
283 " is duplicated with inhno #{inhnoParams[:inhno]}")
284 end
285
286 # intnoに対するCFG_INTがない場合(E_OBJ)[NGKI3012]
287 if !$cfgData[:CFG_INT].has_key?(intnoVal)
288 error_ercd("E_OBJ", isrParamsList[0], \
289 "intno `#{isrParamsList[0][:intno]}'" \
290 " is not configured with CFG_INT")
291 else
292 intnoParams = $cfgData[:CFG_INT][intnoVal]
293
294 # intnoに対してCFG_INTで設定された割込み優å…
295ˆåº¦ãŒTMIN_INTPRIよりも
296 # 小さい場合(E_OBJ)[NGKI3014]
297 if intnoParams[:intpri] < $TMIN_INTPRI
298 error_ercd("E_OBJ", isrParamsList[0],
299 "intpri `#{intnoParams[:intpri]}' configured for" \
300 " intno `#{isrParamsList[0][:intno]}}' in higher" \
301 " than TMIN_INTPRI")
302 end
303 end
304
305 # 次のDEF_INHに相当するデータを生成
306 # DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
307 params = {
308 :inhno => StrVal.new(inhnoVal.to_s, inhnoVal),
309 :inhatr => $TA_NULL,
310 :inthdr => StrVal.new("_kernel_inthdr_#{intnoVal}")
311 }
312 $cfgData[:DEF_INH][inhnoVal] = params
313
314 # ISR用の割込みハンドラ
315 $kernelCfgC.add("void")
316 $kernelCfgC.add("_kernel_inthdr_#{intnoVal}(void)")
317 $kernelCfgC.add("{")
318 # ISRを優å…
319ˆåº¦é †ã«å‘¼ã³å‡ºã™
320 isrParamsList.sort_by {|params| params[:isrpri]}.each_with_index \
321 do |params, index|
322 if index > 0
323 $kernelCfgC.add
324 $kernelCfgC.add("\tif (sense_lock()) {")
325 $kernelCfgC.add("\t\tunlock_cpu();")
326 $kernelCfgC.add2("\t}")
327 end
328 $kernelCfgC.add("\tLOG_ISR_ENTER(#{params[:isrid]});")
329 $kernelCfgC.add("\t((ISR)(#{params[:isr]}))" \
330 "((intptr_t)(#{params[:exinf]}));")
331 $kernelCfgC.add("\tLOG_ISR_LEAVE(#{params[:isrid]});")
332 end
333 $kernelCfgC.add2("}")
334 end
335end
336
337#
338# 割込みハンドラのための標準的な初期化情
339報の生成
340#
341if $OMIT_INITIALIZE_INTERRUPT.nil? || !$USE_INHINIB_TABLE.nil?
342 #
343 # 定義する割込みハンドラの数
344 #
345 $kernelCfgC.append(<<EOS)
346#define TNUM_DEF_INHNO #{$cfgData[:DEF_INH].size}
347const uint_t _kernel_tnum_def_inhno = TNUM_DEF_INHNO;
348
349EOS
350
351 if $cfgData[:DEF_INH].size != 0
352 #
353 # 割込みハンドラのエントリ
354 #
355 $cfgData[:DEF_INH].each do |id, params|
356 if (params[:inhatr] & $TA_NONKERNEL) == 0
357 $kernelCfgC.add("INTHDR_ENTRY(#{params[:inhno]}, " \
358 "#{params[:inhno].val}, #{params[:inthdr]})")
359 end
360 end
361 $kernelCfgC.add("")
362
363 #
364 # 割込みハンドラ初期化ブロック
365 #
366 $kernelCfgC.add("const INHINIB _kernel_inhinib_table[TNUM_DEF_INHNO] = {")
367 $cfgData[:DEF_INH].each_with_index do |(id, params), index|
368 $kernelCfgC.add(",") if index > 0
369 if (params[:inhatr] & $TA_NONKERNEL) == 0
370 inthdr = "(FP)(INT_ENTRY(#{params[:inhno]}, #{params[:inthdr]}))"
371 else
372 inthdr = "(FP)(#{params[:inthdr]})"
373 end
374 $kernelCfgC.append("\t{ (#{params[:inhno]}), (#{params[:inhatr]}), " \
375 "#{inthdr} }")
376 end
377 $kernelCfgC.add
378 $kernelCfgC.add2("};")
379 else
380 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INHINIB, " \
381 "_kernel_inhinib_table);")
382 end
383end
384
385#
386# 割込み要求ラインのための標準的な初期化情
387報の生成
388#
389if $OMIT_INITIALIZE_INTERRUPT.nil? || !$USE_INTINIB_TABLE.nil?
390 #
391 # 設定する割込み要求ラインの数
392 #
393 $kernelCfgC.append(<<EOS)
394#define TNUM_CFG_INTNO #{$cfgData[:CFG_INT].size}
395const uint_t _kernel_tnum_cfg_intno = TNUM_CFG_INTNO;
396
397EOS
398
399 #
400 # 割込み要求ライン初期化ブロック
401 #
402 if $cfgData[:CFG_INT].size != 0
403 $kernelCfgC.add("const INTINIB _kernel_intinib_table[TNUM_CFG_INTNO] = {")
404 $cfgData[:CFG_INT].each_with_index do |(id, params), index|
405 $kernelCfgC.add(",") if index > 0
406 $kernelCfgC.append("\t{ (#{params[:intno]}), (#{params[:intatr]}), " \
407 "(#{params[:intpri]}) }")
408 end
409 $kernelCfgC.add
410 $kernelCfgC.add2("};")
411 else
412 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INTINIB, " \
413 "_kernel_intinib_table);")
414 end
415end
416
417#
418# 割込み管理機能初期化関数の追加
419#
420$initializeFunctions.push("_kernel_initialize_interrupt();")
Note: See TracBrowser for help on using the repository browser.