source: asp_wo_cfg/trunk/kernel/interrupt.c@ 52

Last change on this file since 52 was 52, checked in by ertl-hiro, 12 years ago

att_isrにもターゲット依存のエラーチェック処理を追加。

  • Property svn:keywords set to Id
File size: 10.6 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2012 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: interrupt.c 52 2012-09-07 06:34:34Z ertl-hiro $
41 */
42
43/*
44 * 割込み管理機能
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "interrupt.h"
51
52/*
53 * トレースログマクロのデフォルト定義
54 */
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 */
62
63#ifndef LOG_CFG_INT_ENTER
64#define LOG_CFG_INT_ENTER(intno, pk_cint)
65#endif /* LOG_CFG_INT_ENTER */
66
67#ifndef LOG_CFG_INT_LEAVE
68#define LOG_CFG_INT_LEAVE(ercd)
69#endif /* LOG_CFG_INT_LEAVE */
70
71#ifndef LOG_ATT_ISR_ENTER
72#define LOG_ATT_ISR_ENTER(pk_cisr)
73#endif /* LOG_ATT_ISR_ENTER */
74
75#ifndef LOG_ATT_ISR_LEAVE
76#define LOG_ATT_ISR_LEAVE(ercd)
77#endif /* LOG_ATT_ISR_LEAVE */
78
79#ifndef LOG_DEF_INH_ENTER
80#define LOG_DEF_INH_ENTER(inhno, pk_dinh)
81#endif /* LOG_DEF_INH_ENTER */
82
83#ifndef LOG_DEF_INH_LEAVE
84#define LOG_DEF_INH_LEAVE(ercd)
85#endif /* LOG_DEF_INH_LEAVE */
86
87#ifndef LOG_DIS_INT_ENTER
88#define LOG_DIS_INT_ENTER(intno)
89#endif /* LOG_DIS_INT_ENTER */
90
91#ifndef LOG_DIS_INT_LEAVE
92#define LOG_DIS_INT_LEAVE(ercd)
93#endif /* LOG_DIS_INT_LEAVE */
94
95#ifndef LOG_ENA_INT_ENTER
96#define LOG_ENA_INT_ENTER(intno)
97#endif /* LOG_ENA_INT_ENTER */
98
99#ifndef LOG_ENA_INT_LEAVE
100#define LOG_ENA_INT_LEAVE(ercd)
101#endif /* LOG_ENA_INT_LEAVE */
102
103#ifndef LOG_CHG_IPM_ENTER
104#define LOG_CHG_IPM_ENTER(intpri)
105#endif /* LOG_CHG_IPM_ENTER */
106
107#ifndef LOG_CHG_IPM_LEAVE
108#define LOG_CHG_IPM_LEAVE(ercd)
109#endif /* LOG_CHG_IPM_LEAVE */
110
111#ifndef LOG_GET_IPM_ENTER
112#define LOG_GET_IPM_ENTER(p_intpri)
113#endif /* LOG_GET_IPM_ENTER */
114
115#ifndef LOG_GET_IPM_LEAVE
116#define LOG_GET_IPM_LEAVE(ercd, intpri)
117#endif /* LOG_GET_IPM_LEAVE */
118
119/*
120 * 割込みサービスルーチンの数
121 */
122#define tnum_isr ((uint_t)(tmax_isrid - TMIN_SEMID + 1))
123
124/*
125 * 割込みサービスルーチンキューへの登録
126 */
127Inline void
128enqueue_isr(QUEUE *p_isr_queue, ISRCB *p_isrcb)
129{
130 QUEUE *p_entry;
131 PRI isrpri = p_isrcb->p_isrinib->isrpri;
132
133 for (p_entry = p_isr_queue->p_next; p_entry != p_isr_queue;
134 p_entry = p_entry->p_next) {
135 if (isrpri < ((ISRCB *) p_entry)->p_isrinib->isrpri) {
136 break;
137 }
138 }
139 queue_insert_prev(p_entry, &(p_isrcb->isr_queue));
140}
141
142#ifdef TOPPERS_isrini
143
144/*
145 * 割込みサービスルーチンキューのエリア
146 */
147QUEUE isr_queue_table[TNUM_INTNO];
148
149/*
150 * 使用していない割込みサービスルーチン管理ブロックのリスト
151 */
152QUEUE free_isrcb;
153
154/*
155 * 割込みサービスルーチン機能の初期化
156 */
157void
158initialize_isr(void)
159{
160 uint_t i;
161 ISRCB *p_isrcb;
162 ISRINIB *p_isrinib;
163
164 for (i = 0; i < TNUM_INTNO; i++) {
165 queue_initialize(&(isr_queue_table[i]));
166 }
167 queue_initialize(&free_isrcb);
168 for (i = 0; i < tnum_isr; i++) {
169 p_isrcb = &(isrcb_table[i]);
170 p_isrinib = &(isrinib_table[i]);
171 p_isrinib->isratr = TA_NOEXS;
172 p_isrcb->p_isrinib = ((const ISRINIB *) p_isrinib);
173 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
174 }
175}
176
177#endif /* TOPPERS_isrini */
178
179/*
180 * 割込みサービスルーチンの呼出し
181 */
182#ifdef TOPPERS_isrcal
183
184void
185inthdr_call_isr(INTNO intno)
186{
187 QUEUE *p_isr_queue, *p_queue;
188 ISRINIB *p_isrinib;
189 PRI saved_ipm;
190
191 i_begin_int(intno);
192 saved_ipm = i_get_ipm();
193 p_isr_queue = &isr_queue_table[INDEX_INTNO(intno)];
194 for (p_queue = p_isr_queue->p_next; p_queue != p_isr_queue;
195 p_queue = p_queue->p_next) {
196 p_isrinib = (ISRINIB *)(((ISRCB *) p_queue)->p_isrinib);
197 LOG_ISR_ENTER(p_isrinib->intno);
198 (*(p_isrinib->isr))(p_isrinib->exinf);
199 LOG_ISR_LEAVE(p_isrinib->intno);
200
201 if (p_queue->p_next != p_isr_queue) {
202 /* ISRの呼出し前の状態に戻す */
203 if (i_sense_lock()) {
204 i_unlock_cpu();
205 }
206 i_set_ipm(saved_ipm);
207 }
208 }
209 i_end_int(intno);
210}
211
212#endif /* TOPPERS_isrcal */
213
214/*
215 * 割込みサービスルーチンの生成
216 */
217#ifdef TOPPERS_att_isr
218
219ER
220att_isr(const T_CISR *pk_cisr)
221{
222 ISRCB *p_isrcb;
223 ISRINIB *p_isrinib;
224 QUEUE *p_isr_queue;
225 INHINIB *p_inhinib;
226 ER ercd;
227
228 LOG_ATT_ISR_ENTER(pk_cisr);
229 CHECK_INIRTN();
230 CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR);
231 CHECK_INTNO_CREISR(pk_cisr->intno);
232 CHECK_ALIGN_FUNC(pk_cisr->isr);
233 CHECK_NONNULL_FUNC(pk_cisr->isr);
234 CHECK_ISRPRI(pk_cisr->isrpri);
235
236 p_inhinib = get_inhinib(INHNO_INTNO(pk_cisr->intno));
237 if (get_intinib(pk_cisr->intno)->intatr == TA_NOEXS
238 || (p_inhinib->inhatr != TA_NOEXS
239 && p_inhinib->inthdr != inthdr_call_isr)) {
240 ercd = E_OBJ;
241 }
242 else if (tnum_isr == 0 || queue_empty(&free_isrcb)) {
243 ercd = E_NOID;
244 }
245 if ((ercd = target_check_aisr(pk_cisr)) == E_OK) {
246 if (p_inhinib->inhatr == TA_NOEXS) {
247 p_inhinib->inhatr = TA_NULL;
248 p_inhinib->inthdr = inthdr_call_isr;
249 }
250 p_isr_queue = &isr_queue_table[INDEX_INTNO(pk_cisr->intno)];
251 p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
252 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
253 p_isrinib->isratr = pk_cisr->isratr;
254 p_isrinib->exinf = pk_cisr->exinf;
255 p_isrinib->intno = pk_cisr->intno;
256 p_isrinib->p_isr_queue = p_isr_queue;
257 p_isrinib->isr = pk_cisr->isr;
258 p_isrinib->isrpri = pk_cisr->isrpri;
259 enqueue_isr(p_isr_queue, p_isrcb);
260 }
261
262 error_exit:
263 LOG_ATT_ISR_LEAVE(ercd);
264 return(ercd);
265}
266
267#endif /* TOPPERS_att_isr */
268
269#ifdef TOPPERS_intini
270
271/*
272 * 割込みハンドラ初期化ブロックのエリア
273 */
274INHINIB inhinib_table[TNUM_INHNO];
275
276/*
277 * 割込み要求ライン初期化ブロックのエリア
278 */
279INTINIB intinib_table[TNUM_INTNO];
280
281/*
282 * 割込み管理機能の初期化
283 */
284void
285initialize_interrupt(void)
286{
287 uint_t i;
288
289 for (i = 0; i < TNUM_INHNO; i++) {
290 inhinib_table[i].inhatr = TA_NOEXS;
291 }
292 for (i = 0; i < TNUM_INTNO; i++) {
293 intinib_table[i].intatr = TA_NOEXS;
294 }
295}
296
297#endif /* TOPPERS_intini */
298
299/*
300 * 割込み要求ラインの属性の設定
301 */
302#ifdef TOPPERS_cfg_int
303
304ER
305cfg_int(INTNO intno, const T_CINT *pk_cint)
306{
307 INTINIB *p_intinib;
308 ER ercd;
309
310 LOG_CFG_INT_ENTER(intno, pk_cint);
311 CHECK_INIRTN();
312 CHECK_PAR(VALID_INTNO_CFGINT(intno));
313 CHECK_RSATR(pk_cint->intatr, TA_ENAINT|TA_EDGE|TARGET_INTATR);
314 CHECK_PAR(VALID_INTPRI_CFGINT(pk_cint->intpri));
315 p_intinib = get_intinib(intno);
316
317 if ((ercd = target_check_cint(intno, pk_cint)) == E_OK) {
318 p_intinib->intatr = pk_cint->intatr;
319 p_intinib->intpri = pk_cint->intpri;
320 }
321
322 error_exit:
323 LOG_CFG_INT_LEAVE(ercd);
324 return(ercd);
325}
326
327#endif /* TOPPERS_cfg_int */
328
329/*
330 * 割込みハンドラの定義
331 */
332#ifdef TOPPERS_def_inh
333
334ER
335def_inh(INHNO inhno, const T_DINH *pk_dinh)
336{
337 INHINIB *p_inhinib;
338 ER ercd;
339
340 LOG_DEF_INH_ENTER(inhno, pk_dinh);
341 CHECK_INIRTN();
342 CHECK_PAR(VALID_INHNO_DEFINH(inhno));
343 CHECK_RSATR(pk_dinh->inhatr, TARGET_INHATR);
344 CHECK_NOSPT(pk_dinh->inthdr != NULL);
345 CHECK_ALIGN_FUNC(pk_dinh->inthdr);
346 CHECK_NONNULL_FUNC(pk_dinh->inthdr);
347 p_inhinib = get_inhinib(inhno);
348
349 if (get_intinib(INTNO_INHNO(inhno))->intatr == TA_NOEXS
350 || p_inhinib->inhatr != TA_NOEXS) {
351 ercd = E_OBJ;
352 }
353 else if ((ercd = target_check_dinh(inhno, pk_dinh)) == E_OK) {
354 p_inhinib->inhatr = pk_dinh->inhatr;
355 p_inhinib->inthdr = (IINTHDR)(pk_dinh->inthdr);
356 }
357
358 error_exit:
359 LOG_DEF_INH_LEAVE(ercd);
360 return(ercd);
361}
362
363#endif /* TOPPERS_def_inh */
364
365/*
366 * 割込みの禁止
367 */
368#ifdef TOPPERS_dis_int
369#ifdef TOPPERS_SUPPORT_DIS_INT
370
371ER
372dis_int(INTNO intno)
373{
374 bool_t locked;
375 ER ercd;
376
377 LOG_DIS_INT_ENTER(intno);
378 CHECK_TSKCTX();
379 CHECK_INTNO_DISINT(intno);
380
381 locked = t_sense_lock();
382 if (!locked) {
383 t_lock_cpu();
384 }
385 if (t_disable_int(intno)) {
386 ercd = E_OK;
387 }
388 else {
389 ercd = E_OBJ;
390 }
391 if (!locked) {
392 t_unlock_cpu();
393 }
394
395 error_exit:
396 LOG_DIS_INT_LEAVE(ercd);
397 return(ercd);
398}
399
400#endif /* TOPPERS_SUPPORT_DIS_INT */
401#endif /* TOPPERS_dis_int */
402
403/*
404 * 割込みの許可
405 */
406#ifdef TOPPERS_ena_int
407#ifdef TOPPERS_SUPPORT_ENA_INT
408
409ER
410ena_int(INTNO intno)
411{
412 bool_t locked;
413 ER ercd;
414
415 LOG_ENA_INT_ENTER(intno);
416 CHECK_TSKCTX();
417 CHECK_INTNO_DISINT(intno);
418
419 locked = t_sense_lock();
420 if (!locked) {
421 t_lock_cpu();
422 }
423 if (t_enable_int(intno)) {
424 ercd = E_OK;
425 }
426 else {
427 ercd = E_OBJ;
428 }
429 if (!locked) {
430 t_unlock_cpu();
431 }
432
433 error_exit:
434 LOG_ENA_INT_LEAVE(ercd);
435 return(ercd);
436}
437
438#endif /* TOPPERS_SUPPORT_ENA_INT */
439#endif /* TOPPERS_ena_int */
440
441/*
442 * 割込み優先度マスクの変更
443 */
444#ifdef TOPPERS_chg_ipm
445
446ER
447chg_ipm(PRI intpri)
448{
449 ER ercd;
450
451 LOG_CHG_IPM_ENTER(intpri);
452 CHECK_TSKCTX_UNL();
453 CHECK_INTPRI_CHGIPM(intpri);
454
455 t_lock_cpu();
456 t_set_ipm(intpri);
457 if (intpri == TIPM_ENAALL) {
458 ipmflg = true;
459 if (!disdsp) {
460 dspflg = true;
461 if (p_runtsk != p_schedtsk) {
462 dispatch();
463 }
464 }
465 if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
466 call_texrtn();
467 }
468 }
469 else {
470 ipmflg = false;
471 dspflg = false;
472 }
473 ercd = E_OK;
474 t_unlock_cpu();
475
476 error_exit:
477 LOG_CHG_IPM_LEAVE(ercd);
478 return(ercd);
479}
480
481#endif /* TOPPERS_chg_ipm */
482
483/*
484 * 割込み優先度マスクの参照
485 */
486#ifdef TOPPERS_get_ipm
487
488ER
489get_ipm(PRI *p_intpri)
490{
491 ER ercd;
492
493 LOG_GET_IPM_ENTER(p_intpri);
494 CHECK_TSKCTX_UNL();
495
496 t_lock_cpu();
497 *p_intpri = t_get_ipm();
498 ercd = E_OK;
499 t_unlock_cpu();
500
501 error_exit:
502 LOG_GET_IPM_LEAVE(ercd, *p_intpri);
503 return(ercd);
504}
505
506#endif /* TOPPERS_get_ipm */
Note: See TracBrowser for help on using the repository browser.