source: rubycfg_ssp/trunk/interrupt.trb@ 285

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

Tracのソース閲覧時に文字化けするためmimetypewo

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