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

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

mruby版ECNLプロトタイピング・ツールを追加

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