source: rubycfg_ssp/trunk/interrupt.trb@ 284

Last change on this file since 284 was 284, checked in by nmir-saito, 6 years ago

trunkディレクトリの作成及びファイルの移動

File size: 15.0 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TOPPERS/SSP 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# Copyright (C) 2017 by Naoki Saito
11# Nagoya Municipal Industrial Research Institute, JAPAN
12#
13# 上記著作権者
14は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
15# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
16# 変・再é…
17å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
18# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
19# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
20# スコード中に含まれていること.
21# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
22# 用できる形で再é…
23å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
24å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
25# 者
26マニュアルなど)に,上記の著作権表示,この利用条件および下記
27# の無保証規定を掲載すること.
28# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
29# 用できない形で再é…
30å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
31# と.
32# (a) 再é…
33å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
34マニュアルなど)に,上記の著
35# 作権表示,この利用条件および下記の無保証規定を掲載すること.
36# (b) 再é…
37å¸ƒã®å½¢æ…
38‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
39# 報告すること.
40# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
41# 害からも,上記著作権者
42およびTOPPERSプロジェクトをå…
43è²¬ã™ã‚‹ã“と.
44# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
45# 由に基づく請求からも,上記著作権者
46およびTOPPERSプロジェクトを
47# å…
48è²¬ã™ã‚‹ã“と.
49#
50# 本ソフトウェアは,無保証で提供されているものである.上記著作権者
51お
52# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
53# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
54# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
55# の責任を負わない.
56#
57# $Id: interrupt.trb 678 2016-03-06 02:36:09Z ertl-hiro $
58#
59
60#
61# 割込み管理機能の生成スクリプト
62#
63
64$kernelCfgC.comment_header("Interrupt Management Functions")
65
66#
67# トレースログマクロのデフォルト定義
68#
69$kernelCfgC.add(<<EOS)
70#ifndef LOG_ISR_ENTER
71#define LOG_ISR_ENTER(intno)
72#endif /* LOG_ISR_ENTER */
73
74#ifndef LOG_ISR_LEAVE
75#define LOG_ISR_LEAVE(intno)
76#endif /* LOG_ISR_LEAVE */
77EOS
78
79#
80# CRE_ISRで使用できる割込み番号とそれに対応する割込みハンドラ番号のデ
81# フォルト定義
82#
83if $INTNO_CREISR_VALID.nil?
84 $INTNO_CREISR_VALID = $INTNO_VALID
85end
86if $INHNO_CREISR_VALID.nil?
87 $INHNO_CREISR_VALID = $INHNO_VALID
88end
89
90#
91# CFG_INTで使用できる割込み優å…
92ˆåº¦ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå®šç¾©
93#
94if $INTPRI_CFGINT_VALID.nil?
95 $INTPRI_CFGINT_VALID = $TMIN_INTPRI.upto($TMAX_INTPRI).to_a
96end
97
98#
99# 割込み番号と割込みハンドラ番号の変換テーブルの作成
100#
101if $INTNO_CREISR_VALID.length != $INHNO_CREISR_VALID.length
102 error_exit("length of `INTNO_CREISR_VALID' is different from" \
103 " length of `INHNO_CREISR_VALID'")
104end
105$toInhnoVal = {}
106$toIntnoVal = {}
107inhno_creisr_valid = $INHNO_CREISR_VALID.dup
108$INTNO_CREISR_VALID.each do |intnoVal|
109 inhnoVal = inhno_creisr_valid.shift
110 $toInhnoVal[intnoVal] = inhnoVal
111 $toIntnoVal[inhnoVal] = intnoVal
112end
113
114#
115# 割込み要求ラインに関するエラーチェック
116#
117$cfgData[:CFG_INT].each do |key, params|
118 # intnoが割込み番号として正しくない場合(E_PAR)
119 if $INTNO_VALID.index(params[:intno]).nil?
120 error_illegal("E_PAR", params, :intno)
121 end
122
123 # intatrが無効の場合(E_RSATR)
124 #(TA_ENAINT,TA_EDGE,TARGET_INTATR以外のビットがセットされている場合)
125 if (params[:intatr] & ~($TA_ENAINT|$TA_EDGE|$TARGET_INTATR)) != 0
126 error_illegal_sym("E_RSATR", params, :intatr, :intno)
127 end
128
129 # intpriがCFG_INTに対する割込み優å…
130ˆåº¦ã¨ã—て正しくない場合(E_PAR)
131 if $INTPRI_CFGINT_VALID.index(params[:intpri]).nil?
132 error_illegal_sym("E_PAR", params, :intpri, :intno)
133 end
134
135 # カーネル管理外に固定されているintnoに対して,intpriにTMIN_INTPRIよ
136 # りも小さい値が指定されなかった場合(E_OBJ)
137 if !$INTNO_FIX_NONKERNEL.nil?
138 if !$INTNO_FIX_NONKERNEL.index(params[:intno]).nil?
139 if params[:intpri] >= $TMIN_INTPRI
140 error_ercd("E_OBJ", params, "%%intno must have higher priority " \
141 "than TMIN_INTPRI in %apiname")
142 end
143 end
144 end
145
146 # カーネル管理に固定されているintnoに対して,intpriにTMIN_INTPRIより
147 # も小さい値が指定された場合(E_OBJ)
148 if !$INTNO_FIX_KERNEL.nil?
149 if !$INTNO_FIX_KERNEL.index(params[:intno]).nil?
150 if params[:intpri] < $TMIN_INTPRI
151 error_ercd("E_OBJ", params, "%%intno must have lower or equal " \
152 "priority to TMIN_INTPRI in %apiname")
153 end
154 end
155 end
156end
157
158#
159# 割込みハンドラに関するエラーチェック
160#
161$cfgData[:DEF_INH].each do |key, params|
162 # inhnoが割込みハンドラ番号として正しくない場合(E_PAR)
163 if $INHNO_VALID.index(params[:inhno]).nil?
164 error_illegal("E_PAR", params, :inhno)
165 end
166
167 # inhatrが無効の場合(E_RSATR)
168 #(TARGET_INHATR以外のビットがセットされている場合)
169 if (params[:inhatr] & ~($TARGET_INHATR)) != 0
170 error_illegal_sym("E_RSATR", params, :inhatr, :inhno)
171 end
172
173 # カーネル管理外に固定されているinhnoに対して,inhatrにTA_NONKERNELが
174 # 指定されていない場合(E_RSATR)
175 if !$INHNO_FIX_NONKERNEL.nil?
176 if !$INHNO_FIX_NONKERNEL.index(params[:inhno]).nil?
177 if (params[:inhatr] & $TA_NONKERNEL) == 0
178 error_ercd("E_RSATR", params, "%%inhno must be " \
179 "non-kernel interrupt in %apiname")
180 end
181 end
182 end
183
184 # カーネル管理に固定されているinhnoに対して,inhatrにTA_NONKERNELが指
185 # 定されている場合(E_RSATR)
186 if !$INHNO_FIX_KERNEL.nil?
187 if !$INHNO_FIX_KERNEL.index(params[:inhno]).nil?
188 if (params[:inhatr] & $TA_NONKERNEL) != 0
189 error_ercd("E_RSATR", params, "%%inhno must not be " \
190 "non-kernel interrupt in %apiname")
191 end
192 end
193 end
194
195 if $toIntnoVal.has_key?(params[:inhno].val)
196 intnoVal = $toIntnoVal[params[:inhno].val]
197
198 # inhnoに対応するintnoに対するCFG_INTがない場合(E_OBJ)
199 if !$cfgData[:CFG_INT].has_key?(intnoVal)
200 error_ercd("E_OBJ", params, "intno `#{intnoVal}' corresponding to " \
201 "%%inhno in %apiname is not configured with CFG_INT")
202 else
203 intnoParams = $cfgData[:CFG_INT][intnoVal]
204 if (params[:inhatr] & $TA_NONKERNEL) == 0
205 # inhatrにTA_NONKERNELが指定されておらず,inhnoに対応するintno
206 # に対してCFG_INTで設定された割込み優å…
207ˆåº¦ãŒTMIN_INTPRIよりも小
208 # さい場合(E_OBJ)
209 if intnoParams[:intpri] < $TMIN_INTPRI
210 error_ercd("E_OBJ", params, "intpri `#{intnoParams[:intpri]}' " \
211 "configured for %%inhno must be lower or equal to TMIN_INTPRI")
212 end
213 else
214 # inhatrにTA_NONKERNELが指定されており,inhnoに対応するintnoに
215 # 対してCFG_INTで設定された割込み優å…
216ˆåº¦ãŒTMIN_INTPRI以上である
217 # 場合(E_OBJ)
218 if intnoParams[:intpri] >= $TMIN_INTPRI
219 error_ercd("E_OBJ", params, "intpri `#{intnoParams[:intpri]}' " \
220 "configured for %%inhno must be higher than TMIN_INTPRI")
221 end
222 end
223 end
224 end
225end
226
227#
228# 割込みサービスルーチン(ISR)に関するエラーチェックと割込みハンドラの生成
229#
230$cfgData[:ATT_ISR].sort.each do |key, params|
231 # isratrが無効の場合(E_RSATR)
232 #(TARGET_ISRATR以外のビットがセットされている場合)
233 if (params[:isratr] & ~($TARGET_ISRATR)) != 0
234 error_illegal("E_RSATR", params, "isratr")
235 end
236
237 # intnoがATT_ISRに対する割込み番号として正しくない場合(E_PAR)
238 if $INTNO_ATTISR_VALID.index(params[:intno]).nil?
239 error_illegal("E_PAR", params, "intno")
240 end
241
242 # (TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合(E_PAR)
243 if !($TMIN_ISRPRI <= params[:isrpri] && params[:isrpri] <= $TMAX_ISRPRI)
244 error_illegal("E_PAR", params, "isrpri")
245 end
246end
247
248$INTNO_ATTISR_VALID.each do |intnoVal|
249 # 割込み番号intnoに対して登録されたISRのリストの作成
250 isrParamsList = []
251 $cfgData[:ATT_ISR].sort.each do |key, params|
252 if params[:intno] == intnoVal
253 isrParamsList.push(params)
254 end
255 end
256
257 # 割込み番号intnoに対して登録されたISRが存在する場合
258 if isrParamsList.size > 0
259 inhnoVal = $toInhnoVal[intnoVal]
260
261 # intnoに対応するinhnoに対してDEF_INHがある場合(E_OBJ)
262 if $cfgData[:DEF_INH].has_key?(inhnoVal)
263 inhnoParams = $cfgData[:DEF_INH][inhnoVal]
264 error_ercd("E_OBJ", isrParamsList[0], "%%intno in %apiname " \
265 "is duplicated with inhno #{inhnoParams[:inhno]}")
266 end
267
268 # intnoに対するCFG_INTがない場合(E_OBJ)
269 if !$cfgData[:CFG_INT].has_key?(intnoVal)
270 error_ercd("E_OBJ", isrParamsList[0], "%%intno in %apiname " \
271 "is not configured with CFG_INT")
272 else
273 intnoParams = $cfgData[:CFG_INT][intnoVal]
274
275 # intnoに対してCFG_INTで設定された割込み優å…
276ˆåº¦ãŒTMIN_INTPRIよりも
277 # 小さい場合(E_OBJ)
278 if intnoParams[:intpri] < $TMIN_INTPRI
279 error_ercd("E_OBJ", isrParamsList[0],
280 "intpri `#{intnoParams[:intpri]}' configured for " \
281 "%%intno with CFG_INT in higher than TMIN_INTPRI")
282 end
283 end
284
285 # 次のDEF_INHに相当するデータを生成
286 # DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
287 $cfgData[:DEF_INH][inhnoVal] = {
288 inhno: NumStr.new(inhnoVal),
289 inhatr: NumStr.new($TA_NULL, "TA_NULL"),
290 inthdr: "_kernel_inthdr_#{intnoVal}"
291 }
292
293 # 割込みサービスルーチン用の割込みハンドラ
294 $kernelCfgC.add("void")
295 $kernelCfgC.add("_kernel_inthdr_#{intnoVal}(void)")
296 $kernelCfgC.add("{")
297
298 if isrParamsList.size > 1
299 $kernelCfgC.add("\tPRI saved_ipm;")
300 $kernelCfgC.add
301 $kernelCfgC.add("\ti_begin_int(#{intnoVal});")
302 $kernelCfgC.add("\tsaved_ipm = i_get_ipm();")
303 else
304 $kernelCfgC.add("\ti_begin_int(#{intnoVal});")
305 end
306
307 # 割込みサービスルーチンを優å…
308ˆåº¦é †ã«å‘¼ã³å‡ºã™
309 i = 0 # stable sortを行うための変数
310 isrParamsList.sort_by {|params| [ params[:isrpri].val, i += 1 ]} \
311 .each_with_index do |params, index|
312 if index > 0
313 $kernelCfgC.add
314 $kernelCfgC.add("\tif (i_sense_lock()) {")
315 $kernelCfgC.add("\t\ti_unlock_cpu();")
316 $kernelCfgC.add2("\t}")
317 $kernelCfgC.add("\ti_set_ipm(saved_ipm);")
318 end
319 $kernelCfgC.add("\tLOG_ISR_ENTER(#{intnoVal});")
320 $kernelCfgC.add("\t((ISR)(#{params[:isr]}))" \
321 "((intptr_t)(#{params[:exinf]}));")
322 $kernelCfgC.add("\tLOG_ISR_LEAVE(#{intnoVal});")
323 end
324 $kernelCfgC.add("\ti_end_int(#{intnoVal});")
325 $kernelCfgC.add2("}")
326 end
327end
328
329#
330# 割込みハンドラのための標準的な初期化情
331報の生成
332#
333if !$OMIT_INITIALIZE_INTERRUPT || $USE_INHINIB_TABLE
334 #
335 # 定義する割込みハンドラの数
336 #
337 $kernelCfgC.add(<<EOS)
338#define TNUM_INHNO #{$cfgData[:DEF_INH].size}
339const uint_t _kernel_tnum_inhno = TNUM_INHNO;
340EOS
341
342 if $cfgData[:DEF_INH].size != 0
343 #
344 # 割込みハンドラのエントリ
345 #
346 $cfgData[:DEF_INH].each do |key, params|
347 $kernelCfgC.add("INTHDR_ENTRY(#{params[:inhno]}, " \
348 "#{params[:inhno].val}, #{params[:inthdr]})")
349 end
350 $kernelCfgC.add("")
351
352 #
353 # 割込みハンドラ初期化ブロック
354 #
355 $kernelCfgC.append("const INHNO\t_kernel_inhinib_inhno[TNUM_INHNO] = {")
356 $cfgData[:DEF_INH].each.with_index do |(key, params), index|
357 $kernelCfgC.append(",") if index > 0
358 $kernelCfgC.append("(#{params[:inhno]})")
359 end
360 $kernelCfgC.add("};")
361
362 $kernelCfgC.append("const ATR\t_kernel_inhinib_inhatr[TNUM_INHNO] = {")
363 $cfgData[:DEF_INH].each.with_index do |(key, params), index|
364 $kernelCfgC.append(",") if index > 0
365 $kernelCfgC.append("(#{params[:inhatr]})")
366 end
367 $kernelCfgC.add("};")
368
369 $kernelCfgC.append("const FP\t_kernel_inhinib_entry[TNUM_INHNO] = {")
370 $cfgData[:DEF_INH].each.with_index do |(key, params), index|
371 $kernelCfgC.append(",") if index > 0
372 $kernelCfgC.append("(FP)(INT_ENTRY(#{params[:inhno]}, #{params[:inthdr]}))")
373 end
374 $kernelCfgC.add2("};")
375 else
376 $kernelCfgC.add("TOPPERS_EMPTY_LABEL(const INHNO, _kernel_inhinib_inhno);")
377 $kernelCfgC.add("TOPPERS_EMPTY_LABEL(const ATR, _kernel_inhinib_inhatr);")
378 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const FP, _kernel_inhinib_entry);")
379 end
380end
381
382#
383# 割込み要求ラインのための標準的な初期化情
384報の生成
385#
386if !$OMIT_INITIALIZE_INTERRUPT || $USE_INTINIB_TABLE
387
388 #
389 # 設定する割込み要求ラインの数
390 #
391 $kernelCfgC.add(<<EOS)
392#define TNUM_INTNO #{$cfgData[:CFG_INT].size}
393const uint_t _kernel_tnum_intno = TNUM_INTNO;
394EOS
395
396 #
397 # 割込み要求ライン初期化ブロック
398 #
399 if $cfgData[:CFG_INT].size != 0
400 $kernelCfgC.append("const INTNO _kernel_intinib_intno[TNUM_INTNO] = {")
401 $cfgData[:CFG_INT].each_with_index do |(key, params), index|
402 $kernelCfgC.append(",") if index > 0
403 $kernelCfgC.append("(#{params[:intno]})")
404 end
405 $kernelCfgC.add("};")
406
407 $kernelCfgC.append("const ATR _kernel_intinib_intatr[TNUM_INTNO] = {")
408 $cfgData[:CFG_INT].each_with_index do |(key, params), index|
409 $kernelCfgC.append(",") if index > 0
410 $kernelCfgC.append("(#{params[:intatr]})")
411 end
412 $kernelCfgC.add("};")
413
414 $kernelCfgC.append("const PRI _kernel_intinib_intpri[TNUM_INTNO] = {")
415 $cfgData[:CFG_INT].each_with_index do |(key, params), index|
416 $kernelCfgC.append(",") if index > 0
417 $kernelCfgC.append("(#{params[:intpri]})")
418 end
419 $kernelCfgC.add2("};")
420
421 else
422 $kernelCfgC.add("TOPPERS_EMPTY_LABEL(const INTNO, _kernel_intinib_intno);")
423 $kernelCfgC.add("TOPPERS_EMPTY_LABEL(const ATR, _kernel_intinib_intatr);")
424 $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const PRI, _kernel_intinib_intpri);")
425 end
426end
427
428#
429# 割込み管理機能初期化関数の追加
430#
431$initializeFunctions.push("_kernel_initialize_interrupt();")
Note: See TracBrowser for help on using the repository browser.