source: rubycfg_asp/trunk/asp_dcre/kernel/interrupt.trb@ 313

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

ソースを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 17.7 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# ATT_ISRで使用できる割込み番号とそれに対応する割込みハンドラ番号のデ
69# フォルト定義
70#
71if $INTNO_ATTISR_VALID.nil?
72 $INTNO_ATTISR_VALID = $INTNO_VALID
73end
74if $INHNO_ATTISR_VALID.nil?
75 $INHNO_ATTISR_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_ATTISR_VALID.length != $INHNO_ATTISR_VALID.length
90 error_exit("length of `INTNO_ATTISR_VALID' is different from" \
91 " length of `INHNO_ATTISR_VALID'")
92end
93$toInhnoVal = {}
94$toIntnoVal = {}
95inhno_attisr_valid = $INHNO_ATTISR_VALID.dup
96$INTNO_ATTISR_VALID.each do |intnoVal|
97 inhnoVal = inhno_attisr_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[:ATT_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がATT_ISRに対する割込み番号として正しくない場合(E_PAR)
227 # ï¼»NGKI3003ï¼½
228 if $INTNO_ATTISR_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_ATTISR_VALID.each do |intnoVal|
240 # 割込み番号intnoに対して登録されたISRのリストの作成
241 isrParamsList = []
242 $cfgData[:ATT_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_ATTISR_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("\ti_begin_int(#{intnoVal});")
333 $kernelCfgC.add("\t_kernel_call_isr(#{$isrQueueHeader[intnoVal]});");
334 $kernelCfgC.add("\ti_end_int(#{intnoVal});")
335 $kernelCfgC.add2("}")
336end
337
338#
339# 割込みサービスルーチンに関する一般的な情
340報の生成
341#
342class IsrObject
343 def initialize()
344 @inibList = { "ISRINIB" => "aisrinib_table"}
345 end
346
347 def generate()
348 # AID_ISRの処理
349 numAutoObjid = 0
350 $cfgData[:AID_ISR].each do |key, params|
351 numAutoObjid += params["noisr".to_sym]
352 end
353 numObjid = $cfgData[:ATT_ISR].size + numAutoObjid
354
355 # kernel_cfg.hの生成
356 $kernelCfgH.add("#define TNUM_ISRID\t#{numAutoObjid}")
357
358 # オブジェクトのID番号のマクロ定義の生成
359 $cfgData[:ATT_ISR].sort.each do |key, params|
360 if params[:isrid]
361 $kernelCfgH.add("#define #{params[:isrid]}\t#{params[:isrid].val}")
362 end
363 end
364 $kernelCfgH.add()
365
366 # オブジェクトのID番号を保持する変数
367 if $USE_EXTERNAL_ID
368 $cfgData[:ATT_ISR].sort.each do |key, params|
369 if params[:isrid]
370 $kernelCfgC.add("const ID #{params[:isrid]}_id" \
371 " = #{params[:isrid].val};")
372 end
373 end
374 $kernelCfgC.add()
375 end
376
377 # 静的に生成されたオブジェクトの数
378 $kernelCfgC.add("#define TNUM_SISR\t#{$cfgData[:ATT_ISR].size}")
379 $kernelCfgC.add("#define TNUM_ISR\t#{numObjid}")
380
381 # オブジェクトID番号の最大値
382 $kernelCfgC.add("const ID _kernel_tmax_isrid" \
383 " = (TMIN_ISRID + TNUM_ISRID - 1);")
384 $kernelCfgC.add("const uint_t _kernel_tnum_sisr = TNUM_SISR;")
385
386 # データ構造
387 if $cfgData[:ATT_ISR].size > 0
388 # 事前準備(エラーチェック,メモリ領域の生成)
389 $cfgData[:ATT_ISR].sort.each do |key, params|
390 prepare(key, params)
391 end
392
393 # オブジェクトå…
394¨ä½“に対して必
395要なメモリ領域の生成(オプション)
396 if respond_to?(:generateData)
397 generateData()
398 end
399
400 # オブジェクト初期化ブロックの生成
401 $kernelCfgC.add("const ISRINIB _kernel_sisrinib_table" \
402 "[TNUM_SISR] = {")
403 $cfgData[:ATT_ISR].sort.each_with_index do |(key, params), index|
404 $kernelCfgC.add(",") if index > 0
405 $kernelCfgC.append("\t{ " + generateInib(key, params) + " }")
406 end
407 $kernelCfgC.add
408 $kernelCfgC.add2("};")
409 else
410 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const ISRINIB, " \
411 "_kernel_sisrinib_table);")
412 end
413
414 # 動的生成オブジェクト用のオブジェクト初期化ブロック
415 @inibList.each do |type, array|
416 if numAutoObjid > 0
417 $kernelCfgC.add2("#{type} _kernel_#{array}[#{numAutoObjid}];")
418 else
419 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(#{type}, _kernel_#{array});")
420 end
421 end
422
423 if numObjid > 0
424 # オブジェクト管理ブロックの生成
425 $kernelCfgC.add2("ISRCB _kernel_isrcb_table" \
426 "[TNUM_ISR];")
427
428 # オブジェクト初期化関数の追加
429 $initializeFunctions.push("_kernel_initialize_isr();")
430 else
431 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(ISRCB, " \
432 "_kernel_isrcb_table);")
433 end
434 end
435
436 def prepare(key, params)
437 # エラーチェックは実施済みなので,ここでの処理は不要
438 end
439
440 def generateInib(key, params)
441 return("(#{params[:isratr]}), (intptr_t)(#{params[:exinf]}), " \
442 "(#{params[:intno]}), " \
443 "(#{$isrQueueHeader[params[:intno].val]}), " \
444 "(ISR)(#{params[:isr]}), (#{params[:isrpri]})")
445 end
446end
447IsrObject.new.generate()
448
449#
450# 割込みハンドラのための標準的な初期化情
451報の生成
452#
453if !$OMIT_INITIALIZE_INTERRUPT || $USE_INHINIB_TABLE
454 #
455 # 定義する割込みハンドラの数
456 #
457 $kernelCfgC.add(<<EOS)
458#define TNUM_INHNO #{$cfgData[:DEF_INH].size}
459const uint_t _kernel_tnum_inhno = TNUM_INHNO;
460EOS
461
462 if $cfgData[:DEF_INH].size != 0
463 #
464 # 割込みハンドラのエントリ
465 #
466 $cfgData[:DEF_INH].each do |key, params|
467 if (params[:inhatr] & $TA_NONKERNEL) == 0
468 $kernelCfgC.add("INTHDR_ENTRY(#{params[:inhno]}, " \
469 "#{params[:inhno].val}, #{params[:inthdr]})")
470 end
471 end
472 $kernelCfgC.add("")
473
474 #
475 # 割込みハンドラ初期化ブロック
476 #
477 $kernelCfgC.add("const INHINIB _kernel_inhinib_table[TNUM_INHNO] = {")
478 $cfgData[:DEF_INH].each_with_index do |(key, params), index|
479 $kernelCfgC.add(",") if index > 0
480 if (params[:inhatr] & $TA_NONKERNEL) == 0
481 inthdr = "(FP)(INT_ENTRY(#{params[:inhno]}, #{params[:inthdr]}))"
482 else
483 inthdr = "(FP)(#{params[:inthdr]})"
484 end
485 $kernelCfgC.append("\t{ (#{params[:inhno]}), (#{params[:inhatr]}), " \
486 "#{inthdr} }")
487 end
488 $kernelCfgC.add
489 $kernelCfgC.add2("};")
490 else
491 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INHINIB, " \
492 "_kernel_inhinib_table);")
493 end
494end
495
496#
497# 割込み要求ラインのための標準的な初期化情
498報の生成
499#
500if !$OMIT_INITIALIZE_INTERRUPT || $USE_INTINIB_TABLE
501 #
502 # 設定する割込み要求ラインの数
503 #
504 $kernelCfgC.add(<<EOS)
505#define TNUM_INTNO #{$cfgData[:CFG_INT].size}
506const uint_t _kernel_tnum_intno = TNUM_INTNO;
507EOS
508
509 #
510 # 割込み要求ライン初期化ブロック
511 #
512 if $cfgData[:CFG_INT].size != 0
513 $kernelCfgC.add("const INTINIB _kernel_intinib_table[TNUM_INTNO] = {")
514 $cfgData[:CFG_INT].each_with_index do |(key, params), index|
515 $kernelCfgC.add(",") if index > 0
516 $kernelCfgC.append("\t{ (#{params[:intno]}), (#{params[:intatr]}), " \
517 "(#{params[:intpri]}) }")
518 end
519 $kernelCfgC.add
520 $kernelCfgC.add2("};")
521 else
522 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INTINIB, " \
523 "_kernel_intinib_table);")
524 end
525end
526
527#
528# 割込み管理機能初期化関数の追加
529#
530$initializeFunctions.push("_kernel_initialize_interrupt();")
Note: See TracBrowser for help on using the repository browser.