source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/kernel/interrupt.trb@ 337

Last change on this file since 337 was 337, checked in by coas-nagasima, 6 years ago

ASP3版ECNLを追加

  • 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,2016 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 $INTNO_CREISR_VALID.nil?
57 $INTNO_CREISR_VALID = $INTNO_VALID
58end
59if $INHNO_CREISR_VALID.nil?
60 $INHNO_CREISR_VALID = $INHNO_VALID
61end
62
63#
64# CFG_INTで使用できる割込み優先度のデフォルト定義
65#
66if $INTPRI_CFGINT_VALID.nil?
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 |key, params|
90 # intnoが割込み番号として正しくない場合(E_PAR)[NGKI2972]
91 if $INTNO_VALID.index(params[:intno]).nil?
92 error_illegal("E_PAR", params, :intno)
93 end
94
95 # intatrが無効の場合(E_RSATR)[NGKI2969]
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.index(params[:intpri]).nil?
104 error_illegal_sym("E_OBJ", params, :intpri, :intno)
105 end
106
107 # カーネル管理外に固定されているintnoに対して,intpriにTMIN_INTPRIよ
108 # りも小さい値が指定されなかった場合(E_OBJ)[NGKI2983]
109 if !$INTNO_FIX_NONKERNEL.nil?
110 if !$INTNO_FIX_NONKERNEL.index(params[:intno]).nil?
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 end
117
118 # カーネル管理に固定されているintnoに対して,intpriにTMIN_INTPRIより
119 # も小さい値が指定された場合(E_OBJ)[NGKI2984]
120 if !$INTNO_FIX_KERNEL.nil?
121 if !$INTNO_FIX_KERNEL.index(params[:intno]).nil?
122 if params[:intpri] < $TMIN_INTPRI
123 error_ercd("E_OBJ", params, "%%intno must have lower or equal " \
124 "priority to TMIN_INTPRI in %apiname")
125 end
126 end
127 end
128end
129
130#
131# 割込みハンドラに関するエラーチェック
132#
133$cfgData[:DEF_INH].each do |key, params|
134 # inhnoが割込みハンドラ番号として正しくない場合(E_PAR)[NGKI3055]
135 if $INHNO_VALID.index(params[:inhno]).nil?
136 error_illegal("E_PAR", params, :inhno)
137 end
138
139 # inhatrが無効の場合(E_RSATR)[NGKI3052]
140 #(TARGET_INHATR以外のビットがセットされている場合)
141 if (params[:inhatr] & ~($TARGET_INHATR)) != 0
142 error_illegal_sym("E_RSATR", params, :inhatr, :inhno)
143 end
144
145 # カーネル管理外に固定されているinhnoに対して,inhatrにTA_NONKERNELが
146 # 指定されていない場合(E_RSATR)[NGKI3067]
147 if !$INHNO_FIX_NONKERNEL.nil?
148 if !$INHNO_FIX_NONKERNEL.index(params[:inhno]).nil?
149 if (params[:inhatr] & $TA_NONKERNEL) == 0
150 error_ercd("E_RSATR", params, "%%inhno must be " \
151 "non-kernel interrupt in %apiname")
152 end
153 end
154 end
155
156 # カーネル管理に固定されているinhnoに対して,inhatrにTA_NONKERNELが指
157 # 定されている場合(E_RSATR)[NGKI3068]
158 if !$INHNO_FIX_KERNEL.nil?
159 if !$INHNO_FIX_KERNEL.index(params[:inhno]).nil?
160 if (params[:inhatr] & $TA_NONKERNEL) != 0
161 error_ercd("E_RSATR", params, "%%inhno must not be " \
162 "non-kernel interrupt in %apiname")
163 end
164 end
165 end
166
167 if $toIntnoVal.has_key?(params[:inhno].val)
168 intnoVal = $toIntnoVal[params[:inhno].val]
169
170 # inhnoに対応するintnoに対するCFG_INTがない場合(E_OBJ)[NGKI3062]
171 if !$cfgData[:CFG_INT].has_key?(intnoVal)
172 error_ercd("E_OBJ", params, "intno `#{intnoVal}' corresponding to " \
173 "%%inhno in %apiname is not configured with CFG_INT")
174 else
175 intnoParams = $cfgData[:CFG_INT][intnoVal]
176 if (params[:inhatr] & $TA_NONKERNEL) == 0
177 # inhatrにTA_NONKERNELが指定されておらず,inhnoに対応するintno
178 # に対してCFG_INTで設定された割込み優先度がTMIN_INTPRIよりも小
179 # さい場合(E_OBJ)[NGKI3065]
180 if intnoParams[:intpri] < $TMIN_INTPRI
181 error_ercd("E_OBJ", params, "intpri `#{intnoParams[:intpri]}' " \
182 "configured for %%inhno must be lower or equal to TMIN_INTPRI")
183 end
184 else
185 # inhatrにTA_NONKERNELが指定されており,inhnoに対応するintnoに
186 # 対してCFG_INTで設定された割込み優先度がTMIN_INTPRI以上である
187 # 場合(E_OBJ)[NGKI3066]
188 if intnoParams[:intpri] >= $TMIN_INTPRI
189 error_ercd("E_OBJ", params, "intpri `#{intnoParams[:intpri]}' " \
190 "configured for %%inhno must be higher than TMIN_INTPRI")
191 end
192 end
193 end
194 end
195end
196
197#
198# 割込みサービスルーチン(ISR)に関するエラーチェック
199#
200$cfgData[:CRE_ISR].sort.each do |key, params|
201 # isratrが無効の場合(E_RSATR)[NGKI2998]
202 #(TARGET_ISRATR以外のビットがセットされている場合)
203 if (params[:isratr] & ~($TARGET_ISRATR)) != 0
204 error_illegal("E_RSATR", params, "isratr")
205 end
206
207 # intnoがCRE_ISRに対する割込み番号として正しくない場合(E_PAR)
208 # [NGKI3003]
209 if $INTNO_CREISR_VALID.index(params[:intno]).nil?
210 error_illegal("E_PAR", params, "intno")
211 end
212
213 # (TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合(E_PAR)
214 # [NGKI3005]
215 if !($TMIN_ISRPRI <= params[:isrpri] && params[:isrpri] <= $TMAX_ISRPRI)
216 error_illegal("E_PAR", params, "isrpri")
217 end
218end
219
220$INTNO_CREISR_VALID.each do |intnoVal|
221 # 割込み番号intnoに対して登録されたISRのリストの作成
222 isrParamsList = []
223 $cfgData[:CRE_ISR].sort.each do |key, params|
224 if params[:intno] == intnoVal
225 isrParamsList.push(params)
226 end
227 end
228
229 # 割込み番号intnoに対して登録されたISRが存在する場合
230 if isrParamsList.size > 0
231 inhnoVal = $toInhnoVal[intnoVal]
232
233 # intnoに対応するinhnoに対してDEF_INHがある場合(E_OBJ)[NGKI3013]
234 if $cfgData[:DEF_INH].has_key?(inhnoVal)
235 inhnoParams = $cfgData[:DEF_INH][inhnoVal]
236 error_ercd("E_OBJ", isrParamsList[0], "%%intno in %apiname " \
237 "is duplicated with inhno #{inhnoParams[:inhno]}")
238 end
239
240 # intnoに対するCFG_INTがない場合(E_OBJ)[NGKI3012]
241 if !$cfgData[:CFG_INT].has_key?(intnoVal)
242 error_ercd("E_OBJ", isrParamsList[0], "%%intno in %apiname " \
243 "is not configured with CFG_INT")
244 else
245 intnoParams = $cfgData[:CFG_INT][intnoVal]
246
247 # intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRIよりも
248 # 小さい場合(E_OBJ)[NGKI3014]
249 if intnoParams[:intpri] < $TMIN_INTPRI
250 error_ercd("E_OBJ", isrParamsList[0],
251 "intpri `#{intnoParams[:intpri]}' configured for " \
252 "%%intno with CFG_INT in higher than TMIN_INTPRI")
253 end
254 end
255 end
256end
257
258#
259# 割込みサービスルーチン(ISR)管理のデータ構造
260#
261intnoIsrList = []
262$INTNO_CREISR_VALID.each do |intnoVal|
263 inhnoVal = $toInhnoVal[intnoVal]
264 if $cfgData[:CFG_INT].has_key?(intnoVal) \
265 && !$cfgData[:DEF_INH].has_key?(inhnoVal)
266 intnoIsrList.push(intnoVal)
267 end
268end
269
270intnoIsrList.sort!
271$isrQueueHeader = {}
272intnoIsrList.each_with_index do |intnoVal, index|
273 $isrQueueHeader[intnoVal] = "&(_kernel_isr_queue_table[#{index}])"
274end
275
276$kernelCfgC.add2("const uint_t _kernel_tnum_isr_queue = #{intnoIsrList.size};")
277
278if intnoIsrList.size > 0
279 $kernelCfgC.add("const ISR_ENTRY _kernel_isr_queue_list" \
280 "[#{intnoIsrList.size}] = {")
281 intnoIsrList.each_with_index do |intnoVal, index|
282 $kernelCfgC.add(",") if index > 0
283 $kernelCfgC.append("\t{ #{intnoVal}, #{$isrQueueHeader[intnoVal]} }")
284 end
285 $kernelCfgC.add
286 $kernelCfgC.add2("};")
287 $kernelCfgC.add2("QUEUE _kernel_isr_queue_table[#{intnoIsrList.size}];")
288else
289 $kernelCfgC.add("TOPPERS_EMPTY_LABEL(const ISR_ENTRY, " \
290 "_kernel_isr_queue_list);")
291 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(QUEUE, _kernel_isr_queue_table);")
292end
293
294#
295# 割込みサービスルーチン(ISR)呼出しのための割込みハンドラ
296#
297intnoIsrList.each do |intnoVal|
298 inhnoVal = $toInhnoVal[intnoVal]
299
300 # 次のDEF_INHに相当するデータを生成
301 # DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
302 $cfgData[:DEF_INH][inhnoVal] = {
303 inhno: NumStr.new(inhnoVal),
304 inhatr: NumStr.new($TA_NULL, "TA_NULL"),
305 inthdr: "_kernel_inthdr_#{intnoVal}"
306 }
307
308 # 割込みサービスルーチン用の割込みハンドラ
309 $kernelCfgC.add("void")
310 $kernelCfgC.add("_kernel_inthdr_#{intnoVal}(void)")
311 $kernelCfgC.add("{")
312 $kernelCfgC.add("\t_kernel_call_isr(#{$isrQueueHeader[intnoVal]});");
313 $kernelCfgC.add2("}")
314end
315
316#
317# 割込みサービスルーチンに関する一般的な情報の生成
318#
319class IsrObject < KernelObject
320 def initialize()
321 super("isr", "isr")
322 end
323
324 def prepare(key, params)
325 # エラーチェックは実施済みなので,ここでの処理は不要
326 end
327
328 def generateInib(key, params)
329 return("(#{params[:isratr]}), (intptr_t)(#{params[:exinf]}), " \
330 "(#{$isrQueueHeader[params[:intno].val]}), " \
331 "(ISR)(#{params[:isr]}), (#{params[:isrpri]})")
332 end
333end
334IsrObject.new.generate()
335
336# 割込みサービスルーチン生成順序テーブルの生成
337if $cfgData[:CRE_ISR].size != 0
338 $kernelCfgC.add("const ID _kernel_isrorder_table[TNUM_SISRID] = { ")
339 $kernelCfgC.append("\t")
340 $cfgData[:CRE_ISR].each_with_index do |(key, params), index|
341 $kernelCfgC.append(", ") if index > 0
342 $kernelCfgC.append("#{params[:isrid]}")
343 end
344 $kernelCfgC.add
345 $kernelCfgC.add2("};")
346else
347 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const ID, " \
348 "_kernel_isrorder_table);")
349end
350
351#
352# 割込みハンドラのための標準的な初期化情報の生成
353#
354if !$OMIT_INITIALIZE_INTERRUPT || $USE_INHINIB_TABLE
355 #
356 # 定義する割込みハンドラの数
357 #
358 $kernelCfgC.add(<<EOS)
359#define TNUM_DEF_INHNO #{$cfgData[:DEF_INH].size}
360const uint_t _kernel_tnum_def_inhno = TNUM_DEF_INHNO;
361EOS
362
363 if $cfgData[:DEF_INH].size != 0
364 #
365 # 割込みハンドラのエントリ
366 #
367 $cfgData[:DEF_INH].each do |key, params|
368 if (params[:inhatr] & $TA_NONKERNEL) == 0
369 $kernelCfgC.add("INTHDR_ENTRY(#{params[:inhno]}, " \
370 "#{params[:inhno].val}, #{params[:inthdr]})")
371 end
372 end
373 $kernelCfgC.add("")
374
375 #
376 # 割込みハンドラ初期化ブロック
377 #
378 $kernelCfgC.add("const INHINIB _kernel_inhinib_table[TNUM_DEF_INHNO] = {")
379 $cfgData[:DEF_INH].each_with_index do |(key, params), index|
380 $kernelCfgC.add(",") if index > 0
381 if (params[:inhatr] & $TA_NONKERNEL) == 0
382 inthdr = "(FP)(INT_ENTRY(#{params[:inhno]}, #{params[:inthdr]}))"
383 else
384 inthdr = "(FP)(#{params[:inthdr]})"
385 end
386 $kernelCfgC.append("\t{ (#{params[:inhno]}), (#{params[:inhatr]}), " \
387 "#{inthdr} }")
388 end
389 $kernelCfgC.add
390 $kernelCfgC.add2("};")
391 else
392 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INHINIB, " \
393 "_kernel_inhinib_table);")
394 end
395end
396
397#
398# 割込み要求ラインのための標準的な初期化情報の生成
399#
400if !$OMIT_INITIALIZE_INTERRUPT || $USE_INTINIB_TABLE
401 #
402 # 設定する割込み要求ラインの数
403 #
404 $kernelCfgC.add(<<EOS)
405#define TNUM_CFG_INTNO #{$cfgData[:CFG_INT].size}
406const uint_t _kernel_tnum_cfg_intno = TNUM_CFG_INTNO;
407EOS
408
409 #
410 # 割込み要求ライン初期化ブロック
411 #
412 if $cfgData[:CFG_INT].size != 0
413 $kernelCfgC.add("const INTINIB _kernel_intinib_table[TNUM_CFG_INTNO] = {")
414 $cfgData[:CFG_INT].each_with_index do |(key, params), index|
415 $kernelCfgC.add(",") if index > 0
416 $kernelCfgC.append("\t{ (#{params[:intno]}), (#{params[:intatr]}), " \
417 "(#{params[:intpri]}) }")
418 end
419 $kernelCfgC.add
420 $kernelCfgC.add2("};")
421 else
422 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INTINIB, " \
423 "_kernel_intinib_table);")
424 end
425end
426
427#
428# 割込み管理機能初期化関数の追加
429#
430$initializeFunctions.push("_kernel_initialize_interrupt();")
Note: See TracBrowser for help on using the repository browser.