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

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

3.0.0のリリース版に追従

File size: 14.4 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 612 2016-02-08 04:27:57Z 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 |key, 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 |key, 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 |key, 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 |key, 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 # 割込み番号intnoに対して登録されたISRのリストの作成
267 isrParamsList = []
268 $cfgData[:CRE_ISR].sort.each do |key, params|
269 if params[:intno].val == intnoVal
270 isrParamsList.push(params)
271 end
272 end
273
274 # 割込み番号intnoに対して登録されたISRが存在する場合
275 if isrParamsList.size > 0
276 inhnoVal = $toInhnoVal[intnoVal]
277
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 # 割込みサービスルーチン用の割込みハンドラ
315 $kernelCfgC.add("void")
316 $kernelCfgC.add("_kernel_inthdr_#{intnoVal}(void)")
317 $kernelCfgC.add("{")
318 # 割込みサービスルーチンを優å…
319ˆåº¦é †ã«å‘¼ã³å‡ºã™
320 i = 0 # stable sortを行うための変数
321 isrParamsList.sort_by {|params| [ params[:isrpri].val, i += 1 ]} \
322 .each_with_index do |params, index|
323 if index > 0
324 $kernelCfgC.add
325 $kernelCfgC.add("\tif (sense_lock()) {")
326 $kernelCfgC.add("\t\tunlock_cpu();")
327 $kernelCfgC.add2("\t}")
328 end
329 $kernelCfgC.add("\tLOG_ISR_ENTER(#{params[:isrid]});")
330 $kernelCfgC.add("\t((ISR)(#{params[:isr]}))" \
331 "((intptr_t)(#{params[:exinf]}));")
332 $kernelCfgC.add("\tLOG_ISR_LEAVE(#{params[:isrid]});")
333 end
334 $kernelCfgC.add2("}")
335 end
336end
337
338#
339# 割込みハンドラのための標準的な初期化情
340報の生成
341#
342if $OMIT_INITIALIZE_INTERRUPT.nil? || !$USE_INHINIB_TABLE.nil?
343 #
344 # 定義する割込みハンドラの数
345 #
346 $kernelCfgC.append(<<EOS)
347#define TNUM_DEF_INHNO #{$cfgData[:DEF_INH].size}
348const uint_t _kernel_tnum_def_inhno = TNUM_DEF_INHNO;
349
350EOS
351
352 if $cfgData[:DEF_INH].size != 0
353 #
354 # 割込みハンドラのエントリ
355 #
356 $cfgData[:DEF_INH].each do |key, params|
357 if (params[:inhatr] & $TA_NONKERNEL) == 0
358 $kernelCfgC.add("INTHDR_ENTRY(#{params[:inhno]}, " \
359 "#{params[:inhno].val}, #{params[:inthdr]})")
360 end
361 end
362 $kernelCfgC.add("")
363
364 #
365 # 割込みハンドラ初期化ブロック
366 #
367 $kernelCfgC.add("const INHINIB _kernel_inhinib_table[TNUM_DEF_INHNO] = {")
368 $cfgData[:DEF_INH].each_with_index do |(key, params), index|
369 $kernelCfgC.add(",") if index > 0
370 if (params[:inhatr] & $TA_NONKERNEL) == 0
371 inthdr = "(FP)(INT_ENTRY(#{params[:inhno]}, #{params[:inthdr]}))"
372 else
373 inthdr = "(FP)(#{params[:inthdr]})"
374 end
375 $kernelCfgC.append("\t{ (#{params[:inhno]}), (#{params[:inhatr]}), " \
376 "#{inthdr} }")
377 end
378 $kernelCfgC.add
379 $kernelCfgC.add2("};")
380 else
381 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INHINIB, " \
382 "_kernel_inhinib_table);")
383 end
384end
385
386#
387# 割込み要求ラインのための標準的な初期化情
388報の生成
389#
390if $OMIT_INITIALIZE_INTERRUPT.nil? || !$USE_INTINIB_TABLE.nil?
391 #
392 # 設定する割込み要求ラインの数
393 #
394 $kernelCfgC.append(<<EOS)
395#define TNUM_CFG_INTNO #{$cfgData[:CFG_INT].size}
396const uint_t _kernel_tnum_cfg_intno = TNUM_CFG_INTNO;
397
398EOS
399
400 #
401 # 割込み要求ライン初期化ブロック
402 #
403 if $cfgData[:CFG_INT].size != 0
404 $kernelCfgC.add("const INTINIB _kernel_intinib_table[TNUM_CFG_INTNO] = {")
405 $cfgData[:CFG_INT].each_with_index do |(key, params), index|
406 $kernelCfgC.add(",") if index > 0
407 $kernelCfgC.append("\t{ (#{params[:intno]}), (#{params[:intatr]}), " \
408 "(#{params[:intpri]}) }")
409 end
410 $kernelCfgC.add
411 $kernelCfgC.add2("};")
412 else
413 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INTINIB, " \
414 "_kernel_intinib_table);")
415 end
416end
417
418#
419# 割込み管理機能初期化関数の追加
420#
421$initializeFunctions.push("_kernel_initialize_interrupt();")
Note: See TracBrowser for help on using the repository browser.