source: EcnlProtoTool/trunk/asp3_dcre/kernel/interrupt.trb

Last change on this file was 439, checked in by coas-nagasima, 4 years ago

mrubyを2.1.1に更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
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-2019 by Embedded and Real-Time Systems Laboratory
9# Graduate School of Information Science, Nagoya Univ., JAPAN
10#
11# 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
12# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16# スコード中に含まれていること.
17# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20# の無保証規定を掲載すること.
21# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23# と.
24# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25# 作権表示,この利用条件および下記の無保証規定を掲載すること.
26# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27# 報告すること.
28# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32# 免責すること.
33#
34# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38# の責任を負わない.
39#
40# $Id$
41#
42
43#
44# 割込み管理機能の生成スクリプト
45#
46
47#
48# kernel_cfg.cの生成
49#
50$kernelCfgC.comment_header("Interrupt Management Functions")
51
52#
53# CRE_ISRで使用できる割込み番号とそれに対応する割込みハンドラ番号のデ
54# フォルト定義
55#
56if !defined?($INTNO_CREISR_VALID)
57 $INTNO_CREISR_VALID = $INTNO_VALID
58end
59if !defined?($INHNO_CREISR_VALID)
60 $INHNO_CREISR_VALID = $INHNO_VALID
61end
62
63#
64# CFG_INTで使用できる割込み優先度のデフォルト定義
65#
66if !defined?($INTPRI_CFGINT_VALID)
67 $INTPRI_CFGINT_VALID = $TMIN_INTPRI.upto($TMAX_INTPRI).to_a
68end
69
70#
71# 割込み番号と割込みハンドラ番号の変換テーブルの作成
72#
73if $INTNO_CREISR_VALID.length != $INHNO_CREISR_VALID.length
74 error_exit("length of `INTNO_CREISR_VALID' is different from" \
75 " length of `INHNO_CREISR_VALID'")
76end
77$toInhnoVal = {}
78$toIntnoVal = {}
79inhno_creisr_valid = $INHNO_CREISR_VALID.dup
80$INTNO_CREISR_VALID.each do |intnoVal|
81 inhnoVal = inhno_creisr_valid.shift
82 $toInhnoVal[intnoVal] = inhnoVal
83 $toIntnoVal[inhnoVal] = intnoVal
84end
85
86#
87# 割込み要求ラインに関するエラーチェック
88#
89$cfgData[:CFG_INT].each do |_, params|
90 # intnoが有効範囲外の場合(E_PAR)[NGKI2972]
91 if !$INTNO_VALID.include?(params[:intno])
92 error_illegal("E_PAR", params, :intno)
93 end
94
95 # intatrが無効の場合(E_RSATR)[NGKI2969][NGKI2944][NGKI2945]
96 #(TA_ENAINT,TA_EDGE,TARGET_INTATR以外のビットがセットされている場合)
97 if (params[:intatr] & ~($TA_ENAINT|$TA_EDGE|$TARGET_INTATR)) != 0
98 error_illegal_sym("E_RSATR", params, :intatr, :intno)
99 end
100
101 # intpriがCFG_INTに対する割込み優先度として正しくない場合(E_PAR)
102 # [NGKI2973]
103 if !$INTPRI_CFGINT_VALID.include?(params[:intpri])
104 error_illegal_sym("E_PAR", params, :intpri, :intno)
105 end
106
107 # カーネル管理外に固定されているintnoに対して,intpriにTMIN_INTPRI以
108 # 上の値が指定された場合(E_OBJ)[NGKI2983]
109 if defined?($INTNO_FIX_NONKERNEL) \
110 && $INTNO_FIX_NONKERNEL.include?(params[:intno])
111 if params[:intpri] >= $TMIN_INTPRI
112 error_ercd("E_OBJ", params, "%%intno must have higher priority " \
113 "than TMIN_INTPRI in %apiname")
114 end
115 end
116
117 # カーネル管理に固定されているintnoに対して,intpriにTMIN_INTPRIより
118 # も小さい値が指定された場合(E_OBJ)[NGKI2984]
119 if defined?($INTNO_FIX_KERNEL) \
120 && $INTNO_FIX_KERNEL.include?(params[:intno])
121 if params[:intpri] < $TMIN_INTPRI
122 error_ercd("E_OBJ", params, "%%intno must have lower or equal " \
123 "priority to TMIN_INTPRI in %apiname")
124 end
125 end
126
127 # ターゲット依存のエラーチェック[NGKI2985]
128 if defined? TargetCheckCfgInt()
129 TargetCheckCfgInt(params)
130 end
131end
132
133#
134# 割込みハンドラに関するエラーチェック
135#
136$cfgData[:DEF_INH].each do |_, params|
137 # inhnoが有効範囲外の場合(E_PAR)[NGKI3055]
138 if !$INHNO_VALID.include?(params[:inhno])
139 error_illegal("E_PAR", params, :inhno)
140 end
141
142 # inhatrが無効の場合(E_RSATR)[NGKI3052][NGKI2957][NGKI2959]
143 #(TARGET_INHATR以外のビットがセットされている場合)
144 if (params[:inhatr] & ~($TARGET_INHATR)) != 0
145 error_illegal_sym("E_RSATR", params, :inhatr, :inhno)
146 end
147
148 # カーネル管理外に固定されているinhnoに対して,inhatrにTA_NONKERNELが
149 # 指定されていない場合(E_RSATR)[NGKI3067]
150 if defined?($INHNO_FIX_NONKERNEL) \
151 && $INHNO_FIX_NONKERNEL.include?(params[:inhno])
152 if (params[:inhatr] & $TA_NONKERNEL) == 0
153 error_ercd("E_RSATR", params, "%%inhno must be " \
154 "non-kernel interrupt in %apiname")
155 end
156 end
157
158 # カーネル管理に固定されているinhnoに対して,inhatrにTA_NONKERNELが指
159 # 定されている場合(E_RSATR)[NGKI3068]
160 if defined?($INHNO_FIX_KERNEL) \
161 && $INHNO_FIX_KERNEL.include?(params[:inhno])
162 if (params[:inhatr] & $TA_NONKERNEL) != 0
163 error_ercd("E_RSATR", params, "%%inhno must not be " \
164 "non-kernel interrupt in %apiname")
165 end
166 end
167
168 if $INHNO_CREISR_VALID.include?(params[:inhno])
169 # 割込みハンドラ番号に対応する割込み番号がある場合
170 intnoVal = $toIntnoVal[params[:inhno].val]
171
172 # inhnoに対応するintnoに対するCFG_INTがない場合(E_OBJ)[NGKI3062]
173 if !$cfgData[:CFG_INT].has_key?(intnoVal)
174 error_ercd("E_OBJ", params, "intno `#{intnoVal}' corresponding to " \
175 "%%inhno in %apiname is not configured with CFG_INT")
176 else
177 intnoParams = $cfgData[:CFG_INT][intnoVal]
178
179 if (params[:inhatr] & $TA_NONKERNEL) == 0
180 # inhatrにTA_NONKERNELが指定されておらず,inhnoに対応するintno
181 # に対してCFG_INTで設定された割込み優先度がTMIN_INTPRIよりも小
182 # さい場合(E_OBJ)[NGKI3065]
183 if intnoParams[:intpri] < $TMIN_INTPRI
184 error_ercd("E_OBJ", params, "intpri `#{intnoParams[:intpri]}' " \
185 "configured for %%inhno must be lower or equal to TMIN_INTPRI")
186 end
187 else
188 # inhatrにTA_NONKERNELが指定されており,inhnoに対応するintnoに
189 # 対してCFG_INTで設定された割込み優先度がTMIN_INTPRI以上である
190 # 場合(E_OBJ)[NGKI3066]
191 if intnoParams[:intpri] >= $TMIN_INTPRI
192 error_ercd("E_OBJ", params, "intpri `#{intnoParams[:intpri]}' " \
193 "configured for %%inhno must be higher than TMIN_INTPRI")
194 end
195 end
196 end
197 end
198
199 # ターゲット依存のエラーチェック[NGKI3078]
200 if defined? TargetCheckDefInh()
201 TargetCheckDefInh(params)
202 end
203end
204
205#
206# 割込みサービスルーチン(ISR)に関するエラーチェック
207#
208$cfgData[:CRE_ISR].sort.each do |_, params|
209 # isratrが無効の場合(E_RSATR)[NGKI2998][NGKI2952][NGKI5176]
210 #(TARGET_ISRATR以外のビットがセットされている場合)
211 if (params[:isratr] & ~($TARGET_ISRATR)) != 0
212 error_illegal("E_RSATR", params, "isratr")
213 end
214
215 # intnoが有効範囲外の場合(E_PAR)[NGKI3003]
216 if !$INTNO_CREISR_VALID.include?(params[:intno])
217 error_illegal("E_PAR", params, "intno")
218 end
219
220 # isrpriが有効範囲外の場合(E_PAR)[NGKI3005]
221 #(TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRIでない場合)
222 if !($TMIN_ISRPRI <= params[:isrpri] && params[:isrpri] <= $TMAX_ISRPRI)
223 error_illegal("E_PAR", params, "isrpri")
224 end
225
226 # intnoに対応するinhnoに対してDEF_INHがある場合(E_OBJ)[NGKI3013]
227 inhnoVal = $toInhnoVal[params[:intno].val]
228 if $cfgData[:DEF_INH].has_key?(inhnoVal)
229 error_ercd("E_OBJ", params, "%%intno in %apiname is duplicated " \
230 "with inhno #{$cfgData[:DEF_INH][inhnoVal][:inhno]}")
231 end
232
233 # intnoに対するCFG_INTがない場合(E_OBJ)[NGKI3012]
234 if !$cfgData[:CFG_INT].has_key?(params[:intno])
235 error_ercd("E_OBJ", params, "%%intno in %apiname " \
236 "is not configured with CFG_INT")
237 else
238 intnoParams = $cfgData[:CFG_INT][params[:intno]]
239
240 # intnoでカーネル管理外の割込みを指定した場合(E_OBJ)[NGKI3014]
241 #(intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRIよりも小
242 # さい場合)
243 if intnoParams[:intpri] < $TMIN_INTPRI
244 error_ercd("E_OBJ", params,
245 "intpri `#{intnoParams[:intpri]}' configured for " \
246 "%%intno with CFG_INT in higher than TMIN_INTPRI")
247 end
248 end
249
250 # ターゲット依存のエラーチェック
251 if defined? TargetCheckCreIsr()
252 TargetCheckCreIsr(params)
253 end
254end
255
256#
257# 割込みサービスルーチン(ISR)管理のデータ構造
258#
259intnoIsrList = []
260$INTNO_CREISR_VALID.each do |intnoVal|
261 inhnoVal = $toInhnoVal[intnoVal]
262 if $cfgData[:CFG_INT].has_key?(intnoVal) \
263 && !$cfgData[:DEF_INH].has_key?(inhnoVal)
264 intnoIsrList.push(intnoVal)
265 end
266end
267
268intnoIsrList.sort!
269$isrQueueHeader = {}
270intnoIsrList.each_with_index do |intnoVal, index|
271 $isrQueueHeader[intnoVal] = "&(_kernel_isr_queue_table[#{index}])"
272end
273
274$kernelCfgC.add2("const uint_t _kernel_tnum_isr_queue = #{intnoIsrList.size};")
275
276if intnoIsrList.size > 0
277 $kernelCfgC.add("const ISR_ENTRY _kernel_isr_queue_list" \
278 "[#{intnoIsrList.size}] = {")
279 intnoIsrList.each_with_index do |intnoVal, index|
280 $kernelCfgC.add(",") if index > 0
281 $kernelCfgC.append("\t{ #{intnoVal}, #{$isrQueueHeader[intnoVal]} }")
282 end
283 $kernelCfgC.add
284 $kernelCfgC.add2("};")
285 $kernelCfgC.add2("QUEUE _kernel_isr_queue_table[#{intnoIsrList.size}];")
286else
287 $kernelCfgC.add("TOPPERS_EMPTY_LABEL(const ISR_ENTRY, " \
288 "_kernel_isr_queue_list);")
289 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(QUEUE, _kernel_isr_queue_table);")
290end
291
292#
293# 割込みサービスルーチン(ISR)呼出しのための割込みハンドラ
294#
295intnoIsrList.each do |intnoVal|
296 inhnoVal = $toInhnoVal[intnoVal]
297
298 # 次の静的APIに相当するデータを生成
299 # DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
300 $cfgData[:DEF_INH][inhnoVal] = {
301 inhno: NumStr.new(inhnoVal),
302 inhatr: NumStr.new($TA_NULL, "TA_NULL"),
303 inthdr: "_kernel_inthdr_#{intnoVal}"
304 }
305
306 # 割込みサービスルーチンを呼び出す割込みハンドラの生成[NGKI2941]
307 $kernelCfgC.add("void")
308 $kernelCfgC.add("_kernel_inthdr_#{intnoVal}(void)")
309 $kernelCfgC.add("{")
310 $kernelCfgC.add("\t_kernel_call_isr(#{$isrQueueHeader[intnoVal]});");
311 $kernelCfgC.add2("}")
312end
313
314#
315# 割込みサービスルーチンに関する一般的な情報の生成
316#
317class IsrObject < KernelObject
318 def initialize()
319 super("isr", "isr")
320 end
321
322 def prepare(key, params)
323 # エラーチェックは実施済みなので,ここでの処理は不要
324 end
325
326 def generateInib(key, params)
327 return("(#{params[:isratr]}), (intptr_t)(#{params[:exinf]}), " \
328 "(#{$isrQueueHeader[params[:intno].val]}), " \
329 "(ISR)(#{params[:isr]}), (#{params[:isrpri]})")
330 end
331end
332IsrObject.new.generate()
333
334# 割込みサービスルーチン生成順序テーブルの生成
335if $cfgData[:CRE_ISR].size != 0
336 $kernelCfgC.add("const ID _kernel_isrorder_table[TNUM_SISRID] = { ")
337 $kernelCfgC.append("\t")
338 $cfgData[:CRE_ISR].each_with_index do |(_, params), index|
339 $kernelCfgC.append(", ") if index > 0
340 $kernelCfgC.append("#{params[:isrid]}")
341 end
342 $kernelCfgC.add
343 $kernelCfgC.add2("};")
344else
345 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const ID, " \
346 "_kernel_isrorder_table);")
347end
348
349#
350# 割込みハンドラのための標準的な初期化情報の生成
351#
352if !$OMIT_INITIALIZE_INTERRUPT || $USE_INHINIB_TABLE
353 #
354 # 定義する割込みハンドラの数
355 #
356 $kernelCfgC.add(<<EOS)
357#define TNUM_DEF_INHNO #{$cfgData[:DEF_INH].size}
358const uint_t _kernel_tnum_def_inhno = TNUM_DEF_INHNO;
359EOS
360
361 if $cfgData[:DEF_INH].size != 0
362 #
363 # 割込みハンドラのエントリ
364 #
365 $cfgData[:DEF_INH].each do |_, params|
366 if (params[:inhatr] & $TA_NONKERNEL) == 0
367 $kernelCfgC.add("INTHDR_ENTRY(#{params[:inhno]}, " \
368 "#{params[:inhno].val}, #{params[:inthdr]})")
369 end
370 end
371 $kernelCfgC.add("")
372
373 #
374 # 割込みハンドラ初期化ブロック
375 #
376 $kernelCfgC.add("const INHINIB _kernel_inhinib_table[TNUM_DEF_INHNO] = {")
377 $cfgData[:DEF_INH].each_with_index do |(_, params), index|
378 $kernelCfgC.add(",") if index > 0
379 if (params[:inhatr] & $TA_NONKERNEL) == 0
380 inthdr = "(FP)(INT_ENTRY(#{params[:inhno]}, #{params[:inthdr]}))"
381 else
382 inthdr = "(FP)(#{params[:inthdr]})"
383 end
384 $kernelCfgC.append("\t{ (#{params[:inhno]}), (#{params[:inhatr]}), " \
385 "#{inthdr} }")
386 end
387 $kernelCfgC.add
388 $kernelCfgC.add2("};")
389 else
390 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INHINIB, " \
391 "_kernel_inhinib_table);")
392 end
393end
394
395#
396# 割込み要求ラインのための標準的な初期化情報の生成
397#
398if !$OMIT_INITIALIZE_INTERRUPT || $USE_INTINIB_TABLE
399 #
400 # 設定する割込み要求ラインの数
401 #
402 $kernelCfgC.add(<<EOS)
403#define TNUM_CFG_INTNO #{$cfgData[:CFG_INT].size}
404const uint_t _kernel_tnum_cfg_intno = TNUM_CFG_INTNO;
405EOS
406
407 #
408 # 割込み要求ライン初期化ブロック
409 #
410 if $cfgData[:CFG_INT].size != 0
411 $kernelCfgC.add("const INTINIB _kernel_intinib_table[TNUM_CFG_INTNO] = {")
412 $cfgData[:CFG_INT].each_with_index do |(_, params), index|
413 $kernelCfgC.add(",") if index > 0
414 $kernelCfgC.append("\t{ (#{params[:intno]}), (#{params[:intatr]}), " \
415 "(#{params[:intpri]}) }")
416 end
417 $kernelCfgC.add
418 $kernelCfgC.add2("};")
419 else
420 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INTINIB, " \
421 "_kernel_intinib_table);")
422 end
423end
424
425#
426# 割込み管理機能初期化関数の追加
427#
428$initializeFunctions.push("_kernel_initialize_interrupt();")
Note: See TracBrowser for help on using the repository browser.