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

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

3.1.0を反映

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